面试题答案
一键面试主要步骤
- 创建网络请求对象:构建要发送的网络请求,包括URL、请求方法(GET、POST等)、请求头和请求体。
- 配置后台任务:确保任务在后台执行,而不影响主线程。
- 发送网络请求:启动请求并等待响应。
- 处理响应:根据请求的成功或失败,执行相应的回调逻辑。
- 处理后台任务终止:保存必要的状态信息,以便在应用重新启动时可以恢复任务。
关键类和方法
- NSURLSession:用于创建网络请求会话,管理网络请求任务。
- 类方法:
+sharedSession
创建一个共享的会话对象,适用于大多数应用场景;+sessionWithConfiguration:delegate:delegateQueue:
创建一个自定义配置的会话对象,可指定代理和代理队列。 - 实例方法:
-dataTaskWithURL:completionHandler:
创建一个数据任务,用于获取服务器返回的数据,完成后通过完成处理程序回调;-uploadTaskWithRequest:fromData:completionHandler:
创建一个上传任务,用于向服务器上传数据,完成后通过完成处理程序回调。
- 类方法:
- NSURLRequest:表示一个网络请求,包含请求的URL、请求方法、请求头和请求体等信息。
- 初始化方法:
-initWithURL:
使用给定的URL初始化一个请求;-initWithURL:cachePolicy:timeoutInterval:
可以同时指定缓存策略和超时时间。
- 初始化方法:
- NSURLSessionDataTask:NSURLSession创建的任务之一,用于处理HTTP请求并获取数据响应。
- 实例方法:
-resume
启动任务,开始发送请求。
- 实例方法:
处理网络请求成功或失败的回调
- 使用完成处理程序:
NSURLSession *session = [NSURLSession sharedSession]; NSURL *url = [NSURL URLWithString:@"https://example.com/api"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLSessionDataTask *task = [session dataTaskWithURL:url completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { if (!error) { // 请求成功 // 处理返回的数据 NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"成功: %@", responseString); } else { // 请求失败 NSLog(@"失败: %@", error.localizedDescription); } }]; [task resume];
- 使用代理方法:
- 首先创建一个遵守
NSURLSessionDataDelegate
协议的类。
@interface MySessionDelegate : NSObject <NSURLSessionDataDelegate> @end @implementation MySessionDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { // 可以逐步处理接收到的数据 } - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (!error) { // 请求成功 NSLog(@"成功"); } else { // 请求失败 NSLog(@"失败: %@", error.localizedDescription); } } @end
- 然后使用自定义配置创建会话并设置代理。
NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; MySessionDelegate *delegate = [[MySessionDelegate alloc] init]; NSURLSession *session = [NSURLSession sessionWithConfiguration:configuration delegate:delegate delegateQueue:nil]; NSURL *url = [NSURL URLWithString:@"https://example.com/api"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; NSURLSessionDataTask *task = [session dataTaskWithRequest:request]; [task resume];
- 首先创建一个遵守
处理后台任务可能被系统终止的情况
- 使用NSURLSession的后台配置:
- 创建一个后台配置的
NSURLSessionConfiguration
。
NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.backgroundSession"];
- 使用该配置创建
NSURLSession
。
NSURLSession *backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:nil];
- 创建一个后台配置的
- 保存任务状态:在任务执行过程中,定期保存任务的进度和状态信息到持久化存储(如
NSUserDefaults
、文件系统等)。 - 应用启动时恢复任务:在应用启动时,检查保存的任务状态信息,重新创建并恢复被终止的任务。
- 在
AppDelegate
的application:didFinishLaunchingWithOptions:
方法中:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSURLSessionConfiguration *backgroundConfiguration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"com.example.backgroundSession"]; self.backgroundSession = [NSURLSession sessionWithConfiguration:backgroundConfiguration delegate:self delegateQueue:nil]; // 检查是否有需要恢复的任务 if (launchOptions[UIApplicationLaunchOptionsURLKey]) { NSArray *pendingTasks = [self.backgroundSession tasksWithCompletionHandler:^(NSArray<NSURLSessionTask *> * _Nonnull tasks) { for (NSURLSessionTask *task in tasks) { [task resume]; } }]; } return YES; }
- 在
- 实现代理方法处理任务恢复:实现
NSURLSession
的代理方法,如URLSession:task:didCompleteWithError:
,在任务完成或失败时更新任务状态并处理可能的恢复逻辑。- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { if (error) { // 处理失败,记录错误信息 } else { // 处理成功,更新任务状态为已完成 } // 检查是否需要重新启动任务 if (/* 满足重新启动条件 */) { // 重新创建并启动任务 } }