2013-03-04 86 views
3

我正在使用Photoshop Connection SDK讓我的iPad應用程序連接到Photoshop。Photoshop SDK - 發送多個消息?

雖然我有工作,它很難爲我解決我的問題,因爲我不:

http://www.adobe.com/devnet/photoshop/sdk.html所有樣品的iOS項目的SDK可以,如果你想仔細看在這裏下載)完全理解iPad和Photoshop之間的聯網。因此,這裏是我的問題:

NSString *s1 = [NSString stringWithUTF8String:"app.activeDocument.layers[0].name;"]; 
NSData *dataToSend = [s1 dataUsingEncoding:NSUTF8StringEncoding]; 
[self sendJavaScriptMessage:dataToSend]; 
artLayerName_transaction = transaction_id -1; 

還有就是一小段代碼,在索引0的偉大工程,發送消息詢問圖層的名稱。但是,讓我們說,我試着發送相同的消息後,但索引1以及。

這兩個消息都被髮送,但只有一個返回它的字符串。字符串返回: - (void)流:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent;

如果您看到示例項目的內容相同,每個消息都有自己的事務ID。該方法經過了一堆解密和東西收到該字符串,然後達到此:

NSString *string = [[NSString alloc] initWithBytes:received_data length:received_length encoding:NSUTF8StringEncoding]; 
if (content != 1) 
{ 
    if (transaction == artLayerName_transaction) 
     { 
       [self processLayerName:string]; 
       needOutput = NO; 
     } 
} 

我已經走出底部全分析的全部方法。

它檢查它是否接收到特定的消息,以便我可以接收結果(字符串,我的圖層名稱)並按照我喜歡的方式進行操作。但是,當我嘗試使用相同的事務ID發送多個消息時,我只能得到兩個結果中的一個。在上面的代碼中,string給了我兩個圖層名稱,但if語句只被調用一次。

我不知道爲什麼,我希望你能幫上忙。有沒有一種方法可以一次發送幾條消息?我試圖得到一個數組而不是幾個字符串,但沒有運氣。

顯然我需要修改代碼以接受更多的消息。然而,我不太瞭解代碼,所以如果任何人都可以解釋任何背後的原則,它將非常感激。

希望你能幫忙,謝謝。

- (void)stream:(NSStream *)aStream handleEvent:(NSStreamEvent)streamEvent 
{ 
    NSInputStream * istream; 
    switch(streamEvent) 
    { 
     case NSStreamEventHasBytesAvailable:; 

      UInt8 buffer[1024]; 
      unsigned int actuallyRead = 0; 

      istream = (NSInputStream *)aStream; 
      if (!dataBuffer) 
      { 
       dataBuffer = [[NSMutableData alloc] initWithCapacity:2048]; 
      } 

      actuallyRead = [istream read:buffer maxLength:1024]; 

      [dataBuffer appendBytes:buffer length:actuallyRead]; 

      // see if we have enough to process, loop over messages in buffer 
      while(YES) 
      { 

       // Did we read the header yet? 
       if (packetBodySize == -1) 
       { 
        // Do we have enough bytes in the buffer to read the header? 
        if ([dataBuffer length] >= sizeof(int)) { 
         // extract length 
         memcpy(&packetBodySize, [dataBuffer bytes], sizeof(int)); 
         packetBodySize = ntohl(packetBodySize);  // size is in network byte order 

         // remove that chunk from buffer 
         NSRange rangeToDelete = {0, sizeof(int)}; 
         [dataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0]; 
        } 
        else { 
         // We don't have enough yet. Will wait for more data. 
         break; 
        } 
       } 

       // We should now have the header. Time to extract the body. 
       if ([dataBuffer length] >= ((NSUInteger) packetBodySize)) 
       { 
        // We now have enough data to extract a meaningful packet. 
        const int kPrologLength = 16; 
        char *buffer = (char *)[dataBuffer bytes]; 

        // if incoming message is color change, then don't display message 
        BOOL needOutput = YES; 

        // fetch the communication status 
        unsigned long com_status = *((unsigned long *)(buffer + 0)); 
        com_status = ntohl(com_status); 

        // decrypt the message 
        size_t decryptedLength = (size_t) packetBodySize - 4; // don't include com status 

        int skip_message = 0; 

        if (com_status == 0 && sCryptorRef) 
        { 
         PSCryptorStatus decryptResult = EncryptDecrypt (sCryptorRef, false, buffer+4, decryptedLength, buffer+4, decryptedLength, &decryptedLength); 

         if (kCryptorSuccess != decryptResult) 
         { 
          // failed to decrypt. Ingore messageg and disconnect 
          skip_message = 1; 
          [self logMessage:@"ERROR: Decryption failed. Wrong password.\n" clearLine:NO]; 
         } 
        } 
        else 
        { 
         if (com_status != 0) 
         [self logMessage:@"ERROR: Problem with communication, possible wrong password.\n" clearLine:NO]; 

         if (!sCryptorRef) 
         [self logMessage:@"ERROR: Cryptor Ref is NULL, possible reason being that password was not supplied or password binding function failed.\n" clearLine:NO]; 
        } 

        // Interpret encrypted section 
        if (!skip_message) 
        { 
         // version, 32 bit unsigned int, network byte order 
         unsigned long protocol_version = *((unsigned long *)(buffer + 4)); 
         protocol_version = ntohl(protocol_version); 

         if (protocol_version != 1) 
         { 
          // either the message is corrupted or the protocol is newer. 
          [self logMessage:@"Incoming protocol version is different the expected. (or the message is corrupted.) Not processing.\n" clearLine:NO]; 
          skip_message = 1; 
         } 

         if (!skip_message) 
         { 
          // transaction, 32 bit unsigned int, network byte order 
          unsigned long transaction = *((unsigned long *)(buffer + 8)); 
          transaction = ntohl(transaction); 

          // content type, 32 bit unsigned int, network byte order 
          unsigned long content = *((unsigned long *)(buffer + 12)); 
          content = ntohl(content); 

          unsigned char *received_data = (unsigned char *)(buffer+kPrologLength); 
          int received_length = (decryptedLength-(kPrologLength-4)); 

          if (content == 3) // image data 
          { 
           // process image data 
           unsigned char image_type = *((unsigned char *)received_data); 
           [self logMessage:@"Incoming data is IMAGE. Skipping\n" clearLine:NO]; 

           if (image_type == 1) // JPEG 
           { 
            [self logMessage:@"By the way, incoming image is JPEG\n" clearLine:NO]; 
           } 
           else if (image_type == 2) // Pixmap 
           { 
            [self logMessage:@"By the way, incoming image is Pixmap\n" clearLine:NO]; 
           } 
           else 
           { 
            [self logMessage:@"Unknown image type\n" clearLine:NO]; 
           } 
          } 
          else 
          { 
           // Set the response string 
           NSString *string = [[NSString alloc] initWithBytes:received_data length:received_length encoding:NSUTF8StringEncoding]; 

           //NSLog(@"string: %@\n id:%li", string, transaction); 

           // see if this is a response we're looking for 
           if (content != 1) 
           {          
            if (transaction == foregroundColor_subscription || transaction == foregroundColor_transaction) 
            { 
             [self processForegroundChange:string]; 
             needOutput = NO; 
            } 
            if (transaction == backgroundColor_subscription || transaction == backgroundColor_transaction) 
            { 
             [self processBackgroundChange:string]; 
             needOutput = NO; 
            } 
            if (transaction == tool_transaction) 
            { 
             [self processToolChange:string]; 
             needOutput = NO; 
            } 
            if (transaction == artLayerName_transaction) 
            { 
             [self processLayerName:string]; 
             needOutput = NO; 
            } 
           } 
           //Tells me about every event thats happened (spammy tech nonsence, no good for user log) 
           //if (needOutput) [self logMessage:string clearLine:NO]; 
          } 
         } 

        } 

        // Remove that chunk from buffer 
        NSRange rangeToDelete = {0, packetBodySize}; 
        [dataBuffer replaceBytesInRange:rangeToDelete withBytes:NULL length:0]; 

        // We have processed the packet. Resetting the state. 
        packetBodySize = -1; 
       } 
       else 
       { 
        // Not enough data yet. Will wait. 
        break; 
       } 
      } 

      break; 
     case NSStreamEventEndEncountered:; 
      [self closeStreams]; 
      [self logMessage:[NSString stringWithFormat: @"%@ End encountered, closing stream.\n", outputMessage.text] clearLine:NO]; 
      break; 
     case NSStreamEventHasSpaceAvailable: 
     case NSStreamEventErrorOccurred: 
     case NSStreamEventOpenCompleted: 
     case NSStreamEventNone: 
     default: 
      break; 
    } 
} 

編輯:

雖然這工作,它撞到我到另一個問題。我查看了psconnection示例,看到了你在說的內容,但是我沒有使用完整的框架,但是可以像其他示例項目那樣進行連接。每次處理圖層名稱時,我都會簡單地將我的事務ID增加1,如上面的代碼中所示。

像這樣:

if (transaction == docName_transaction) 
{ 
    docName_transaction++; 
    [self processDocName:string]; 
} 

這適用於大多數情況,但是如果我在同一時間,我得到的重疊做到這一點到另一個事務ID。這意味着我最終會在錯誤的時間處理一個id的結果。假設我獲得了文檔的總數和每個文檔的名稱。所以我有兩個if語句像上面那樣,但是我最終在兩個if語句中處理了總文檔,並且我看不到如何在這個重疊之上。它能夠一次接收多條消息非常重要,所以任何幫助都會被讚賞,因爲它會讓我瘋狂,也許我只需要第二雙眼睛來檢查我的錯誤。

回答

0

我剛剛下載了樣本,並且據我所見,您應該使用唯一的事務ID來處理等待響應的事務。

我的意思是如果您發送layer_name請求與transactionID 1,您不能使用1,直到它收到響應。

所以更好的情況是,將您的transactionID存儲在Dictionary中(transactionID作爲鍵),並將消息類型存儲爲值。

就像:

transactions [transaction_id] = @「layername」;

,當您收到響應:

使用: 交易[TRANSACTION_ID]得到的消息類型(例如:layername)根據此行爲。

你也可以把其他一些細節的交易詞典(你可以把包含所有信息,這指揮,哪個對象等字典)

+0

謝謝您的回答,不知道我跟着雖然。你是否建議我有一個transactionIDs字典?我試圖避免的是有幾十個事務ID。另外,我甚至不知道需要多少個,所以每個photoshop文檔都可以有不同數量的圖層,因此我無法知道需要多少個ID。 – 2013-03-09 19:38:15

+0

據我所知,你不能再次使用相同的transactionID,除非你得到第一個答覆。因此,您可以等待第一個答案,或者您可以使用字典一次使用多個事務ID。 (你會有很多的交易ID,但你會將它們映射到你有限的一組操作) – 2013-03-09 20:47:24

+0

我該如何爲每個交易ID使用一個交易ID,但是當我不知道我需要多少次消息時纔會使用一個交易ID?我可能會得到諸如文件有12層的信息,但是我不能即時聲明這些事務ID,因爲它們被用於寬類而不是單一方法。 – 2013-03-09 22:42:58