私のアプリはこのように動作しています: - アルバムを作成して写真を撮ります - サーバーに送信します - 写真分析後に回答/補足情報を取得します。
送信部分に問題があります。ここにコードがあります
@interface SyncAgent : NSObject <SyncTaskDelegate>
@property NSOperationQueue* _queue;
-(void)launchTasks;
@end
@implementation SyncAgent
@synthesize _queue;
- (id)init
{
self = [super init];
if (self) {
self._queue = [[NSOperationQueue alloc] init];
[self._queue setMaxConcurrentOperationCount:1];
}
return self;
}
-(void) launchTasks {
NSMutableArray *tasks = [DataBase getPendingTasks];
for(Task *t in tasks) {
[self._queue addOperation:[[SyncTask alloc] initWithTask:t]];
}
}
@end
および SyncTask :
@interface SyncTask : NSOperation
@property (strong, atomic) Task *_task;
-(id)initWithTask:(Task *)task;
-(void)mainNewID;
-(void)mainUploadNextPhoto:(NSNumber*)photoSetID;
@end
@implementation SyncTask
@synthesize _task;
-(id)initWithTask:(Task *)task {
if(self = [super init]) {
self._task = task;
}
return self;
}
-(void)main {
NSLog(@"Starting task : %@", [self._task description]);
// checking if everything is ready, sending delegates a message etc
[self mainNewID];
}
-(void)mainNewID {
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] createNewPhotoSet withErrorBlock:^{
NSLog(@"PhotoSet creation : error")
} andSuccessBlock:^(NSNumber *photoSetID) {
NSLog(@"Photoset creation : id is %d", [photoSetID intValue]);
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
-(void)mainUploadNextPhoto:(NSNumber*) photoSetID {
//just admit we have it. won't explain here how it's done
NSString *photoPath;
__block SyncTask *safeSelf = self;
[[WebAPI sharedClient] uploadToPhotosetID:photoSetID withPhotoPath:photoPath andErrorBlock:^(NSString *photoPath) {
NSLog(@"Photo upload error : %@", photoPath);
} andSuccessBlock:^(NSString *photoPath) {
NSLog(@"Photo upload ok : %@", photoPath);
//then we delete the file
[safeSelf mainUploadNextPhoto:photoSetID];
}];
}
@end
すべてのネットワーク操作は、次のように AFNetworking を使用して行われます。
-(void)myDummyDownload:(void (^)(NSData * data))successBlock
{
AFHTTPClient* _httpClient = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.google.com/"]];
[_httpClient registerHTTPOperationClass:[AFHTTPRequestOperation class]];
NSMutableURLRequest *request = [_httpClient requestWithMethod:@"GET" path:@"/" nil];
[request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
AFHTTPRequestOperation *operation = [_httpClient HTTPRequestOperationWithRequest:(NSURLRequest *)request
success:^(AFHTTPRequestOperation *operation, id data) {
if(dataBlock)
dataBlock(data);
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(@"Cannot download : %@", error);
}];
[operation setShouldExecuteAsBackgroundTaskWithExpirationHandler:^{
NSLog(@"Request time out");
}];
[_httpClient enqueueHTTPRequestOperation:operation];
}
私の問題は次のとおりです。私の接続は非同期で行われるため、前のタスクが終了するのを待たずにすべてのタスクが一緒に起動さ[self._queue setMaxConcurrentOperationCount:1]
れSyncAgent
ます。
すべての接続を同期的に実行する必要がありますか? 接続をこの方法で行うべきではなく、これらのメソッドを他の場所で使用してバックグラウンドで実行する必要がある可能性があるため、これは良い考えではないと思いますが、より良い方法を見つけることができません。何か案が ?
ああ、私のコードにエラー/タイプミスがある場合は、貼り付ける前に要約しようとしたときに表示されたことを保証できます。今のところ問題なく動作しています。
ありがとう !
PS: 問題を説明するより良い方法を見つけられなかった長い貼り付けで申し訳ありません。
編集:セマフォを使用する方がセットアップと理解が簡単であることがわかりました:非同期にディスパッチされたブロックが完了するのを待つにはどうすればよいですか?