如何使用iOS向Twitter好友发送直接消息

时间:2016-04-20 22:12:35

标签: ios post twitter

我想直接向Twitter好友发送消息。我使用以下代码(appdelegate.twitterAccount是来自iOS ACAccountStore的Twitter帐户):

AppDelegate *appdelegate = (AppDelegate *)[UIApplication sharedApplication].delegate;
NSString *idString = @"123456789"; // should be some read user_id
NSString *urlString = @"https://api.twitter.com/1.1/direct_messages/new.json?";
NSURL *postDirectMessageRequestURL = [NSURL URLWithString:urlString];
NSDictionary *parameters = @{@"user_id": idString,
                             @"text": @"some text"};
SLRequest *postDirectMessageRequest = [SLRequest requestForServiceType:SLServiceTypeTwitter 
                                                         requestMethod:SLRequestMethodPOST 
                                                                   URL:postDirectMessageRequestURL 
                                                            parameters:parameters];
postDirectMessageRequest.account = appdelegate.twitterAccount;
[postDirectMessageRequest performRequestWithHandler:^(NSData *data, NSHTTPURLResponse *urlResponse, NSError *error) {
    if (nil != error) {
        NSLog(@"Error: %@", error);
    } else {
        NSLog(@"urlResponse: %@", urlResponse);
    }
}];

不幸的是,我收到了以下错误,尽管在iOS中正确设置了Twitter帐户:

Error Domain=kCFErrorDomainCFNetwork Code=-1012 "(null)" UserInfo={_kCFURLErrorAuthFailedResponseKey=<CFURLResponse 0x160352490 [0x19ebeb150]>{url = https://api.twitter.com/1.1/direct_messages/new.json?}}}, NSErrorFailingURLKey=https://api.twitter.com/1.1/direct_messages/new.json?}

因此,身份验证出了问题,但是什么?

1 个答案:

答案 0 :(得分:0)

对于出现问题的简单答案(可能是错误的,见下文)是由iOS登录到Twitter的应用程序没有直接的消息许可,如所使用的Twitter帐户的“应用程序”设置中所示:
enter image description here 对不起德国人。它表示读写许可,即没有直接的消息许可。

我使用Fabric和Twitter框架解决了这个问题 我下载了Mac Fabric app,可以让您轻松安装Twitter框架。它甚至可以让你复制和粘贴所需的基本代码 我为我定义了一个包含以下方法的Twitter_Helper类:

+(void)twitterInit {
    [Fabric with:@[[Twitter class]]]; // initialize Twitter
}

+(void)loginCompletion:(void(^)(TWTRSession *, NSError *))completionBlock_ {
    [[Twitter sharedInstance] logInWithMethods:TWTRLoginMethodSystemAccounts | TWTRLoginMethodWebBased 
                                    completion:^(TWTRSession *session, NSError *error) {
        if (nil == session) {
            NSLog(@"error: %@", [error localizedDescription]);
        }
        completionBlock_(session, error);
    }];
}

+(TWTRAPIClient *)getTwitterClientForCurrentSession {
    NSString *userID = [Twitter sharedInstance].sessionStore.session.userID;
    TWTRAPIClient *client = [[TWTRAPIClient alloc] initWithUserID:userID];
    return client;
}

+(void)loadFollowersOfUserWithId:(NSString *)userId completion:(void(^)(NSDictionary *, NSError *))completionBlock_ {
    TWTRAPIClient *client = [Twitter_Helper getTwitterClientForCurrentSession];
    NSString *loadFollowersEndpoint = @"https://api.twitter.com/1.1/followers/ids.json";
    NSDictionary *params = @{@"user_id" : userId};
    NSError *clientError;

    NSURLRequest *request = [client URLRequestWithMethod:@"GET" URL:loadFollowersEndpoint parameters:params error:&clientError];

    if (request) {
        [client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            if (data) {
                NSDictionary *followersDictionary = [NSJSONSerialization JSONObjectWithData:data
                                                                                  options:NSJSONReadingMutableContainers
                                                                                    error:nil];
                completionBlock_(followersDictionary, nil);
            }
            else {
                completionBlock_(nil, connectionError);
            }
        }];
    }
    else {
        completionBlock_(nil, clientError);
    }
}

+(void)sendDirectMessage:(NSString *)message toUserWithId:(NSString *)userId completion:(void(^)(NSError *))completionBlock_ {
    TWTRAPIClient *client = [Twitter_Helper getTwitterClientForCurrentSession];
    NSString *sendDirectMessageEndpoint = @"https://api.twitter.com/1.1/direct_messages/new.json";
    NSDictionary *params = @{@"user_id" : userId,
                             @"text"    : message};
    NSError *clientError;

    NSURLRequest *request = [client URLRequestWithMethod:@"POST" URL:sendDirectMessageEndpoint parameters:params error:&clientError];

    if (request) {
        [client sendTwitterRequest:request completion:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
            completionBlock_(connectionError);
        }];
    }
    else {
        completionBlock_(clientError);
    }
}

当我想向用户的关注者发送直接消息时(我只能向关注者发送直接消息),我使用loginCompletion:登录用户,通过{{1}加载用户的关注者ID },然后按loadFollowersOfUserWithId:completion:发送消息 这没有任何问题。

我不明白的是:
我首先使用sendDirectMessage:toUserWithId:completion:登录,因为Twitter docs说:
TWTRLoginMethodWebBased 尝试使用系统帐户登录用户。此登录方法仅向返回的oauth令牌授予有限的应用程序权限。如果您希望获得更多应用程序权限,则必须使用TWTRLoginMethodWebBased并正确配置您的应用程序。
TWTRLoginMethodSystemAccounts 提供允许用户登录的Web视图。此方法允许开发人员请求更多应用程序权限。

但是,当我使用TWTRLoginMethodWebBased登录时,我没有机会申请直接邮件权限。这是登录界面:
enter image description here

它说我没有获得直接的消息许可,当我查找应用程序设置时,该权限确实只是读写: enter image description here 更奇怪的是,当我使用TWTRLoginMethodWebBased登录时,我也可以发送直接消息。也许直接邮件权限只需要阅读或删除直接邮件,但不能用于发送,但我回到原来的问题...