美文网首页iOS/macOS/watchOSiOS技术资料
干货!Alamofire/AFNetWorking 使用及二次封

干货!Alamofire/AFNetWorking 使用及二次封

作者: 66b6d3e5fc98 | 来源:发表于2017-03-16 09:51 被阅读1468次

Swift—— Alamofire

1,一个单例 + 工厂方法
import Foundation
import Alamofire

class CD_Alamofire {
    open static let shared: CD_Alamofire = CD_Alamofire()
    fileprivate let _manager = SessionManager.default
    
    let CD_NetStatusNotifyName = "CD_NetworkReachabilityStatus"
    ///取消上传
    var cd_uploadCancel = false
    ///当前网络状态
    var cd_netStatusNow:CD_NetworkReachabilityStatus = .tNnknown {
        didSet{
            NotificationCenter.default.post(name: NSNotification.Name(rawValue:CD_NetStatusNotifyName), object: cd_netStatusNow, userInfo: [:])
        }
    }
    fileprivate var openNetStatus:Bool = false
}
//MARK:--- 请求,上传,下载 ----------
/// 网络请求回调闭包 success:是否成功 result:数据 progress:请求进度 error:错误信息
typealias cd_netComBlock = (_ success: Bool, _ result: Any?, _ error: String?) -> Void
typealias cd_netProgressBlock = (_ progress:Progress?) -> Void

extension CD_Alamofire {
    ///请求
    class func cd_request(
        _ url: String,
        method: HTTPMethod = .get,
        parameters:[String:String] = [:],
        encoding: ParameterEncoding = URLEncoding.default,
        headers: HTTPHeaders? = nil,
        block: cd_netComBlock? = nil) {
        guard !url.isEmpty else {
            block?(false,"","空地址")
            return
        }
        CD_Alamofire.shared._manager.request(url, method: method, parameters: parameters, encoding: encoding, headers: headers).responseJSON { response in
            CD_Alamofire.disposeResponse(response, block:block)
        }
    }
    ///上传
    class func cd_upload(
        _ url:String,
        param:[String:String] = [:],
        uploadParams:[CD_UploadParam],
        headers: HTTPHeaders? = nil,
        progressBlock: cd_netProgressBlock? = nil,
        block: cd_netComBlock? = nil) {
        guard !url.isEmpty else {
            block?(false,"","空地址")
            return
        }
        CD_Alamofire.shared.cd_uploadCancel = false
        CD_Alamofire.shared._manager.upload(multipartFormData: { (formData) in
            for item in uploadParams {
                switch (item.type) {
                case .tData:
                    formData.append(item.fileData, withName: item.serverName, fileName: item.filename, mimeType: item.mimeType)
                case .tFileURL:
                    if let fileUrl = item.fileURL {
                        formData.append(fileUrl, withName: item.serverName, fileName: item.filename, mimeType: item.mimeType)
                    }
                }
            }
            for item in param {
                let dat:Data = item.value.data(using: String.Encoding.utf8) ?? Data()
                formData.append(dat, withName: item.key)
            }
        }, to: url, headers:headers, encodingCompletion: { (encodingResult) in
            switch encodingResult {
            case .success(let uploads, _, _):
                if CD_Alamofire.shared.cd_uploadCancel {
                    uploads.cancel()
                }
                uploads.uploadProgress(closure: { (progress) in
                    progressBlock?(progress)
                }).responseJSON { response in
                    CD_Alamofire.disposeResponse(response, block:block)
                }
            case .failure(let error):
                block?(false,"",cd_returnNSError(error))
            }
        })
    }
    ///下载
    class func cd_downLoad(
        _ url:String,
        param:[String:Any],
        progressBlock: cd_netProgressBlock? = nil,
        block: cd_netComBlock? = nil) {
        
    }
    ///数据处理
    fileprivate class func disposeResponse(_ response:DataResponse<Any>, block:cd_netComBlock? = nil) {
        var error = ""
        var isOk = false
        switch response.result {
        case .success(let json):
            if (response.result.value != nil) {
                isOk = true
                error = ""
            } else{
                isOk = false
                error = CD_ErrorType.noData.stringValue
            }
            block?(isOk,json,error)
        case .failure(let error):
            isOk = false
            block?(isOk,"",cd_returnNSError(error))
        }
    }
}
//MARK:--- 网络监测 建议在 AppDelegate 中开启,响应存在不及时----------
fileprivate let CD_NetworkManager = NetworkReachabilityManager(host: "www.baidu.com")
extension CD_Alamofire {
    public enum CD_NetworkReachabilityStatus {
        case tNotReachable
        case tNnknown
        case tEthernetOrWiFi
        case tWWAN
    }
    ///开启网络监测
    class func cd_OpenNetStatus() {
        guard !CD_Alamofire.shared.openNetStatus else {
            CD_Alamofire.shared.cd_netStatusNow = CD_Alamofire.shared.cd_netStatusNow
            return
        }
        CD_Alamofire.shared.openNetStatus = true
        //首次进入有网络会响应,但没网络不响应
        CD_NetworkManager!.listener = { status in
            switch status {
            case .notReachable:
                CD_Alamofire.shared.cd_netStatusNow = .tNotReachable
            case .unknown:
                CD_Alamofire.shared.cd_netStatusNow = .tNnknown
            case .reachable(.ethernetOrWiFi):
                CD_Alamofire.shared.cd_netStatusNow = .tEthernetOrWiFi
            case .reachable(.wwan):
                CD_Alamofire.shared.cd_netStatusNow = .tWWAN
            }
        }
        CD_NetworkManager!.startListening()
    }
}

//MARK:--- SSL认证 ([来自航歌](http://www.hangge.com/blog/cache/detail_991.html))-----------------------------
extension CD_Alamofire {
    //存储认证相关信息
    struct CD_IdentityAndTrust {
        var identityRef:SecIdentity
        var trust:SecTrust
        var certArray:AnyObject
    }
    
    func cd_SSL(_ hosts:[String], p12:(name:String, pwd:String)) {
        let selfSignedHosts = hosts//["192.168.1.112", "www.hangge.com"]
        _manager.delegate.sessionDidReceiveChallenge = { session, challenge in
            //认证服务器(这里不使用服务器证书认证,只需地址是我们定义的几个地址即可信任)
            if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodServerTrust
                && selfSignedHosts.contains(challenge.protectionSpace.host)
            {
                print("服务器认证!")
                let credential = URLCredential(trust: challenge.protectionSpace.serverTrust!)
                return (.useCredential, credential)
            }
                //认证客户端证书
            else if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodClientCertificate
            {
                print("客户端证书认证!")
                //获取客户端证书相关信息
                let identityAndTrust:CD_IdentityAndTrust = self.extractIdentity(p12);
                let urlCredential:URLCredential = URLCredential(
                    identity: identityAndTrust.identityRef,
                    certificates: identityAndTrust.certArray as? [AnyObject],
                    persistence: URLCredential.Persistence.forSession);
                
                return (.useCredential, urlCredential);
            }
                // 其它情况(不接受认证)
            else
            {
                print("其它情况(不接受认证)")
                return (.cancelAuthenticationChallenge, nil)
            }
        }
    }
    //MARK:--- 双向认证 -----------------------------
    func cd_SSL(_ cerName:String ,p12:(name:String, pwd:String)) {
        
        _manager.delegate.sessionDidReceiveChallenge = { (session, challenge) in
            //认证服务器证书
            if challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust
            {
                print("服务端证书认证!")
                let serverTrust:SecTrust = challenge.protectionSpace.serverTrust!
                let certificate = SecTrustGetCertificateAtIndex(serverTrust, 0)!
                let remoteCertificateData
                    = CFBridgingRetain(SecCertificateCopyData(certificate))!
                //证书目录
                let cerPath = Bundle.main.path(forResource: cerName, ofType: "cer")!
                let cerUrl = URL(fileURLWithPath:cerPath)
                let localCertificateData = try! Data(contentsOf: cerUrl)
                if (remoteCertificateData.isEqual(localCertificateData) == true) {
                    let credential = URLCredential(trust: serverTrust)
                    challenge.sender?.use(credential, for: challenge)
                    return (URLSession.AuthChallengeDisposition.useCredential,
                            URLCredential(trust: challenge.protectionSpace.serverTrust!))
                }else {
                    return (.cancelAuthenticationChallenge, nil)
                }
            }
                //认证客户端证书
            else if challenge.protectionSpace.authenticationMethod
                == NSURLAuthenticationMethodClientCertificate
            {
                print("客户端证书认证!")
                //获取客户端证书相关信息
                let identityAndTrust:CD_IdentityAndTrust = self.extractIdentity(p12);
                
                let urlCredential:URLCredential = URLCredential(
                    identity: identityAndTrust.identityRef,
                    certificates: identityAndTrust.certArray as? [AnyObject],
                    persistence: URLCredential.Persistence.forSession);
                
                return (.useCredential, urlCredential);
            }
                // 其它情况(不接受认证)
            else
            {
                print("其它情况(不接受认证)")
                return (.cancelAuthenticationChallenge, nil)
            }
        }
    }
    //MARK:--- 获取客户端证书相关信息 -----------------------------
    fileprivate func extractIdentity(_ p12:(name:String, pwd:String)) -> CD_IdentityAndTrust {
        
        var identityAndTrust:CD_IdentityAndTrust!
        var securityError:OSStatus = errSecSuccess
        //客户端证书 p12 文件目录
        let path: String = Bundle.main.path(forResource: p12.name, ofType: "p12")!
        let PKCS12Data = NSData(contentsOfFile:path)!
        let key : NSString = kSecImportExportPassphrase as NSString
        let options : NSDictionary = [key : p12.pwd] //客户端证书密码
        //create variable for holding security information
        //var privateKeyRef: SecKeyRef? = nil
        var items : CFArray?
        securityError = SecPKCS12Import(PKCS12Data, options, &items)
        if securityError == errSecSuccess {
            let certItems:CFArray = items as CFArray!;
            let certItemsArray:Array = certItems as Array
            let dict:AnyObject? = certItemsArray.first;
            if let certEntry:Dictionary = dict as? Dictionary<String, AnyObject> {
                // grab the identity
                let identityPointer:AnyObject? = certEntry["identity"];
                let secIdentityRef:SecIdentity = identityPointer as! SecIdentity!
                //print("\(identityPointer)  :::: \(secIdentityRef)")
                // grab the trust
                let trustPointer:AnyObject? = certEntry["trust"]
                let trustRef:SecTrust = trustPointer as! SecTrust
                //print("\(trustPointer)  :::: \(trustRef)")
                // grab the cert
                let chainPointer:AnyObject? = certEntry["chain"]
                identityAndTrust = CD_IdentityAndTrust(identityRef: secIdentityRef,
                                                       trust: trustRef, certArray:  chainPointer!)
            }
        }
        return identityAndTrust;
    }
}
2, CD_UploadParam
enum CD_UploadParamType {
    case tData
    case tFileURL
}
struct CD_UploadParam {
    ///Data数据流
    var fileData = Data()
    ///文件的FileURL
    var fileURL:URL?
    ///服务器对应的参数名称
    var serverName = ""
    ///文件的名称(上传到服务器后,服务器保存的文件名)
    var filename = ""
    ///文件的MIME类型(image/png,image/jpg,application/octet-stream/video/mp4等)
    var mimeType = "image/png"
    ///文件类型
    var type:CD_UploadParamType = .tData
}
3,反馈编码
//error = CD_ErrorType.noData.stringValue
//block?(isOk,"",cd_returnNSError(error))
enum CD_ErrorType:Int {
    case noData      = 10000000
    case nsurlErrorUnknown = -1
    ……
    var stringValue:String {
        switch self {
        case .nsurlErrorUnknown:                                 return cd_Localization("未知错误",from:"CD_ErrorType")
        case .nsurlErrorCancelled:                               return cd_Localization("取消了网址",from:"CD_ErrorType")
    ……
    }
}
//省略一堆反馈编码
4,反馈编码国际化
//省略一堆反馈编码国际化
5,使用示例
        CD_Alamofire.cd_request("") { (isOk, data, error) in
            
        }

OC—— AFNetWorking

1,一个单例
#import "CD_UploadParam.h"
/**
 *  网络连接类型
 */
typedef NS_ENUM(NSInteger) {
    tUnknown,
    tNotNet,
    tWWAN,
    tWiFi
}CD_AFNetType;
typedef NS_ENUM(NSInteger) {
    tGet,
    tPost,
    tPut,
}CD_AFMethod;

typedef void (^RequestResult)(id result, NSError * error);
typedef void (^ProgressResult)(NSProgress * progress);

@interface CD_AF : NSObject
@property(nonatomic,strong) NSString *name;
+ (CD_AF*)shared;
+ (void)cd_print;


#pragma mark --- 监测网络的可链接性
/*
 netTypeBlock, 在需要监听网络链接状态改变时使用
 haveNet 在判断是否有网络链接时用
 */
@property (nonatomic, weak) __block void (^netTypeBlock)(CD_AFNetType type);
- (BOOL) haveNet;
/** 请求头 Header*/
@property(nonatomic,strong) NSDictionary * httpHeader;
/** 最大并发数*/
@property(nonatomic,assign) NSInteger maxOperationCount;
/** 不设置会报 error 3840 (text/html) (application/json; charset=utf-8)(application/json)*/
@property(nonatomic,strong) NSString * contentTypes;
/** https:    SSL*/
- (void)sslWithNone;
- (void)sslWithPublicKey;
- (void)sslWithCertificateFromPath:(NSString*)path;
#pragma mark --- 发送请求
/**
 *  发送请求
 *   method            请求类型
 *   urlString         请求的网址字符串
 *   parameters        请求的参数
 *   requestResult     请求成功/失败的回调
 */
- (void)requestWithMethod:(CD_AFMethod)method
                urlString:(NSString *)urlString
               parameters:(id)parameters
         withRequestBlock:(RequestResult)requestResult;

#pragma mark --- 上传图片
/**
 *  上传图片
 *
 *   URLString         上传图片的网址字符串
 *   parameters        上传图片的参数
 *   uploadParam       上传图片的信息
 *   progress          上传进度的回调
 *   requestResult     上传成功/失败的回调
 */
- (void)uploadWithURLString:(NSString *)urlString
                 parameters:(id)parameters
                uploadParam:(NSArray <CD_UploadParam *> *)uploadParams
          withProgressBlock:(ProgressResult)progress
           withRequestBlock:(RequestResult)requestResult;

#pragma mark --- 下载数据
/**
 *  下载数据
 *
 *   URLString         下载数据的网址
 *   parameters        下载数据的参数
 *   progress          下载进度的回调
 *   requestResult     下载成功/失败的回调
 */
- (void)downLoadWithURLString:(NSString *)urlString
                   parameters:(id)parameters
            withProgressBlock:(ProgressResult)progress
             withRequestBlock:(RequestResult)requestResult;

@end
#import <AFNetworking/AFNetworking.h>

static CD_AF* shared = nil;

@interface CD_AF(){
    AFHTTPSessionManager * _manager;
    __block BOOL _hasReachability;
    __block CD_AFNetType _netState;
}

@end


@implementation CD_AF
#pragma mark ----- 单例 -----
+ (CD_AF*) shared
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        if (shared == nil) {
            shared = [[self alloc] init];
        }
    });
    return shared;
}
/**
 覆盖该方法主要确保当用户通过[[* alloc] init]创建对象时对象的唯一性,alloc方法会调用该方法,只不过zone参数默认为nil,因该类覆盖了allocWithZone方法,所以只能通过其父类分配内存,即[super allocWithZone:zone]
 */
+(id)allocWithZone:(struct _NSZone *)zone
{
    static dispatch_once_t token;
    dispatch_once(&token, ^{
        if(shared == nil){
            shared = [super allocWithZone:zone];
        }
    });
    return shared;
}
//自定义初始化方法
- (instancetype)init
{
    self = [super init];
    if(self){
        [self makeManager];
    }
    return self;
}
//覆盖该方法主要确保当用户通过copy方法产生对象时对象的唯一性
- (id)copy
{
    return self;
}
//覆盖该方法主要确保当用户通过mutableCopy方法产生对象时对象的唯一性
- (id)mutableCopy
{
    return self;
}
//自定义描述信息,用于log详细打印
- (NSString *)description
{
    return [NSString stringWithFormat:@"memeory address:%p,property name:%@",self,self.name];
}
//测试
+ (void)cd_print {
    CD_AF *allocSingleton = [[CD_AF alloc] init];
    NSLog(@"allocSingleton:\n%@",allocSingleton);
    CD_AF *copySingleton = [allocSingleton copy];
    NSLog(@"copySingleton:\n%@",copySingleton);
    CD_AF *mutebleCopySingleton = [allocSingleton mutableCopy];
    NSLog(@"mutebleCopySingleton:\n%@",mutebleCopySingleton);
    CD_AF *defaultManagerSingleton =[CD_AF shared];
    NSLog(@"defaultManagerSingleton:\n%@",defaultManagerSingleton);
}


- (void)makeManager{
    _manager = [AFHTTPSessionManager manager];
    [_manager.requestSerializer willChangeValueForKey:@"timeoutInterval"];
    _manager.requestSerializer.timeoutInterval = 15.0;
    [_manager.requestSerializer didChangeValueForKey:@"timeoutInterval"];
    
    //支持Cookie
    _manager.requestSerializer.HTTPShouldHandleCookies = YES;
    //不设置会报-1016或者会有编码问题
    _manager.responseSerializer = [AFHTTPResponseSerializer serializer];
    //设置默认的ContentType
    [self setContentTypes:@"application/json"];
}
- (void) setContentTypes:(NSString *)contentTypes {
    //不设置会报 error 3840 (text/html) (application/json; charset=utf-8)(application/json)
    _manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:contentTypes];
}

- (void)sslWithNone{
    _manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeNone];
    //allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO//如果是需要验证自建证书,需要设置为YES
    [_manager.securityPolicy setAllowInvalidCertificates:YES];
    //validatesDomainName 是否需要验证域名,默认为YES;
    [_manager.securityPolicy setValidatesDomainName:NO];
}
- (void)sslWithPublicKey{
}
- (void)sslWithCertificateFromPath:(NSString*)path{
    // 2.设置证书模式
    NSString * cerPath = [[NSBundle mainBundle] pathForResource:path ofType:@"cer"];
    NSData * cerData = [NSData dataWithContentsOfFile:cerPath];
    if (cerData == nil) {return;}
    _manager.securityPolicy = [AFSecurityPolicy policyWithPinningMode:AFSSLPinningModeCertificate withPinnedCertificates:[[NSSet alloc] initWithObjects:cerData, nil]];
    //allowInvalidCertificates 是否允许无效证书(也就是自建的证书),默认为NO//如果是需要验证自建证书,需要设置为YES
    [_manager.securityPolicy setAllowInvalidCertificates:YES];
    //validatesDomainName 是否需要验证域名,默认为YES;
    [_manager.securityPolicy setValidatesDomainName:YES];
}

- (void)setHttpHeader:(NSDictionary *)httpHeader{
    [httpHeader enumerateKeysAndObjectsUsingBlock:^(id  _Nonnull key, id  _Nonnull obj, BOOL * _Nonnull stop) {
        [_manager.requestSerializer setValue:obj forHTTPHeaderField:key];
    }];
}
- (NSDictionary *)httpHeader{
    return _manager.requestSerializer.HTTPRequestHeaders;
};

- (void)setMaxOperationCount:(NSInteger)maxOperationCount{
    //请求队列的最大并发数
    _manager.operationQueue.maxConcurrentOperationCount = maxOperationCount;
}
#pragma 监测网络的可链接性
- (BOOL) haveNet {
    if (!_hasReachability) {
        AFNetworkReachabilityManager *reachability = [AFNetworkReachabilityManager sharedManager];
        [reachability setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
            // 当网络状态改变时调用
            switch (status) {
                case AFNetworkReachabilityStatusUnknown:
                    _netState = YES;
                    if (_netTypeBlock) {
                        _netTypeBlock(tUnknown);
                    }
                    break;
                case AFNetworkReachabilityStatusNotReachable:
                    _netState = NO;
                    if (_netTypeBlock) {
                        _netTypeBlock(tNotNet);
                    }
                    break;
                case AFNetworkReachabilityStatusReachableViaWWAN:
                    _netState = YES;
                    if (_netTypeBlock) {
                        _netTypeBlock(tWWAN);
                    }
                    break;
                case AFNetworkReachabilityStatusReachableViaWiFi:
                    _netState = YES;
                    if (_netTypeBlock) {
                        _netTypeBlock(tWiFi);
                    }
                    break;
            }
        }];
        //开始监控
        [reachability startMonitoring];
        _hasReachability = YES;
    }
    return _netState;
}

#pragma mark --- 发送请求
/**
 *  发送get请求
 *   method            请求类型
 *   urlString         请求的网址字符串
 *   parameters        请求的参数
 *   requestResult     请求成功/失败的回调
 */
- (void)requestWithMethod:(CD_AFMethod)method
                urlString:(NSString *)urlString
               parameters:(id)parameters
         withRequestBlock:(RequestResult)requestResult {
    switch (method) {
        case tGet:
            [self getWithURLString:urlString parameters:parameters withRequestBlock:requestResult];
            break;
        case tPost:
            [self postWithURLString:urlString parameters:parameters withRequestBlock:requestResult];
            break;
        case tPut:
            [self putWithURLString:urlString parameters:parameters withRequestBlock:requestResult];
            break;
    }
    
}
#pragma mark --- 发送get请求
/**
 *  发送post请求
 *
 *   URLString         请求的网址字符串
 *   parameters        请求的参数
 *   requestResult     请求成功/失败的回调
 */
- (void)getWithURLString:(NSString *)urlString
               parameters:(id)parameters
         withRequestBlock:(RequestResult)requestResult {
    [_manager GET:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        requestResult(responseObject,nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        requestResult(nil,error);
    }];
}
#pragma mark --- 发送post请求
/**
 *  发送post请求
 *
 *   URLString         请求的网址字符串
 *   parameters        请求的参数
 *   requestResult     请求成功/失败的回调
 */
- (void)postWithURLString:(NSString *)urlString
               parameters:(id)parameters
         withRequestBlock:(RequestResult)requestResult {
    
    [_manager POST:urlString parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        requestResult(responseObject,nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        requestResult(nil,error);
    }];
}
#pragma mark --- 发送put请求
/**
 *  发送post请求
 *
 *   URLString         请求的网址字符串
 *   parameters        请求的参数
 *   requestResult     请求成功/失败的回调
 */
- (void)putWithURLString:(NSString *)urlString
               parameters:(id)parameters
         withRequestBlock:(RequestResult)requestResult {
    
    [_manager PUT:urlString parameters:parameters success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        requestResult(responseObject,nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        requestResult(nil,error);
    }];
}
#pragma mark --- 上传图片
/**
 *  上传图片
 *
 *   URLString         上传图片的网址字符串
 *   parameters        上传图片的参数
 *   uploadParam       上传图片的信息
 *   progress          上传进度的回调
 *   requestResult     上传成功/失败的回调
 */
- (void)uploadWithURLString:(NSString *)urlString
                 parameters:(id)parameters
                uploadParam:(NSArray <CD_UploadParam *> *)uploadParams
          withProgressBlock:(ProgressResult)progress
           withRequestBlock:(RequestResult)requestResult {
    [_manager POST:urlString parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        //上传文件参数
        for (CD_UploadParam *param in uploadParams) {
            switch (param.type) {
                case tData:
                    [formData appendPartWithFileData:param.fileData name:param.serverName fileName:param.fileName mimeType:param.mimeType];
                    break;
                case tFileURL:
                    [formData appendPartWithFileURL:[NSURL fileURLWithPath:param.fileURL] name:param.serverName fileName:param.fileName mimeType:param.mimeType error:nil];
                    break;
                default:
                    break;
            }
        }
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //打印下上传进度
        //NSLog(@"%lf",1.0 *uploadProgress.completedUnitCount / uploadProgress.totalUnitCount);
        progress(uploadProgress);
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        requestResult(responseObject,nil);
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        requestResult(nil,error);
    }];
}

#pragma mark --- 下载数据
/**
 *  下载数据
 *
 *   URLString         下载数据的网址
 *   parameters        下载数据的参数
 *   progress          下载进度的回调
 *   requestResult     下载成功/失败的回调
 *
 */
- (void)downLoadWithURLString:(NSString *)urlString
                   parameters:(id)parameters
            withProgressBlock:(ProgressResult)progress
             withRequestBlock:(RequestResult)requestResult {
}
@end

2,CD_UploadParam模型类
/**
 *  文件类型
 */
typedef NS_ENUM(NSUInteger) {
    tData,
    tFileURL
}CD_UploadParamType;
@interface CD_UploadParam : NSObject
/**
 *  NSData数据
 */
@property (nonatomic, copy) NSData * fileData;
/**
 *  文件的FileURL
 */
@property (nonatomic, copy) NSString * fileURL;
/**
 *  服务器对应的参数名称
 */
@property (nonatomic, copy) NSString * serverName;
/**
 *  文件的名称(上传到服务器后,服务器保存的文件名)
 */
@property (nonatomic, copy) NSString * fileName;
/**
 *  文件的MIME类型(image/png,image/jpg,application/octet-stream/video/mp4等)
 */
@property (nonatomic, copy) NSString * mimeType;
/**
 *  文件的类型
 */
@property (nonatomic, assign) CD_UploadParamType type;
@end
3,示例
+ (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{
                           
                       }
                   }];
    
};
4,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
/********************* .m *****************/
@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

相关文章

网友评论

  • Maj_sunshine:oc我看懂了 但是swift调用起来是啥呀

本文标题:干货!Alamofire/AFNetWorking 使用及二次封

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