iOS开发:背景任务与Web服务处理
1. 背景下载大文件
在开发应用时,有时需要下载大文件,并且希望在下载过程中用户仍能正常使用手机,即便应用被暂停或终止。
1.1 解决方案
使用
NSURLSession
来启动可在后台继续的下载任务。
1.2 实现步骤
-
配置
NSURLSession-
创建
NSURLSessionConfiguration对象并设置属性:
-
创建
var configuration = NSURLSessionConfiguration.backgroundSessionConfigurationWithIdentifier("uniqueIdentifier")
configuration.sessionSendsLaunchEvents = true
configuration.discretionary = true
- 创建`NSURLSession`实例:
var session = NSURLSession(configuration: configuration, delegate: self, delegateQueue: nil)
- 创建并启动下载任务
var task = session.downloadTaskWithURL(NSURL(string:"http://www.brainloaf.com/introduction-to-ios.mp4")!)
task.resume()
-
实现协议方法
-
URLSession:downloadTask:didFinishDownloadingToURL::文件下载完成后调用,需将文件从临时位置移动到永久位置。
-
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didFinishDownloadingToURL location: NSURL) {
println("Temporary file path: \(location)")
var fileManager = NSFileManager()
var err : NSError?
var destination = NSSearchPathForDirectoriesInDomains(.DocumentDirectory, .UserDomainMask, true).first?.stringByAppendingString("/introduction-to-ios.mp4") as String!
if fileManager.moveItemAtURL(location, toURL: NSURL(fileURLWithPath: destination)!, error: &err) {
println("File downloaded to \(destination)")
} else {
println("Failed to save \(err?.description)")
}
}
- `URLSession:downloadTask:didWriteData:`:可用于更新用户界面以显示下载进度。
func URLSession(session: NSURLSession, downloadTask: NSURLSessionDownloadTask, didWriteData bytesWritten: Int64, totalBytesWritten: Int64, totalBytesExpectedToWrite: Int64) {
println("Wrote an additional \(bytesWritten) bytes")
println ("total \(totalBytesWritten) bytes) out \(totalBytesExpectedToWrite) total bytes.")
}
- `URLSession:didCompleteWithError:`:告知代理下载任务完成,若有错误则包含错误信息。
func URLSession(session: NSURLSession, task: NSURLSessionTask, didCompleteWithError error: NSError?) {
if error == nil {
println("Download completed")
} else {
println("Download failed with error \(error?.description)")
}
var appDelegate = UIApplication.sharedApplication().delegate as! AppDelegate
if let complete = appDelegate.completionHandler {
complete()
appDelegate.completionHandler = nil
}
}
-
处理应用被系统暂停或终止后的情况
-
在
AppDelegate中添加completionHandler属性:
-
在
var completionHandler: (() -> Void)?
- 实现`application:handleEventsForBackgroundURLSession:completionHandler`方法:
func application(application: UIApplication, handleEventsForBackgroundURLSession identifier: String, completionHandler: () -> Void) {
self.completionHandler = completionHandler
}
1.3 注意事项
- 下载大文件时,应禁用通过移动网络下载的功能,或让用户选择是否使用数据连接,因为这可能会产生额外费用。
- 若用户强制退出应用,所有下载任务将被取消。
以下是整个流程的mermaid流程图:
graph TD;
A[创建NSURLSessionConfiguration] --> B[设置属性];
B --> C[创建NSURLSession];
C --> D[创建下载任务];
D --> E[启动任务];
E --> F[实现协议方法];
F --> G{应用是否被暂停或终止};
G -- 是 --> H[重新创建NSURLSession];
G -- 否 --> I[继续下载];
H --> J[处理完成后调用completionHandler];
I --> K[完成下载];
2. 创建长时间运行的背景任务
应用可能需要在后台执行一些任务,如播放音频、导航、下载内容等,需要让这些任务在应用进入后台时继续运行。
2.1 解决方案
在iOS中,可通过为应用声明特定功能来利用长时间运行的背景任务。
2.2 背景模式说明
| UIBackgroundModes值 | 描述 |
|---|---|
| Audio | 表示应用在后台播放音频,使用麦克风的应用在使用前会提示用户授权。 |
| location | 应用更新用户的GPS位置并根据位置提供更新。 |
| voip | 应用用于进行网络电话通话。 |
| newsstand - content | 应用下载如期刊等内容。 |
| external - accessory | 应用与通过外部配件框架提供更新的硬件配件进行交互。 |
| bluetooth - central | 应用与通过核心蓝牙框架提供更新的蓝牙配件配合工作。 |
| bluetooth - peripheral | 应用充当蓝牙LE配件,使用此模式需要用户授权。 |
| fetch | 应用定期检查并下载少量内容,如电子邮件。 |
| remote - notification | 应用在收到推送通知时下载内容。 |
2.3 实现步骤
-
在Xcode中声明背景模式
- 在Xcode的“Capabilities”选项卡中,选择应用所需的模式。
- 选择应用目标,然后从标签栏中选择“Capabilities”,将“Background Modes”开关打开,并选择每个所需的功能。
-
以位置更新为例
-
添加Core Location框架
- 在项目导航器中选择项目,再选择应用目标,点击“Build Phases”标签。
-
展开“Link Binary With Libraries”部分,点击加号,选择
CoreLocation.framework并点击“Add”按钮。
-
添加自定义属性
- 在项目导航器中选择项目,选择应用目标,然后选择“Info”标签。
- 展开“Custom iOS Target Properties”,点击加号,输入键名“NSLocationWhenInUseUsageDescription”并提供一个要显示的字符串。
-
实现
CLLocationManager协议
-
添加Core Location框架
class ViewController: UIViewController, CLLocationManagerDelegate {
var locationManager : CLLocationManager!
override func viewDidLoad() {
super.viewDidLoad()
locationManager = CLLocationManager()
locationManager.requestWhenInUseAuthorization()
if CLLocationManager.locationServicesEnabled() {
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.startUpdatingLocation()
} else {
println("Please allow access to your location in your settings.")
}
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var lastLocation = locations.last as? CLLocation
if let location = lastLocation {
println("Location Updated to: \(location.coordinate.latitude) Lat., \(location.coordinate.longitude) Long.")
}
}
}
以下是位置更新背景任务的mermaid流程图:
graph TD;
A[添加Core Location框架] --> B[添加自定义属性];
B --> C[实现CLLocationManager协议];
C --> D[请求用户授权];
D --> E{用户是否授权};
E -- 是 --> F[设置代理和精度];
E -- 否 --> G[提示用户到设置中授权];
F --> H[开始更新位置];
H --> I[更新位置信息];
3. Web服务相关处理
3.1 解析JSON
在开发应用时,常常需要解析JSON数据以供应用使用。
3.2 解决方案
使用
NSJSONSerialization
类来解析JSON。
3.3 实现原理
JSON(JavaScript Object Notation)是当今Web服务和API中常用的一种数据交换格式,由数据的名/值对组成。例如下面这个定义食谱的JSON示例:
{
"name" : "Pot Pie",
"serves" : 1,
"preparation-time" : 60
}
NSJSONSerialization
将解析后的JSON文档以数据数组和字典的形式返回。上述JSON示例会被解析为一个填充了名/值对的
NSDictionary
,冒号左边的名称用作字典的键,右边的值使用该键存储在字典中。JSON格式还允许对象数组,假设存在一个名为
data
的
String
变量,其中包含前面所示的JSON字符串且包含对象数组,
NSJSONSerialization
会将该字符串解析为一个
NSArray
,数组中的每个元素都是一个
NSDictionary
实例。
以下是使用
NSJSONSerialization
解析
data
变量中JSON的代码:
var error: NSError?
var parsedObject : AnyObject? = NSJSONSerialization.JSONObjectWithData(data, options: nil, error: &error)
解析JSON后,需要了解数据结构才能使用它。可以使用返回的
NSArray
或
NSDictionary
实例访问值,但由于每次索引数组或从字典中检索值都可能为
nil
,代码可能会变得很冗长,会有大量嵌套的
nil
检查。例如,要从
parsedObject
变量中检索食谱的名称,需要进行如下操作:
if let recipes = parsedObject as? NSArray {
if let firstRecipe = recipes[0] as? NSDictionary {
if let name = firstRecipe["name"] as? String {
println("Name: \(name)")
}
}
}
以下是解析JSON的mermaid流程图:
graph TD;
A[获取JSON数据] --> B[使用NSJSONSerialization解析];
B --> C{解析是否成功};
C -- 是 --> D[根据数据结构访问值];
C -- 否 --> E[处理错误];
总结
本文详细介绍了iOS开发中背景任务和Web服务处理的相关内容。在背景任务方面,涵盖了大文件的背景下载以及长时间运行的背景任务的实现方法,包括配置、代码实现和注意事项,并通过流程图清晰展示了整个流程。在Web服务处理中,重点讲解了JSON数据的解析,说明了使用
NSJSONSerialization
类的具体步骤和原理。通过这些技术,开发者可以更好地实现应用在后台的稳定运行以及对Web数据的有效处理,提升用户体验。
希望开发者们能够根据这些内容,结合实际需求,灵活运用这些技术,为iOS应用开发带来更多的可能性。同时,在实际开发过程中,要注意各种细节和异常情况的处理,确保应用的稳定性和可靠性。
iOS后台任务与Web服务处理
超级会员免费看
1221

被折叠的 条评论
为什么被折叠?



