1

ユーザーが UIActivityViewController から共有アクティビティを選択したら、共有シートが表示される前にアップロード タスクを実行したいと考えています。

具体的には、アクティビティで使用するアップロードされた画像の URL が必要です。

私はすでにサブクラス化UIActivityItemProviderしており、メソッドでアップロードできると考えていますitemForActivityTypeが、アップロードコードはブロックベースであり、ブロックが完了するのを待つ方法がわかりません。これは可能ですか?単純なコーディング エラーかもしれません。長い 1 日でした。

ユーザーが共有ボタンを押したときに画像をアップロードしたくありません。これは、アップロードされた画像が使用されていないことを意味するアクティビティ ビューをキャンセルする可能性があるためです。

これは私が現在持っているコードですが、画像がアップロードされる前に nil を返し、ブロック内ではエラーに対して 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 を選択することができます。電子メールが選択されている場合にのみ画像をアップロードする必要があり、これを実行できる唯一の場所はアクティビティ プロバイダー サブクラスであると思います。

4

1 に答える 1

2

を実装する代わりに- (id)activityViewController:(UIActivityViewController *)activityViewController itemForActivityType:(NSString *)activityType、UIActivityItemProvider の をオーバーライドしてみてください- (id)item。このメソッドは、バックグラウンド スレッドにある NSOperation のメイン メソッドから呼び出されます。

ネットワーク完了ブロックがトリガーされるまで待つことについては、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");

ただし、これはバックグラウンド スレッドでのみ使用してください。そうしないと、メイン スレッドがブロックされます。

于 2013-07-30T01:34:45.550 に答える