gpt4 book ai didi

ios - 等待 NSURLSessionDataTask 回来

转载 作者:行者123 更新时间:2023-11-29 00:55:42 33 4
gpt4 key购买 nike

我对 Objective C 和 iOS 开发总体来说是新手。我正在尝试创建一个应用程序,它会发出 http 请求并在标签上显示内容。

当我开始测试时,我注意到标签是空白的,尽管我的日志显示我已经恢复了数据。显然发生这种情况是因为标签文本更新时响应尚未准备好。

我在顶部放了一个循环来解决这个问题,但我几乎确信一定有更好的方法来处理这个问题。

ViewController.m

- (IBAction)buttonSearch:(id)sender {

HttpRequest *http = [[HttpRequest alloc] init];
[http sendRequestFromURL: @"https://en.wiktionary.org/wiki/incredible"];

//I put this here to give some time for the url session to comeback.
int count;
while (http.responseText ==nil) {
self.outputLabel.text = [NSString stringWithFormat: @"Getting data %i ", count];
}

self.outputLabel.text = http.responseText;

}

HttpRequest.h

#import <Foundation/Foundation.h>

@interface HttpRequest : NSObject

@property (strong, nonatomic) NSString *responseText;

- (void) sendRequestFromURL: (NSString *) url;
- (NSString *) getElementBetweenText: (NSString *) start andText: (NSString *) end;

@end

HttpRequest.m

@implementation HttpRequest

- (void) sendRequestFromURL: (NSString *) url {

NSURL *myURL = [NSURL URLWithString: url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: myURL];
NSURLSession *session = [NSURLSession sharedSession];


NSURLSessionDataTask *task = [session dataTaskWithRequest: request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
self.responseText = [[NSString alloc] initWithData: data
encoding: NSUTF8StringEncoding];
}];
[task resume];

}

非常感谢您的帮助:)

更新

在阅读了很多这里非常有用的评论之后,我意识到我错过了全部要点。因此,从技术上讲,NSURLSessionDataTask 会将任务添加到队列中,该队列将异步进行调用,然后我必须为该调用提供一段代码,以便在任务生成的线程完成时执行。

Duncan 非常感谢您的回复和代码中的评论。这对我的理解有很大帮助。

所以我使用提供的信息重写了我的程序。请注意,它们有点冗长,但我希望现在能理解整个概念。 (我声明一个代码块而不是嵌套它们)

HttpRequest.m

- (void) sendRequestFromURL: (NSString *) url
completion:(void (^)(NSString *, NSError *))completionBlock {

NSURL *myURL = [NSURL URLWithString: url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: myURL];
NSURLSession *session = [NSURLSession sharedSession];


NSURLSessionDataTask *task = [session dataTaskWithRequest: request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {

//Create a block to handle the background thread in the dispatch method.
void (^runAfterCompletion)(void) = ^void (void) {
if (error) {
completionBlock (nil, error);
} else {
NSString *dataText = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
completionBlock(dataText, error);
}
};

//Dispatch the queue
dispatch_async(dispatch_get_main_queue(), runAfterCompletion);
}];
[task resume];

}

ViewController.m

- (IBAction)buttonSearch:(id)sender {

NSString *const myURL = @"https://en.wiktionary.org/wiki/incredible";

HttpRequest *http = [[HttpRequest alloc] init];

[http sendRequestFromURL: myURL
completion: ^(NSString *str, NSError *error) {
if (error) {
self.outputText.text = [error localizedDescription];
} else {
self.outputText.text = str;
}
}];
}

请随时对我的新代码发表评论。风格、不正确的用法、不正确的流程;在这个学习阶段,反馈非常重要,这样我才能成为更好的开发人员:)

再次非常感谢您的回复。

最佳答案

你知道吗,使用 AFNetworking以挽救您的生命。

或者只是修改你的 HttpRequest 的 sendRequestFromURL:

- (void)sendRequestFromURL:(NSString *)url completion:(void(^)(NSString *str, NSError *error))completionBlock {

NSURL *myURL = [NSURL URLWithString: url];
NSURLRequest *request = [[NSURLRequest alloc] initWithURL: myURL];
NSURLSession *session = [NSURLSession sharedSession];


NSURLSessionDataTask *task = [session dataTaskWithRequest: request
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
dispatch_async(dispatch_get_main_queue(), ^{
if (error) {
completionBlock(nil, error);
} else {
completionBlock([[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding], error);
}
});
}];
[task resume];
}

并像这样调用

[http sendRequestFromURL:@"https://en.wiktionary.org/wiki/incredible" completion:^(NSString *str, NSError *error) {
if (!error) {
self.outputLabel.text = str;
}
}];

关于ios - 等待 NSURLSessionDataTask 回来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37628930/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com