• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

swift 项目搭建

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

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("\n/*---- Request ----\n\(request.debugDescription)\n------------------*/\n\n")
        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("\n/*---- Response ----\nRequest URL = \(request?.URLString)\n\nResult = \(json)\n------------------*/\n")
           
            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)
    }
}
 
 
 

鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
热门推荐
热门话题
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap