我有一个应用程序,允许用户快速相互发送照片,但我们都知道用户不总是有完美的互联网连接,所以我们决定创建一个系统,临时存储目录中的所有照片和一组字典中的每个api请求的信息。如果用户拍摄2张照片并且第一张照片由于没有连接而失败,那么几分钟之后用户在连接互联网时拍摄第3张照片就会发生这种情况(伪),但我们会得到一些重复和奇怪的如果队列开始备份并且整个过程被多次触发,那么这样做会发生这种情况。所以我们做了一些研究,dispatch_groups似乎就是答案,但我们无法弄清楚每次如何使用相同的调度组,以便没有多个调度组队列,如果用户需要同时触发相同的请求20张图片真快。
该系统的另一个重要部分是它必须以相同的顺序上传所有图像,理想情况下应避免重复
-(void)upload:(NSString*)typeOfUpload{
[_resendBtn setHidden:YES];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
NSMutableArray *pendingRequests=[[NSMutableArray alloc] init];
NSString *pendingRequestsFrom= [NSString stringWithFormat:@"pendingRequestsForUid%@",[defaults objectForKey:@"uid"]];
NSLog(@"PENDINGREQUESTFROM:%@",pendingRequestsFrom);
if ([defaults objectForKey:pendingRequestsFrom]){
pendingRequests= [[defaults objectForKey:pendingRequestsFrom]mutableCopy];
}
NSMutableDictionary *requestDict=[[NSMutableDictionary alloc] init];
NSDate *now = [NSDate date];
int timestamp = [[NSDate date] timeIntervalSince1970];
[requestDict setObject:[NSString stringWithFormat:@"%d",timestamp] forKey:@"timestamp"];
if(_convertedVideoURL){
NSString*urlPath= [_convertedVideoURL path];
[requestDict setObject:urlPath forKey:@"videoURL"];
}
if([typeOfUpload isEqualToString:@"PHOTO"]){
// Get image data. Here you can use UIImagePNGRepresentation if you need transparency
NSData *imageData = UIImageJPEGRepresentation(_imgToSend, 8);
// Get image path in user's folder and store file with name image_CurrentTimestamp.jpg (see documentsPathForFileName below)
//Create temporary URL to record to
NSDate *now = [NSDate date];
NSTimeInterval nowEpochSeconds = [now timeIntervalSince1970];
NSString *intervalString = [NSString stringWithFormat:@"%f", nowEpochSeconds];
NSString *main_img_path = [[NSString alloc] initWithFormat:@"%@image%@.jpg", NSTemporaryDirectory(), intervalString];
// Write image data to user's folder
[imageData writeToFile:main_img_path atomically:YES];
[requestDict setObject:main_img_path forKey:@"imgToSendStored"];
}
[requestDict setObject:_selectedUserString forKey:@"recip_uid"];
[requestDict setObject:typeOfUpload forKey:@"MEDIA_TYPE"];
if([typeOfUpload isEqualToString:@"TEXT"]){
[requestDict setObject:_textMsgView.coverCaption.text forKey:@"body"];
}
NSLog(@"params being stored for later %@", requestDict);
[pendingRequests addObject:requestDict];
NSArray *newArray= [NSArray arrayWithArray:pendingRequests];
NSLog(@"TOTAL_PENDING_VIDS == %@, araay count == %d",newArray,[newArray count]);
[defaults setObject:newArray forKey:pendingRequestsFrom];
[defaults synchronize];
_imgToSend=nil;
_textToSend=nil;
_isTextDropDownDisplayed=NO;
[UIView animateWithDuration:.5 animations:^{
[_textMsgView setFrame:CGRectMake(0, -300, 320, 10)];
_textMsgView.coverCaption.text=@"";
//secondView.alpha = 1.0;
[self swippedAway];
}];
[self uploadStoredVidsFunction:@"UPLOAD"];
}
-(void)uploadStoredVidsFunction:(NSString*)typeOfResend
{
NSString *pendingRequestsFrom= [NSString stringWithFormat:@"pendingRequestsForUid%@",[defaults objectForKey:@"uid"]];
pendingRequests= [[defaults objectForKey:pendingRequestsFrom]mutableCopy];
NSLog(@"PENDING_REQUESTS%@",pendingRequests);
dispatch_group_t group = dispatch_group_create();
for (int i=0;i<[pendingRequests count]; i++) {
dispatch_group_enter(group);
MAKE AFNETWORKING REQUEST
success{
remove request from pending array
// start next request
dispatch_group_leave(group);
}
failure {
//STOP THE QUEUE from continuing to execute the rest of the requests in line/give user their options ( aka retry sending all/ delete all/save for later )
}
}
}
答案 0 :(得分:2)
您可以使用while
在一个无终止的NSCondition
循环中生成一个处理所有这一切的新线程,以确保线程安全。
// Somewhere in your initialization:
requestLock = [[NSCondition alloc] init];
[self performSelectorInBackground:@selector(processRequests)];
- (void)processRequests {
while (![[NSThread currentThread] isCancelled]) {
[requestLock lock];
if ([pendingRequests count] == 0 /* || delay time not yet reached */) {
[requestLock waitUntilDate:someTimeoutDate];
[requestLock unlock];
continue;
}
NSMutableArray *remainingRequests = [pendingRequests copy];
[pendingRequests removeAllObjects];
[requestLock unlock];
for (Request *request in requests) {
if (success) {
// Process the request and then..
[remainingRequests removeObject:request];
} else {
break;
}
}
[requestLock lock];
[pendingRequests insertObjects:remainingRequests atIndexes:[NSIndexSet indexSetWithIndexesInRange:NSMakeRange(0, [remainingRequests count])]];
[requestLock unlock];
}
}
- (void)addRequest:(Request *)request {
[requestLock lock];
[pendingRequests addObject:request];
[requestLock broadcast];
[requestLock unlock];
}