我正在编写一个从 Yelp 请求数据的 iOS 应用程序。
我目前有管理 Yelp 请求/响应并解析内部返回的 JSON 数据的代码。当前代码使用 Jon Crosby 的 OAuthConsumer 为其请求构建 OAuth 参数。
我昨天遇到了 RestKit,发现它非常吸引人。它可能会消除我正在做的大部分请求提交和响应解析。
但是我遇到了障碍,因为我无法弄清楚如何使用 RestKit 生成 Yelp 所需的 OAuth 参数。我在http://www.raywenderlich.com/13097/intro-to-restkit-tutorial完成了 Ray Wenderlich RestKit 教程,但它使用了客户端 ID 和客户端密码(根据 Foursquare 的要求)。
Yelp 请求需要有一个消费者密钥、令牌、签名方法、签名、时间戳和随机数。我一直无法找到可以生成这组特定 OAuth 参数的 RestKit 插件。
我现在使用由 Matt Thompson 开发的 AFOAuth1Client 生成我的 RestKit GET 请求。现在,当我发送请求时,Yelp API 返回一个无效签名错误。
我很困惑,因为我检查了 HTTP 授权标头中的字段,它们看起来是正确的。该错误似乎表明 Yelp 想要 URL 中的 oauth 参数,但 API 文档说可以在授权标头中发送它们。
这是我得到的无效签名错误:
2013-08-26 15:34:54.806 RestKitYelpGroupon[2157:400b] E restkit.network:RKObjectRequestOperation.m:575 对象请求失败:基础 HTTP 请求操作失败并出现错误:错误域 = org.restkit.RestKit.ErrorDomain 代码 = -1011 “预期状态码在 (200-299),得到 400” UserInfo=0xa876190 {NSLocalizedRecoverySuggestion={"error": {"text": "Signature was invalid", "id": "INVALID_SIGNATURE", "description": “无效签名。预期的签名基字符串:GET\u0026http%3A%2F%2Fapi.yelp.com%2Fv2%2Fsearch\u0026ll%3D32.893282%252C-117.195083%26oauth_consumer_key%3D(MY CONSUMER KEY)%26oauth_nonce%3DC0F25D91- B473-4059-B5F6-2D850A144A1D%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1377556409%26oauth_token%3D(我的 OAUTH 令牌)%26oauth_version%3D1。0%26term%3Dsushi"}}, AFNetworkingOperationFailingURLRequestErrorKey=http://api.yelp.com/v2/search?ll=32.893282%2C-117.195083&term=sushi>, NSErrorFailingURLKey=http://api.yelp.com/v2/search?ll=32.893282%2C-117.195083&term=sushi , NSLocalizedDescription=预期状态码在 (200-299), 得到 400, AFNetworkingOperationFailingURLResponseErrorKey=}
这是我用来生成请求的代码:
NSURL *baseURL = [NSURL URLWithString:@"http://api.yelp.com/v2"];
AFOAuth1Client *oauth1Client = [[AFOAuth1Client alloc] initWithBaseURL:baseURL key:consumerKey secret:consumerSecret];
oauth1Client.accessToken = [[AFOAuth1Token alloc] initWithKey:tokenKey
secret:tokenSecret
session:nil
expiration:[NSDate distantFuture]
renewable:NO];
[oauth1Client registerHTTPOperationClass:[AFJSONRequestOperation class]];
// Accept HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1
[oauth1Client setDefaultHeader:@"Accept" value:@"application/json"];
RKObjectManager *objectManager = [[RKObjectManager alloc] initWithHTTPClient:oauth1Client];
RKObjectMapping *couponMapping = [RKObjectMapping mappingForClass:[Coupon class]];
[couponMapping addAttributeMappingsFromDictionary:@{@"id" : @"id"}];
RKObjectMapping *businessMapping = [RKObjectMapping mappingForClass:[Business class]];
[businessMapping addAttributeMappingsFromDictionary:@{@"name" : @"name"}];
[businessMapping addPropertyMapping:[RKRelationshipMapping relationshipMappingFromKeyPath:@"deals" toKeyPath:@"location" withMapping:couponMapping]];
RKResponseDescriptor * responseDescriptor = [RKResponseDescriptor
responseDescriptorWithMapping:businessMapping
method:RKRequestMethodGET
pathPattern:nil
keyPath:@"response.venues"
statusCodes:RKStatusCodeIndexSetForClass(RKStatusCodeClassSuccessful)];
[objectManager addResponseDescriptor:responseDescriptor];
[objectManager getObjectsAtPath:@"http://api.yelp.com/v2/search"
parameters:queryParams
success:^(RKObjectRequestOperation * operaton, RKMappingResult *mappingResult)
非常感谢任何进一步的帮助!