1、首先將AFN最新的包導入工程,可以使用cocopods。
2、新建一個類,我的類名GlobalNetWorking。首先封裝了一下判斷是否有網,具體代碼如下
GlobalNetWorking.h
#import <Foundation/Foundation.h>
#import "AFNetworking.h"
@interface GlobalNetWorking : NSObject
//判斷是否有網絡
+(BOOL)isHasNetwork;
GlobalNetWorking.m中實現:
+(AFNetworkReachabilityStatus)currentNetworkStatus{
static AFNetworkReachabilityStatus currentNetworkStatus = AFNetworkReachabilityStatusUnknown;
static dispatch_once_t predicate;
dispatch_once(&predicate, ^{
/*
AFNetworkReachabilityStatusUnknown = -1, // 未知
AFNetworkReachabilityStatusNotReachable = 0, // 無連接
AFNetworkReachabilityStatusReachableViaWWAN = 1, // 移動網絡
AFNetworkReachabilityStatusReachableViaWiFi = 2, // WiFi
*/
[[AFNetworkReachabilityManager sharedManager] startMonitoring];
[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
currentNetworkStatus = status;
}];
});
return currentNetworkStatus;
}
+(BOOL)isHasNetwork{
BOOL flag = YES;
AFNetworkReachabilityStatus statue = [self currentNetworkStatus];
//無連接或未知錯誤返回NO
if (statue == AFNetworkReachabilityStatusUnknown || statue == AFNetworkReachabilityStatusNotReachable) {
flag = NO;
}
return flag;
}
3、普通post網絡請求。
GlobalNetWorking.h中:
//普通post網絡請求
+(void)networkWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andSuccess:(void (^)(id rootObject, id datasObject, bool isSuccess))success andFailure:(void (^)(NSError *error))failure;//這裏的phpStr是後臺接口鏈接的固定拼接,parameters是傳給後臺數據字段的拼接。這裏可以直接改成url和裝有數據的字典。
GlobalNetWorking.m中
這裏的+(NSDictionary *)createPostParameterDictionaryWithUrlString:(NSString *)urlStr;
這個類方法是將我上面所說的傳給後臺數據拼接的parameters字符串轉化爲字典。(所以這一步在上面可以省略,直接傳入字典。)
#pragma mark - 解析生成post參數
+(NSDictionary *)createPostParameterDictionaryWithUrlString:(NSString *)urlStr
{
if (!urlStr || ![urlStr isKindOfClass:[NSString class]]) {
return nil;
}
NSArray *tmpAndArray = [urlStr componentsSeparatedByString:@"&"];
NSMutableDictionary *tmpDic = [[NSMutableDictionary alloc] init];
for (NSString *tmpString in tmpAndArray) {
if (![tmpString isKindOfClass:[NSString class]]) {
continue;
}
NSArray *tmpEqualArray = [tmpString componentsSeparatedByString:@"="];
if (tmpEqualArray.count == 2) {
NSString *tmpKey = [NSString stringWithFormat:@"%@", tmpEqualArray[0]];
NSString *tmpValue = [NSString stringWithFormat:@"%@", tmpEqualArray[1]];
[tmpDic setValue:tmpValue forKey:tmpKey];
}
}
return tmpDic;
}
+(void)networkWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andSuccess:(void (^)(id rootObject, id datasObject, bool isSuccess))success andFailure:(void (^)(NSError *error))failure
{
AFHTTPSessionManager *sessionManager = [AFHTTPSessionManager manager];
sessionManager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSDictionary *params = [self createPostParameterDictionaryWithUrlString:parameters];
//這裏[NSString stringWithFormat:@"%@%@",HTTP_AFNETWORKING_POST_URL,phpStr]是請求的URL。在項目中進行了封裝,方便管理。
[sessionManager POST:[NSString stringWithFormat:@"%@%@",HTTP_AFNETWORKING_POST_URL,phpStr] parameters:params progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *rootDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
//成功後進行解析,因爲我所做項目中都會包含一個data字段,所以這裏進行這麼判斷,這裏的使用需要根據後臺反饋的數據而定。
if (!rootDic || ![rootDic isKindOfClass:[NSDictionary class]] || ![rootDic.allKeys containsObject:@"data"]) {
NSError * error = [[NSError alloc] initWithDomain:@"datasError" code:ErrorCodeNoDatasKey userInfo:@{NSLocalizedDescriptionKey:@"網絡請求返回值沒有datas字段!"}];
failure(error);
return;
}
id datasValue = [rootDic objectForKey:@"data"];
BOOL isSuccess = [[rootDic valueForKey:@"status"] boolValue];
success(rootDic,datasValue,isSuccess);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
}
4、進行圖片上傳的封裝。
首先看一下我這裏的需求:需要進行表單上傳,其次是多張圖片需要放在數組中。
代碼如下:
GlobalNetWorking.h中:
//圖片上傳
+(void)uploadImageWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andImageArray:(NSArray *)imageArray andSuccess:(void (^)(id rootObject, id datasObject, bool isSuccess))success andFailure:(void (^)(NSError *error))failure;
GlobalNetWorking.m中具體實現:
+(void)uploadImageWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andImageArray:(NSArray *)imageArray andSuccess:(void (^)(id, id, bool))success andFailure:(void (^)(NSError *))failure{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSDictionary *params = [self createPostParameterDictionaryWithUrlString:parameters];
NSLog(@"%@",params);
[manager POST:[NSString stringWithFormat:@"%@%@",HTTP_AFNETWORKING_POST_URL,phpStr] parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
NSUInteger i = 0 ;
for (UIImage *image in imageArray) {
NSData * imgData = UIImageJPEGRepresentation(image, .5);
//拼接data
/*
此方法參數
1. 要上傳的[二進制數據]
2. 對應網站上[upload.php中]處理文件的[字段"file"]
3. 要保存在服務器上的[文件名]
4. 上傳文件的[mimeType]
*/
[formData appendPartWithFileData:imgData name:[NSString stringWithFormat:@"pic[%ld]",(long)i] fileName:@"image.png" mimeType:@"image/jpg"];
i++;
}
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *rootDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
if (!rootDic || ![rootDic isKindOfClass:[NSDictionary class]] || ![rootDic.allKeys containsObject:@"data"]) {
NSError * error = [[NSError alloc] initWithDomain:@"datasError" code:ErrorCodeNoDatasKey userInfo:@{NSLocalizedDescriptionKey:@"網絡請求返回值沒有data字段!"}];
failure(error);
return;
}
id datasValue = [rootDic objectForKey:@"data"];
BOOL isSuccess = [[rootDic valueForKey:@"status"] boolValue];
success(rootDic,datasValue,isSuccess);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
}
5、視頻上傳的方法
視頻上傳和圖片上傳大同小異。具體如下:
GlobalNetWorking.h中:
這裏我將video轉換成NSData進行上傳的。
//視頻上傳
+(void)uploadVideoWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andVideoData:(NSData *)videoData andSuccess:(void (^)(id rootObject, id datasObject, bool isSuccess))success andFailure:(void (^)(NSError *error))failure;
GlobalNetWorking.m中具體實現:
+(void)uploadVideoWithPhpStr:(NSString *)phpStr andParametersString:(NSString *)parameters andVideoData:(NSData *)videoData andSuccess:(void (^)(id, id, bool))success andFailure:(void (^)(NSError *))failure{
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFHTTPResponseSerializer serializer];
NSDictionary *params = [self createPostParameterDictionaryWithUrlString:parameters];
NSLog(@"%@",params);
[manager POST:[NSString stringWithFormat:@"%@%@",HTTP_AFNETWORKING_POST_URL,phpStr] parameters:params constructingBodyWithBlock:^(id<AFMultipartFormData> _Nonnull formData) {
[formData appendPartWithFileData:videoData name:@"video" fileName:@"video.mp4" mimeType:@"video/mp4"];
} progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) {
NSDictionary *rootDic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingMutableContainers error:nil];
if (!rootDic || ![rootDic isKindOfClass:[NSDictionary class]] || ![rootDic.allKeys containsObject:@"data"]) {
NSError * error = [[NSError alloc] initWithDomain:@"datasError" code:ErrorCodeNoDatasKey userInfo:@{NSLocalizedDescriptionKey:@"網絡請求返回值沒有data字段!"}];
failure(error);
return;
}
id datasValue = [rootDic objectForKey:@"data"];
BOOL isSuccess = [[rootDic valueForKey:@"status"] boolValue];
success(rootDic,datasValue,isSuccess);
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
failure(error);
}];
}
以上就是AFN 3.0 的簡單的再次封裝。如果有什麼問題請留言,有錯請指出,謝謝。