我正在使用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