zoukankan      html  css  js  c++  java
  • swift 项目搭建

    1、项目代码结构
    如下为我的项目结构,使用的cocoapods 管理。
    Metadata 存放model数据,Modules 存放功能模块
     
    使用的第三方库

    #source "https://github.com/CocoaPods/Specs"
    #source "https://github.com/shuleihen/Specs"

    # Uncomment this line to define a global platform for your project
    platform :ios, '8.0'

    target 'CrossBorder' do
      # Comment this line if you're not using Swift and don't want to use dynamic frameworks
      use_frameworks!

      # Pods for CrossBorder
      pod 'ReactiveCocoa'
      pod 'Alamofire', '~> 3.4'
      pod 'ObjectMapper', '~> 1.3'
    #  pod 'AlamofireObjectMapper', '~> 3.0'
      pod 'CryptoSwift'
      pod 'KeychainAccess'
      pod 'XCGLogger', '~> 3.3'
      pod 'PKHUD'
      pod 'SQLite.swift', '~> 0.10.1'
      pod 'DynamicColor'
      pod 'SnapKit', '~> 0.30.0.beta1'
      pod 'MBProgressHUD', '~> 0.9.2'
      pod 'RealmSwift', '~> 1.0.0'
      pod 'R.swift'
    end
    以上为Podfile 文件使用到的类库,Alamofire 为网络库,OjectMapper 为json转model库等。具体可以自己到github上查看。
     
     
    2、API 数据格式
    一般服务器返回的json数据格式是:
    {
        "retCode”:"200"
        "retMsg":""
        "retResult:{}
    }
     
    retCode 为协议code,这里的code和http返回的code不同,这里的code是在http请求成功,服务器响应的请求返回的处理code。一般会用200或是0000表示成功,如果服务器处理错误,就在retMsg给出错误描述。
     
    retMsg 为服务器返回的错误内容。由于多平台客服端和跨国问题,retMsg并不一定能作为提示文案。因此,app端会保存一份服务器code码和错误描述的对应表(可以是多语种的),如果服务器返回错误code,根据code查询对应的错误文案,封装成NSError 传递给上层使用。
     
    retResult 为API接口处理成功返回的数据,有时候API接口处理成功没有数据返回会为空。关于retResult 数据是否要转成model网上有争论,我们暂且不论,我们考虑代码简洁性和易读性,依然使用转成model模式。oc 已经有很多比较成熟的json转model库(例如:MJExtension),swift 也有不错的类库,我使用的是 ObjectMapper。
      
     
    3、数据model
    使用ObjectMapper 以登录返回User对象为例:
    import ObjectMapper

    class User: Mappable {
       
        var accessToken: String?
        var expressTime: String?
        var gesturePassword: String?
        var userid: String?
        var phone: String?

        init (){
           
        }
       
        required init?(_ map: Map) {
           
        }
       
        func mapping(map: Map) {
            accessToken <- map["accessToken"]
            expressTime <- map["expressTime"]
            gesturePassword <- map["gesturePassword"]
            userid <- map["userid"]
            phone <- map["phone"]
        } 
     }
     
    4、Response 返回处理
     
    // Restfull API Host
    let URL_HOST = ""
     
    // Restfull API Path
    enum URLPath:String {
        case Login      = "user/login"
        case LoginOut   = "remit/loginout"
    }
     
    // Restfull API Response Struct
    enum ResponseData: String {
        case Code   = "retCode"
        case Msg    = "retMsg"
        case Result = "retResult"
        case Success = "0000"
    }

    class Network {
        class func request(method method:Alamofire.Method,
                                   path:URLPath,
                                   parameters:[String: AnyObject]? = nil)-> Alamofire.Request {
       
            let URLString = URL_HOST + path.rawValue
            let encoding = Alamofire.ParameterEncoding.JSON
            let headers = AppContext.sharedInstance.commRESTHeader()
           
            let request = Manager.sharedInstance.request(method, URLString, parameters: parameters, encoding: encoding, headers: headers)

            NSLog(" /*---- Request ---- (request.debugDescription) ------------------*/ ")
            return request
        }
       
        static let queue = dispatch_queue_create("com.crossborder.network", DISPATCH_QUEUE_SERIAL)
    }

    // MARK: Object
    extension Request {
       
        public func responseObject<T: Mappable>(completionHandler: Response<T, NSError> -> Void) -> Self {
             return response_cb { response in
                if response.result.isSuccess {
                    let value = Mapper<T>().map(response.result.value)
                    let result = Result<T, NSError>.Success(value!)
                   
                    let rsp = Response<T, NSError>(
                        request: response.request,
                        response: response.response,
                        data: response.data,
                        result: result,
                        timeline: response.timeline
                    )
                   
                    dispatch_async(dispatch_get_main_queue()) { completionHandler(rsp) }
                } else {
                    let result = Result<T, NSError>.Failure(response.result.error!)
                   
                    let rsp = Response<T, NSError>(
                        request: response.request,
                        response: response.response,
                        data: response.data,
                        result: result,
                        timeline: response.timeline
                    )
                   
                    dispatch_async(dispatch_get_main_queue()) { completionHandler(rsp) }
                }
            }
        }
    }

    // MARK: Array
    extension Request {

        public func responseArray<T: Mappable>(completionHandler: Response<[T], NSError> -> Void) -> Self {
            return response_cb { response in
                if response.result.isSuccess {
                    let value = Mapper<T>().mapArray(response.result.value)
                    let result = Result<[T], NSError>.Success(value!)
                   
                    let rsp = Response<[T], NSError>(
                        request: response.request,
                        response: response.response,
                        data: response.data,
                        result: result,
                        timeline: response.timeline
                    )
                   
                    dispatch_async(dispatch_get_main_queue()) { completionHandler(rsp) }
                } else {
                    let result = Result<[T], NSError>.Failure(response.result.error!)
                   
                    let rsp = Response<[T], NSError>(
                        request: response.request,
                        response: response.response,
                        data: response.data,
                        result: result,
                        timeline: response.timeline
                    )
                   
                    dispatch_async(dispatch_get_main_queue()) { completionHandler(rsp) }
                }
            }
        }
    }

    // MARK: Dictionary
    extension Request {
       
        public func responseDictionary(completionHandler: Response<AnyObject, NSError> -> Void) -> Self {
            return response_cb { response in
                dispatch_async(dispatch_get_main_queue()) { completionHandler(response) }
            }
        }
       
        public func response_cb(queue queue: dispatch_queue_t? = Network.queue, completionHandler: Response<AnyObject, NSError> -> Void) -> Self {
            return response(queue: queue, responseSerializer: Request.DictionaryMapperSerializer(), completionHandler: {response in
                if response.result.isFailure {
                    dispatch_async(dispatch_get_main_queue()) { ErrorHandler.handler(response.result.error) }
                }
               
                completionHandler(response)
            })
        }
       
        public static func DictionaryMapperSerializer() -> ResponseSerializer<AnyObject, NSError> {
            return ResponseSerializer { request, response, data, error in
                guard error == nil else { return .Failure(error!) }
               
                if let response = response where response.statusCode == 204 { return .Success(NSNull()) }
               
                guard let validData = data where validData.length > 0 else {
                    let reason = "JSON could not be serialized. Input data was nil or zero length."
                    let error = ErrorHandler.error(code: ErrorCode.SerializationFailed.rawValue, reason: reason)
                    return .Failure(error)
                }
               
                let json: AnyObject?
                do {
                    json = try NSJSONSerialization.JSONObjectWithData(data!, options: NSJSONReadingOptions.AllowFragments)
                } catch {
                    return .Failure(error as NSError)
                }
               
                NSLog(" /*---- Response ---- Request URL = (request?.URLString) Result = (json) ------------------*/ ")
               
                let code = json?[ResponseData.Code.rawValue] as? String
                guard let _ = code else {
                    let reason = "Data struct invalid."
                    let error = ErrorHandler.error(code: ErrorCode.DataStructInvalid.rawValue, reason: reason)
                    return .Failure(error)
                }
               
                guard code! == ResponseData.Success.rawValue else {
                    let reason = json?[ResponseData.Msg.rawValue] as? String
                    let error = ErrorHandler.error(code: Int(code!)!, reason: reason)
                    return .Failure(error)
                }
               
                guard let result = json?[ResponseData.Result.rawValue] else {
                    return .Success(NSNull())
                }
               
                return .Success(result!)
            }
        }
    }
     
    5、接口调用
    HUD.show(.LabeledProgress(title: "",subtitle:"登录中..."))

    Network.request(method: Alamofire.Method.POST, path: URLPath.Login, parameters: ["account": account,"password":passwordMD5])
        .responseObject { (response: Alamofire.Response<User, NSError>) in
        if response.result.isSuccess {
            UserHelp.sava(user: response.result.value!,password: password)
           
            HUD.flash(.Success, delay: 0.0,completion: { finish in
                AppDelegate.switchToMain()
            })
         } else {
            HUD.flash(.LabeledError(title: "",subtitle: response.result.error?.localizedDescription), delay: 0.5)
        }
    }
     
     
     
  • 相关阅读:
    C#带日期型默认值参数的函数
    mvc调用webapi上传图片或文件
    mysql增删改查存储过程
    sql 分页存储过程
    sql 出库存储过程
    Ternura
    留言板
    友链
    .net 死锁
    C#微信小程序搜索框
  • 原文地址:https://www.cnblogs.com/shuleihen/p/5663917.html
Copyright © 2011-2022 走看看