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
网友评论