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