Error in NSURLSessionDownloadTask
Asked Answered
B

2

0

I am trying to update the user's location on the backoffice even while the app is in backgound, so I trigger a location update calling the following php script:

-(void)locateUserAtLocation:(CLLocation*)location{
NSDictionary* dict=[self getCurrentAppAndUrlDictionary];
NSString* app=[dict objectForKey:@"app"];
float latitude=location.coordinate.latitude;
float longitude=location.coordinate.longitude;
NSString* language=[[NSLocale currentLocale] localeIdentifier];
NSString* nickName=[[NSUserDefaults standardUserDefaults] objectForKey:@"nickname"];
NSString* myUdid= [udid sharedUdid];
NSString *insertUrlString =[NSString stringWithFormat: @"http://www.miafoto.it/iPhone/inarrivo/taxi/insertUserNew.php?udid=%@&token=%@&nickname=%@&app=%@&language=%@&Latitude=%f&Longitude=%f&new=1",myUdid, token, nickName, app, language, latitude, longitude];
NSLog(@"url=%@", insertUrlString);

 NSURLSessionDownloadTask *insertTask = [[self backgroundSession] downloadTaskWithURL:    [NSURL URLWithString:insertUrlString]];
[insertTask resume];
}

but I get error: Invalid URL scheme for background downloads: (null). Valid schemes are http or http and no url is sent either in foreground or background. I searched on the web I found no hits addressing this issue. I also submitted the issue to the Apple support.

Bartizan answered 13/5, 2014 at 11:53 Comment(2)
BTW, while the problem is probably the URL, as an aside I would have thought that you'd want to create a POST request (which is designed for when submitting data to be processed by web service). Also, if you shifted to https at some future date, this would keep the udid, token, etc., more secure than a GET request would.Carthusian
Yes, sure. I was tricked by the error message. Now it works, yet I found a funny aspect. It seems the url gets only sent while connected to wifi and not when on a cellular connection, notwithstanding I obviously set: configuration.allowsCellularAccess = YES; in the background sessione configuration.Bartizan
C
1

You might have some reserved characters that prevent the NSURL object from instantiating correctly, i.e. URLWithString is probably returning nil.

NSString *insertUrlString =[NSString stringWithFormat: @"http://www.miafoto.it/iPhone/inarrivo/taxi/insertUserNew.php?udid=%@&token=%@&nickname=%@&app=%@&language=%@&Latitude=%f&Longitude=%f&new=1",myUdid, token, nickName, app, language, latitude, longitude];

You can confirm this by checking the NSURL:

NSURL *url = [NSURL URLWithString:insertUrlString];
NSAssert(url, @"problem instantiating NSURL: %@", insertUrlString);

Do any of those strings have spaces or other reserved characters in them? It's always safer to percent escape these values. Personally, I add my parameters to a dictionary, and then have a function that will percent escape the values, e.g.:

NSDictionary *parameters = @{@"udid"      : myUdid,
                             @"token"     : token,
                             @"nickname"  : nickName,
                             @"app"       : app,
                             @"language"  : language,
                             @"Latitude"  : @(latitude),
                             @"Longitude" : @(longitude),
                             @"new"       : @"1"};

NSString *insertUrlString = [NSString stringWithFormat: @"http://www.miafoto.it/iPhone/inarrivo/taxi/insertUserNew.php?%@", [self encodeParameters:parameters]];

NSURL *url = [NSURL URLWithString:insertUrlString];
NSAssert(url, @"problem instantiating NSURL: %@", insertUrlString);

where:

- (NSString *)encodeParameters:(NSDictionary *)parameters
{
    NSMutableArray *parameterArray = [NSMutableArray arrayWithCapacity:[parameters count]];

    for (NSString *key in parameters) {
        NSString *string;
        id value = parameters[key];

        if ([value isKindOfClass:[NSData class]]) {
            string = [[NSString alloc] initWithData:value encoding:NSUTF8StringEncoding];
        } else if ([value isKindOfClass:[NSString class]]) {
            string = value;
        } else if ([value isKindOfClass:[NSNumber class]]) {
            string = [value stringValue];
        } else {                         // if you want to handle other data types, add that here
            string = [value description];
        }
        [parameterArray addObject:[NSString stringWithFormat:@"%@=%@", key, [self percentEscapeString:string]]];
    }

    return [parameterArray componentsJoinedByString:@"&"];
}

- (NSString *)percentEscapeString:(NSString *)string
{
    NSString *result = CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                                                 (CFStringRef)string,
                                                                                 (CFStringRef)@" ",
                                                                                 (CFStringRef)@":/?@!$&'()*+,;=",
                                                                                 kCFStringEncodingUTF8));
    return [result stringByReplacingOccurrencesOfString:@" " withString:@"+"];
}
Carthusian answered 13/5, 2014 at 15:21 Comment(3)
@FabrizioBartolomucci FYI, sometimes web services are case sensitive with respect to the keys, so you might want to make sure that you really meant Latitude and Longitude rather than latitude and longitude. I preserved what you supplied in your question, but you might want to double check those keys.Carthusian
Thanks, but that is an url in my own REST server, so I could have called them MickeyMouse and DonaldDuck :-) My problem is that the url gets sent while the app is under a wifi cover, and not so when on the cellular network. Notwithstanding the session configuration. How do I check if the Session is actually properly configured?Bartizan
I don't know what you mean by "properly configured." The only things that would affect wifi v cellular, AFAIK, is (a) the allowsCellularAccess setting; (b) if you have some custom Reachability code that is doing anything conditional on the basis of the connection type; (c) you're connecting to some server on your LAN which isn't accessible via the Internet; or (d) you're using some exceptionally short timeout settings that are sufficient for LAN but not cellular.Carthusian
G
0

Here is easier solution

 NSURL *url = [NSURL URLWithString: [[yourURLinString
 stringByAddingPercentEscapesUsingEncoding: NSUTF8StringEncoding]
 stringByTrimmingCharactersInSet:[NSCharacterSet
 whitespaceAndNewlineCharacterSet]]];

Parse your string url this way and it should work.

Gorski answered 30/8, 2016 at 11:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.