我正在使用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语句中处理了总文档,并且我看不到如何在这个重叠之上。它能够一次接收多条消息非常重要,所以任何帮助都会被赞赏,因为它会让我疯狂,也许我只需要第二双眼睛来检查我的错误。
谢谢您的回答,不知道我跟着虽然。你是否建议我有一个transactionIDs字典?我试图避免的是有几十个事务ID。另外,我甚至不知道需要多少个,所以每个photoshop文档都可以有不同数量的图层,因此我无法知道需要多少个ID。 – 2013-03-09 19:38:15
据我所知,你不能再次使用相同的transactionID,除非你得到第一个答复。因此,您可以等待第一个答案,或者您可以使用字典一次使用多个事务ID。 (你会有很多的交易ID,但你会将它们映射到你有限的一组操作) – 2013-03-09 20:47:24
我该如何为每个交易ID使用一个交易ID,但是当我不知道我需要多少次消息时才会使用一个交易ID?我可能会得到诸如文件有12层的信息,但是我不能即时声明这些事务ID,因为它们被用于宽类而不是单一方法。 – 2013-03-09 22:42:58