我在我的應用程序中使用官方Ricoh Theta iOS SDK(Link)連接到360°理光Theta相機。 SDK使用多個HTTP請求來觸發圖像的捕獲和從相機下載圖像。自NSRunLoop無法工作,因爲升級到iOS10
SDK內部使用信號來同步請求,但自從升級到iOS 10後,由於某種原因,這似乎不再有效。根據開發者論壇,這個問題是衆所周知的,但理光顯然並不在乎。
我將其縮小到SDK中的特定部分,其中SDK通過RunLoop每0.5秒發送一次請求來檢查圖像是否可用。
這發生在這個函數:
/**
* Start status monitoring
* @param command ID of command to be monitored
* @return Status indicating completion or error
*/
- (NSString*)run:(NSString*)command
{
// Create and keep HTTP session
NSURLSessionConfiguration* config = [NSURLSessionConfiguration defaultSessionConfiguration];
_session= [NSURLSession sessionWithConfiguration:config];
_commandId = command;
// Semaphore for synchronization (cannot be entered until signal is called)
_semaphore = dispatch_semaphore_create(0);
// Create and start timer
NSTimer *timer = [NSTimer timerWithTimeInterval:0.5f
target:self
selector:@selector(getState:)
userInfo:nil
repeats:YES];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addTimer:timer forMode:NSRunLoopCommonModes];
[runLoop run];
// Wait until signal is called
dispatch_semaphore_wait(_semaphore, DISPATCH_TIME_FOREVER);
NSLog(@"HERE");
return _state;
}
的問題是,即使信號燈的方法的getState(dispatch_semaphore_signal(_semaphore);
)觸發NSLog(@"HERE");
永遠不會被調用。我確實通過在調試器中逐行了解這一點。
/**
* Delegate called during each set period of time
* @param timer Timer
*/
- (void)getState:(NSTimer*)timer {
// Create JSON data
NSDictionary *body = @{@"id": _commandId};
// Set the request-body.
[_request setHTTPBody:[NSJSONSerialization dataWithJSONObject:body options:0 error:nil]];
// Send the url-request.
NSURLSessionDataTask* task =
[_session dataTaskWithRequest:_request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
if (!error) {
NSArray* array = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingAllowFragments error:nil];
_state = [array valueForKey:@"state"];
_fileUri = [array valueForKeyPath:@"results.fileUri"];
NSLog(@"result: %@", _state);
} else {
_state = @"error";
NSLog(@"GetStorageInfo: received data is invalid.");
}
if (![_state isEqualToString:@"inProgress"]) {
[timer invalidate];
dispatch_semaphore_signal(_semaphore);
// Stop timer
[timer invalidate];
}
}];
[task resume]; }
我已經看到出現了iOS的10一些小的改動NSRunLoop,是這可能與要面對什麼,我在這裏?我得到的另一種感覺是,也許iOS沒有得到一個新的線程,將調用dispatch_semaphore_wait
。
在過去的幾個小時裏,我一直對着桌子猛撞我的頭,真的希望你們中的一個能幫助我們!
非常感謝您的非常詳細的答案!對此,我真的非常感激! 我發現了這個要點,它會遵循你的建議方法(https://gist.github.com/maicki/7622108),但我現在想知道如何將它包含在現有的SDK中。使用調度定時器,我可能會被迫使用完成塊,但是當前SDK在以信號量的同步方式等待之後返回值。有沒有辦法將這兩種方法結合起來? –
你仍然會使用信號量。它只是用一個調度計時器源代替'NSTimer',然後你不需要運行運行循環。 –
有道理!你做了我的一天,嚴重不能夠感謝你! –