如何通过hashtag检索推文而无需身份验证?

时间:2013-10-30 09:56:52

标签: ios iphone twitter

我需要使用Twitter API 1.1更新我的应用程序。 以前我使用以下网址检索推文:

  

http://search.twitter.com/search.json?tag=ios&rpp=25

但现在它不起作用。 我尝试使用Twitter API文档中的以下URL:

  

https://api.twitter.com/1.1/search/tweets.json?q=%23freebandnames&since_id=24012619984051000&max_id=250126199840518145&result_type=mixed&count=4

但它返回以下错误:

{"errors":[{"message":"Bad Authentication data","code":215}]}

如何检索这些推文?

我想使用Twitter.framework,但任何建议都将受到赞赏。

2 个答案:

答案 0 :(得分:6)

我找到了解决方案。 Twitter接受two types of authentication进行tweest检索:

  1. 应用程序用户身份验证
  2. 仅应用程序身份验证 第一种类型需要登录和传递,第二种类型不需要,但它需要bearer token
  3. 首先,我的请求以下列方式查看:

    NSURL *URL = [NSURL URLWithString:@"http://search.twitter.com/search.json?tag=ios&rpp=25"];
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];   
    NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
    

    现在看起来如下:

    if(self.bearerToken == nil) return;
    NSURL *URL = [NSURL URLWithString:@"https://api.twitter.com/1.1/search/tweets.json?q=%%23ios&count=25"];
    NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:URL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:30.0];
    [urlRequest setValue:[NSString stringWithFormat:@"Bearer %@", self.bearerToken] forHTTPHeaderField:@"Authorization"];
    NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
    

    此方法还需要添加两个方法bearerToken_base64Encode

    - (NSString *)bearerToken
    {
        if(_bearerToken == nil)
        {
            NSString * consumerKey = [config.consumerKey stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
            NSString * consumerSecret = [config.consumerSecret stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
            //the combined authentication key is "CONSUMER_KEY:CONSUMER_SECRET" run through base64 encoding.
            //we'll use NSData instead of NSString here so that we can feed it directly to the HTTPRequest later.
            NSString * combinedKey = [[self class] _base64Encode:[[NSString stringWithFormat:@"%@:%@", consumerKey, consumerSecret] dataUsingEncoding:NSUTF8StringEncoding]];
    
            NSMutableURLRequest *urlRequest = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"https://api.twitter.com/oauth2/token"]];
            [urlRequest setHTTPMethod:@"POST"];
            [urlRequest setValue:[NSString stringWithFormat:@"Basic %@", combinedKey] forHTTPHeaderField:@"Authorization"];
            [urlRequest setValue:[NSString stringWithFormat:@"application/x-www-form-urlencoded;charset=UTF-8"] forHTTPHeaderField:@"Content-Type"];
            [urlRequest setHTTPBody:[@"grant_type=client_credentials" dataUsingEncoding:NSUTF8StringEncoding]];
            NSData *data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
            NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
            _bearerToken = [responseJSON valueForKey:@"access_token"];
        }
        return _bearerToken;
    }
    +(NSString *)_base64Encode:(NSData *)data{
        //Point to start of the data and set buffer sizes
        int inLength = [data length];
        int outLength = ((((inLength * 4)/3)/4)*4) + (((inLength * 4)/3)%4 ? 4 : 0);
        const char *inputBuffer = [data bytes];
        char *outputBuffer = malloc(outLength);
        outputBuffer[outLength] = 0;
    
        //64 digit code
        static char Encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
    
        //start the count
        int cycle = 0;
        int inpos = 0;
        int outpos = 0;
        char temp;
    
        //Pad the last to bytes, the outbuffer must always be a multiple of 4
        outputBuffer[outLength-1] = '=';
        outputBuffer[outLength-2] = '=';
    
        /* http://en.wikipedia.org/wiki/Base64
         Text content   M           a           n
         ASCII          77          97          110
         8 Bit pattern  01001101    01100001    01101110
    
         6 Bit pattern  010011  010110  000101  101110
         Index          19      22      5       46
         Base64-encoded T       W       F       u
         */
    
    
        while (inpos < inLength){
            switch (cycle) {
                case 0:
                    outputBuffer[outpos++] = Encode[(inputBuffer[inpos]&0xFC)>>2];
                    cycle = 1;
                    break;
                case 1:
                    temp = (inputBuffer[inpos++]&0x03)<<4;
                    outputBuffer[outpos] = Encode[temp];
                    cycle = 2;
                    break;
                case 2:
                    outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xF0)>> 4];
                    temp = (inputBuffer[inpos++]&0x0F)<<2;
                    outputBuffer[outpos] = Encode[temp];
                    cycle = 3;
                    break;
                case 3:
                    outputBuffer[outpos++] = Encode[temp|(inputBuffer[inpos]&0xC0)>>6];
                    cycle = 4;
                    break;
                case 4:
                    outputBuffer[outpos++] = Encode[inputBuffer[inpos++]&0x3f];
                    cycle = 0;
                    break;
                default:
                    cycle = 0;
                    break;
            }
        }
        NSString *pictemp = [NSString stringWithUTF8String:outputBuffer];
        free(outputBuffer);
        return pictemp;
    }
    

    响应也发生了变化,所以我不得不改变解析器。 以前的版本:

    NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithString:jsonStr];
    if (responseDictionary)
    {
        id data = responseDictionary[@"results"];
        if ([data isKindOfClass:NSArray.class])
        {
            NSArray *dataArray = (NSArray*)data;
            for (NSDictionary *post in dataArray)
            {
                    avatarUrl = post[@"profile_image_url"];
                author = post[@"from_user"];
                message = post[@"text"];
    
                    NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
                    [inputFormatter setDateFormat:@"EEE',' dd MMM yyyy HH:mm:ss ZZZZ"];
                date = [inputFormatter dateFromString: post[@"created_at"]];
            }
        }
    }
    

    当前版本:

    NSDictionary *responseDictionary = [NSJSONSerialization JSONObjectWithString:jsonStr];
    if (responseDictionary)
    {
        id data = [responseDictionary valueForKey:@"statuses"];
        if ([data isKindOfClass:NSArray.class])
        {
            NSArray *dataArray = (NSArray*)data;
            for (NSDictionary *post in dataArray)
            {               
                avatarUrl = post[@"user"][@"profile_image_url"];
                author = post[@"user" ][@"name"];;
                message = post[@"text"];         
                        NSDateFormatter *inputFormatter = [[NSDateFormatter alloc] init];
                        [inputFormatter setDateFormat:@"EEE MMM dd HH:mm:ss ZZZZ yyyy"];
                    date = [inputFormatter dateFromString: post[@"created_at"]];
            }
        }
    }
    

答案 1 :(得分:1)

根据this doc,如果没有Hashtag feed,则无法抓取Authentication

但您可以在服务器端管理它。在服务器端,您可以在AuthenticateTwitter并从Twitter获取Hash tag feed(此处还需要进行身份验证以获取Feed)。因此,当用户Authenticate iPhone时,您必须致电Web Service并且网络服务将返回您在服务器端代码管理的HashTag feed

如果在iOS设备(iPhone)上使用已验证,则可以使用iOS获取Feed。