从请求中获取数据到主线程
Get data from a request to the main thread
我对 Objective C 和移动开发还很陌生。我想在此会话之外执行获取和使用响应,谁能告诉我该怎么做?
现在我收到错误“使用未声明的标识符 '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);
dataTaskWithRequest
方法 异步运行, 即稍后运行。你不能只引用块外的变量。
典型的解决方案是为执行此请求的方法提供一个块参数,一个完成处理程序,并在 dataTaskWithRequest
.
的异步块内调用完成处理程序
例如,您可能有:
- (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];
}
然后这样称呼它:
[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
我对 Objective C 和移动开发还很陌生。我想在此会话之外执行获取和使用响应,谁能告诉我该怎么做?
现在我收到错误“使用未声明的标识符 '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);
dataTaskWithRequest
方法 异步运行, 即稍后运行。你不能只引用块外的变量。
典型的解决方案是为执行此请求的方法提供一个块参数,一个完成处理程序,并在 dataTaskWithRequest
.
例如,您可能有:
- (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];
}
然后这样称呼它:
[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