I get a issue, situation is I want to upload 9 photos to server, and I use a for-circle to upload my photos, and in the for-circle, there is resultBlock for me, which returns the result of uploaded image’s url for me, I use the 9 url to splice to a nesting, but I use my method, some times it will not splice all 9 url.
I have use for reference some similar problems, but I did not find which is solution for my issue: iOS GCD Sync with Async Block
This is my code:
__block NSString * files = @"";
if (_cell1.selectedAssets.count == 0) {
[self doUploadMessageWithFiles:nil];
} else {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
__block int comemntCount = 0;
for (int i = 0; i < _cell1.selectedAssets.count; i ++) {
[Util uploadImage:_cell1.selectedPhotos[i] withUrl:@"prescription/uploadImages" withBlock:^(NSString *returnUrl) {
if (i == 0) {
files = returnUrl;
}else {
files = [files stringByAppendingString:[NSString stringWithFormat:@",%@", returnUrl]];
}
comemntCount ++;
if (comemntCount == _cell1.selectedAssets.count) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self doUploadMessageWithFiles:files]; // this line is my last step, but the files is not 9 url's composition. because there are asnyc blocks.
}
NSLog(@"*%@", returnUrl);
}];
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(60.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
}
The Util's function:
+ (void)uploadImage:(UIImage *)image withUrl:(NSString *)uploadUrl withBlock:(void (^)(NSString *))returnUrl {
UIImage *img = image;
UIImage *com_img = [Util compressImage:img toMaxFileSize:200 * 1000];
NSData *dataObj = UIImagePNGRepresentation(com_img);
NSDictionary * param1 = @{
@"id":@1,
@"imgFile":dataObj
};
AFHTTPSessionManager * session = [AFHTTPSessionManager manager];
session.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json",@"application/xml",@"text/json",@"text/javascript",@"text/html",@"text/plain",@"multipart/form-data",nil];
NSString *url = [NSString stringWithFormat:@"%@%@", BASE_URL, uploadUrl]; // uploadHeader uploadImages
[session POST:url parameters:param1 constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
UIImage *img = image; // response
NSData *data = UIImagePNGRepresentation(img);
// schoolListItem@2x
[formData appendPartWithFileData:data name:@"imgFile" fileName:@"imgFile.png"mimeType:@"image/png"];
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nonnull responseObject) {
NSLog(@"success+%@", responseObject);
NSString *return_url = [NSString stringWithFormat:@"%@",responseObject[@"data"]]; //
returnUrl(return_url);
} failure:^(NSURLSessionDataTask * _Nonnull task, NSError * _Nonnull error) {
NSLog(@"fail");
}];
}
EDIT:I have tried the static dispatch_semaphore_t semaphore;
, but I don't think this is a good solution for the issue, because this can make the upload process very slowly.
- (void)sendInfo {
__block NSString * files = @"";
if (_cell1.selectedAssets.count == 0) {
[self doUploadMessageWithFiles:nil];
} else {
[MBProgressHUD showHUDAddedTo:self.view animated:YES];
__block int comemntCount = 0;
NSString *url = @"prescription/uploadImages";
static dispatch_once_t onceToken;
static dispatch_semaphore_t semaphore;
static dispatch_queue_t queue;
dispatch_once(&onceToken, ^{
semaphore = dispatch_semaphore_create(1);
//queue = dispatch_queue_create("com.MyApp.task", NULL);
queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
});
for (int i = 0; i < _cell1.selectedAssets.count; i ++) { //_photosChooseArr
dispatch_async(queue, ^{
dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
[Util uploadImage:_cell1.selectedPhotos[i] withUrl:url withBlock:^(NSString *returnUrl) {
if (i == 0) {
files = returnUrl;
comemntCount ++;
if (comemntCount == _cell1.selectedAssets.count) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self doUploadMessageWithFiles:files];
}
}else {
files = [files stringByAppendingString:[NSString stringWithFormat:@",%@", returnUrl]];
comemntCount ++;
if (comemntCount == _cell1.selectedAssets.count) {
[MBProgressHUD hideHUDForView:self.view animated:YES];
[self doUploadMessageWithFiles:files];
//NSLog(@"i = %d, returnUrl = %@, files = %@", i, returnUrl, files);
}
}
dispatch_semaphore_signal(semaphore);
}];
});
}
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(180.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
[MBProgressHUD hideHUDForView:self.view animated:YES];
});
}
}