ios - 用户从 UIActivityViewController 选择事件后执行上传 - 可能是 block 问题

标签 ios objective-c-blocks uiactivityviewcontroller uiactivity

我想在用户从 UIActivityViewController 选择共享事件后,但在显示共享表之前执行上传任务。

具体来说,我需要上传图片的 url 以在 Activity 中使用。

我已经对 UIActivityItemProvider 进行了子类化,并且认为我可以在 itemForActivityType 方法中进行上传,但是上传代码是基于 block 的,我不知道如何让它等待 block 完成。这可能吗? 这可能是一个简单的编码错误,这是漫长的一天。

我不想在用户按下分享按钮时上传图片,因为他们可能会取消 Activity View,这意味着上传的图片就放在那里没有被使用。

这是我目前拥有的代码,但它在图片上传之前返回 nil,并且在 block 内它不允许我为错误返回 nil:

- (id) activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType
{

    [self getShortUrlForUploadedImageWithCompletionHandler:^(NSString *shortUrl, NSError *error) {
        if (!error) {
            if ( [activityType isEqualToString:UIActivityTypeMail] ) {

                NSString *shareString = @"Email content here using shortUrl";

                return shareString;
            } else {
                return @"";
            }

        } else {

            return @"";
        }
    }];

    return nil;
}

-(void)getShortUrlForUploadedImageWithCompletionHandler:(NSString* (^)(NSString *shortUrl, NSError *error))completionHandler
{
    NSData *imageToUpload = UIImageJPEGRepresentation(_image, 75);
    AFHTTPClient *client= [AFHTTPClient clientWithBaseURL:[NSURL URLWithString:kShareURL]];

    NSDictionary *params = [NSDictionary dictionaryWithObjectsAndKeys:
                            @"image", @"action",
                            @"simple", @"format",
                            nil];
    NSMutableURLRequest *request = [client multipartFormRequestWithMethod:@"POST" path:nil parameters:params constructingBodyWithBlock: ^(id <AFMultipartFormData>formData) {
        [formData appendPartWithFileData: imageToUpload name:@"image" fileName:@"temp.png" mimeType:@"image/jpeg"];
    }];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];

    [operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
        NSString *response = [operation responseString];
        NSLog(@"response: %@",response);

        completionHandler(response, nil);

    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

        if([operation.response statusCode] == 403){
            NSLog(@"Upload Failed");
            return;
        }
        NSLog(@"error: %@", [operation error]);

        completionHandler(nil, error);
    }];

    [operation start];
}

-------- 编辑

在这方面我真的需要一些帮助。我目前的解决方法是在用户单击我的共享按钮时,在事件选择之前上传图像。所以他们可以取消分享,我会留下多余的上传图片,或者他们可以选择不需要上传图片的 Twitter。 如果选择了电子邮件,我只需要上传图像,我认为我唯一可以做到这一点的地方是在 Activity Provider 子类中。

最佳答案

代替实现 - (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType,尝试覆盖 UIActivityItemProvider 的 - (id)item。此方法将从后台线程上的 NSOperation 的主要方法调用。

至于等待网络完成 block 触发,我建议您考虑使用 dispatch_semaphore。这是一个例子:

dispatch_semaphore_t semaphore = dispatch_semaphore_create(0);
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    NSLog(@"doing some work");
    sleep(5);
    NSLog(@"done with work");
    dispatch_semaphore_signal(semaphore);
});
double delayInSeconds = 60.0;
dispatch_time_t waitTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC));
NSLog(@"waiting for background thread to finish");
dispatch_semaphore_wait(semaphore, waitTime);
NSLog(@"background thread finished, or took too long");

确保只在后台线程中使用它,否则你会阻塞主线程。

关于ios - 用户从 UIActivityViewController 选择事件后执行上传 - 可能是 block 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17709761/

相关文章:

ios - 如何将图像和标签添加到 UINavigationBar 作为标题?

ios - Swift 3.0 迁移后未调用 MFMailComposeViewControllerDelegate 方法

iOS tableview 在 UiBuilder 中显示为空

objective-c - 为什么这个 block 不是全局的?

iOS:如何在社交网络上分享文字和图片?

ios - 为什么我无法使用 swift 3 在 iOS 上获取本地通知?

swift - 在 AFNetworking 中调用 Objective C 代码时完成处理程序不起作用

objective-c - __weak 和 __block 引用有什么区别?

swift - 邮件 - 从 UIActivityController 添加帐户屏幕

ios - UIActivityViewController:视频分享到 Youtube