iOS今日扩展POST请求到Google Directions API



我不知道我是否错过了一些明显的东西,但应该看起来正确的东西不起作用。也许我需要一双新鲜的眼睛?

我正在为我的一个应用程序测试Today Extension(小部件),在这个小部件中,我试图向Google Directions API发出请求。

我的普通应用程序本身在发出和接收请求时没有问题,但小部件本身运行不正常。

在我的普通应用程序中,我使用AFNetworking,但AFNetworking有一些问题,[UIApplication sharedApplication]在小部件中无法访问,所以我使用NSURLSession发出POST请求:

NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:nil];
NSString *directionsURL = [@"https://maps.googleapis.com/maps/api/" stringByAppendingString:@"directions/json"];
NSURL *url = [NSURL URLWithString:directionsURL];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
                                                       cachePolicy:NSURLRequestUseProtocolCachePolicy
                                                   timeoutInterval:60.0];
[request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
[request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
[request setHTTPMethod:@"POST"];
// ------------------------------------------------------------------
// setup params
// ------------------------------------------------------------------
NSMutableDictionary *params = [[NSMutableDictionary alloc] init];
NSString *strOrigin = [[NSString alloc] initWithFormat:@"%lf,%lf", fromLocation.latitude, fromLocation.longitude];
NSString *strDestination = [[NSString alloc] initWithFormat:@"%lf,%lf", toLocation.latitude, toLocation.longitude];
[params setValue:strOrigin forKey:@"origin"];
[params setValue:strDestination forKey:@"destination"];
[params setValue:@"transit" forKey:@"mode"];
[params setValue:@"true" forKey:@"alternatives"];
NSString *GoogleAPIBrowserKey = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GoogleAPIBrowserKey"];
[params setValue:GoogleAPIBrowserKey forKey:@"key"];
[params setValue:@"fewer_transfers" forKey:@"transit_routing_preference"];
DLog(@"widget params = %@", params);
NSData *postData = [NSJSONSerialization dataWithJSONObject:params options:0 error:&error];
if(error)
{
    DLog(@"error setting up PostData: %@", error.localizedDescription);
}
[request addValue:[NSString stringWithFormat:@"%d", postData.length] forHTTPHeaderField:@"Content-Length"];
[request setHTTPBody:postData];

NSURLSessionDataTask *postDataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if(error)
    {
        DLog(@"Widget Error requesting route: %@", error.localizedDescription);
    }
    else
    {
        NSError *jsonError = nil;
        NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
        if(error)
        {
            DLog(@"Error converting widget response data: %@", error.localizedDescription);
        }
        DLog(@"Widget Google Response = %@", responseDict);
    }
}];
[postDataTask resume];

我的Xcode控制台输出以下内容:

widget params = {
    alternatives = true;
    destination = "-31.834382,115.804225";
    key = **********************;
    mode = transit;
    origin = "-31.833961,115.806565";
    "transit_routing_preference" = "fewer_transfers";
}
Widget Google Response = 
{
    "error_message" = "Invalid request. Missing the 'origin' parameter.";
    routes =     (
    );
    status = "REQUEST_DENIED";
}

这让我相信我的requestHTTP Body在网络请求操作过程中不知何故丢失了。当日志显示"origin"是我的params字典的一部分时,它怎么会丢失?

我尝试过po data来查看data变量是否为nil,但它不是nil。

我为这件事伤透了脑筋。如果有人能看到我哪里出了问题并向我指出,我会很高兴的。

为什么我总是这样对自己?

简短回答

使用GET请求包,而不是POST

答案很长

去散步,1小时后回家。问题解决了。

当我看到我使用AFNetworking的代码的普通应用程序版本时,我意识到我犯了一个明显的错误。

我在Today Extension中使用POST请求,而我应该像在AFNetworking代码中那样使用GET请求。

出于这个原因,新的params需要进行URL编码,而不是作为HTTP主体的一部分,所以现在的新代码是:

NSError *error;
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration];
// ------------------------------------------------------------------
// setup URL params
// ------------------------------------------------------------------
NSMutableString *urlParams = [[NSMutableString alloc] initWithString:@"?"];
NSString *strOrigin = [[NSString alloc] initWithFormat:@"%lf,%lf", fromLocation.latitude, fromLocation.longitude];
NSString *strDestination = [[NSString alloc] initWithFormat:@"%lf,%lf", toLocation.latitude, toLocation.longitude];
NSString *GoogleAPIBrowserKey = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"GoogleAPIBrowserKey"];
[urlParams appendFormat:@"origin=%@&destination=%@&mode=transit&alternatives=true&key=%@&transit_routing_preference=fewer_transfers", strOrigin, strDestination, GoogleAPIBrowserKey];
NSString *directionsURL = [[NSString alloc] initWithFormat:@"https://maps.googleapis.com/maps/api/%@%@", @"directions/json", urlParams];
NSURL *url = [NSURL URLWithString:directionsURL];
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url];
[request setHTTPMethod:@"GET"];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    if(error)
    {
        DLog(@"Widget Error requesting route: %@", error.localizedDescription);
    }
    else
    {
        NSError *jsonError = nil;
        NSDictionary* responseDict = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:&jsonError];
        if(jsonError)
        {
            DLog(@"Error converting widget response data: %@", error.localizedDescription);
        }
        DLog(@"Widget Google Response = %@", responseDict);
    }
}];
[dataTask resume];

太糟糕了。对不起,我今天已经盯着屏幕看了好几个小时了:D

相关内容

  • 没有找到相关文章

最新更新