美文网首页swift干货swiftSwift
Swift2网络操作和异常处理

Swift2网络操作和异常处理

作者: Sheepy | 来源:发表于2015-10-09 22:37 被阅读1854次

相信写过Swift的人应该都知道Alamofire,它是AFNetworking的Swift版本,同一个作者写的。之前在项目中我也一直使用Alamofire,但是升级到Xcode7之后旧版的Alamofire不能用了,最新版的又只支持iOS8之后的系统,而公司项目还得兼容iOS7,所以接下来不打算用它了。

我的需求比较简单,只要能发送GET请求获取数据以及发送POST请求提交数据就好了,大致看了一下Alamofire的源码又上网查了点资料之后,花了不到半天写了几个简单的函数,项目又能正常跑起来了。

iOS7之后的系统都支持NSURLSession,我们就把它稍微封装一下好了。

func getDataFrom(urlString: String, method: HTTPMethod, parameter: [String: String]?, completionHandler: Callback) throws {
    //    let config = NSURLSessionConfiguration.defaultSessionConfiguration()
    //    config.timeoutIntervalForRequest = 20
    //    let session = NSURLSession(configuration: config)
    guard let url = NSURL(string: urlString) else {
        throw Error.InvalidURL
    }
    
    let session = NSURLSession.sharedSession()
    let request = NSMutableURLRequest(URL: url)
    request.HTTPMethod = method.rawValue
    
    switch method {
    case .POST:
        //如果参数为nil或者字典中没有元素,则抛出异常
        guard let param = parameter else {
            throw Error.NoParameter
        }
        guard param.isEmpty else {
            throw Error.NoParameter
        }
        
        request.addValue("application/json", forHTTPHeaderField: "Content-Type")
        request.addValue("application/json", forHTTPHeaderField: "Accept")
        
        do {
            request.HTTPBody = try NSJSONSerialization.dataWithJSONObject(param, options: [])
        } catch {
            print(error)
        }
    
    case .GET:
        break
    }
    
    let task = session.dataTaskWithRequest(request) {data, response, error in
        guard let result = data where error == nil else {
            printLog("no data: \(error)")
            return
        }
        
        completionHandler(data: result)
    }
    //启动
    task.resume()
    
}

这个函数声明的时候在->前加了一个throws,表明这个函数是可以抛出异常的。其实以往iOS开发比较推崇"Let it crash!"的哲学,不过Swift一直很强调安全性,Apple显然也并不仅仅满足于让Swift困守iOS开发领域,加上早就公布了年底要开源,大家也很期待它作为一门通用编程语言在其他领域的作为。从各方面来看,Swift2.0增加了对异常处理的支持都在情理之中。从此你的App就不能轻易的狗带了~

ha~.jpg

我对异常处理的理解很浅薄,说实话平常自己也不怎么喜欢用。在我看来异常处理最重要的用途有两点:

  • 写底层框架的时候可以抛出一些异常让框架的使用者去处理,这样框架会显得更加灵活。
  • 保存错误日志,便于查询和调试。

像我上面那个函数,如果纯粹是自己用的话,其实我会选择在出错的地方直接处理错误或者打印错误信息,譬如把throw Error.InvalidURL改成

printLog("Invalid URL")
return

这样也省得调用函数的时候一堆try-catch。当然有些错误当前函数确实是处理不了,那该抛还得抛。

上面那个函数还可以封装一下,分成两个,一个用来发送 GET请求接收JSON数据,一个用来POST JSON数据并接收返回信息。具体如下:

func getJsonFrom(url: String, completion: (json: JSON) -> Void) {
    do {
        try getDataFrom(url, method: HTTPMethod.GET, parameter: nil) { data in
            let json = JSON(data: data)
            //主线程进行UI操作
            dispatch_sync(dispatch_get_main_queue()) {
                completion(json: json)
            }
        }
    } catch Error.InvalidURL {
        printLog("GET: invalid url")
    } catch {
        printLog("Unknown error")
    }
    
}

func postJson(dict: [String: String], toUrl url: String, completion: (json: JSON) -> Void) {
    do {
        try getDataFrom(url, method: HTTPMethod.POST, parameter: dict) { data in
            let json = JSON(data: data)
            //主线程进行UI操作
            dispatch_sync(dispatch_get_main_queue()) {
                completion(json: json)
            }
        }
    } catch Error.InvalidURL {
        printLog("POST: invalid url")
    } catch Error.NoParameter {
        printLog("Parameter is empty")
    } catch {
        printLog("Unknown error")
    }
    
}

完整代码在这里,里面还有一个图片缓存的函数,有兴趣的话可以看看。如果跟我有同样需求的同学可以把HttpManager.swiftclone下来直接拖到项目里,建议配合SwiftyJSON(一个很好用的第三方JSON解析库)使用,直接把Source文件夹里的SwiftyJSON.swift这个文件也一起拖到项目中好了,要用Cocoapods导入framework的话似乎只能支持iOS8之后的系统了。

对了还有一点,我一开始用JSON(data: data)来初始化JSON数据的时候总是不成功,于是我看了下SwiftyJSON中JSON这个struct的构造函数,它先调用了苹果提供的class func JSONObjectWithData(_ data: NSData, options opt: NSJSONReadingOptions) throws -> AnyObject函数,然后把返回的AnyObject对象赋值给自身属性object

public init(data:NSData, options opt: NSJSONReadingOptions = .AllowFragments, error: NSErrorPointer = nil) {
    do {
        let object: AnyObject = try NSJSONSerialization.JSONObjectWithData(data, options: opt)
        self.init(object)
    } catch let aError as NSError {
        if error != nil {
            error.memory = aError
        }
        self.init(NSNull())
    }
}

public init(_ object: AnyObject) {
    self.object = object
}

opt这个参数有三个可选值:MutableContainers, MutableLeaves, AllowFragments,分别表示:

  • 可以把数组或者字典转化成可变对象;
  • 可以把JSON对象树中作为叶子节点的字符串转化成可变字符串;
  • 允许解析最外层对象不是NSArrayNSDictionary实例的JSON数据

三种我都试了,都不行,最后我试了下[],也就是传入一个空值,居然行了。于是我索性把JSON的初始化函数改了:

public init(data:NSData, options opt: NSJSONReadingOptions = [], error: NSErrorPointer = nil) {
    //其余不变

和我遇到相同问题的同学也可以这样试试。有什么问题或指教欢迎评论。

相关文章

  • Swift2网络操作和异常处理

    相信写过Swift的人应该都知道Alamofire,它是AFNetworking的Swift版本,同一个作者写的。...

  • Python文件操作和异常处理

    一、文件的介绍 文件的作用: 使用文件的目的:保存数据存放在磁盘 把一些存储存放起来,可以让程序下一次执行的时候直...

  • 交互规范说明

    1、单位:历程、时间、金额。 2、网络异常处理:网络异常时、网络切换时、网络中断等情况下。 3、dialog和to...

  • 第一章 初见网络爬虫

    1.1、网络连接 1.2、运行BeautifulSoup 1.3、异常处理

  • Java基础题

    此文非原创,来源网络上的面试题 Java的异常处理 Java中异常分为哪些种类按照异常需要处理的时机,分为编译时异...

  • app通用考虑问题

    需考虑到的异常处理: 1.没有网络时异常(网络检测); (提示: 网络不稳定或者连接错误,请重新连接) 2.客...

  • vue_axios请求封装、异常拦截统一处理

    1、前端网络请求封装、异常统一处理 vue中采用axios处理网络请求,避免请求接口重复代码,以及各种网络情况造成...

  • java异常处理

    java异常处理 java异常 异常指不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。异常是一个事件...

  • Netty入门

    原生NIO的缺点(New Input/ Output)) 类库和api繁杂客户端需要断连,重连,异常处理,网络异常...

  • 同步或异步异常处理

    同步或异步异常处理 同步读取异常处理 异步读取文件异常处理

网友评论

  • 痕迹Dev:不应该把称为AFNetworking的Swift版
    Sheepy:@痕迹BLANK 我听说AFNetworking中的AF~就是Alamofire的缩写嘛。而且是同一个人写的,功能又差不多。并不一定要一句句翻译过来才算吧。OC跟Swift本来也不能一句句翻译。

本文标题:Swift2网络操作和异常处理

本文链接:https://www.haomeiwen.com/subject/mwvncttx.html