Home > Net >  Get data from a request to the main thread
Get data from a request to the main thread

Time:05-19

I'm very new to Objective C and mobile development. I want to perform a get and use the response outside this session, can anyone tell me how I can do this?

Now i got the error "Use of undeclared identifier 'username'

    NSMutableURLRequest *request = [[NSMutableURLRequest alloc] init];
[request setURL:[NSURL URLWithString:url]];
[request setHTTPMethod:@"GET"];NSURLSession *session = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];

[[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
    NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSASCIIStringEncoding];
    
    NSRange rangeUsername = [requestReply rangeOfString:@"<username>"];
    NSString *username = [requestReply substringFromIndex:rangeUsername.location];
    username = [username stringByReplacingOccurrencesOfString:@"<username>" withString:@""];
    username = [username stringByReplacingOccurrencesOfString:@"</username>" withString:@""];
    
    NSRange rangeDomain = [requestReply rangeOfString:@"<SIP_domain>"];
    NSString *domain = [requestReply substringFromIndex:rangeDomain.location];
    domain = [domain stringByReplacingOccurrencesOfString:@"<SIP_domain>" withString:@""];
    domain = [domain stringByReplacingOccurrencesOfString:@"</SIP_domain>" withString:@""];
}] resume];

NSLog(@"Username: %@", username);
NSLog(@"Domain: %@", domain);

CodePudding user response:

The dataTaskWithRequest method runs asynchronously, i.e., later. You can’t just reference the variables outside of the block.

The typical solution is to provide a block parameter to your method that performs this request, a completion handler, and call the completion handler inside the asynchronous block of dataTaskWithRequest.


E.g., you might have:

- (void)performRequestWithURL:(NSURL *)url completion:(void (^ _Nonnull)(NSString *username, NSString *domain, NSError *error))completion {
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];

    NSURLSession *session = [NSURLSession sharedSession];

    [[session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
        if (error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                completion(nil, nil, error);
            });
            return;
        }

        NSString *requestReply = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];

        NSRange rangeUsername = [requestReply rangeOfString:@"<username>"];
        NSString *username = [requestReply substringFromIndex:rangeUsername.location];
        username = [username stringByReplacingOccurrencesOfString:@"<username>" withString:@""];
        username = [username stringByReplacingOccurrencesOfString:@"</username>" withString:@""];

        NSRange rangeDomain = [requestReply rangeOfString:@"<SIP_domain>"];
        NSString *domain = [requestReply substringFromIndex:rangeDomain.location];
        domain = [domain stringByReplacingOccurrencesOfString:@"<SIP_domain>" withString:@""];
        domain = [domain stringByReplacingOccurrencesOfString:@"</SIP_domain>" withString:@""];

        dispatch_async(dispatch_get_main_queue(), ^{
            completion(username, domain, nil);
        });
    }] resume];
}

And call it like so:

[self performRequestWithURL:url completion:^(NSString *username, NSString *domain, NSError *error) {
    if (error) {
        NSLog(@"error = %@", error);
        return;
    }

    // use `username` and `domain` here ...
}];

// ... but not here, because the above runs asynchronously
  • Related