2013-03-04 34 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