[iOS] Fabric 入門 #7 Twitter に画像付きツイートを投稿する (REST API 編)

2015.02.06

画像付きツイートを投稿する

前回は REST API からツイートを投稿する実装方法を紹介しました。このままでは文章しか送れませんが、POST media/upload を併用することで画像付きツイートを投稿することができます。

ちなみに以前までは POST statuses/update_with_media を利用していましたが、こちらの API は Deprecated (非推奨) になりました。 POST statuses/update のリクエストパラメータに media_ids を付ける方法が推奨されています。

POST media/upload を使って画像ファイルをアップロードする

ということで、画像ファイルをアップロードしてツイートに貼り付けてみます。iOS 7 から NSData#base64EncodedStringWithOptions が利用できるようになったので、Base64 エンコーディングも簡単です。前回ご紹介したツイートを投稿する実装と組み合わせることで、簡単に実装できます。

#import "ViewController.h"
#import <TwitterKit/TwitterKit.h>
  
@interface ViewController ()
  
@property (weak, nonatomic) TWTRLogInButton *logInButton;
  
@end
  
@implementation ViewController
  
- (void)viewDidLoad {
    [super viewDidLoad];
      
    // TWTRLogInButtonの設定
    TWTRLogInButton *logInButton = [TWTRLogInButton buttonWithLogInCompletion:^(TWTRSession *session, NSError *error) {
        if (error) {
            NSLog(@"Error : %@", error);
        } else {
            NSLog(@"UserName : %@", session.userName);
            self.logInButton.hidden = YES;
            [self uploadImage];
        }
    }];
    logInButton.center = self.view.center;
    self.logInButton = logInButton;
    [self.view addSubview:logInButton];
}
 
- (void)uploadImage
{
    NSString *endpoint = @"https://upload.twitter.com/1.1/media/upload.json";
    UIImage *image = [UIImage imageNamed:@"Sample"];
    NSData* imageData = UIImagePNGRepresentation(image);
    NSDictionary *parameters = @{@"media":[imageData base64EncodedStringWithOptions:NSDataBase64EncodingEndLineWithLineFeed]};
    NSError *error = nil;
    TWTRAPIClient *client = [[Twitter sharedInstance] APIClient];
    NSURLRequest *request = [client URLRequestWithMethod:@"POST"
                                                     URL:endpoint
                                              parameters:parameters
                                                   error:&error];
    if (error) {
        NSLog(@"Error: %@", error);
        return;
    }
    [client sendTwitterRequest:request
                    completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                        if (connectionError) {
                            NSLog(@"Error: %@", error);
                            return;
                        }
                        NSError *jsonError = nil;
                        id jsonData = [NSJSONSerialization JSONObjectWithData:data
                                                                      options:NSJSONReadingMutableContainers
                                                                        error:&jsonError];
                        if (jsonError) {
                            NSLog(@"Error: %@", jsonError);
                            return;
                        }
                        NSLog(@"Result : %@", jsonData);
                        NSString *mediaId = jsonData[@"media_id_string"];
                        [self composeTweetREST:mediaId];
                    }];
}
 
- (void)composeTweetREST:(NSString *)mediaId
{
    // タイムラインを取得
    NSString *endpoint = @"https://api.twitter.com/1.1/statuses/update.json";
    NSDictionary *parameters = @{@"status":@"ダンソン フィーザキー トゥーザフィーザーザ コンサ",
                                 @"media_ids":mediaId};
    NSError *error = nil;
    TWTRAPIClient *client = [[Twitter sharedInstance] APIClient];
    NSURLRequest *request = [client URLRequestWithMethod:@"POST"
                                                     URL:endpoint
                                              parameters:parameters
                                                   error:&error];
    if (error) {
        NSLog(@"Error: %@", error);
        return;
    }
    [client sendTwitterRequest:request
                    completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
                        if (connectionError) {
                            NSLog(@"Error: %@", error);
                            return;
                        }
                        NSError *jsonError = nil;
                        id jsonData = [NSJSONSerialization JSONObjectWithData:data
                                                                      options:NSJSONReadingMutableContainers
                                                                        error:&jsonError];
                        if (jsonError) {
                            NSLog(@"Error: %@", jsonError);
                            return;
                        }
                        NSLog(@"Result : %@", jsonData);
                    }];
}
 
@end

POST media/upload API に対しては media パラメータに NSData を Base64 エンコーディングしてセットします。正常にアップロードが完了すると、レスポンスの media_id_string で メディアの ID が取得できるので、POST statuses/update のリクエストパラメータである media_ids にセットします。こうすることで、アップロードしたメディアを添付したツイートが投稿できます。

upload_media

なお media_ids で分かるように、複数のメディアをセットすることもできます。

まとめ

カメラアプリでよく見かける「ついでにツイッターに投稿しておく」的な機能が実装できました。こちらも利用する機会の多い実装ですので、ぜひ参考にしてください。

参考