Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>First, if you wanted to coordinate two different threads <code>dispatch_semaphore_t</code> might be more appropriate than <code>dispatch_group_t</code>.</p> <p>Second, and more importantly, you should not take an asynchronous method such as <code>performRequestWithHandler</code>, invoke it from the main queue in a synchronous manner. You <em>never</em> should be blocking the main queue.</p> <p>Fortunately <code>performRequestWithHandler</code> gives us a <code>handler</code> block which we can use to perform actions after the tweet is done. In your comments, you say you simply want to update your HUD after the tweet, so you should do that <code>performRequestWithHandler</code> (dispatching that UI update back to the main queue, because, as <a href="http://developer.apple.com/library/ios/documentation/Social/Reference/SLRequest_Class/Reference/Reference.html#//apple_ref/occ/instm/SLRequest/performRequestWithHandler%3a" rel="nofollow">the documentation</a> says, "handler is not guaranteed to be called on any particular thread"):</p> <pre><code>- (void)postMyTweet { ACAccountStore *accountStore = [[ACAccountStore alloc] init]; ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) { if (granted) { NSArray *allAccounts = [accountStore accountsWithAccountType:accountType]; if ([allAccounts count] &gt; 0) { ACAccount *userAccount = [allAccounts objectAtIndex:0]; NSURL *reqURL = [NSURL URLWithString:ENDPOINT_MEDIA_UPLOAD]; NSDictionary *parameter = [NSDictionary dictionaryWithObject:tweetTitle forKey:@"status"]; SLRequest *twitterRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:reqURL parameters:parameter]; [twitterRequest addMultipartData:tweetImage withName:PARAM_MEDIA type:CONTENT_TYPE_MULTIPART_FORM_DATA filename:nil]; [twitterRequest setAccount:userAccount]; [twitterRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { if (error) NSLog(@"tweet fail; error = %@", error); else { long result = [urlResponse statusCode]; if (result == 200) NSLog(@"%ld",result); else NSLog(@"Unexpected response: %@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]]); } // Dispatch UI updates back to main queue dispatch_async(dispatch_get_main_queue(), ^{ // do your MBProgressHUD stuff here }); }]; } } else { NSLog(@"Not authorized"); } }]; } </code></pre> <p>You also asked "How can I pass the HTTP response result to the viewcontroller?" You obviously do all of this in <code>performRequestWithHandler</code>, where you have the HTTP response (and the response data).</p> <hr> <p>If you want <code>postTweet</code> to operate synchronously, then best practices would dictate that you don't submit it from the main queue (because, at the risk of sounding like a broken record, you never want to block the main queue). But you could have <code>actuallySendTweet</code> dispatch this tweet from a background queue, e.g.:</p> <pre><code>- (void) actuallySendTweet { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ PostTweet * pt = [[PostTweet alloc] init]; [pt postTweetSynchronously]; NSLog(@"Done"); dispatch_async(dispatch_get_main_queue(), ^{ // Now do any UI updates you want here. // For example, do your MBProgressHUD update here. }); }); } - (void)postTweetSynchronously { dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); ACAccountStore *accountStore = [[ACAccountStore alloc] init]; ACAccountType *accountType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; [accountStore requestAccessToAccountsWithType:accountType options:nil completion:^(BOOL granted, NSError *error) { if (granted) { NSArray *allAccounts = [accountStore accountsWithAccountType:accountType]; if ([allAccounts count] &gt; 0) { ACAccount *userAccount = [allAccounts objectAtIndex:0]; NSURL *reqURL = [NSURL URLWithString:ENDPOINT_MEDIA_UPLOAD]; NSDictionary *parameter = [NSDictionary dictionaryWithObject:tweetTitle forKey:@"status"]; SLRequest *twitterRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:reqURL parameters:parameter]; [twitterRequest addMultipartData:tweetImage withName:PARAM_MEDIA type:CONTENT_TYPE_MULTIPART_FORM_DATA filename:nil]; [twitterRequest setAccount:userAccount]; [twitterRequest performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { // do whatever you want here, perhaps updating some class properties // now that we're done, signal the semaphore dispatch_semaphore_signal(semaphore); }]; } } else { NSLog(@"Not authorized"); dispatch_semaphore_signal(semaphore); // make sure to signal here, too } }]; dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload