SlideShare uma empresa Scribd logo
1 de 23
Baixar para ler offline
Social.framework
              Account.framework
                  MediaTechnologyLabs
                       黒田 樹




13年1月25日金曜日
自己紹介
  • TwitterID : i2key
  • MediaTecnologyLabsのJavaエンジニア
   • Social x Music App「Attacca」
     • 企画&開発(ObjC/Java)&運用
  • 前職時代はSIerにてアーキテクトとして
      官公庁のシステム開発(Java/C#)に参画

13年1月25日金曜日
Agenda
  •   サンプルアプリの紹介

  •   Tweet / Wall Post

      •   SLComposeViewController

  •   Login

      •   ACAccountStore , ACAccount , ACCredential

  •   Tweet / Wall Post

      •   SLRequest

  •   ReverseAuth

13年1月25日金曜日
サンプルアプリ紹介
再生している曲情報をTwitter/Facebookに投稿
Github : i2key
https://github.com/i2key/SocialframeworkExample




13年1月25日金曜日
13年1月25日金曜日
Tweet/WallPost
    SLComposeViewController

- (IBAction)tweet:(id)sender {
    SLComposeViewController *twitterPostVC
      = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter];
    [twitterPostVC setInitialText:@”メッセージ本文”];
     [twitterPostVC addImage:UIImageクラスによる画像データ];
     [self presentViewController:twitterPostVC animated:YES completion:nil];
}


- (IBAction)postWall:(id)sender {
    SLComposeViewController *facebookPostVC
      = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook];
    [facebookPostVC setInitialText:@”メッセージ本文”];
     [facebookPostVC addImage: UIImageクラスによる画像データ];
     [self presentViewController:facebookPostVC animated:YES completion:nil];
}



    iOS5 : TWTweetComposeViewController
    iOS6 : SLComposeViewController
13年1月25日金曜日
Login(Twitter)
    ACAccountStore, ACAccount

 Accountへのアクセス要求
- (IBAction)showTwitterAccounts:(id)sender {
! ACAccountStore *accountStore = [[ACAccountStore alloc] init];
   ACAccountType *twitterType
      = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter];

    [accountStore requestAccessToAccountsWithType:twitterType
                                          options:Nil
                                       completion:^(BOOL granted, NSError *error) {
        if (granted) {
! !    ! //ActionSheetを表示する処理
! !      }
      }];

}



 Accountを取り出す
self.accounts = [self.accountStore accountsWithAccountType:serviceType];



13年1月25日金曜日
Login(Twitter)
 ACAccountStore, ACAccount




                             入力だるい
                             離脱・・?



13年1月25日金曜日
Login(Twitter)
 ACAccountStore, ACAccount

                             便利になったものの、iOSにアカウント
                             設定していない人は・・?




                             TweetSheetであれば設定へ遷移させる
                             ことが出来るが、この場合は出来ない
                             のでユーザに設定させることになる
                             ・・・離脱・・?
13年1月25日金曜日
Login(Twitter)
 ACAccountStore, ACAccount
                               Migration
                                  to
                              AccountFW
                 設定無し




                                                           Login


                 設定済み
                             Serverでも
iOS5 > version               AccessToken必要
                                             ReverseAuth


13年1月25日金曜日
Login(Facebook)
 ACAccountStore, ACAccount

 Accountへのアクセス要求
- (IBAction)showFacebookAccounts:(id)sender {
 ACAccountType *facebookType
 = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

     NSDictionary *options = @{ACFacebookAppIdKey : @"AppID",
                         ACFacebookPermissionsKey : @[@"email"],
                            ACFacebookAudienceKey : ACFacebookAudienceOnlyMe};

     [self.accountStore requestAccessToAccountsWithType:facebookType
                                                options:options
                                             completion:^(BOOL granted, NSError *error) {
         if(granted){
             //ActionSheet表示する処理
            }
      }];

}

 Accountを取り出す
self.accounts = [self.accountStore accountsWithAccountType:serviceType];

13年1月25日金曜日
Login(Facebook)
 ACAccountStore, ACAccount

 Accountへのアクセス要求
- (IBAction)showFacebookAccounts:(id)sender {
 ACAccountType *facebookType
 = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

     NSDictionary *options = @{ACFacebookAppIdKey : @"AppId",
                         ACFacebookPermissionsKey : @[@"email"],
                            ACFacebookAudienceKey : ACFacebookAudienceOnlyMe};

     [self.accountStore requestAccessToAccountsWithType:facebookType
                                                options:options
                                             completion:^(BOOL granted, NSError *error) {
         if(granted){
             //ActionSheet表示する処理
       ACFacebookAppIdKey : APPID
            }
      }];
       ACFacebookPermissionsKey : 取得したいパーミッション
}

 Accountを取り出す
    ACFacebookAudienceKey           : 開示範囲

self.accounts = [self.accountStore accountsWithAccountType:serviceType];

13年1月25日金曜日
ACFacebookAppIdKey : APPID
ACFacebookPermissionsKey : 取得したいパーミッション
ACFacebookAudienceKey : 開示範囲
              https://developers.facebook.com/apps




13年1月25日金曜日
ACFacebookAppIdKey : APPID
ACFacebookPermissionsKey : 取得したいパーミッション
 ACFacebookAudienceKey : 開示範囲
https://developers.facebook.com/docs/howtos/ios-6/
 Step 1: Request basic profile information
                                            初めから書き込み権限、読み込み要求はNG
                                            例1)ACFacebookPermissionsKey :
 Step 2: Request read permissions
                                             @[@”publish_actions”]

                                            例2)ACFacebookPermissionsKey :
                                             @[@”email”,@”read_stream”]

                                            以下のようなエラーが出る
                                            The Facebook server could not fulfill this
                                            access request: The app must ask for a
                                            basic read permission at install time.”
                                            初めから基本情報権限要求のみはOK
                                            ACFacebookPermissionsKey :
                                             @[@”email”]
  Step 3: Request publish permissions
                                            基本情報権限要求後なら書き込み権限要求OK
                                            ACFacebookPermissionsKey :
                                             @[@”publish_action”]
13年1月25日金曜日
ACFacebookAppIdKey : APPID
ACFacebookPermissionsKey : 取得したいパーミッション
ACFacebookAudienceKey : 開示範囲




13年1月25日金曜日
ACFacebookAppIdKey : APPID
ACFacebookPermissionsKey : 取得したいパーミッション
ACFacebookAudienceKey : 開示範囲




  ACFacebookAudienceEveryone : Posts are visible to everyone.

  ACFacebookAudienceFriends : Posts are visible only to friends.

  ACFacebookAudienceOnlyMe : Posts are visible to the user only.




13年1月25日金曜日
Tweet/WallPost (Twitter)
 SLRequest(iOS5 : TWRequest)

 - (void)tweetUsingSLRequest{
     if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) {
         NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1.1/statuses/update_with_media.json"];
         NSDictionary *params = [NSDictionary dictionaryWithObject:[[MusicManager sharedManager] createShareMessage]
 forKey:@"status"];
         SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter
                                                 requestMethod:SLRequestMethodPOST
                                                           URL:url
                                                    parameters:params];

         NSData *imageData=UIImagePNGRepresentation([[MusicManager sharedManager] trackImage]);
         [request addMultipartData:imageData withName:@"media[]" type:@"multipart/form-data" filename:@"hoge"];

         [request setAccount:self.selectedAccount];
         [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
             NSLog(@"responseData=%@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]);
         }];
     }
 }




13年1月25日金曜日
Tweet/WallPost (Facebook)
    SLRequest
- (void)postWallUsingSLRequest{
    ACAccountStore *accountStore = [[ACAccountStore alloc] init];
    ACAccountType *facebookType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook];

    NSDictionary *options = @{ACFacebookAppIdKey : @"AppID",
                        ACFacebookPermissionsKey : @[@"publish_actions"],
                            ACFacebookAudienceKey : ACFacebookAudienceOnlyMe};

    [accountStore requestAccessToAccountsWithType:facebookType options:options completion:^(BOOL granted, NSError *error) {
        if(granted){
            NSString *urlStr = [NSString stringWithFormat:@"https://graph.facebook.com/me/feed"];
            NSURL *url = [NSURL URLWithString:urlStr];
            NSDictionary *params = @{@"message" : [[MusicManager sharedManager] createShareMessage]};

             SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook
                                                     requestMethod:SLRequestMethodPOST
                                                               URL:url parameters:params];

              [request setAccount:self.selectedAccount];
              [request performRequestWithHandler:^(NSData *response, NSHTTPURLResponse *urlResponse, NSError *error){
                  NSLog(@"response:%@",[[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding]);
              }];
          }else{
              NSLog(@"error post:%@",[error description]);
          }
    }];

}




13年1月25日金曜日
ReverseAuth (Twitter)
    ServerサイドでもTwitterAPIを利用する場合、
    AccessTokenが必要になるが、
    ACAccount.frameworkからは取り出せない




13年1月25日金曜日
ReverseAuth (Twitter)
https://dev.twitter.com/docs/ios/using-reverse-auth
Step1: Special Request Token取得
                 <input>
                          header : consumer_key...etc
                          body: x_auth_mode(reverseauth)
              Singed                                       https://api.twitter.com
                                                           /oauth/request_token
              Request
                          <output>
                          reverseauth用token...etc


Step2: Access Token取得
                          <input>                               Twitter
                          Singned Requestのresponse

              SLRequest ConsumerKey                        https://api.twitter.com
                                                           /oauth/access_token
              ACAcount
                        <output>
                        oauth_token
                        oauth_tokenSecret
                 Social screen_name
              framework user_id
13年1月25日金曜日
ReverseAuth (Twitter)
Step1: Special Request Token取得
   Signed Request(Header)の作り方
     https://dev.twitter.com/docs/auth/authorizing-request




13年1月25日金曜日
ReverseAuth (Twitter)
Step1: Special Request Token取得




   https://github.com/seancook/TWReverseAuthExample
13年1月25日金曜日
ReverseAuth (Twitter)
- (IBAction)reverseAuth:(id)sender {
    // Step 1) Ask Twitter for a special request_token for reverse auth
!   NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN];
!
!   // "reverse_auth" is a required parameter
!   NSDictionary *dict = [NSDictionary dictionaryWithObject:TW_X_AUTH_MODE_REVERSE_AUTH forKey:TW_X_AUTH_MODE_KEY];
!   TWSignedRequest *signedRequest = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST];
!
!   [signedRequest performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
!   !      if (!data) {
!   !      !    [self dismissProgress:@"Error occurred in Step 1."];
!   !      }
!   !      else {
!   !      !    NSString *signedReverseAuthSignature = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
!   !      !
!   !      !    // Step 2) Ask Twitter for the user's auth token and secret
!   !      !    //            include x_reverse_auth_target=CK2 and x_reverse_auth_parameters=signedReverseAuthSignature parameters
!   !      !    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
!   !      !    !     NSDictionary *step2Params = [NSDictionary dictionaryWithObjectsAndKeys:[TWSignedRequest consumerKey], TW_X_AUTH_REVERSE_TARGET,
                                                                                           signedReverseAuthSignature, TW_X_AUTH_REVERSE_PARMS, nil];
!   !      !    !     NSURL *authTokenURL = [NSURL URLWithString:TW_OAUTH_URL_AUTH_TOKEN];

                  //-- iOS5 -----
!       !     !   //TWRequest *step2Request = [[TWRequest alloc] initWithURL:authTokenURL parameters:step2Params requestMethod:TWRequestMethodPOST];
                  //-------------
                  //-- iOS6 -----
!       !     !   !     SLRequest *step2Request = [SLRequest requestForServiceType:SLServiceTypeTwitter
                                                                     requestMethod:SLRequestMethodPOST
                                                                               URL:authTokenURL
                                                                        parameters:step2Params];
                  //-------------

!       !     !   !     [step2Request setAccount:self.selectedAccount];
!       !     !   !     [step2Request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) {
!       !     !   !     !    if (!responseData || ((NSHTTPURLResponse*)response).statusCode >= 400) {
!       !     !   !     !    !     [self dismissProgress:@"Error occurred in Step 2."];
!       !     !   !     !    } else {
!       !     !   !     !    !     NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
                                   NSLog(@"AuthData : %@",responseStr);
    !   !     !   !     !    }
!       !     !   !     }];
!       !     !   });
!       !     }
!       }];
}



13年1月25日金曜日

Mais conteúdo relacionado

Semelhante a Social.framework&Account.framework #twtr_hack

MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!p1us2er0
 
Windows PhoneアプリをSNSとつなげよう
Windows PhoneアプリをSNSとつなげようWindows PhoneアプリをSNSとつなげよう
Windows PhoneアプリをSNSとつなげようjunichi anno
 
Launch a Web Service in 3 Days Using WordPress
Launch a Web Service in 3 Days Using WordPressLaunch a Web Service in 3 Days Using WordPress
Launch a Web Service in 3 Days Using WordPressKite Koga
 
Windows storeアプリ brekky
Windows storeアプリ brekkyWindows storeアプリ brekky
Windows storeアプリ brekkySatoshi Sekine
 
Twitter連携chrome extension作り方
Twitter連携chrome extension作り方Twitter連携chrome extension作り方
Twitter連携chrome extension作り方Hiroshi Oyamada
 
リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)Mariko Goda
 
C#で作成するfacebookアプリ mvp community camp
C#で作成するfacebookアプリ mvp community campC#で作成するfacebookアプリ mvp community camp
C#で作成するfacebookアプリ mvp community campShinichi Hirauchi
 

Semelhante a Social.framework&Account.framework #twtr_hack (8)

MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!MailFluteでメール送信を楽しもう!
MailFluteでメール送信を楽しもう!
 
Windows PhoneアプリをSNSとつなげよう
Windows PhoneアプリをSNSとつなげようWindows PhoneアプリをSNSとつなげよう
Windows PhoneアプリをSNSとつなげよう
 
Launch a Web Service in 3 Days Using WordPress
Launch a Web Service in 3 Days Using WordPressLaunch a Web Service in 3 Days Using WordPress
Launch a Web Service in 3 Days Using WordPress
 
Windows storeアプリ brekky
Windows storeアプリ brekkyWindows storeアプリ brekky
Windows storeアプリ brekky
 
Twitter連携chrome extension作り方
Twitter連携chrome extension作り方Twitter連携chrome extension作り方
Twitter連携chrome extension作り方
 
PFI Seminar 2012/02/24
PFI Seminar 2012/02/24PFI Seminar 2012/02/24
PFI Seminar 2012/02/24
 
リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)リアルFacebookガジェットを作った(ロングバージョン)
リアルFacebookガジェットを作った(ロングバージョン)
 
C#で作成するfacebookアプリ mvp community camp
C#で作成するfacebookアプリ mvp community campC#で作成するfacebookアプリ mvp community camp
C#で作成するfacebookアプリ mvp community camp
 

Mais de Itsuki Kuroda

大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナーItsuki Kuroda
 
カネとAgile(大企業新規事業編) #rsgt2021
カネとAgile(大企業新規事業編) #rsgt2021カネとAgile(大企業新規事業編) #rsgt2021
カネとAgile(大企業新規事業編) #rsgt2021Itsuki Kuroda
 
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumicItsuki Kuroda
 
大企業アジャイルの勘所 #devlovex #devlovexd
大企業アジャイルの勘所 #devlovex #devlovexd大企業アジャイルの勘所 #devlovex #devlovexd
大企業アジャイルの勘所 #devlovex #devlovexdItsuki Kuroda
 
フロー効率性とリソース効率性、再入門 #devlove #devkan
フロー効率性とリソース効率性、再入門 #devlove #devkanフロー効率性とリソース効率性、再入門 #devlove #devkan
フロー効率性とリソース効率性、再入門 #devlove #devkanItsuki Kuroda
 
カネとAgile #RSGT2018
カネとAgile #RSGT2018カネとAgile #RSGT2018
カネとAgile #RSGT2018Itsuki Kuroda
 
Leanstartupをリーンにヤル #リーンスタートアップ
Leanstartupをリーンにヤル #リーンスタートアップLeanstartupをリーンにヤル #リーンスタートアップ
Leanstartupをリーンにヤル #リーンスタートアップItsuki Kuroda
 
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartupItsuki Kuroda
 
フロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugフロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugItsuki Kuroda
 
事業が対峙する現実からエンジニアリングを俯瞰する #devlove
事業が対峙する現実からエンジニアリングを俯瞰する #devlove事業が対峙する現実からエンジニアリングを俯瞰する #devlove
事業が対峙する現実からエンジニアリングを俯瞰する #devloveItsuki Kuroda
 
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkan
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkanリーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkan
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkanItsuki Kuroda
 
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumiItsuki Kuroda
 
LEANSTARTUPアンチパターン #devlove #leanstartup
LEANSTARTUPアンチパターン #devlove #leanstartupLEANSTARTUPアンチパターン #devlove #leanstartup
LEANSTARTUPアンチパターン #devlove #leanstartupItsuki Kuroda
 
日経BPリーン式創業塾 #leanstartup #リーンスタートアップ
日経BPリーン式創業塾 #leanstartup #リーンスタートアップ日経BPリーン式創業塾 #leanstartup #リーンスタートアップ
日経BPリーン式創業塾 #leanstartup #リーンスタートアップItsuki Kuroda
 
LEAN STARTUP OVERVIEW
LEAN STARTUP OVERVIEWLEAN STARTUP OVERVIEW
LEAN STARTUP OVERVIEWItsuki Kuroda
 
エンジニアが成長のエンジンになる日 #devsumi #natsumiC7
エンジニアが成長のエンジンになる日 #devsumi  #natsumiC7エンジニアが成長のエンジンになる日 #devsumi  #natsumiC7
エンジニアが成長のエンジンになる日 #devsumi #natsumiC7Itsuki Kuroda
 
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiBItsuki Kuroda
 
LEANSTARTUPの現場 #leanstartup
LEANSTARTUPの現場 #leanstartupLEANSTARTUPの現場 #leanstartup
LEANSTARTUPの現場 #leanstartupItsuki Kuroda
 
リーンスタートアップ概論
リーンスタートアップ概論リーンスタートアップ概論
リーンスタートアップ概論Itsuki Kuroda
 
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove 社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove Itsuki Kuroda
 

Mais de Itsuki Kuroda (20)

大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
大企業アジャイルの勘所(ver1.1) #アジャイルマネジメントセミナー
 
カネとAgile(大企業新規事業編) #rsgt2021
カネとAgile(大企業新規事業編) #rsgt2021カネとAgile(大企業新規事業編) #rsgt2021
カネとAgile(大企業新規事業編) #rsgt2021
 
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic
大規模レガシー環境に立ち向かう有機的な開発フォーメーション #devsumi #devsumic
 
大企業アジャイルの勘所 #devlovex #devlovexd
大企業アジャイルの勘所 #devlovex #devlovexd大企業アジャイルの勘所 #devlovex #devlovexd
大企業アジャイルの勘所 #devlovex #devlovexd
 
フロー効率性とリソース効率性、再入門 #devlove #devkan
フロー効率性とリソース効率性、再入門 #devlove #devkanフロー効率性とリソース効率性、再入門 #devlove #devkan
フロー効率性とリソース効率性、再入門 #devlove #devkan
 
カネとAgile #RSGT2018
カネとAgile #RSGT2018カネとAgile #RSGT2018
カネとAgile #RSGT2018
 
Leanstartupをリーンにヤル #リーンスタートアップ
Leanstartupをリーンにヤル #リーンスタートアップLeanstartupをリーンにヤル #リーンスタートアップ
Leanstartupをリーンにヤル #リーンスタートアップ
 
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup結果的に組織がAgileな状態であること #agile #scrum #leanstartup
結果的に組織がAgileな状態であること #agile #scrum #leanstartup
 
フロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjugフロー効率性とリソース効率性について #xpjug
フロー効率性とリソース効率性について #xpjug
 
事業が対峙する現実からエンジニアリングを俯瞰する #devlove
事業が対峙する現実からエンジニアリングを俯瞰する #devlove事業が対峙する現実からエンジニアリングを俯瞰する #devlove
事業が対峙する現実からエンジニアリングを俯瞰する #devlove
 
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkan
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkanリーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkan
リーンスタートアップと顧客開発とアジャイル開発を一気通貫するッ #devlove #devkan
 
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi
新規事業が対峙する現実からエンジニアリングを俯瞰する #devsumiB #devsumi
 
LEANSTARTUPアンチパターン #devlove #leanstartup
LEANSTARTUPアンチパターン #devlove #leanstartupLEANSTARTUPアンチパターン #devlove #leanstartup
LEANSTARTUPアンチパターン #devlove #leanstartup
 
日経BPリーン式創業塾 #leanstartup #リーンスタートアップ
日経BPリーン式創業塾 #leanstartup #リーンスタートアップ日経BPリーン式創業塾 #leanstartup #リーンスタートアップ
日経BPリーン式創業塾 #leanstartup #リーンスタートアップ
 
LEAN STARTUP OVERVIEW
LEAN STARTUP OVERVIEWLEAN STARTUP OVERVIEW
LEAN STARTUP OVERVIEW
 
エンジニアが成長のエンジンになる日 #devsumi #natsumiC7
エンジニアが成長のエンジンになる日 #devsumi  #natsumiC7エンジニアが成長のエンジンになる日 #devsumi  #natsumiC7
エンジニアが成長のエンジンになる日 #devsumi #natsumiC7
 
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について45分拡大版 #devsumi #devsumiB
 
LEANSTARTUPの現場 #leanstartup
LEANSTARTUPの現場 #leanstartupLEANSTARTUPの現場 #leanstartup
LEANSTARTUPの現場 #leanstartup
 
リーンスタートアップ概論
リーンスタートアップ概論リーンスタートアップ概論
リーンスタートアップ概論
 
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove 社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove
社内スタートアップによる組織の成長に伴い発生する痛みとその解決策について(Rebuild) #devlove
 

Social.framework&Account.framework #twtr_hack

  • 1. Social.framework Account.framework MediaTechnologyLabs 黒田 樹 13年1月25日金曜日
  • 2. 自己紹介 • TwitterID : i2key • MediaTecnologyLabsのJavaエンジニア • Social x Music App「Attacca」 • 企画&開発(ObjC/Java)&運用 • 前職時代はSIerにてアーキテクトとして 官公庁のシステム開発(Java/C#)に参画 13年1月25日金曜日
  • 3. Agenda • サンプルアプリの紹介 • Tweet / Wall Post • SLComposeViewController • Login • ACAccountStore , ACAccount , ACCredential • Tweet / Wall Post • SLRequest • ReverseAuth 13年1月25日金曜日
  • 6. Tweet/WallPost SLComposeViewController - (IBAction)tweet:(id)sender { SLComposeViewController *twitterPostVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeTwitter]; [twitterPostVC setInitialText:@”メッセージ本文”]; [twitterPostVC addImage:UIImageクラスによる画像データ]; [self presentViewController:twitterPostVC animated:YES completion:nil]; } - (IBAction)postWall:(id)sender { SLComposeViewController *facebookPostVC = [SLComposeViewController composeViewControllerForServiceType:SLServiceTypeFacebook]; [facebookPostVC setInitialText:@”メッセージ本文”]; [facebookPostVC addImage: UIImageクラスによる画像データ]; [self presentViewController:facebookPostVC animated:YES completion:nil]; } iOS5 : TWTweetComposeViewController iOS6 : SLComposeViewController 13年1月25日金曜日
  • 7. Login(Twitter) ACAccountStore, ACAccount Accountへのアクセス要求 - (IBAction)showTwitterAccounts:(id)sender { ! ACAccountStore *accountStore = [[ACAccountStore alloc] init]; ACAccountType *twitterType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierTwitter]; [accountStore requestAccessToAccountsWithType:twitterType options:Nil completion:^(BOOL granted, NSError *error) { if (granted) { ! ! ! //ActionSheetを表示する処理 ! ! } }]; } Accountを取り出す self.accounts = [self.accountStore accountsWithAccountType:serviceType]; 13年1月25日金曜日
  • 8. Login(Twitter) ACAccountStore, ACAccount 入力だるい 離脱・・? 13年1月25日金曜日
  • 9. Login(Twitter) ACAccountStore, ACAccount 便利になったものの、iOSにアカウント 設定していない人は・・? TweetSheetであれば設定へ遷移させる ことが出来るが、この場合は出来ない のでユーザに設定させることになる ・・・離脱・・? 13年1月25日金曜日
  • 10. Login(Twitter) ACAccountStore, ACAccount Migration to AccountFW 設定無し Login 設定済み Serverでも iOS5 > version AccessToken必要 ReverseAuth 13年1月25日金曜日
  • 11. Login(Facebook) ACAccountStore, ACAccount Accountへのアクセス要求 - (IBAction)showFacebookAccounts:(id)sender { ACAccountType *facebookType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; NSDictionary *options = @{ACFacebookAppIdKey : @"AppID", ACFacebookPermissionsKey : @[@"email"], ACFacebookAudienceKey : ACFacebookAudienceOnlyMe}; [self.accountStore requestAccessToAccountsWithType:facebookType options:options completion:^(BOOL granted, NSError *error) { if(granted){ //ActionSheet表示する処理 } }]; } Accountを取り出す self.accounts = [self.accountStore accountsWithAccountType:serviceType]; 13年1月25日金曜日
  • 12. Login(Facebook) ACAccountStore, ACAccount Accountへのアクセス要求 - (IBAction)showFacebookAccounts:(id)sender { ACAccountType *facebookType = [self.accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; NSDictionary *options = @{ACFacebookAppIdKey : @"AppId", ACFacebookPermissionsKey : @[@"email"], ACFacebookAudienceKey : ACFacebookAudienceOnlyMe}; [self.accountStore requestAccessToAccountsWithType:facebookType options:options completion:^(BOOL granted, NSError *error) { if(granted){ //ActionSheet表示する処理 ACFacebookAppIdKey : APPID } }]; ACFacebookPermissionsKey : 取得したいパーミッション } Accountを取り出す ACFacebookAudienceKey : 開示範囲 self.accounts = [self.accountStore accountsWithAccountType:serviceType]; 13年1月25日金曜日
  • 13. ACFacebookAppIdKey : APPID ACFacebookPermissionsKey : 取得したいパーミッション ACFacebookAudienceKey : 開示範囲 https://developers.facebook.com/apps 13年1月25日金曜日
  • 14. ACFacebookAppIdKey : APPID ACFacebookPermissionsKey : 取得したいパーミッション ACFacebookAudienceKey : 開示範囲 https://developers.facebook.com/docs/howtos/ios-6/ Step 1: Request basic profile information 初めから書き込み権限、読み込み要求はNG 例1)ACFacebookPermissionsKey : Step 2: Request read permissions @[@”publish_actions”] 例2)ACFacebookPermissionsKey : @[@”email”,@”read_stream”] 以下のようなエラーが出る The Facebook server could not fulfill this access request: The app must ask for a basic read permission at install time.” 初めから基本情報権限要求のみはOK ACFacebookPermissionsKey : @[@”email”] Step 3: Request publish permissions 基本情報権限要求後なら書き込み権限要求OK ACFacebookPermissionsKey : @[@”publish_action”] 13年1月25日金曜日
  • 15. ACFacebookAppIdKey : APPID ACFacebookPermissionsKey : 取得したいパーミッション ACFacebookAudienceKey : 開示範囲 13年1月25日金曜日
  • 16. ACFacebookAppIdKey : APPID ACFacebookPermissionsKey : 取得したいパーミッション ACFacebookAudienceKey : 開示範囲 ACFacebookAudienceEveryone : Posts are visible to everyone. ACFacebookAudienceFriends : Posts are visible only to friends. ACFacebookAudienceOnlyMe : Posts are visible to the user only. 13年1月25日金曜日
  • 17. Tweet/WallPost (Twitter) SLRequest(iOS5 : TWRequest) - (void)tweetUsingSLRequest{ if ([SLComposeViewController isAvailableForServiceType:SLServiceTypeTwitter]) { NSURL *url = [NSURL URLWithString:@"http://api.twitter.com/1.1/statuses/update_with_media.json"]; NSDictionary *params = [NSDictionary dictionaryWithObject:[[MusicManager sharedManager] createShareMessage] forKey:@"status"]; SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:url parameters:params]; NSData *imageData=UIImagePNGRepresentation([[MusicManager sharedManager] trackImage]); [request addMultipartData:imageData withName:@"media[]" type:@"multipart/form-data" filename:@"hoge"]; [request setAccount:self.selectedAccount]; [request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { NSLog(@"responseData=%@", [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]); }]; } } 13年1月25日金曜日
  • 18. Tweet/WallPost (Facebook) SLRequest - (void)postWallUsingSLRequest{ ACAccountStore *accountStore = [[ACAccountStore alloc] init]; ACAccountType *facebookType = [accountStore accountTypeWithAccountTypeIdentifier:ACAccountTypeIdentifierFacebook]; NSDictionary *options = @{ACFacebookAppIdKey : @"AppID", ACFacebookPermissionsKey : @[@"publish_actions"], ACFacebookAudienceKey : ACFacebookAudienceOnlyMe}; [accountStore requestAccessToAccountsWithType:facebookType options:options completion:^(BOOL granted, NSError *error) { if(granted){ NSString *urlStr = [NSString stringWithFormat:@"https://graph.facebook.com/me/feed"]; NSURL *url = [NSURL URLWithString:urlStr]; NSDictionary *params = @{@"message" : [[MusicManager sharedManager] createShareMessage]}; SLRequest *request = [SLRequest requestForServiceType:SLServiceTypeFacebook requestMethod:SLRequestMethodPOST URL:url parameters:params]; [request setAccount:self.selectedAccount]; [request performRequestWithHandler:^(NSData *response, NSHTTPURLResponse *urlResponse, NSError *error){ NSLog(@"response:%@",[[NSString alloc]initWithData:response encoding:NSUTF8StringEncoding]); }]; }else{ NSLog(@"error post:%@",[error description]); } }]; } 13年1月25日金曜日
  • 19. ReverseAuth (Twitter) ServerサイドでもTwitterAPIを利用する場合、 AccessTokenが必要になるが、 ACAccount.frameworkからは取り出せない 13年1月25日金曜日
  • 20. ReverseAuth (Twitter) https://dev.twitter.com/docs/ios/using-reverse-auth Step1: Special Request Token取得 <input> header : consumer_key...etc body: x_auth_mode(reverseauth) Singed https://api.twitter.com /oauth/request_token Request <output> reverseauth用token...etc Step2: Access Token取得 <input> Twitter Singned Requestのresponse SLRequest ConsumerKey https://api.twitter.com /oauth/access_token ACAcount <output> oauth_token oauth_tokenSecret Social screen_name framework user_id 13年1月25日金曜日
  • 21. ReverseAuth (Twitter) Step1: Special Request Token取得 Signed Request(Header)の作り方 https://dev.twitter.com/docs/auth/authorizing-request 13年1月25日金曜日
  • 22. ReverseAuth (Twitter) Step1: Special Request Token取得 https://github.com/seancook/TWReverseAuthExample 13年1月25日金曜日
  • 23. ReverseAuth (Twitter) - (IBAction)reverseAuth:(id)sender { // Step 1) Ask Twitter for a special request_token for reverse auth ! NSURL *url = [NSURL URLWithString:TW_OAUTH_URL_REQUEST_TOKEN]; ! ! // "reverse_auth" is a required parameter ! NSDictionary *dict = [NSDictionary dictionaryWithObject:TW_X_AUTH_MODE_REVERSE_AUTH forKey:TW_X_AUTH_MODE_KEY]; ! TWSignedRequest *signedRequest = [[TWSignedRequest alloc] initWithURL:url parameters:dict requestMethod:TWSignedRequestMethodPOST]; ! ! [signedRequest performRequestWithHandler:^(NSData *data, NSURLResponse *response, NSError *error) { ! ! if (!data) { ! ! ! [self dismissProgress:@"Error occurred in Step 1."]; ! ! } ! ! else { ! ! ! NSString *signedReverseAuthSignature = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; ! ! ! ! ! ! // Step 2) Ask Twitter for the user's auth token and secret ! ! ! // include x_reverse_auth_target=CK2 and x_reverse_auth_parameters=signedReverseAuthSignature parameters ! ! ! dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ ! ! ! ! NSDictionary *step2Params = [NSDictionary dictionaryWithObjectsAndKeys:[TWSignedRequest consumerKey], TW_X_AUTH_REVERSE_TARGET, signedReverseAuthSignature, TW_X_AUTH_REVERSE_PARMS, nil]; ! ! ! ! NSURL *authTokenURL = [NSURL URLWithString:TW_OAUTH_URL_AUTH_TOKEN]; //-- iOS5 ----- ! ! ! //TWRequest *step2Request = [[TWRequest alloc] initWithURL:authTokenURL parameters:step2Params requestMethod:TWRequestMethodPOST]; //------------- //-- iOS6 ----- ! ! ! ! SLRequest *step2Request = [SLRequest requestForServiceType:SLServiceTypeTwitter requestMethod:SLRequestMethodPOST URL:authTokenURL parameters:step2Params]; //------------- ! ! ! ! [step2Request setAccount:self.selectedAccount]; ! ! ! ! [step2Request performRequestWithHandler:^(NSData *responseData, NSHTTPURLResponse *urlResponse, NSError *error) { ! ! ! ! ! if (!responseData || ((NSHTTPURLResponse*)response).statusCode >= 400) { ! ! ! ! ! ! [self dismissProgress:@"Error occurred in Step 2."]; ! ! ! ! ! } else { ! ! ! ! ! ! NSString *responseStr = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding]; NSLog(@"AuthData : %@",responseStr); ! ! ! ! ! } ! ! ! ! }]; ! ! ! }); ! ! } ! }]; } 13年1月25日金曜日