Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Session 306 - Integrating With Facebook, Twitte...

wwdcman
July 01, 2012
200

Session 306 - Integrating With Facebook, Twitter and Sina Weibo

wwdcman

July 01, 2012
Tweet

Transcript

  1. These are confidential sessions—please refrain from streaming, blogging, or taking

    pictures Social Engineering Session 306 Integrating with Facebook, Twitter, and Sina Weibo Lestat Ali iOS Software Engineer Julien Robert OS X Software Engineer
  2. Your App Shareable Content Social Networks . . . Text

    Images Movies Files Facebook Twitter Weibo
  3. Your App Shareable Content Social Networks . . . Text

    Images Movies Files Facebook Twitter Weibo UIActivityViewController NSSharingServicePicker
  4. Your App Shareable Content Social Networks . . . Text

    Images Movies Files Facebook Twitter Weibo UIActivityViewController NSSharingServicePicker
  5. Benefits of Using Built-in UI •Creates a consistent user experience

    •Uses single sign-on •Easy to integrate
  6. Benefits of Using Built-in UI •Creates a consistent user experience

    •Uses single sign-on •Easy to integrate •Improves over time
  7. UIActivityViewController Presentation NSString *textToShare = @”Hello World!”; UIImage *imageToShare =

    [UIImage imageNamed:@”world.png”]; NSArray *activityItems = @[textToShare, imageToShare]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
  8. UIActivityViewController Presentation NSString *textToShare = @”Hello World!”; UIImage *imageToShare =

    [UIImage imageNamed:@”world.png”]; NSArray *activityItems = @[textToShare, imageToShare]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
  9. UIActivityViewController Presentation NSString *textToShare = @”Hello World!”; UIImage *imageToShare =

    [UIImage imageNamed:@”world.png”]; NSArray *activityItems = @[textToShare, imageToShare]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
  10. UIActivityViewController Presentation NSString *textToShare = @”Hello World!”; UIImage *imageToShare =

    [UIImage imageNamed:@”world.png”]; NSArray *activityItems = @[textToShare, imageToShare]; UIActivityViewController *activityVC = [[UIActivityViewController alloc] initWithActivityItems:activityItems applicationActivities:nil]; [self presentViewController:activityVC animated:YES completion:nil];
  11. Social Framework •Expands on Twitter framework •Provides SLComposeViewController •Factory for

    sharing sheets [SLComposeViewController composeViewControllerForType:]
  12. Presenting an SLComposeViewController SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”Hello

    World!”]; [facebookPostVC addImage:[UIImage imageNamed:@”world.png”]]; [self presentViewController:facebookPostVC animated:YES completion:nil];
  13. Presenting an SLComposeViewController SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”Hello

    World!”]; [facebookPostVC addImage:[UIImage imageNamed:@”world.png”]]; [self presentViewController:facebookPostVC animated:YES completion:nil];
  14. Presenting an SLComposeViewController SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”Hello

    World!”]; [facebookPostVC addImage:[UIImage imageNamed:@”world.png”]]; [self presentViewController:facebookPostVC animated:YES completion:nil];
  15. Presenting an SLComposeViewController SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”Hello

    World!”]; [facebookPostVC addImage:[UIImage imageNamed:@”world.png”]]; [self presentViewController:facebookPostVC animated:YES completion:nil];
  16. Presenting an SLComposeViewController SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”Hello

    World!”]; [facebookPostVC addImage:[UIImage imageNamed:@”world.png”]]; [self presentViewController:facebookPostVC animated:YES completion:nil];
  17. What Can You Share? •Basic types ▪ NSImage ▪ NSString,

    NSAttributedString ▪ NSURL (local or remote)
  18. What Can You Share? •Basic types ▪ NSImage ▪ NSString,

    NSAttributedString ▪ NSURL (local or remote) •Custom types that implement NSPasteboardWriting
  19. Adding a Sharing Menu to Your App 1. Create share

    button 2. On click, present NSSharingServicePicker
  20. Adding a Sharing Menu to Your App 1. Create share

    button 2. On click, present NSSharingServicePicker 3. Specify a delegate for the user-selected service
  21. Adding a Sharing Menu to Your App 1. Create share

    button 2. On click, present NSSharingServicePicker 3. Specify a delegate for the user-selected service 4. Implement the delegate methods for the service
  22. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  23. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  24. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  25. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  26. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  27. Creating the button Adding a Sharing Menu to Your App

    NSButton *button = [[NSButton alloc] init]; [button setImage:[NSImage imageNamed:NSImageNameShareTemplate]]; [button sendActionOn:NSLeftMouseDownMask]; [button setTarget:self]; [button setAction:@selector(showServicePicker:)];
  28. Presenting the sharing menu Adding a Sharing Menu to Your

    App - (void)showServicePicker:(id)sender { NSArray *items = @[@"Hello world", anImage]; NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:items]; picker.delegate = self; [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; }
  29. Presenting the sharing menu Adding a Sharing Menu to Your

    App - (void)showServicePicker:(id)sender { NSArray *items = @[@"Hello world", anImage]; NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:items]; picker.delegate = self; [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; }
  30. Presenting the sharing menu Adding a Sharing Menu to Your

    App - (void)showServicePicker:(id)sender { NSArray *items = @[@"Hello world", anImage]; NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:items]; picker.delegate = self; [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; }
  31. Presenting the sharing menu Adding a Sharing Menu to Your

    App - (void)showServicePicker:(id)sender { NSArray *items = @[@"Hello world", anImage]; NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:items]; picker.delegate = self; [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; }
  32. Presenting the sharing menu Adding a Sharing Menu to Your

    App - (void)showServicePicker:(id)sender { NSArray *items = @[@"Hello world", anImage]; NSSharingServicePicker *picker = [[NSSharingServicePicker alloc] initWithItems:items]; picker.delegate = self; [picker showRelativeToRect:NSZeroRect ofView:sender preferredEdge:NSMinYEdge]; }
  33. NSSharingServiceDelegate Implementing the Service Delegate •Called immediately before items are

    shared - (void)sharingService:(NSSharingService *)service willShareItems:(NSArray *)items
  34. NSSharingServiceDelegate Implementing the Service Delegate •Called immediately before items are

    shared - (void)sharingService:(NSSharingService *)service willShareItems:(NSArray *)items •Called immediately after items are shared - (void)sharingService:(NSSharingService *)service didShareItems:(NSArray *)items
  35. NSSharingServiceDelegate Implementing the Service Delegate •Called immediately before items are

    shared - (void)sharingService:(NSSharingService *)service willShareItems:(NSArray *)items •Called immediately after items are shared - (void)sharingService:(NSSharingService *)service didShareItems:(NSArray *)items •When sharing fails - (void)sharingService:(NSSharingService *)service didFailToShareItems:(NSArray *)items error:(NSError *)error
  36. NSSharingServiceDelegate Implementing the Service Delegate •Called immediately before items are

    shared - (void)sharingService:(NSSharingService *)service willShareItems:(NSArray *)items •Called immediately after items are shared - (void)sharingService:(NSSharingService *)service didShareItems:(NSArray *)items •When sharing fails - (void)sharingService:(NSSharingService *)service didFailToShareItems:(NSArray *)items error:(NSError *)error •Watch out for NSUserCancelledError
  37. Make sharing a beautiful user experience Animating the Share Sheet

    •Have these ready ▪ Shared item’s frame
  38. Make sharing a beautiful user experience Animating the Share Sheet

    •Have these ready ▪ Shared item’s frame ▪ Transition image
  39. Make sharing a beautiful user experience Animating the Share Sheet

    •Have these ready ▪ Shared item’s frame ▪ Transition image ▪ Source window
  40. Make sharing a beautiful user experience Animating the Share Sheet

    •Have these ready ▪ Shared item’s frame ▪ Transition image ▪ Source window ▪ Content scope
  41. Providing item frame and transition image Animating the Share Sheet

    •Give the frame of the shared item - (NSRect)sharingService: sourceFrameOnScreenForShareItem:(id)item
  42. Providing item frame and transition image Animating the Share Sheet

    •Give the frame of the shared item - (NSRect)sharingService: sourceFrameOnScreenForShareItem:(id)item •Its transition image - (NSImage *)sharingService: transitionImageForShareItem:item contentRect:(NSRect *)contentRect
  43. Providing item frame and transition image Animating the Share Sheet

    •Give the frame of the shared item - (NSRect)sharingService: sourceFrameOnScreenForShareItem:(id)item •Its transition image - (NSImage *)sharingService: transitionImageForShareItem:item contentRect:(NSRect *)contentRect
  44. Providing item frame and transition image Animating the Share Sheet

    •Give the frame of the shared item - (NSRect)sharingService: sourceFrameOnScreenForShareItem:(id)item •Its transition image - (NSImage *)sharingService: transitionImageForShareItem:item contentRect:(NSRect *)contentRect
  45. Providing item frame and transition image Animating the Share Sheet

    •Give the frame of the shared item - (NSRect)sharingService: sourceFrameOnScreenForShareItem:(id)item •Its transition image - (NSImage *)sharingService: transitionImageForShareItem:item contentRect:(NSRect *)contentRect QLThumbnailGetContentRect
  46. Providing source window and content scope Animating the Share Sheet

    - (NSWindow *)sharingService:(NSSharingService *)service sourceWindowForShareItems:(NSArray *)items sharingContentScope:(NSSharingContentScope *)sharingContentScope
  47. Content scopes—hints for the animation Animating the Share Sheet •From

    a list NSSharingContentScopeItem •Extracted from a larger content NSSharingContentScopePartial
  48. Content scopes—hints for the animation Animating the Share Sheet •From

    a list NSSharingContentScopeItem •Extracted from a larger content NSSharingContentScopePartial •Whole document NSSharingContentScopeFull
  49. Presenting a Share Sheet •When your trigger UI is clicked

    service = [NSSharingService sharingServiceNamed: NSSharingServiceNamePostOnTwitter];
  50. Presenting a Share Sheet •When your trigger UI is clicked

    service = [NSSharingService sharingServiceNamed: NSSharingServiceNamePostOnTwitter]; service.delegate = self;
  51. Presenting a Share Sheet •When your trigger UI is clicked

    service = [NSSharingService sharingServiceNamed: NSSharingServiceNamePostOnTwitter]; service.delegate = self; [service performWithItems:items];
  52. Presenting a Share Sheet •When your trigger UI is clicked

    service = [NSSharingService sharingServiceNamed: NSSharingServiceNamePostOnTwitter]; service.delegate = self; [service performWithItems:items]; •Enable your control conditionally
  53. Presenting a Share Sheet •When your trigger UI is clicked

    service = [NSSharingService sharingServiceNamed: NSSharingServiceNamePostOnTwitter]; service.delegate = self; [service performWithItems:items]; •Enable your control conditionally enable = [service canPerformWithItems:items];
  54. Sample Request https://graph.facebook.com/me Your App Facebook Server { “id”: “12345”,

    “name”: “Lestat Ali”, “first_name”: “Lestat”, “last_name”: “Ali”, “username”: “lestat.ali”, “gender”: “male”, “locale”: “en_US” }
  55. Sample Request https://graph.facebook.com/me Your App Facebook Server { “id”: “12345”,

    “name”: “Lestat Ali”, “first_name”: “Lestat”, “last_name”: “Ali”, “username”: “lestat.ali”, “gender”: “male”, “locale”: “en_US” }
  56. Using SLRequest 1. Request access to the user’s account 2.

    Get the user’s account 3. Create an SLRequest
  57. Using SLRequest 1. Request access to the user’s account 2.

    Get the user’s account 3. Create an SLRequest 4. Provide the SLRequest with the account
  58. Using SLRequest 1. Request access to the user’s account 2.

    Get the user’s account 3. Create an SLRequest 4. Provide the SLRequest with the account 5. Send the SLRequest
  59. Accessing User Accounts •Accounts framework controls access •Request access with

    -[ACAccountStore requestAccessToAccountsWithType:withCompletionHandler:]
  60. Accessing User Accounts •Accounts framework controls access •Request access with

    -[ACAccountStore requestAccessToAccountsWithType:withCompletionHandler:] •For Facebook, need a special dictionary in Info.plist
  61. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  62. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  63. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  64. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  65. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  66. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  67. Getting Access to Facebook Accounts self.accountStore = [[ACAccountStore alloc] init];

    ACAccountType *facebookAccountType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; [self.accountStore requestAccessToAccountsWithType:facebookAccountType withCompletionHandler:^(BOOL granted, NSError *e) { if (granted) { NSArray *accounts = [self.accountStore accountsWithAccountType:facebookAccountType]; self.facebookAccount = [accounts lastObject]; } else { // Fail gracefully... } }];
  68. Building Your Request •Initialize an SLRequest instance with ▪ URL

    ▪ HTTP Method ▪ Parameters •Set the account property
  69. Building Your Request •Initialize an SLRequest instance with ▪ URL

    ▪ HTTP Method ▪ Parameters •Set the account property •Perform the request and handle the response
  70. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  71. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  72. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  73. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  74. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  75. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  76. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  77. Accessing a User’s Facebook Profile NSURL *requestURL = [NSURL URLWithString:@”https://graph.facebook.com/me”];

    SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodGET URL:requestURL parameters:nil]; request.account = self.facebookAccount; [request performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *response, NSError *error) { // Handle the response... }];
  78. Facebook Account Access •Account access is more nuanced than Twitter

    •Need to request specific permissions •Permissions are documented on Facebook’s website
  79. Facebook Access Dictionary •Add this dictionary to Info.plist under the

    key ACFacebookClientAccessInfo @{ ACFacebookAppIDKey: @”123456789”, ACFacebookAppVersionKey: @”1.0”, ACFacebookPermissionsKey: @[@”publish_stream”, ...], ACFacebookPermissionGroupKey: @”write” }
  80. Facebook Access Dictionary •Add this dictionary to Info.plist under the

    key ACFacebookClientAccessInfo @{ ACFacebookAppIDKey: @”123456789”, ACFacebookAppVersionKey: @”1.0”, ACFacebookPermissionsKey: @[@”publish_stream”, ...], ACFacebookPermissionGroupKey: @”write” } •In next seed, pass it as an argument when requesting access
  81. Choosing right Facebook Permission Group ACFacebookPermissionGroupRead ACFacebookPermissionGroupWrite user_about_me, user_birthday, ...

    publish_actions friends_about_me, friends_birthday, ... publish_stream email Need permissions from both groups? ACFacebookPermissionGroupReadWrite
  82. The forbidden fruit Facebook Permissions •Extended permissions cannot be requested

    using the iOS API ▪ Reading the user’s timeline ▪ Managing pages
  83. The forbidden fruit Facebook Permissions •Extended permissions cannot be requested

    using the iOS API ▪ Reading the user’s timeline ▪ Managing pages ▪ More in the documentation
  84. Managing Facebook Access •Might lose access at any time ▪

    Token expiration ▪ User removes app from website
  85. Managing Facebook Access •Might lose access at any time ▪

    Token expiration ▪ User removes app from website ▪ User flips switch in Settings
  86. Managing Facebook Access •If server returns error 190, access token

    is invalid •Attempt to renew by calling -[ACAccountStore renewCredentialsForAccount:withHandler:]
  87. Managing Facebook Access •If server returns error 190, access token

    is invalid •Attempt to renew by calling -[ACAccountStore renewCredentialsForAccount:withHandler:] •On completion
  88. Managing Facebook Access •If server returns error 190, access token

    is invalid •Attempt to renew by calling -[ACAccountStore renewCredentialsForAccount:withHandler:] •On completion ACAccountCredentialRenewalRenewed
  89. Managing Facebook Access •If server returns error 190, access token

    is invalid •Attempt to renew by calling -[ACAccountStore renewCredentialsForAccount:withHandler:] •On completion ACAccountCredentialRenewalRenewed ACAccountCredentialRenewalRejected
  90. Managing Facebook Access •If server returns error 190, access token

    is invalid •Attempt to renew by calling -[ACAccountStore renewCredentialsForAccount:withHandler:] •On completion ACAccountCredentialRenewalRenewed ACAccountCredentialRenewalRejected ACAccountCredentialRenewalFailed
  91. More Information Paul Marcos Application Services Evangelist [email protected] Documentation Accounts

    Framework https://developer.apple.com/library/ios/ Social Framework https://developer.apple.com/ue Apple Developer Forums https://devforums.apple.com Third-Party Documentation Facebook SDK https://developers.facebook.com/docs/ Twitter API https://dev.twitter.com/docs Sina Weibo API http://open.weibo.com/wiki/
  92. Summary •UI Integration is easy ▪ On iOS—UIActivityViewController ▪ On

    OS X—NSSharingServicePicker •Advanced integration gives you more control
  93. Summary •UI Integration is easy ▪ On iOS—UIActivityViewController ▪ On

    OS X—NSSharingServicePicker •Advanced integration gives you more control ▪ Accounts framework allows access to user account
  94. Summary •UI Integration is easy ▪ On iOS—UIActivityViewController ▪ On

    OS X—NSSharingServicePicker •Advanced integration gives you more control ▪ Accounts framework allows access to user account ▪ Let SLRequest sign requests for you
  95. Summary •UI Integration is easy ▪ On iOS—UIActivityViewController ▪ On

    OS X—NSSharingServicePicker •Advanced integration gives you more control ▪ Accounts framework allows access to user account ▪ Let SLRequest sign requests for you •FBConnect will get you automatic support