網絡請求的封裝
設置開發環境與生產環境的地址開關,結合AFNetworking進行封裝,我直接用我以前實現的代碼先大致說明下實現後的效果。
- 上圖的簡單流程便是,根據返回後的數據是array類型還是一個字典類型來選擇不同的方法
- 請求的地址
- 上傳服務器時和服務器方協定的一些加密請求規則,這個根據公司情況決定是否要添加,我後面舉例就暫時不添加了。
- 上傳服務器需要傳遞的參數
- 獲得的服務器數據轉換爲的model類型
- 將轉化的model數據指向本地的一個對應屬性
- 完成網絡請求成功或失敗的操作
現在我通過新浪的一個ip地址信息查詢接口來進行下演示。
http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.4.255.255
以此接口我們設定服務器方給我們的基本地址是http://int.dpool.sina.com.cn,這個地址是生產環境的,如果需要改爲開發環境也就是說只改這個地址即可,後面跟着的地址參數等無需變動
iplookup/iplookup.php可作爲請求數據的地址參數
format=json&ip=218.4.255.255 可作爲請求的兩個參數
所以我們先簡單實現.h文件的設置
#import <Foundation/Foundation.h>
#import "AFNetworking.h"
#import "BaseModel.h"
@interface WebServiceHelper : NSObject
//新浪的ip獲取地址
//http://int.dpool.sina.com.cn/iplookup/iplookup.php?format=json&ip=218.4.255.255
// 0 - 正式服 1 - 測試服
#define DEBUGMODE 0
#if DEBUGMODE
#define kHTTPREQUEST_BASE_URL @"http://int.dpool.sina.com.cn"//測試環境
#else
#define kHTTPREQUEST_BASE_URL @"http://int.dpool.sina.com.cn"//生成環境網絡請求
#endif
#pragma mark --------------------------------返回帶有對象控制權的model數據---------------
/**
* 請求帶有對象控制器的字典Model
*
* @param url 地址
* @param parameters 上傳的參數
* @param modelClass Model類型
* @param requester 對象所有者
* @param key 屬性名
* @param success 成功返回字典Model數據
* @param failure 失敗
*/
+ (void)postAndGetJsonModelWithURLString:(NSString *)url
parameters:(NSDictionary *)parameters
modelClass:(Class)modelClass
requester:(id)requester
key:(NSString *)key
success:(void (^)(BaseModel *baseModel))success
failure:(void (^)(NSError *error))failure;
@end
關於.m的實現我就不一一解釋了,詳情看代碼
#import "WebServiceHelper.h"
#define CustomErrorDomain @"com.WebServiceHelper"
typedef enum
{
PARAMETER_ERROR = 0,//參數錯誤
EXCEPTION_DESCRIPTION, //網絡錯誤
INTERFACE_CHECKFAIL,//接口驗證失敗
BC_CODEFAIL//渠道碼不存在
}CustomErrorFailed;// 用於表示錯誤類型
@implementation WebServiceHelper
#pragma mark 請求最基本數據
+(void)postWithURLString:(NSString *)url
parameters:(NSDictionary *)parameters
success:(void (^)(id))success
failure:(void (^)(NSError *))failure
{
NSString *postUrl = [NSString stringWithFormat:@"%@/%@",kHTTPREQUEST_BASE_URL,url];
//需要提交的參數(原參數加加密驗證的數據)
AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
manager.responseSerializer = [AFJSONResponseSerializer serializer];
manager.responseSerializer.acceptableContentTypes = [NSSet setWithObject:@"application/json"];
manager.requestSerializer.timeoutInterval = 30;
//因爲這個測試的地址需要用GET方法獲取,所以這裏我先用GET的方法調用了
[manager GET:postUrl parameters:parameters progress:^(NSProgress * _Nonnull uploadProgress) {
} success:^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject)
{
if (success)
{
success(responseObject);
}
} failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
if (failure) {
failure(error);
}
}];
}
#pragma mark ------------------------------請求model數據--------------------------
#pragma mark 請求model數據
+ (void)postAndGetJsonModelWithURLString:(NSString *)url
parameters:(NSDictionary *)parameters
modelClass:(Class)modelClass
success:(void (^)(BaseModel *baseModel))success
failure:(void (^)(NSError *error))failure
{
// 檢查需要返回的model類型是否存在
if (modelClass == nil)
{
if (failure != nil)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"is a parameter error" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomErrorDomain code:PARAMETER_ERROR userInfo:userInfo];
failure(aError);
NSLog(@"\n\nmodelClass參數 == nil\n\n");
}
return ;
}
[WebServiceHelper postWithURLString:url parameters:parameters success:^(id responseObject) {
// 檢查data
if (![responseObject isKindOfClass:[NSDictionary class]])
{
NSLog(@"\n\njsonModelRequestWithInfo請求的數據不是字典類型: data is invalid\n\n");
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"數據不是字典類型" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomErrorDomain code:PARAMETER_ERROR userInfo:userInfo];
failure(aError);
}
else
{
// 正常返回
BaseModel *baseModel = [[modelClass alloc] initWithDataDic:responseObject];
if (success != nil)
{
success(baseModel);
}
}
} failure:^(NSError *error) {
failure(error);
}];
}
#pragma mark ------------------------------請求有對象所有選的model數據--------------------------
#pragma mark 請求有對象所有選的model數據
+ (void)postAndGetJsonModelWithURLString:(NSString *)url
parameters:(NSDictionary *)parameters
modelClass:(Class)modelClass
requester:(id)requester
key:(NSString *)key
success:(void (^)(BaseModel *baseModel))success
failure:(void (^)(NSError *error))failure
{
// 檢查實參
if (requester == nil || key == nil)
{
if (failure != nil)
{
NSDictionary *userInfo = [NSDictionary dictionaryWithObject:@"請求的參數requester == nil, or key ==nil" forKey:NSLocalizedDescriptionKey];
NSError *aError = [NSError errorWithDomain:CustomErrorDomain code:PARAMETER_ERROR userInfo:userInfo];
failure(aError);
}
return ;
}
[WebServiceHelper postAndGetJsonModelWithURLString:url parameters:parameters modelClass:modelClass success:^(BaseModel *baseModel) {
//kvo設置屬性值
[requester setValue:baseModel forKey:key];
if (success != nil) {
success(baseModel);
}
} failure:^(NSError *error) {
if (error != nil) {
// //如果網絡請求失敗,則調用一下pageNum的值減1,防止pullUp失敗時也會讓pageNum加1
// if ([requester isKindOfClass:[BaseViewController class]]) {
// [requester reducePageNum];
// }
failure(error);
}
}];
}
@end
實現網絡請求
第一創建對應的model爲FriendIPModel
model數據中添加返回數據的所有屬性
- 在控制器中添加一個FriendIPModel的對象屬性
- 開始網絡請求
#import "FriendViewController.h"
#import "FriendIPModel.h"
@interface FriendViewController ()
@property (nonatomic,strong)FriendIPModel *friendModel;
@property (weak, nonatomic) IBOutlet UITextField *textFied;
@property (weak, nonatomic) IBOutlet UITextView *containTextV;
@end
@implementation FriendViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.title = @"好友";
}
#pragma mark ---------Actions--------
- (IBAction)resetAction {
self.textFied.text = @"53.223.108.40";
self.containTextV.text = @"";
[self.textFied resignFirstResponder];
}
- (IBAction)searcheAction {
[self requestData];
self.containTextV.text = @"";
[self.textFied resignFirstResponder];
}
#pragma mark 請求網路
- (void)requestData
{
[super requestData];
NSMutableDictionary *muDic = [NSMutableDictionary dictionary];
[muDic setObject:self.textFied.text forKey:@"ip"];
[muDic setObject:@"json" forKey:@"format"];
//key值必須和上面定義的屬性名一致
[WebServiceHelper postAndGetJsonModelWithURLString:@"iplookup/iplookup.php" parameters:muDic modelClass:[FriendIPModel class] requester:self key:@"friendModel" success:^(BaseModel *baseModel) {
[self requestSuccess];
self.containTextV.text = self.friendModel.country;
} failure:^(NSError *error) {
self.isLoading = NO;
self.containTextV.text = @"請求數據錯誤";
}];
}