美文网首页
干货!Swift/OC高效管理API接口

干货!Swift/OC高效管理API接口

作者: 66b6d3e5fc98 | 来源:发表于2017-12-06 18:04 被阅读198次

    Swift——enum管理模式

    1,API接口
    import Foundation
    enum My_API {
        case t新闻列表(page:Int,type:Int,processID:String)
        case t书本列表(q:String)
    }
    
    2,各项值配置
    //MARK:--- mainURL ----------
    extension My_API {
        var mainURLValue:String {
            switch self {
            case .t新闻列表(_ , _, _):
                return "http://admin.militaryapp.china.com"
            case .t书本列表(_):
                return "https://api.douban.com"
            }
        }
    }
    //MARK:--- pathURLString ----------
    extension My_API {
        var pathValue:String {
            switch self {
            case .t新闻列表(_ , _, _):
                return "/News/NewsServlet.do"
            case .t书本列表(_):
                return "/v2/book/search"
            }
        }
    }
    //MARK:--- parames ----------
    extension My_API {
        var paramesValue:[String:Any] {
            switch self {
            case .t新闻列表(let page, let type, let processID):
                return ["page":page,"type":type,"processID":processID,"page-size":20]
            case .t书本列表(let q):
                return ["q":q]
            }
        }
    }
    //MARK:--- heard ----------
    extension My_API {
        var headerValue:[String:String] {
            switch self {
            case .t新闻列表(_,_,_):
                return [:]
            case .t书本列表(_):
                return [:]
            }
        }
    }
    //MARK:--- encoding ----------
    extension My_API {
        var encodingValue: ParameterEncoding {
            switch self {
            case .t新闻列表(_, _, _):
                return URLEncoding.default
            case .t书本列表(_):
                return JSONEncoding(options: [])
            }
        }
    }
    //MARK:--- HTTPMethod ----------
    import Alamofire
    extension My_API {
        var methodValue: HTTPMethod {
            switch self {
            case .t新闻列表(_ , _, _):
                return .get
            case .t书本列表(_):
                return .post
            }
        }
    }
    
    3,请求
    typealias my_apiBlock = (_ isOk: Bool, _ data: Any, _ error: String) -> Void
    //MARK:--- 上传 ----------
    extension My_API {
        func upload<T: My_JsonModel>(_ model: T.Type, block:((Bool,Any,String) -> Void)? = nil, progressBlock:cd_netProgressBlock? = nil) {
            
        }
    }
    //MARK:--- 请求 ----------
    extension My_API {
        func request<T: My_JsonModel>(_ model: T.Type,
                                        objType:My_APIObjectType = .tObject,
                                        block:my_apiBlock? = nil)
        {
            CD_Alamofire.cd_request(mainURLValue+pathValue, method: methodValue, parameters: paramesValue, encoding: encodingValue, headers: headerValue) { (isOk, res, error) in
                print("\(self)(\(self.mainURLValue+self.pathValue))==>\(JSON(res!))")//统一打印
                My_API.my_ApiBlock(model, objType: objType, data: (isOk,res,error),block:block)
            }
        }
    }
    
    4,数据处理 + 转模型(泛型整合)

    转模型框架SwiftyJSONHandyJSON各有各的优势
    本例使用SwiftyJSON,因为SwiftyJSON需要自定义协议泛型化,当初趟过坑。

    import SwiftyJSON
    //MARK:--- 通用模型 ----------
    struct M_MyCommon {
        //媒体上传 - 返回媒体地址
        var media_url = ""
        var media_img = ""
    }
    extension M_MyCommon:My_JsonModel {
        init(_ json: JSON) {
            if json.isEmpty{return}
            media_url = json["url"].stringValue
            media_img = json["media_img_url"].stringValue
        }
    }
    
    //MARK:--- Json 数据 与后台的约定和错误处理----------
    let My_Net_Code = "code"
    let My_Net_Msg = "msg"
    let My_Net_Data = "data"
    //--- 数据初步处理
    enum My_APIObjectType {
        case tObject
        case tArray
    }
    public protocol My_JsonModel {
        //所有的转模型通过遵循 My_JsonModel 协议
        init()
        init(_ json:JSON)
    }
    //MARK:--- 数据处理 + 转模型 ----------
    extension My_API {
        static func my_ApiBlock<T: My_JsonModel>(_ model: T.Type, objType:My_APIObjectType, data:( isOk:Bool, response:Any?, error:String?), block:my_apiBlock? = nil) {
            switch objType {
            case .tObject:
                My_API.map_Object(model, data:data, haveCode:true, block: block)
            default:
                My_API.map_Array(model, data:data, haveCode:true, block: block)
            }
        }
        ///SwiftyJSON  Json->Model
        static func map_FromJSON<T: My_JsonModel>(_ jsonData:JSON, classType: T.Type) -> T? {
            return T(jsonData)
        }
        
        static func map_Array<T: My_JsonModel>(_ type: T.Type, data:( isOk:Bool, response:Any?, error:String?), haveCode:Bool = true, block:((Bool,[T],String)->Void)? = nil){
            /*
            if data.isOk {
                let json = JSON(data.response!)
                var array:[JSON] = []
                if haveCode {
                    guard json[My_Net_Code].stringValue == My_NetCodeError.t成功.rawValue else{
                        let message = (My_NetCodeError(rawValue: json[My_Net_Code].stringValue) ?? .tError).stringValue
                        block?(false,[],message)
                        
                        if json[My_Net_Code].stringValue == My_NetCodeError.t需要登录.rawValue {
                            My_API.needLogin()
                        }
                        
                        return
                    }
                    
                    guard let arr:[JSON] = json[My_Net_Data].array else{
                        block?(true,[],cd_Localization(My_NetCodeError.t没有数据.rawValue))
                        return
                    }
                    array = arr
                }else{
                    
                    array = json.arrayValue
                }
                
                var objects = [T]()
                
                if array.count > 0 {
                    for object in array {//转模型
                        if let obj = My_API.map_FromJSON(object, classType:type)  {
                            objects.append(obj)
                        }
                    }
                    block?(true,objects,"")
                } else {
                    block?(true,[],cd_Localization(My_NetCodeError.t没有数据.rawValue))
                }
            }else{
                block?(false,[],data.error!)
            }*/
        }
        
        static func map_Object<T: My_JsonModel>(_ type: T.Type, data:( isOk:Bool, response:Any?, error:String?), haveCode:Bool = true,  block:((Bool,T,String)->Void)? = nil){
            //省略一堆处理(同上)
        }
        6
        //登录失效处理
        /*
        static func needLogin() {
            SP_User.shared.needLogin()
        }*/
        
    }
    
    5,使用示例
    My_API.t新闻列表(page: 1, type: 1, processID: "getNewsList")
          .request(M_MyCommon.self, objType: .tArray)
          { [weak self](isOk, res, error) in
                    
    }
    

    Swift——Moya管理(不太推荐,没必要)

    1,各项值配置()
    import Moya
    extension My_API: TargetType {
        var baseURL: URL {
            switch self {
            case .t新闻列表(_ , _, _):
                return URL(string: "http://admin.militaryapp.china.com/")!
            case .t书本列表(_):
                return URL(string: "https://api.douban.com/")!
            }
            
        }
        
        var path: String {
            switch self {
            case .t新闻列表(_ , _, _):
                return "News/NewsServlet.do"
            case .t书本列表(_):
                return "v2/book/search"
            }
        }
        
        var method: Moya.Method {
            switch self {
            case .t新闻列表(_ , _, _):
                return .get
            case .t书本列表(_):
                return .post
            }
        }
        var parameters: [String: Any] {
            switch self {
            case .t新闻列表(let page, let type, let processID):
                return ["page":page,"type":type,"processID":processID]
            case .t书本列表(let q):
                return ["q":q]
            }
        }
        
        var parameterEncoding: ParameterEncoding {
            switch self {
            case .t新闻列表(_, _, _):
                return URLEncoding.default
            case .t书本列表(_):
                return JSONEncoding(options: [])
            }
        }
        var sampleData: Data {
            return "".data(using: String.Encoding.utf8)!
        }
        
        var task: Task {
            return .requestParameters(parameters: parameters, encoding: parameterEncoding)
        }
        
        var headers: [String : String]? {
            switch self {
            case .t新闻列表(_,_,_):
                return [:]
            case .t书本列表(_):
                return [:]
            }
        }
    }
    
    2,使用示例(配合RxSwift)
    myApiProvider.rx
      .request(.t新闻列表(page: 1, type: 1, processID: "getNewsList"))
      .mapJSON()//可扩展RxSwift  Single 自定义mapJSON,再配合SwiftyJSON/HandyJSON进一步做数据处理
      .subscribe(onSuccess: { (res) in
          print(JSON(res))
      }) { (error) in
                    
      }
     .disposed(by:disposeBag)
    

    Swift——其他管理模式

    //管理方法很多,个人觉得不利用第三方 enum 管理较轻便
    

    OC——常量+工厂管理(拒绝使用宏)

    1,常量管理API接口地址
    @interface My_URLs : NSObject
    #pragma mark ----- 配置 (拒绝使用宏)-----
    /** pageSize 每页条数 */
    extern NSString* const pageSize;
    /** code 数据反馈标识 */
    extern NSString* const code;
    /** msg 数据反馈信息 */
    extern NSString* const msg;
    /** data 数据内容 */
    extern NSString* const data;
    
    /** 根地址*/
    extern NSString* const main_URL;
    /** 获取新闻列表*/
    extern NSString* const getNewsServlet;
    /** 获取书本列表*/
    extern NSString* const getBooks;
    @end
    
    #import "My_URLs.h"
    
    @implementation My_URLs
    NSString * const pageSize = @"20";
    NSString * const code = @"status";
    NSString * const msg = @"msg";
    NSString * const data = @"data";
    
    NSString * const main_URL = @"";
    
    NSString * const getNewsServlet = @"http://admin.militaryapp.china.com/News/NewsServlet.do";
    NSString * const getBooks = @"https://api.douban.com/v2/book/search";
    @end
    
    2,工厂化
    //block:(void (^)(BOOL isOk, NSDictionary * data, NSString* msg))block
    typedef void (^DataBlock)(BOOL isOk, NSDictionary * data, NSString* msg);
    @interface My_API : NSObject
    + (void) getNewsListWithParams:(NSDictionary*)params  block:(DataBlock)block;
    + (void) getBooksWithParams:(NSDictionary*)params block:(DataBlock)block;
    @end
    
    #import "My_API.h"
    #import "CD_AF.h"
    #import "My_URLs.h"
    #import <AFNetworking/AFNetworking.h>
    #define My_APIS(string, args...) [NSString stringWithFormat:string, args]
    
    @implementation My_API
    
    + (void) getNewsListWithParams:(NSDictionary*)params  block:(DataBlock)block {
        [CD_AF.shared setContentTypes:@"text/html"];
        __block NSMutableDictionary * dic = [NSMutableDictionary dictionary];
        [dic setValue:pageSize forKey:@"pageSize"];
        [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [dic setValue:obj forKey:key];
        }];
        [CD_AF.shared requestWithMethod:tGet
                              urlString:My_APIS(@"%@%@",main_URL,getNewsServlet)
                             parameters:dic
                       withRequestBlock:^(id result, NSError *error) {
                           if (!error) {
                               [My_API makeArray:result block:block];
                           }else{
                               
                           }
                       }];
    };
    
    + (void) getBooksWithParams:(NSDictionary*)params block:(DataBlock)block {
        [CD_AF.shared setContentTypes:@"application/json"];
        __block NSMutableDictionary * dic = [NSMutableDictionary dictionary];
        [params enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
            [dic setValue:obj forKey:key];
        }];
        [CD_AF.shared requestWithMethod:tGet
                              urlString:My_APIS(@"%@%@",main_URL,getBooks)
                             parameters:dic
                       withRequestBlock:^(id result, NSError *error) {
                           if (!error) {
                               [My_API makeArray:result block:block];
                           }else{
                               
                           }
                       }];
        
    };
    
    /**数据处理*/
    + (void) makeObj:(id)result block:(DataBlock)block {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingMutableLeaves error:nil];
        NSLog(@"%@",dic);
        if ([dic[code] isEqualToString:@"0"]) {
            block(YES,dic[data],@"");
        }else{
            block(NO,nil,dic[msg]);
        }
        
    }
    + (void) makeArray:(id)result block:(DataBlock)block {
        NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:result options:NSJSONReadingMutableLeaves error:nil];
        //block(YES,dic[@"books"],@"");
        
        if ([dic[code] isEqualToString:@"success"]) {
            block(YES,dic[data],@"");
        }else{
            block(NO,nil,dic[msg]);
        }
    }
    @end
    

    相关文章

      网友评论

          本文标题:干货!Swift/OC高效管理API接口

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