简体   繁体   中英

UIImagePickerController not showing (taking more time to load) camera preview in ios7

I am using GCD in my app to fetch lot of images and data in the background queue and when I present uiimagepickercontroller it takes more time to show the camera preview. After googling around, I found that many have faced this issue with iOS 7 and here is one more post that made some sense to me. ( iOS 7 UIImagePickerController Camera No Image ). The solution was to stop the background threads and then present the picker controller. But I am really stumped and don't know how to stop or pause the background threads, present the picker controller and then resume/start the background thread. Can someone please help me with this.

Here is how I am doing my background fetching of images and data in my networking class (like everyone else). My serial queue is initialized like this.

sharedInstance.serialQueue = dispatch_queue_create("user-detail-queue", DISPATCH_QUEUE_CONCURRENT);

And the code to fetch things in the background is like this.

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        NSString *myUserID = [JNKeychain loadValueForKey:@"userID"];
        NSString *sessionToken = [JNKeychain loadValueForKey:@"sessionToken"];
        if(sessionToken && myUserID)
        {
            dispatch_async([BGNetworkAPI sharedInstance].serialQueue, ^{
                id object = [[BGNetworkAPI sharedInstance].userCache objectForKey:myUserID];
                if(object)
                {
                    NSDictionary *cachedResponseDictionary = (NSDictionary *)object;
                    BGUser *user = [BGUser createUserWithResponseDictionary:cachedResponseDictionary];
                    if(block)
                    {
                        block(user, nil);
                    }
                }
                else
                {
                  [[BGUserManagementClient sharedClient] fetchUserDetailsWithUserId:myUserID withSessionToken:sessionToken withSuccessBlock:^(AFHTTPRequestOperation *operation, id responseObject)
                 {
                     //NSLog(@"The response object of my user object is %@",responseObject);
                     [[BGNetworkAPI sharedInstance].userCache setObject:responseObject forKey:myUserID];
                     NSDictionary *responseDictionary = (NSDictionary *)responseObject;
                     BGUser *user = [BGUser createUserWithResponseDictionary:responseDictionary];
                     if(block)
                     {
                         block(user,nil);
                     }
                 } failure:^(AFHTTPRequestOperation *operation, NSError *error)
                 {
                     NSLog(@"The error while fetching the user details is %@", operation.responseObject);
                     if(block)
                     {
                         block(nil, error);
                     }
                 }];
                }
             }
        });

With the code above you are not doing the fetching in the backgroud as dispatch_get_main_queue() gives you the queue the interface is running on. To perform a background fetch you have to open another queue with dispatch_queue_create("image_queue", NULL) .

When the backgroud fetch is finished and you want to do something with the UI you have to do this in the main queue.

dispatch_async(dispatch_get_main_queue(),^{
  if(block) {
    block(user,nil)
  }
});

After playing around with the code, I figured out the problem. In all the places where I am doing background fetch, I was sending the completion block just like that. When I changed the returning of the completion block in the main block, it started to work properly. Thanks a lot to @HackingOther to point out my mistake.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM