Objective-C异步工作流中任务序列的维护
我正在尝试做一个简单的下载,之后我会收到一个JSON文件。然后,我想将此对象转换为NSDictionary,并在返回格式化对象之前进行一些格式化。我在一个单独的班级里做这件事是为了保持整洁。其思想是初始化类并调用类中的一个函数,该函数将启动下载,并在最后吐回一个NSDictionary(如果过程中出现错误,则进行错误处理) 下面是一个流程图,以说明我想要实现的目标: 问题是,当下载是一个异步任务时,我无法思考如何将这些任务排序在一起,并且在下载完成之前我无法解析JSON: 我知道下载任务有一个完成处理程序,我可以在它启动时调用下一步,但这样我就失去了在最后返回NSDictionary的能力。类似地,如果我将NSDictionary设置为可以从外部访问并存储其中每个步骤的属性,那么我如何知道它何时包含最终结果(初始化时,字典为空;我需要等待序列完成) 因此,我正在寻找一种处理这个看似简单的下载任务的好方法。我希望我清楚地解释了我的问题,但如果你需要任何澄清,请让我知道 最后,这里是一些最相关步骤的代码片段。这是我要处理下载的地方:Objective-C异步工作流中任务序列的维护,objective-c,xcode,asynchronous,Objective C,Xcode,Asynchronous,我正在尝试做一个简单的下载,之后我会收到一个JSON文件。然后,我想将此对象转换为NSDictionary,并在返回格式化对象之前进行一些格式化。我在一个单独的班级里做这件事是为了保持整洁。其思想是初始化类并调用类中的一个函数,该函数将启动下载,并在最后吐回一个NSDictionary(如果过程中出现错误,则进行错误处理) 下面是一个流程图,以说明我想要实现的目标: 问题是,当下载是一个异步任务时,我无法思考如何将这些任务排序在一起,并且在下载完成之前我无法解析JSON: 我知道下载任务有一
- (void) initiateDownload {
// Initialize variables for URL request
NSURL *nasaAPI = [NSURL URLWithString:@"https://api.nasa.gov/planetary/apod?api_key=DEMO_KEY"];
NSURLRequest *urlRequest = [NSURLRequest requestWithURL:nasaAPI];
NSURLSession *urlSession = [NSURLSession sharedSession];
// Setup session to timeout after a specific time interval
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
sessionConfig.timeoutIntervalForRequest = 10.0;
sessionConfig.timeoutIntervalForResource = 30.0;
// Initialize the download task
downloadTask = [urlSession dataTaskWithRequest:urlRequest
completionHandler:^(NSData *data, NSURLResponse *response, NSError *downloadError) {
if (downloadError) {
// Error occured, put it into errorMessage dictionary
[self errorReceived:downloadError];
} else if (data) {
[self dataReceived:data];
}
}];
// Fire download task
[downloadTask resume];
}
这就是我处理解析我下载的JSON的地方:
- (void) parseWeatherJSON:(NSData *)data {
/* ---------- ---------- ---------- ---------- ----------
Returns with an NSDictionary with either
1) the parsed JSON data or 2) an error message.
---------- ---------- ---------- ---------- ---------- */
// Create temporary variables
NSError *jsonError;
NSDictionary *parsedJSON;
// Insiate JSON parsing
parsedJSON = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&jsonError];
// Handle any possible errors
if (jsonError) {
// JSON parsing did not complete, return error message instead
errorDictionary = [NSDictionary dictionaryWithObjectsAndKeys:jsonError, @"error", nil];
[self errorReceived:jsonError];
} else {
// JSON parsing was complete, return parsed NSDictionary
[self dictionaryReceived:parsedJSON];
}
}
更新1.:如果上面的逻辑不适合处理下载/解析序列,我非常愿意接受其他想法。这正是我要做的,但我不是一个训练有素的程序员。也许有更好的办法
// declare in .h
typedef void(^ResponseCallback)(NSError *error, id result);
- (void) initiateDownloadWithCompletion:(ResponseCallback)completion {
...
downloadTask = [urlSession dataTaskWithRequest:urlRequest completionHandler:^(NSData *data, NSURLResponse *response, NSError *downloadError) {
if (downloadError) {
completion(downloadError, nil);
} else if (data) {
[self parseWeatherJSON: data completion: completion];
}
}];
...
}
- (void) parseWeatherJSON:(NSData *)data completion:(ResponseCallback)completion {
...
if (jsonError) {
...
completion(jsonError, nil);
} else {
...
completion(nil, parsedJSON);
}
}
为什么不在
initialedownload
方法中添加一个完成块作为参数?我不知道如何添加。:)我忘了提到我是一个初学者/中级开发人员(只是在业余时间做这件事)。我可以自己做很多事情,但有时我需要提前完成任务的帮助。这是其中一种情况。:)嗨,海森堡,你介意在代码中显示这个吗?我还不知道怎么做。当然,我可以提供一些代码。顺便说一句,如果你是从iOS开始的,为什么不使用Swift?我不是从iOS开始的,我已经做了4-6年了;因此,我不愿意开始一种全新的语言。顺便说一句,我给了斯威夫特一个机会,但没能成功。Obj C对我来说似乎更符合逻辑,更容易理解。