├── TYHttpManagerDemo
├── MBProgressHUD
│ ├── MBProgressHUD.bundle
│ │ ├── error.png
│ │ ├── info.png
│ │ ├── error@2x.png
│ │ ├── info@2x.png
│ │ ├── info@3x.png
│ │ ├── success.png
│ │ └── success@2x.png
│ ├── MBProgressHUD+MJ.h
│ ├── MBProgressHUD+MJ.m
│ └── MBProgressHUD.h
├── ViewController.h
├── TYJSONModel
│ ├── TYJSONModel.h
│ ├── TYClassInfo.h
│ ├── TYPropertyInfo.h
│ ├── NSObject+TYJSONModel.h
│ ├── TYClassInfo.m
│ ├── TYPropertyInfo.m
│ └── NSObject+TYJSONModel.m
├── AppDelegate.h
├── main.m
├── TCategoryRequest.h
├── TCatergoryModel.m
├── TYHttpManager
│ ├── TYRequstConfigure.h
│ ├── TYRequstConfigure.m
│ ├── TYResponseCache.h
│ ├── TYHttpManager.h
│ ├── TYResponseObject.h
│ ├── TYChainRequest.h
│ ├── TYBatchRequest.h
│ ├── TYHttpRequest.h
│ ├── TYResponseObject.m
│ ├── TYRequestProtocol.h
│ ├── TYBaseRequest.h
│ ├── TYBatchRequest.m
│ ├── TYChainRequest.m
│ ├── TYBaseRequest.m
│ ├── TYHttpRequest.m
│ ├── TYResponseCache.m
│ └── TYHttpManager.m
├── THttpRequest.h
├── TResponseObject.h
├── THttpRequest.m
├── TCatergoryModel.h
├── TCategoryRequest.m
├── Assets.xcassets
│ └── AppIcon.appiconset
│ │ └── Contents.json
├── AFNetworking
│ ├── AFNetworking.h
│ ├── AFSecurityPolicy.h
│ ├── AFNetworkReachabilityManager.h
│ ├── AFNetworkReachabilityManager.m
│ ├── AFURLResponseSerialization.h
│ ├── AFSecurityPolicy.m
│ ├── AFHTTPSessionManager.m
│ └── AFHTTPSessionManager.h
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Info.plist
├── TResponseObject.m
├── AppDelegate.m
└── ViewController.m
├── TYHttpManagerDemo.xcodeproj
├── xcuserdata
│ └── tany.xcuserdatad
│ │ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ │ └── xcschemes
│ │ ├── xcschememanagement.plist
│ │ └── TYHttpManagerDemo.xcscheme
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcuserdata
│ └── tany.xcuserdatad
│ └── UserInterfaceState.xcuserstate
└── README.md
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/error.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/error.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/error@2x.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info@2x.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/info@3x.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/success.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/success.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/success@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.bundle/success@2x.png
--------------------------------------------------------------------------------
/TYHttpManagerDemo.xcodeproj/xcuserdata/tany.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # TYHttpManager
2 | 网络请求管理库,基于对AFNetwork的封装
3 | 支持httpRequest,(链式)chainRequest,(批量)batchRequest
4 | 支持数据缓存,josnModel转换
5 | 用法请看 demo
6 | 详细的使用请看[LovePlayNews](https://github.com/12207480/LovePlayNews)项目
7 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/tany.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/12207480/TYHttpManager/HEAD/TYHttpManagerDemo.xcodeproj/project.xcworkspace/xcuserdata/tany.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/TYHttpManagerDemo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/TYJSONModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYJSONModel.h
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/8.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #ifndef TYJSONModel_h
10 | #define TYJSONModel_h
11 |
12 | #import "NSObject+TYJSONModel.h"
13 | #import "TYClassInfo.h"
14 |
15 | #endif /* TYJSONModel_h */
16 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TCategoryRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // TCategoryRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "THttpRequest.h"
10 | #import "TCatergoryModel.h"
11 |
12 | @interface TCategoryRequest : THttpRequest
13 |
14 | + (instancetype)requestWithGender:(NSString *)gender generation:(NSString *)generation;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TCatergoryModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // TCatergoryModel.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TCatergoryModel.h"
10 | #import "TYJSONModel.h"
11 |
12 | @implementation TCatergoryData
13 |
14 | + (NSDictionary *)modelClassInArrayOrDictonary
15 | {
16 | return @{@"secondary_banners":[TCatergoryModel class]};
17 | }
18 |
19 |
20 | @end
21 |
22 | @implementation TCatergoryModel
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYRequstConfigure.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYRequstConfigure.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TYRequstConfigure : NSObject
12 |
13 | @property (nonatomic, strong) NSString *baseURL;
14 |
15 | // session configure
16 | @property (nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration;
17 |
18 | + (TYRequstConfigure *)sharedInstance;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/TYClassInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYClassInfo.h
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYPropertyInfo.h"
11 |
12 | @interface TYClassInfo : NSObject
13 |
14 | @property(nonatomic,strong, readonly) NSDictionary *propertyInfo;// 属性字典
15 | @property(nonatomic,assign, readonly) Class cls; // class
16 |
17 | - (instancetype)initWithClass:(Class )cls;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYRequstConfigure.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYRequstConfigure.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYRequstConfigure.h"
10 |
11 | @implementation TYRequstConfigure
12 |
13 | + (TYRequstConfigure *)sharedInstance {
14 | static id sharedInstance = nil;
15 | static dispatch_once_t onceToken;
16 | dispatch_once(&onceToken, ^{
17 | sharedInstance = [[self alloc] init];
18 | });
19 | return sharedInstance;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/THttpRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // THttpRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYHttpRequest.h"
10 | #import "TResponseObject.h"
11 |
12 | @interface THttpRequest : TYHttpRequest
13 |
14 | @property (nonatomic, strong, readonly) TYResponseObject *responseObject;
15 |
16 | @property (nonatomic, strong) NSString *identifier;
17 |
18 | - (instancetype)initWithModelClass:(Class)modelClass;
19 |
20 | + (instancetype)requestWithModelClass:(Class)modelClass;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TResponseObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseObject.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYResponseObject.h"
10 | #import "TYHttpRequest.h"
11 |
12 |
13 | typedef NS_ENUM(NSInteger, TYStauteCode) {
14 | TYStauteSuccessCode = 200,
15 | };
16 |
17 | @interface TResponseObject : TYResponseObject
18 |
19 |
20 | //@property (nonatomic, assign) NSUInteger pgIndex;//第几页
21 | //@property (nonatomic, assign) NSUInteger pgSize;
22 | //@property (nonatomic, assign) NSUInteger count;//总消息条数
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo.xcodeproj/xcuserdata/tany.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | TYHttpManagerDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 2BF5FA4D1CEEB4640052DF27
16 |
17 | primary
18 |
19 |
20 |
21 |
22 |
23 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYResponseCache.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseCache.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TYResponseCache : NSObject
12 |
13 | - (id )objectForKey:(NSString *)key;
14 |
15 | - (id )objectForKey:(NSString *)key overdueDate:(NSDate *)overdueDate;
16 |
17 | - (void)setObject:(id )object forKey:(NSString *)key;
18 |
19 | - (void)removeObjectForKey:(NSString *)key;
20 |
21 | - (void)removeAllObjects;
22 |
23 | - (void)trimToDate:(NSDate *)date;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/THttpRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // THttpRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "THttpRequest.h"
10 |
11 | @implementation THttpRequest
12 |
13 | @dynamic responseObject;
14 |
15 | - (instancetype)initWithModelClass:(Class)modelClass
16 | {
17 | if (self = [super init]) {
18 | self.responseParser = [[TResponseObject alloc]initWithModelClass:modelClass];
19 | }
20 | return self;
21 | }
22 |
23 | + (instancetype)requestWithModelClass:(Class)modelClass
24 | {
25 | return [[self alloc]initWithModelClass:modelClass];
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYHttpManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYHttpManager.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYRequestProtocol.h"
11 |
12 | @interface TYHttpManager : NSObject
13 |
14 | @property (nonatomic, strong) TYRequstConfigure *requestConfiguration;// session configure
15 |
16 | + (TYHttpManager *)sharedInstance;
17 |
18 | - (void)addRequest:(id)request;
19 |
20 | - (void)cancleRequest:(id)request;
21 |
22 | - (NSString *)buildRequstURL:(id)request;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TCatergoryModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // TCatergoryModel.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TCatergoryData : NSObject
12 |
13 | @property (nonatomic,strong) NSArray *secondary_banners;
14 |
15 | @end
16 |
17 | @interface TCatergoryModel : NSObject
18 |
19 | @property (nonatomic, assign) NSInteger id;
20 | @property (nonatomic, strong) NSString *image_url;
21 | @property (nonatomic, strong) NSString *target_url;
22 | @property (nonatomic, strong) NSString *webp_url;
23 | @property (nonatomic, strong) NSArray *ad_monitors;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TCategoryRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // TCategoryRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TCategoryRequest.h"
10 |
11 | @implementation TCategoryRequest
12 |
13 | + (instancetype)requestWithGender:(NSString *)gender generation:(NSString *)generation
14 | {
15 | TCategoryRequest *request = [TCategoryRequest requestWithModelClass:[TCatergoryData class]];
16 | // 可以在appdeleagte 里 设置 TYRequstConfigure baseURL
17 | request.URLString = @"http://api.liwushuo.com/v2/secondary_banners";
18 | request.parameters = @{@"gender":gender,@"generation":generation};;
19 | return request;
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD+MJ.h:
--------------------------------------------------------------------------------
1 | //
2 | // MBProgressHUD+MJ.h
3 | //
4 | // Created by mj on 13-4-18.
5 | // Copyright (c) 2013年 itcast. All rights reserved.
6 | //
7 |
8 | #import "MBProgressHUD.h"
9 |
10 | @interface MBProgressHUD (MJ)
11 | + (void)showSuccess:(NSString *)success toView:(UIView *)view;
12 | + (void)showError:(NSString *)error toView:(UIView *)view;
13 |
14 | + (MBProgressHUD *)showMessage:(NSString *)message toView:(UIView *)view;
15 |
16 | + (void)showAlert:(NSString *)alert toView:(UIView *)view afterDelay:(NSTimeInterval)time;
17 | + (void)showAlert:(NSString *)alert afterDelay:(NSTimeInterval)time;
18 |
19 |
20 | + (void)showSuccess:(NSString *)success;
21 | + (void)showError:(NSString *)error;
22 |
23 | + (MBProgressHUD *)showMessage:(NSString *)message;
24 |
25 | + (void)hideHUDForView:(UIView *)view;
26 | + (void)hideHUD;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYResponseObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseObject.h
3 | // LovePlayNews
4 | //
5 | // Created by tany on 16/9/7.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYHttpRequest.h"
11 |
12 | @interface TYResponseObject : NSObject
13 |
14 | @property (nonatomic, strong) NSString *msg; // 消息
15 |
16 | @property (nonatomic, assign) NSInteger status; //状态码
17 |
18 | @property (nonatomic, strong) id data;// json 或 model数据
19 |
20 | // 需要自己在parseResponse实现模型转换
21 | @property (nonatomic, assign, readonly) Class modelClass;
22 |
23 | // 初始化方法
24 | - (instancetype)initWithModelClass:(Class)modelClass;
25 |
26 | // 验证
27 | - (BOOL)isValidResponse:(id)response request:(TYHttpRequest *)request error:(NSError *__autoreleasing *)error;
28 |
29 | // 解析 返回ResponseObject
30 | - (id)parseResponse:(id)response request:(TYHttpRequest *)request;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/TYPropertyInfo.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYPropertyInfo.h
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 |
12 | @interface TYPropertyInfo : NSObject
13 |
14 | //@property (nonatomic, assign, readonly) objc_property_t property; // 属性
15 |
16 | @property (nonatomic, strong, readonly) NSString *propertyName; // 属性名
17 |
18 | @property (nonatomic, assign, readonly) Class typeClass; // 属性class类型 如果属性是基本类型为nil
19 |
20 | @property (nonatomic, assign, readonly) BOOL isCustomFondation; // 是否自定义对象类型
21 |
22 | @property (nonatomic, assign, readonly) SEL setter; // 属性 setter 方法
23 |
24 | @property (nonatomic, assign, readonly) SEL getter; // 属性 getter 方法
25 |
26 | - (instancetype)initWithProperty:(objc_property_t)property;
27 |
28 | // 是否是Foundation对象类型
29 | + (BOOL)isClassFromFoundation:(Class)cls;
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYChainRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYChainRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/27.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYRequestProtocol.h"
11 |
12 | @class TYChainRequest;
13 | typedef void (^TYChainRequestSuccessBlock)(TYChainRequest *request);
14 | typedef void (^TYChainRequestFailureBlock)(TYChainRequest *request,NSError *error);
15 |
16 | @interface TYChainRequest : NSObject
17 |
18 | @property (nonatomic, strong, readonly) NSArray *chainRequstArray;
19 | @property (nonatomic, assign, readonly) NSInteger curRequestIndex;
20 |
21 | @property (nonatomic, copy, readonly) TYChainRequestSuccessBlock successBlock; // 请求成功block
22 | @property (nonatomic, copy, readonly) TYChainRequestFailureBlock failureBlock; // 请求失败block
23 |
24 | - (void)addRequest:(id)request;
25 |
26 | - (void)addRequestArray:(NSArray *)requestArray;
27 |
28 | - (void)cancleRequest:(id)request;
29 |
30 | // 设置回调block
31 | - (void)setRequestSuccessBlock:(TYChainRequestSuccessBlock)successBlock failureBlock:(TYChainRequestFailureBlock)failureBlock;
32 |
33 | - (void)loadWithSuccessBlock:(TYChainRequestSuccessBlock)successBlock failureBlock:(TYChainRequestFailureBlock)failureBlock;
34 |
35 | - (void)load;
36 |
37 | - (void)cancle;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYBatchRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYBatchRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/27.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYRequestProtocol.h"
11 |
12 | @class TYBatchRequest;
13 | typedef void (^TYBatchRequestSuccessBlock)(TYBatchRequest *request);
14 | typedef void (^TYBatchRequestFailureBlock)(TYBatchRequest *request,NSError *error);
15 |
16 | @interface TYBatchRequest : NSObject
17 |
18 | @property (nonatomic, strong, readonly) NSArray *batchRequstArray;
19 | @property (nonatomic, assign, readonly) NSInteger requestCompleteCount;
20 |
21 | @property (nonatomic, copy, readonly) TYBatchRequestSuccessBlock successBlock; // 请求成功block
22 | @property (nonatomic, copy, readonly) TYBatchRequestFailureBlock failureBlock; // 请求失败block
23 |
24 | - (void)addRequest:(id)request;
25 |
26 | - (void)addRequestArray:(NSArray *)requestArray;
27 |
28 | - (void)cancleRequest:(id)request;
29 |
30 | // 设置回调block
31 | - (void)setRequestSuccessBlock:(TYBatchRequestSuccessBlock)successBlock failureBlock:(TYBatchRequestFailureBlock)failureBlock;
32 |
33 | - (void)loadWithSuccessBlock:(TYBatchRequestSuccessBlock)successBlock failureBlock:(TYBatchRequestFailureBlock)failureBlock;
34 |
35 | - (void)load;
36 |
37 | - (void)cancle;
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYHttpRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYHttpRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYBaseRequest.h"
10 | #import "TYBatchRequest.h"
11 | #import "TYChainRequest.h"
12 |
13 | @class TYHttpRequest;
14 | // 请求数据解析 protocol
15 | @protocol TYHttpResponseParser
16 |
17 | - (BOOL)isValidResponse:(id)response request:(TYHttpRequest *)request error:(NSError *__autoreleasing *)error;
18 |
19 | - (id)parseResponse:(id)response request:(TYHttpRequest *)request;
20 |
21 | @end
22 |
23 | // 请求数据缓存 protocol
24 | @protocol TYHttpResponseCache
25 |
26 | - (void)setObject:(id )object forKey:(NSString *)key;
27 |
28 | - (id )objectForKey:(NSString *)key overdueDate:(NSDate *)overdueDate;
29 |
30 | @end
31 |
32 | @interface TYHttpRequest : TYBaseRequest
33 |
34 | @property (nonatomic, assign, readonly) BOOL responseFromCache; // response是否来自缓存
35 |
36 | // 是否请求缓存的response 默认NO
37 | @property (nonatomic, assign) BOOL requestFromCache;
38 |
39 | // 是否缓存response ,有效的response才会缓存 默认NO
40 | @property (nonatomic, assign) BOOL cacheResponse;
41 |
42 | // 缓存时间 默认7天
43 | @property (nonatomic, assign) NSInteger cacheTimeInSeconds;
44 |
45 | // 缓存忽略的某些Paramters的key
46 | @property (nonatomic, strong) NSArray *cacheIgnoreParamtersKeys;
47 |
48 | @property (nonatomic, strong) id responseParser; // 数据解析
49 | @property (nonatomic, strong) id responseCache; // 数据缓存
50 |
51 | @end
52 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYResponseObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseObject.m
3 | // LovePlayNews
4 | //
5 | // Created by tany on 16/9/7.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYResponseObject.h"
10 |
11 | @interface TYResponseObject ()
12 |
13 | @property (nonatomic, assign) Class modelClass;
14 |
15 | @end
16 |
17 | @implementation TYResponseObject
18 |
19 | - (instancetype)initWithModelClass:(Class)modelClass
20 | {
21 | if (self = [super init]) {
22 | _modelClass = modelClass;
23 | }
24 | return self;
25 | }
26 |
27 | - (BOOL)isValidResponse:(id)response request:(TYHttpRequest *)request error:(NSError *__autoreleasing *)error
28 | {
29 | if (!response) {
30 | *error = [NSError errorWithDomain:@"response is nil" code: -1 userInfo:nil];
31 | return NO;
32 | }
33 |
34 | NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)request.dataTask.response;
35 | NSInteger responseStatusCode = [httpResponse statusCode];
36 |
37 | // StatusCode
38 | if (responseStatusCode < 200 || responseStatusCode > 299) {
39 | *error = [NSError errorWithDomain:@"invalid http request" code: responseStatusCode userInfo:nil];
40 | return NO;
41 | }
42 | return YES;
43 | }
44 |
45 | - (id)parseResponse:(id)response request:(TYHttpRequest *)request
46 | {
47 | _data = response;
48 | return self;
49 | }
50 |
51 | - (NSString *)description
52 | {
53 | return [NSString stringWithFormat:@"\nstatus:%d\nmsg:%@\n",(int)_status,_msg?_msg : @""];
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFNetworking.h:
--------------------------------------------------------------------------------
1 | // AFNetworking.h
2 | //
3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 | #import
25 | #import
26 |
27 | #ifndef _AFNETWORKING_
28 | #define _AFNETWORKING_
29 |
30 | #import "AFURLRequestSerialization.h"
31 | #import "AFURLResponseSerialization.h"
32 | #import "AFSecurityPolicy.h"
33 |
34 | #if !TARGET_OS_WATCH
35 | #import "AFNetworkReachabilityManager.h"
36 | #endif
37 |
38 | #import "AFURLSessionManager.h"
39 | #import "AFHTTPSessionManager.h"
40 |
41 | #endif /* _AFNETWORKING_ */
42 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | NSAppTransportSecurity
26 |
27 | NSAllowsArbitraryLoads
28 |
29 |
30 | UILaunchStoryboardName
31 | LaunchScreen
32 | UIMainStoryboardFile
33 | Main
34 | UIRequiredDeviceCapabilities
35 |
36 | armv7
37 |
38 | UISupportedInterfaceOrientations
39 |
40 | UIInterfaceOrientationPortrait
41 | UIInterfaceOrientationLandscapeLeft
42 | UIInterfaceOrientationLandscapeRight
43 |
44 | UISupportedInterfaceOrientations~ipad
45 |
46 | UIInterfaceOrientationPortrait
47 | UIInterfaceOrientationPortraitUpsideDown
48 | UIInterfaceOrientationLandscapeLeft
49 | UIInterfaceOrientationLandscapeRight
50 |
51 |
52 |
53 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/NSObject+TYJSONModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+TYJSONModel.h
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol TYJSONModel
12 |
13 | @optional
14 |
15 | // 数组[value,value] 或 字典{key: value,key: value} value模型映射类型
16 | + (NSDictionary *)modelClassInArrayOrDictonary;
17 |
18 | // 属性名 - key 映射
19 | + (NSDictionary *)modelPropertyMapper;
20 |
21 | // 忽略某些属性
22 | + (NSArray *)ignoreModelProperties;
23 |
24 | @end
25 |
26 | @interface NSObject (TYJSONModel)
27 |
28 | // json to model
29 | + (instancetype)ty_ModelWithJSON:(id)json; // json: NSString,NSDictionary,NSData
30 | + (instancetype)ty_ModelWithDictonary:(NSDictionary *)dic;
31 |
32 | - (void)ty_SetModelWithDictonary:(NSDictionary *)dic;
33 |
34 | // model to json
35 | - (id)ty_ModelToJSONObject; // array or dic
36 | - (NSData *)ty_ModelToJSONData;
37 | - (NSString *)ty_ModelToJSONString;
38 | - (NSDictionary *)ty_ModelToDictonary;
39 |
40 | // dic array to model array
41 | + (NSArray *)ty_modelArrayWithDictionaryArray:(NSArray *)dicArray;
42 | // model array to dic array
43 | + (NSArray *)ty_dictionaryArrayWithModelArray:(NSArray *)dicArray;
44 |
45 | // NSCoding
46 | - (void)ty_EncodeWithCoder:(NSCoder *)aCoder;
47 | - (instancetype)ty_InitWithCoder:(NSCoder *)aDecoder;
48 |
49 | @end
50 |
51 |
52 | @interface NSArray (TYJSONModel)
53 |
54 | // to model array
55 | - (NSArray *)ty_ModelArrayWithClass:(Class)cls;
56 |
57 | // to dic array
58 | - (NSArray *)ty_ModelArrayToDicArray;
59 |
60 | @end
61 |
62 | @interface NSDictionary (TYJSONModel)
63 |
64 | // to model dictionary
65 | - (NSDictionary *)ty_ModelDictionaryWithClass:(Class)cls;
66 |
67 | // to dictionary
68 | - (NSDictionary *)ty_ModelDictionaryToDictionary;
69 |
70 | @end
71 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/TYClassInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYClassInfo.m
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYClassInfo.h"
10 |
11 | static NSCache *s_classInfoCache;
12 |
13 | @implementation TYClassInfo
14 |
15 | - (instancetype)initWithClass:(Class )class
16 | {
17 | if (!class) {
18 | return nil;
19 | }
20 |
21 | // 取缓存
22 | id cacheInfo = [self objectOnCacheForClass:class];
23 | if (cacheInfo) {
24 | return cacheInfo;
25 | }
26 |
27 | if (self = [super init]) {
28 |
29 | _cls = class;
30 |
31 | unsigned int propertyCount = 0;
32 | // 获取属性list
33 | objc_property_t *properties = class_copyPropertyList(_cls, &propertyCount);
34 |
35 | if (properties) {
36 | NSMutableDictionary *propertyInfo = [NSMutableDictionary dictionaryWithCapacity:propertyCount];
37 |
38 | for (unsigned int i = 0; i < propertyCount; i++) {
39 | // 生成属性对象
40 | TYPropertyInfo *info = [[TYPropertyInfo alloc] initWithProperty:properties[i]];
41 | if (info.propertyName)
42 | // 添加到(属性名 - 属性对象)字典
43 | propertyInfo[info.propertyName] = info;
44 | }
45 |
46 | free(properties);
47 | _propertyInfo = [propertyInfo copy];
48 | }
49 | }
50 |
51 | // 添加到缓存
52 | [self setObjectToCacheForClass:class];
53 |
54 | return self;
55 | }
56 |
57 | - (id)objectOnCacheForClass:(Class)class
58 | {
59 | static dispatch_once_t onceToken;
60 | dispatch_once(&onceToken, ^{
61 | // 设置 class 缓存
62 | s_classInfoCache = [[NSCache alloc]init];
63 | s_classInfoCache.totalCostLimit = 0.5*1024*1024;
64 | s_classInfoCache.countLimit = 50;
65 | });
66 | id cacheInfo = [s_classInfoCache objectForKey:class];
67 | return cacheInfo;
68 | }
69 |
70 | - (void)setObjectToCacheForClass:(Class)class
71 | {
72 | [s_classInfoCache setObject:self forKey:class];
73 | }
74 |
75 | @end
76 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TResponseObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseObject.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TResponseObject.h"
10 | #import "TYJSONModel.h"
11 |
12 | @implementation TResponseObject
13 |
14 | - (BOOL)isValidResponse:(id)response request:(TYHttpRequest *)request error:(NSError *__autoreleasing *)error
15 | {
16 | if (![super isValidResponse:response request:request error:error]) {
17 | return NO;
18 | }
19 |
20 | // 根据 response 结构 应该为字典
21 | if (![response isKindOfClass:[NSDictionary class]]) {
22 | *error = [NSError errorWithDomain:@"response is invalide, is not NSDictionary" code:-1 userInfo:nil];
23 | return NO;
24 | }
25 |
26 | // 获取自定义的状态码
27 | NSInteger status = [[response objectForKey:@"code"] integerValue];
28 | if (status != TYStauteSuccessCode) {
29 | self.status = status;
30 | self.msg = [response objectForKey:@"message"];
31 | *error = [NSError errorWithDomain:self.msg code:self.status userInfo:nil];
32 | return NO;
33 | }
34 |
35 | return YES;
36 | }
37 |
38 | - (id)parseResponse:(id)response request:(TYHttpRequest *)request
39 | {
40 | self.status = [[response objectForKey:@"code"] integerValue];
41 | self.msg = [response objectForKey:@"message"];
42 | id json = [response objectForKey:@"data"];
43 | // _pgIndex = [[response objectForKey:@"pgIndex"] integerValue];
44 | // _pgSize = [[response objectForKey:@"pgSize"] integerValue];
45 | // _count = [[response objectForKey:@"count"] integerValue];
46 |
47 | if (self.modelClass) {
48 | if ([json isKindOfClass:[NSDictionary class]]) {
49 | self.data = [[self modelClass] ty_ModelWithDictonary:json];
50 | }else if ([json isKindOfClass:[NSArray class]]) {
51 | self.data = [[self modelClass] ty_modelArrayWithDictionaryArray:json];
52 | }
53 | }else {
54 | self.data = json;
55 | }
56 | return self;
57 | }
58 |
59 | //- (void)dealloc
60 | //{
61 | // NSLog(@"%@%s",NSStringFromClass([self class]),__func__);
62 | //}
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYRequestProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYRequestProtocol.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "TYRequstConfigure.h"
11 |
12 | typedef NS_ENUM(NSUInteger, TYRequestMethod) {
13 | TYRequestMethodGet,
14 | TYRequestMethodPost,
15 | TYRequestMethodHead,
16 | TYRequestMethodPut,
17 | TYRequestMethodDelete,
18 | TYRequestMethodPatch
19 | };
20 |
21 | typedef NS_ENUM(NSInteger , TYRequestSerializerType) {
22 | TYRequestSerializerTypeHTTP,
23 | TYRequestSerializerTypeJSON,
24 | TYRequestSerializerTypeString
25 | };
26 |
27 | typedef NS_ENUM(NSUInteger, TYRequestState) {
28 | TYRequestStateReady,
29 | TYRequestStateLoading,
30 | TYRequestStateCancle,
31 | TYRequestStateFinish,
32 | TYRequestStateError
33 | };
34 |
35 | @protocol AFMultipartFormData; // need import afnetwork
36 | typedef void(^AFProgressBlock)(NSProgress * progress);
37 | typedef void(^AFConstructingBodyBlock)(id formData);
38 |
39 |
40 | @protocol TYRequestProtocol;
41 | @protocol TYRequestDelegate
42 |
43 | @optional
44 |
45 | - (void)requestDidFinish:(id)request;
46 |
47 | - (void)requestDidFail:(id)request error:(NSError *)error;
48 |
49 | @end
50 |
51 |
52 | @protocol TYRequestProtocol
53 |
54 | @property (nonatomic, weak) NSURLSessionTask *dataTask;
55 |
56 | @property (nonatomic, assign, readonly) TYRequestState state;
57 | @property (nonatomic, strong, readonly) id responseObject;
58 |
59 | @property (nonatomic, weak) id delegate; // 请求代理
60 | @property (nonatomic, strong) id embedAccesory; // 嵌入请求代理 注意strong
61 |
62 | // baseURL 如果为空,则为全局或者本类requestConfigure.baseURL
63 | - (NSString *)baseURL;
64 |
65 | // 请求的URLString,或者 URL path
66 | - (NSString *)URLString;
67 |
68 | // 请求参数
69 | - (NSDictionary *)parameters;
70 |
71 | // 请求的方法 默认get
72 | - (TYRequestMethod)method;
73 |
74 | // request configure
75 | - (TYRequstConfigure *)configuration;
76 |
77 | // 在HTTP报头添加的自定义参数
78 | - (NSDictionary *)headerFieldValues;
79 |
80 | // 请求的连接超时时间,默认为60秒
81 | - (NSTimeInterval)timeoutInterval;
82 |
83 | // 缓存策略
84 | - (NSURLRequestCachePolicy) cachePolicy;
85 |
86 | // 设置请求格式 默认 JSON
87 | - (TYRequestSerializerType)serializerType;
88 |
89 | // 返回进度block
90 | - (AFProgressBlock)progressBlock;
91 |
92 | // 返回post组装body block
93 | - (AFConstructingBodyBlock)constructingBodyBlock;
94 |
95 | // 处理请求数据, 如果error == nil ,请求成功
96 | - (void)requestDidResponse:(id)responseObject error:(NSError *)error;
97 |
98 | // 请求
99 | - (void)load;
100 |
101 | // 取消
102 | - (void)cancle;
103 |
104 | @end
105 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYBaseRequest.h:
--------------------------------------------------------------------------------
1 | //
2 | // TYBaseRequest.h
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYRequestProtocol.h"
10 |
11 | typedef void (^TYRequestSuccessBlock)(id request);
12 | typedef void (^TYRequestFailureBlock)(id request,NSError *error);
13 |
14 | @protocol TYRequestOverride
15 |
16 | // 收到请求数据, 如果error == nil
17 | - (void)requestDidResponse:(id)responseObject error:(NSError *)error;
18 |
19 | // 验证请求数据
20 | - (BOOL)validResponseObject:(id)responseObject error:(NSError *__autoreleasing *)error;
21 |
22 | // 请求成功
23 | - (void)requestDidFinish;
24 |
25 | // 请求失败
26 | - (void)requestDidFailWithError:(NSError* )error;
27 |
28 | @end
29 |
30 | @interface TYBaseRequest : NSObject
31 |
32 | #pragma mark - request
33 | @property (nonatomic, weak) NSURLSessionDataTask *dataTask;
34 | @property (nonatomic, assign, readonly) TYRequestState state;
35 | @property (nonatomic, strong, readonly) id responseObject;
36 |
37 | @property (nonatomic, weak) id delegate; // 请求代理
38 | @property (nonatomic, strong) id embedAccesory; // 完成请求代理 后调用 注意strong
39 |
40 | @property (nonatomic, assign) BOOL asynCompleteQueue; // 在异步线程中回调 默认NO
41 |
42 | #pragma mark - block
43 | @property (nonatomic, copy, readonly) TYRequestSuccessBlock successBlock; // 请求成功block
44 | @property (nonatomic, copy, readonly) TYRequestFailureBlock failureBlock; // 请求失败block
45 |
46 | @property (nonatomic, copy) AFProgressBlock progressBlock;// 请求进度block
47 | @property (nonatomic, copy) AFConstructingBodyBlock constructingBodyBlock;// post请求组装body block
48 |
49 | #pragma mark - request params
50 | // baseURL 如果为空,则为全局或者本类requestConfigure.baseURL
51 | @property (nonatomic, strong) NSString *baseURL;
52 |
53 | // 请求的URLString 或者 URL path
54 | @property (nonatomic, strong) NSString *URLString;
55 |
56 | // 请求方法 默认GET
57 | @property (nonatomic, assign) TYRequestMethod method;
58 |
59 | // 请求参数
60 | @property (nonatomic, strong) NSDictionary *parameters;
61 |
62 | // 设置请求格式 默认 JSON
63 | @property (nonatomic, assign) TYRequestSerializerType serializerType;
64 |
65 | // 请求缓存策略
66 | @property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy;
67 |
68 | // 请求的连接超时时间,默认为60秒
69 | @property (nonatomic, assign) NSTimeInterval timeoutInterval;
70 |
71 | // 请求设置 默认 使用 全局的requestConfigure
72 | @property (nonatomic, strong) TYRequstConfigure *configuration;
73 |
74 | // 在HTTP报头添加的自定义参数
75 | @property (nonatomic, strong) NSDictionary *headerFieldValues;
76 |
77 | // 请求
78 | - (void)load;
79 |
80 | // 设置回调block
81 | - (void)setRequestSuccessBlock:(TYRequestSuccessBlock)successBlock failureBlock:(TYRequestFailureBlock)failureBlock;
82 |
83 | - (void)loadWithSuccessBlock:(TYRequestSuccessBlock)successBlock failureBlock:(TYRequestFailureBlock)failureBlock;
84 |
85 | // 取消
86 | - (void)cancle;
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD+MJ.m:
--------------------------------------------------------------------------------
1 | //
2 | // MBProgressHUD+MJ.m
3 | //
4 | // Created by mj on 13-4-18.
5 | // Copyright (c) 2013年 itcast. All rights reserved.
6 | //
7 |
8 | #import "MBProgressHUD+MJ.h"
9 |
10 | @implementation MBProgressHUD (MJ)
11 | #pragma mark 显示信息
12 | + (void)show:(NSString *)text icon:(NSString *)icon view:(UIView *)view afterDelay:(NSTimeInterval)time
13 | {
14 | if (view == nil) view = [[UIApplication sharedApplication].windows lastObject];
15 | [MBProgressHUD hideAllHUDsForView:view animated:NO];
16 | // 快速显示一个提示信息
17 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
18 | hud.labelText = text;
19 | hud.margin = 12.0f;
20 | // 设置图片
21 | hud.customView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:[NSString stringWithFormat:@"MBProgressHUD.bundle/%@", icon]]];
22 | // 再设置模式
23 | hud.mode = MBProgressHUDModeCustomView;
24 |
25 | // 隐藏时候从父控件中移除
26 | hud.removeFromSuperViewOnHide = YES;
27 | hud.square = NO;
28 | // 1秒之后再消失
29 | [hud hide:YES afterDelay:time];
30 | }
31 |
32 | #pragma mark 显示错误信息
33 | + (void)showAlert:(NSString *)alert toView:(UIView *)view afterDelay:(NSTimeInterval)time
34 | {
35 | [self show:alert icon:@"info.png" view:view afterDelay:time];
36 | }
37 |
38 | + (void)showAlert:(NSString *)alert afterDelay:(NSTimeInterval)time
39 | {
40 | [self show:alert icon:@"info.png" view:nil afterDelay:time];
41 | }
42 |
43 | + (void)showError:(NSString *)error toView:(UIView *)view{
44 | [self show:error icon:@"error.png" view:view afterDelay:1.0];
45 | }
46 |
47 | + (void)showSuccess:(NSString *)success toView:(UIView *)view
48 | {
49 | [self show:success icon:@"success.png" view:view afterDelay:1.0];
50 | }
51 |
52 | #pragma mark 显示一些信息
53 | + (MBProgressHUD *)showMessage:(NSString *)message toView:(UIView *)view {
54 | if (view == nil) view = [[UIApplication sharedApplication].windows lastObject];
55 | [MBProgressHUD hideAllHUDsForView:view animated:NO];
56 | // 快速显示一个提示信息
57 | MBProgressHUD *hud = [MBProgressHUD showHUDAddedTo:view animated:YES];
58 | hud.labelText = message;
59 | // 隐藏时候从父控件中移除
60 | hud.removeFromSuperViewOnHide = YES;
61 | // YES代表需要蒙版效果
62 | hud.dimBackground = NO;
63 | return hud;
64 | }
65 |
66 | + (void)showSuccess:(NSString *)success
67 | {
68 | [self showSuccess:success toView:nil];
69 | }
70 |
71 | + (void)showError:(NSString *)error
72 | {
73 | [self showError:error toView:nil];
74 | }
75 |
76 | + (void)showAlert:(NSString *)message
77 | {
78 | [self showAlert:message afterDelay:1.0];
79 | }
80 |
81 | + (MBProgressHUD *)showMessage:(NSString *)message
82 | {
83 | return [self showMessage:message toView:nil];
84 | }
85 |
86 | + (void)hideHUDForView:(UIView *)view
87 | {
88 | if (view == nil) view = [[UIApplication sharedApplication].windows lastObject];
89 | [self hideHUDForView:view animated:YES];
90 | }
91 |
92 | + (void)hideHUD
93 | {
94 | [self hideHUDForView:nil];
95 | }
96 | @end
97 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYBatchRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYBatchRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/27.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYBatchRequest.h"
10 |
11 | @interface TYBatchRequest ()
12 | @property (nonatomic, strong) NSMutableArray *batchRequstArray;
13 | @property (nonatomic, assign) NSInteger requestCompleteCount;
14 | @property (nonatomic, assign) BOOL isLoading;
15 | @end
16 |
17 | @implementation TYBatchRequest
18 |
19 | - (instancetype)init
20 | {
21 | if (self = [super init]) {
22 | _batchRequstArray = [NSMutableArray array];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)addRequest:(id)request
28 | {
29 | if (_isLoading) {
30 | NSLog(@"TYBatchRequest is Running,can't add request");
31 | return;
32 | }
33 | request.embedAccesory = self;
34 | [_batchRequstArray addObject:request];
35 | }
36 |
37 | - (void)addRequestArray:(NSArray *)requestArray
38 | {
39 | for (id request in requestArray) {
40 | if ([request conformsToProtocol:@protocol(TYRequestProtocol) ]) {
41 | [self addRequest:request];
42 | }
43 | }
44 | }
45 |
46 | - (void)cancleRequest:(id)request
47 | {
48 | request.embedAccesory = nil;
49 | [request cancle];
50 | [_batchRequstArray removeObject:request];
51 | }
52 |
53 | - (void)setRequestSuccessBlock:(TYBatchRequestSuccessBlock)successBlock failureBlock:(TYBatchRequestFailureBlock)failureBlock
54 | {
55 | _successBlock = successBlock;
56 | _failureBlock = failureBlock;
57 |
58 | }
59 |
60 | - (void)loadWithSuccessBlock:(TYBatchRequestSuccessBlock)successBlock failureBlock:(TYBatchRequestFailureBlock)failureBlock
61 | {
62 | [self setRequestSuccessBlock:successBlock failureBlock:failureBlock];
63 |
64 | [self load];
65 | }
66 |
67 | - (void)load{
68 | if (_isLoading ||_batchRequstArray.count == 0) {
69 | return;
70 | }
71 | _isLoading = YES;
72 | _requestCompleteCount = 0;
73 | for (id request in _batchRequstArray) {
74 | [request load];
75 | }
76 | }
77 |
78 | - (void)cancle
79 | {
80 | for (id request in _batchRequstArray) {
81 | request.embedAccesory = nil;
82 | [request cancle];
83 | }
84 | [_batchRequstArray removeAllObjects];
85 | _requestCompleteCount = 0;
86 | _isLoading = NO;
87 | }
88 |
89 | #pragma mark - delegate
90 |
91 | - (void)requestDidFinish:(id)request
92 | {
93 | NSInteger index = [_batchRequstArray indexOfObject:request];
94 | if (index != NSNotFound) {
95 | ++_requestCompleteCount;
96 | }
97 |
98 | if (_requestCompleteCount == _batchRequstArray.count) {
99 | if (_successBlock) {
100 | _successBlock(self);
101 | }
102 | [_batchRequstArray removeAllObjects];
103 | _isLoading = NO;
104 | }
105 | }
106 |
107 | - (void)requestDidFail:(id)request error:(NSError *)error
108 | {
109 | if (_failureBlock) {
110 | _failureBlock(self,error);
111 | }
112 | [_batchRequstArray removeAllObjects];
113 | _isLoading = NO;
114 |
115 | }
116 |
117 | - (void)clearBlocks
118 | {
119 | _successBlock = nil;
120 | _failureBlock = nil;
121 | }
122 |
123 | - (void)dealloc
124 | {
125 | [self clearBlocks];
126 | }
127 |
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo.xcodeproj/xcuserdata/tany.xcuserdatad/xcschemes/TYHttpManagerDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYChainRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYChainRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/27.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYChainRequest.h"
10 |
11 | @interface TYChainRequest ()
12 | @property (nonatomic, strong) NSMutableArray *chainRequstArray;
13 | @property (nonatomic, assign) NSInteger curRequestIndex;
14 | @property (nonatomic, assign) BOOL isLoading;
15 | @end
16 |
17 | @implementation TYChainRequest
18 |
19 | - (instancetype)init
20 | {
21 | if (self = [super init]) {
22 | _chainRequstArray = [NSMutableArray array];
23 | }
24 | return self;
25 | }
26 |
27 | - (void)addRequest:(id)request
28 | {
29 | if (_isLoading) {
30 | NSLog(@"TYChainRequest is Running,can't add request");
31 | return;
32 | }
33 | request.embedAccesory = self;
34 | [_chainRequstArray addObject:request];
35 | }
36 |
37 | - (void)addRequestArray:(NSArray *)requestArray
38 | {
39 | for (id request in requestArray) {
40 | if ([request conformsToProtocol:@protocol(TYRequestProtocol) ]) {
41 | [self addRequest:request];
42 | }
43 | }
44 | }
45 |
46 | - (void)cancleRequest:(id)request
47 | {
48 | request.embedAccesory = nil;
49 | [request cancle];
50 | [_chainRequstArray removeObject:request];
51 | }
52 |
53 | - (void)load
54 | {
55 | if (_isLoading ||_chainRequstArray.count == 0) {
56 | return;
57 | }
58 |
59 | _isLoading = YES;
60 | [self loadNextChainRequestWithCurIndex:-1];
61 | }
62 |
63 | - (void)setRequestSuccessBlock:(TYChainRequestSuccessBlock)successBlock failureBlock:(TYChainRequestFailureBlock)failureBlock
64 | {
65 | _successBlock = successBlock;
66 | _failureBlock = failureBlock;
67 |
68 | }
69 |
70 | - (void)loadWithSuccessBlock:(TYChainRequestSuccessBlock)successBlock failureBlock:(TYChainRequestFailureBlock)failureBlock
71 | {
72 | [self setRequestSuccessBlock:successBlock failureBlock:failureBlock];
73 |
74 | [self load];
75 | }
76 |
77 | - (void)cancle
78 | {
79 | for (id request in _chainRequstArray) {
80 | request.embedAccesory = nil;
81 | }
82 |
83 | if (_curRequestIndex >= 0 && _curRequestIndex < _chainRequstArray.count) {
84 | id request = _chainRequstArray[_curRequestIndex];
85 | [request cancle];
86 | }
87 |
88 | [_chainRequstArray removeAllObjects];
89 | _curRequestIndex = 0;
90 | _isLoading = NO;
91 | }
92 |
93 | - (void)loadNextChainRequestWithCurIndex:(NSInteger)index
94 | {
95 | NSInteger count = _chainRequstArray.count;
96 | if (index >= -1 && index < count - 1) {
97 | _curRequestIndex = index + 1;
98 | id request = _chainRequstArray[_curRequestIndex];
99 | [request load];
100 | }else {
101 | if (_successBlock) {
102 | _successBlock(self);
103 | }
104 | [_chainRequstArray removeAllObjects];
105 | _isLoading = NO;
106 | }
107 | }
108 |
109 | #pragma mark - delegate
110 |
111 | - (void)requestDidFinish:(id)request
112 | {
113 | NSInteger index = [_chainRequstArray indexOfObject:request];
114 | if (index != NSNotFound) {
115 | [self loadNextChainRequestWithCurIndex:index];
116 | }
117 | }
118 |
119 | - (void)requestDidFail:(id)request error:(NSError *)error
120 | {
121 | if (_failureBlock) {
122 | _failureBlock(self,error);
123 | }
124 | [_chainRequstArray removeAllObjects];
125 | _isLoading = NO;
126 |
127 | }
128 |
129 | - (void)clearBlocks
130 | {
131 | _successBlock = nil;
132 | _failureBlock = nil;
133 | }
134 |
135 | - (void)dealloc
136 | {
137 | [self clearBlocks];
138 | }
139 |
140 | @end
141 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYBaseRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYBaseRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYBaseRequest.h"
10 | #import "TYHttpManager.h"
11 |
12 | @interface TYBaseRequest ()
13 | @property (nonatomic, copy) TYRequestSuccessBlock successBlock;
14 | @property (nonatomic, copy) TYRequestFailureBlock failureBlock;
15 |
16 | @property (nonatomic, assign) TYRequestState state;
17 | @property (nonatomic, strong) id responseObject;
18 | @end
19 |
20 | @implementation TYBaseRequest
21 |
22 | -(instancetype)init
23 | {
24 | if (self = [super init]) {
25 | _method = TYRequestMethodGet;
26 | _serializerType = TYRequestSerializerTypeJSON;
27 | _timeoutInterval = 60;
28 | }
29 | return self;
30 | }
31 |
32 | #pragma mark - load request
33 |
34 | // 请求
35 | - (void)load
36 | {
37 | [[TYHttpManager sharedInstance] addRequest:self];
38 | _state = TYRequestStateLoading;
39 | }
40 |
41 | // 取消
42 | - (void)cancle
43 | {
44 | [_dataTask cancel];
45 | [self clearRequestBlock];
46 | _delegate = nil;
47 | _state = TYRequestStateCancle;
48 | }
49 |
50 | - (void)setRequestSuccessBlock:(TYRequestSuccessBlock)successBlock failureBlock:(TYRequestFailureBlock)failureBlock
51 | {
52 | _successBlock = successBlock;
53 | _failureBlock = failureBlock;
54 |
55 | }
56 |
57 | - (void)loadWithSuccessBlock:(TYRequestSuccessBlock)successBlock failureBlock:(TYRequestFailureBlock)failureBlock
58 | {
59 | [self setRequestSuccessBlock:successBlock failureBlock:failureBlock];
60 |
61 | [self load];
62 | }
63 |
64 | #pragma mark - call delegate , block
65 |
66 | // 收到数据
67 | - (void)requestDidResponse:(id)responseObject error:(NSError *)error
68 | {
69 | if (error) {
70 | [self requestDidFailWithError:error];
71 | }else {
72 | if ([self validResponseObject:responseObject error:&error]){
73 | [self requestDidFinish];
74 | }else{
75 | [self requestDidFailWithError:error];
76 | }
77 | }
78 | }
79 |
80 | // 验证数据
81 | - (BOOL)validResponseObject:(id)responseObject error:(NSError *__autoreleasing *)error
82 | {
83 | _responseObject = responseObject;
84 | return _responseObject ? YES : NO;
85 | }
86 |
87 | // 请求成功
88 | - (void)requestDidFinish
89 | {
90 | _state = TYRequestStateFinish;
91 |
92 | void (^finishBlock)() = ^{
93 | if ([_delegate respondsToSelector:@selector(requestDidFinish:)]) {
94 | [_delegate requestDidFinish:self];
95 | }
96 |
97 | if (_successBlock) {
98 | _successBlock(self);
99 | }
100 |
101 | if (_embedAccesory && [_embedAccesory respondsToSelector:@selector(requestDidFinish:)]) {
102 | [_embedAccesory requestDidFinish:self];
103 | }
104 | };
105 |
106 | if (_asynCompleteQueue) {
107 | finishBlock();
108 | }else {
109 | dispatch_async(dispatch_get_main_queue(),finishBlock);
110 | }
111 | }
112 |
113 | // 请求失败
114 | - (void)requestDidFailWithError:(NSError* )error
115 | {
116 | _state = TYRequestStateError;
117 |
118 | void (^failBlock)() = ^{
119 | if ([_delegate respondsToSelector:@selector(requestDidFail:error:)]) {
120 | [_delegate requestDidFail:self error:error];
121 | }
122 |
123 | if (_failureBlock) {
124 | _failureBlock(self,error);
125 | }
126 |
127 | if (_embedAccesory && [_embedAccesory respondsToSelector:@selector(requestDidFail:error:)]) {
128 | [_embedAccesory requestDidFail:self error:error];
129 | }
130 | };
131 |
132 | if (_asynCompleteQueue) {
133 | failBlock();
134 | }else {
135 | dispatch_async(dispatch_get_main_queue(),failBlock);
136 | }
137 | }
138 | // 清除block引用
139 | - (void)clearRequestBlock
140 | {
141 | _successBlock = nil;
142 | _failureBlock = nil;
143 | _progressBlock = nil;
144 | _constructingBodyBlock = nil;
145 | }
146 |
147 | - (void)dealloc
148 | {
149 | [self clearRequestBlock];
150 | [_dataTask cancel];
151 | _delegate = nil;
152 | }
153 |
154 | @end
155 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/TYPropertyInfo.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYPropertyInfo.m
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYPropertyInfo.h"
10 | #import
11 |
12 | @implementation TYPropertyInfo
13 |
14 | - (instancetype)initWithProperty:(objc_property_t)property
15 | {
16 | if (!property) {
17 | return nil;
18 | }
19 |
20 | if (self = [super init]) {
21 |
22 | //_property = property;
23 | // 获取属性名
24 | const char *cPropertyName = property_getName(property);
25 | if (cPropertyName) {
26 | _propertyName = [NSString stringWithUTF8String:cPropertyName];
27 | }
28 |
29 | BOOL readOnlyProperty = NO;
30 | unsigned int attrCount;
31 | // 获取属性的属性list
32 | objc_property_attribute_t *attrs = property_copyAttributeList(property, &attrCount);
33 | for (unsigned int idx = 0; idx < attrCount; ++idx) {
34 | switch (attrs[idx].name[0]) {
35 | case 'T': // 属性
36 | if (attrs[idx].name[0] == 'T') {
37 | size_t len = strlen(attrs[idx].value);
38 | if (len>3) {
39 | char name[len - 2];
40 | name[len - 3] = '\0';
41 | memcpy(name, attrs[idx].value + 2, len - 3);
42 | // 获取 属性类型名 (基本类型 _typeClass = ni )
43 | _typeClass = objc_getClass(name);
44 | }
45 | }
46 | break;
47 | case 'R':
48 | readOnlyProperty = YES;
49 | break;
50 | case 'G': // 自定义getter方法
51 | if (attrs[idx].value) {
52 | _getter = NSSelectorFromString([NSString stringWithUTF8String:attrs[idx].value]);
53 | }
54 | break;
55 | case 'S': // 自定义setter方法
56 | if (attrs[idx].value) {
57 | _setter = NSSelectorFromString([NSString stringWithUTF8String:attrs[idx].value]);
58 | }
59 | break;
60 |
61 | default:
62 | break;
63 | }
64 | }
65 |
66 | if (attrs) {
67 | free(attrs);
68 | }
69 |
70 | if (_typeClass) {
71 | // 判断是否自定义对象类型
72 | _isCustomFondation = ![[self class] isClassFromFoundation:_typeClass];
73 | }
74 |
75 | if (_typeClass && _propertyName.length > 0) {
76 | // 如果是对象类型 生成 getter setter 方法
77 | if (!_getter) {
78 | _getter = NSSelectorFromString(_propertyName);
79 | }
80 | if (!_setter && !readOnlyProperty) {
81 | _setter = NSSelectorFromString([NSString stringWithFormat:@"set%@%@:", [_propertyName substringToIndex:1].uppercaseString, [_propertyName substringFromIndex:1]]);
82 | }
83 | }
84 |
85 | }
86 | return self;
87 | }
88 |
89 | // 是否是Foundation对象类型
90 | + (BOOL)isClassFromFoundation:(Class)class
91 | {
92 | if (class == [NSString class] || class == [NSObject class])
93 | return YES;
94 |
95 | static NSArray *s_foundations;
96 | static dispatch_once_t onceToken;
97 | dispatch_once(&onceToken, ^{
98 | s_foundations = @[[NSURL class],
99 | [NSDate class],
100 | [NSValue class],
101 | [NSData class],
102 | [NSError class],
103 | [NSArray class],
104 | [NSDictionary class],
105 | [NSString class],
106 | [NSAttributedString class]];
107 | });
108 |
109 | BOOL result = NO;
110 | for (Class foundationClass in s_foundations) {
111 | if ([class isSubclassOfClass:foundationClass]) {
112 | result = YES;
113 | break;
114 | }
115 | }
116 |
117 | return result;
118 | }
119 |
120 | @end
121 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYHttpRequest.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYHttpRequest.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYHttpRequest.h"
10 | #import "TYResponseCache.h"
11 | #import "TYHttpManager.h"
12 |
13 | @interface TYResponseCache ()
14 | @end
15 |
16 | @implementation TYHttpRequest
17 |
18 | - (instancetype)init
19 | {
20 | if (self = [super init]) {
21 | _cacheTimeInSeconds = 60*60*24*7;
22 | }
23 | return self;
24 | }
25 |
26 | #pragma mark - load reqeust
27 |
28 | - (id)responseCache
29 | {
30 | if (_responseCache == nil) {
31 | _responseCache = [[TYResponseCache alloc]init];
32 | }
33 | return _responseCache;
34 | }
35 |
36 | - (void)load
37 | {
38 | _responseFromCache = NO;
39 | if (_requestFromCache && _cacheTimeInSeconds >= 0) {
40 | // 从缓存中获取
41 | [self loadResponseFromCache];
42 | }
43 | //NSLog(@"responseFromCache %d",_responseFromCache);
44 | if (!_responseFromCache) {
45 | // 请求数据
46 | [super load];
47 | }
48 | }
49 |
50 | // 从缓存中获取数据
51 | - (void)loadResponseFromCache
52 | {
53 | id responseCache = [self responseCache];
54 |
55 | if (!responseCache) {
56 | return;
57 | }
58 |
59 | // 计算过期时间
60 | double pastTimeInterval = [[NSDate date] timeIntervalSince1970]-[self cacheTimeInSeconds];
61 | NSDate *pastDate = [NSDate dateWithTimeIntervalSince1970:pastTimeInterval];
62 |
63 | // 根据URL 和 过期时间 获取缓存
64 | NSString *urlKey = [self serializeURLKey];
65 | id responseObject = [responseCache objectForKey:urlKey overdueDate:pastDate];
66 | if (responseObject) {
67 | // 获取到缓存
68 | _responseFromCache = YES;
69 | [self requestDidResponse:responseObject error:nil];
70 | }
71 | }
72 |
73 | // 验证缓存
74 | - (BOOL)validResponseObject:(id)responseObject error:(NSError *__autoreleasing *)error
75 | {
76 | id responseParser = [self responseParser];
77 | if (responseParser == nil) {
78 | [self cacheRequsetResponse:responseObject];
79 | return [super validResponseObject:responseObject error:error];
80 | }
81 |
82 | if (_responseFromCache || [responseParser isValidResponse:responseObject request:self error:error]) {
83 | // 有效的数据 才可以缓存
84 | [self cacheRequsetResponse:responseObject];
85 | // 验证后 解析数据
86 | id responseParsedObject = [responseParser parseResponse:responseObject request:self];
87 | return [super validResponseObject:responseParsedObject error:error];
88 | }else {
89 | return NO;
90 | }
91 | }
92 |
93 | #pragma mark - private
94 |
95 | - (void)cacheRequsetResponse:(id)responseObject
96 | {
97 | if (responseObject && _cacheResponse && !_responseFromCache) {
98 | NSString *urlKey = [self serializeURLKey];
99 | [[self responseCache]setObject:responseObject forKey:urlKey];
100 | }
101 | }
102 | // 拼装url key
103 | - (NSString *)serializeURLKey
104 | {
105 | NSDictionary *paramters = [self parameters];
106 | NSArray *ignoreParamterKeys = [self cacheIgnoreParamtersKeys];
107 | if (ignoreParamterKeys) {
108 | NSMutableDictionary *fiterParamters = [NSMutableDictionary dictionaryWithDictionary:paramters];
109 | [fiterParamters removeObjectsForKeys:ignoreParamterKeys];
110 | paramters = fiterParamters;
111 | }
112 | NSString *URLString = [[TYHttpManager sharedInstance]buildRequstURL:self];
113 | return [URLString stringByAppendingString:[self serializeParams:paramters]];
114 | }
115 |
116 | // 拼接params
117 | - (NSString *)serializeParams:(NSDictionary *)params {
118 | NSMutableArray *parts = [NSMutableArray array];
119 | [params enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
120 | NSString *encodedKey = [key stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
121 | NSString *encodedValue = [obj.description stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLQueryAllowedCharacterSet]];
122 | NSString *part = [NSString stringWithFormat: @"%@=%@", encodedKey, encodedValue];
123 | [parts addObject: part];
124 | }];
125 | NSString *queryString = [parts componentsJoinedByString: @"&"];
126 | return queryString?[NSString stringWithFormat:@"?%@", queryString]:@"";
127 | }
128 |
129 | @end
130 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/20.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "MBProgressHUD+MJ.h"
11 | #import "TCategoryRequest.h"
12 | #import "TYChainRequest.h"
13 | #import "TYBatchRequest.h"
14 |
15 | @interface ViewController ()
16 | @property (nonatomic, weak) THttpRequest *request;
17 |
18 | @end
19 |
20 | @implementation ViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 | // Do any additional setup after loading the view, typically from a nib.
25 | }
26 |
27 | // 请求 使用block
28 | - (IBAction)requestBlockAction:(id)sender {
29 |
30 | [MBProgressHUD showMessage:@"加载中..." toView:self.view];
31 |
32 | // request 使用继承
33 | [_request cancle];
34 | _request = [TCategoryRequest requestWithGender:@"1" generation:@"1"];
35 | // 缓存数据
36 | _request.requestFromCache = YES;
37 | _request.cacheResponse = YES;
38 |
39 | [_request loadWithSuccessBlock:^(TCategoryRequest *request) {
40 | NSLog(@"%@ data:%@",request.responseObject,request.responseObject.data);
41 | [MBProgressHUD showSuccess:@"加载成功!" toView:self.view];
42 | } failureBlock:^(TCategoryRequest *request, NSError *error) {
43 | [MBProgressHUD showError:@"加载失败!" toView:self.view];
44 | }];
45 | }
46 |
47 | // 请求 使用delegate
48 | - (IBAction)requestDelegateAction:(id)sender {
49 |
50 | [MBProgressHUD showMessage:@"加载中..." toView:self.view];
51 |
52 | // 不用继承 直接使用request
53 | THttpRequest *request = [THttpRequest requestWithModelClass:[TCatergoryData class]];
54 | // 可以在appdeleagte 里 设置 TYRequstConfigure baseURL
55 | request.URLString = @"http://api.liwushuo.com/v2/secondary_banners";
56 | request.parameters = @{@"gender":@"1",@"generation":@"1"};
57 | request.delegate = self;
58 | [request load];
59 | }
60 |
61 | - (IBAction)chainRquestAction:(id)sender {
62 | [MBProgressHUD showMessage:@"加载中..." toView:self.view];
63 |
64 | THttpRequest *request1 = [self reuqetWithidentifer:@"11111"];
65 | THttpRequest *request2 = [self reuqetWithidentifer:@"22222"];
66 | THttpRequest *request3 = [self reuqetWithidentifer:@"33333"];
67 | THttpRequest *request4 = [self reuqetWithidentifer:@"44444"];
68 | THttpRequest *request5 = [self reuqetWithidentifer:@"55555"];
69 |
70 | TYChainRequest *chainRequest = [[TYChainRequest alloc]init];
71 | [chainRequest addRequest:request1];
72 | [chainRequest addRequest:request2];
73 | [chainRequest addRequest:request3];
74 | [chainRequest addRequest:request4];
75 | [chainRequest addRequest:request5];
76 |
77 | [chainRequest loadWithSuccessBlock:^(TYChainRequest *request) {
78 | // TYChainRequest
79 | [MBProgressHUD showSuccess:@"chainRequest 加载成功!" toView:self.view];
80 | } failureBlock:^(TYChainRequest *request, NSError *error) {
81 | // TYChainRequest
82 | [MBProgressHUD showError:@"chainRequest 加载失败!" toView:self.view];
83 | }];
84 | }
85 |
86 | - (IBAction)batchRequestAction:(id)sender {
87 | [MBProgressHUD showMessage:@"加载中..." toView:self.view];
88 |
89 | THttpRequest *request1 = [self reuqetWithidentifer:@"11111"];
90 | THttpRequest *request2 = [self reuqetWithidentifer:@"22222"];
91 | THttpRequest *request3 = [self reuqetWithidentifer:@"33333"];
92 | THttpRequest *request4 = [self reuqetWithidentifer:@"44444"];
93 | THttpRequest *request5 = [self reuqetWithidentifer:@"55555"];
94 |
95 | TYBatchRequest *batchRequest = [[TYBatchRequest alloc]init];
96 | [batchRequest addRequest:request1];
97 | [batchRequest addRequest:request2];
98 | [batchRequest addRequest:request3];
99 | [batchRequest addRequest:request4];
100 | [batchRequest addRequest:request5];
101 |
102 | [batchRequest loadWithSuccessBlock:^(TYBatchRequest *request) {
103 | // batchRequest
104 | [MBProgressHUD showSuccess:@"batchRequest 加载成功!" toView:self.view];
105 | } failureBlock:^(TYBatchRequest *request, NSError *error) {
106 | // batchRequest
107 | [MBProgressHUD showError:@"batchRequest 加载失败!" toView:self.view];
108 | }];
109 |
110 | }
111 |
112 | - (THttpRequest *)reuqetWithidentifer:(NSString *)identifer
113 | {
114 | THttpRequest *request = [TCategoryRequest requestWithGender:@"1" generation:@"1"];
115 | request.identifier = identifer;
116 | // 缓存数据
117 | // request.requestFromCache = YES;
118 | // request.cacheResponse = YES;
119 |
120 | [request setRequestSuccessBlock:^(TCategoryRequest *request) {
121 | NSLog(@"请求成功 request id %@",request.identifier);
122 | } failureBlock:^(TCategoryRequest *request, NSError *error) {
123 | NSLog(@"请求失败 request id %@",request.identifier);
124 | }];
125 | return request;
126 | }
127 |
128 | #pragma mark - delegate
129 |
130 | - (void)requestDidFinish:(THttpRequest *)request
131 | {
132 | NSLog(@"%@ data:%@",request.responseObject,request.responseObject.data);
133 | [MBProgressHUD showSuccess:@"加载成功!" toView:self.view];
134 | }
135 |
136 | - (void)requestDidFail:(THttpRequest *)request error:(NSError *)error
137 | {
138 | [MBProgressHUD showError:@"加载失败!" toView:self.view];
139 | }
140 |
141 | - (void)didReceiveMemoryWarning {
142 | [super didReceiveMemoryWarning];
143 | // Dispose of any resources that can be recreated.
144 | }
145 |
146 | @end
147 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFSecurityPolicy.h:
--------------------------------------------------------------------------------
1 | // AFSecurityPolicy.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 | #import
24 |
25 | typedef NS_ENUM(NSUInteger, AFSSLPinningMode) {
26 | AFSSLPinningModeNone,
27 | AFSSLPinningModePublicKey,
28 | AFSSLPinningModeCertificate,
29 | };
30 |
31 | /**
32 | `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections.
33 |
34 | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled.
35 | */
36 |
37 | NS_ASSUME_NONNULL_BEGIN
38 |
39 | @interface AFSecurityPolicy : NSObject
40 |
41 | /**
42 | The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`.
43 | */
44 | @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
45 |
46 | /**
47 | The certificates used to evaluate server trust according to the SSL pinning mode.
48 |
49 | By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`.
50 |
51 | Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches.
52 | */
53 | @property (nonatomic, strong, nullable) NSSet *pinnedCertificates;
54 |
55 | /**
56 | Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`.
57 | */
58 | @property (nonatomic, assign) BOOL allowInvalidCertificates;
59 |
60 | /**
61 | Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`.
62 | */
63 | @property (nonatomic, assign) BOOL validatesDomainName;
64 |
65 | ///-----------------------------------------
66 | /// @name Getting Certificates from the Bundle
67 | ///-----------------------------------------
68 |
69 | /**
70 | Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`.
71 |
72 | @return The certificates included in the given bundle.
73 | */
74 | + (NSSet *)certificatesInBundle:(NSBundle *)bundle;
75 |
76 | ///-----------------------------------------
77 | /// @name Getting Specific Security Policies
78 | ///-----------------------------------------
79 |
80 | /**
81 | Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys.
82 |
83 | @return The default security policy.
84 | */
85 | + (instancetype)defaultPolicy;
86 |
87 | ///---------------------
88 | /// @name Initialization
89 | ///---------------------
90 |
91 | /**
92 | Creates and returns a security policy with the specified pinning mode.
93 |
94 | @param pinningMode The SSL pinning mode.
95 |
96 | @return A new security policy.
97 | */
98 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode;
99 |
100 | /**
101 | Creates and returns a security policy with the specified pinning mode.
102 |
103 | @param pinningMode The SSL pinning mode.
104 | @param pinnedCertificates The certificates to pin against.
105 |
106 | @return A new security policy.
107 | */
108 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates;
109 |
110 | ///------------------------------
111 | /// @name Evaluating Server Trust
112 | ///------------------------------
113 |
114 | /**
115 | Whether or not the specified server trust should be accepted, based on the security policy.
116 |
117 | This method should be used when responding to an authentication challenge from a server.
118 |
119 | @param serverTrust The X.509 certificate trust of the server.
120 | @param domain The domain of serverTrust. If `nil`, the domain will not be validated.
121 |
122 | @return Whether or not to trust the server.
123 | */
124 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
125 | forDomain:(nullable NSString *)domain;
126 |
127 | @end
128 |
129 | NS_ASSUME_NONNULL_END
130 |
131 | ///----------------
132 | /// @name Constants
133 | ///----------------
134 |
135 | /**
136 | ## SSL Pinning Modes
137 |
138 | The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes.
139 |
140 | enum {
141 | AFSSLPinningModeNone,
142 | AFSSLPinningModePublicKey,
143 | AFSSLPinningModeCertificate,
144 | }
145 |
146 | `AFSSLPinningModeNone`
147 | Do not used pinned certificates to validate servers.
148 |
149 | `AFSSLPinningModePublicKey`
150 | Validate host certificates against public keys of pinned certificates.
151 |
152 | `AFSSLPinningModeCertificate`
153 | Validate host certificates against pinned certificates.
154 | */
155 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
27 |
34 |
41 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYResponseCache.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYResponseCache.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/24.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYResponseCache.h"
10 | #import
11 |
12 | @interface TYResponseCache ()
13 |
14 | @property (nonatomic, strong) NSFileManager *fileManager;
15 | @property (nonatomic, strong) NSString *cachePath;
16 | @property (nonatomic, strong) dispatch_queue_t queue;
17 |
18 | @end
19 |
20 | static NSString * const TYRequestManagerCacheDirectory = @"TYRequestCacheDirectory";
21 |
22 | @implementation TYResponseCache
23 |
24 | + (dispatch_queue_t)cacheQueue {
25 | static dispatch_queue_t cacheQueue = NULL;
26 | static dispatch_once_t onceToken;
27 | dispatch_once(&onceToken, ^{
28 | cacheQueue = dispatch_queue_create("com.TYResponseCache.cacheQueue", DISPATCH_QUEUE_CONCURRENT);
29 | dispatch_set_target_queue(cacheQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
30 | });
31 | return cacheQueue;
32 | }
33 |
34 | - (dispatch_queue_t)queue
35 | {
36 | return [[self class] cacheQueue];
37 | }
38 |
39 | - (NSString *)cachePath
40 | {
41 | if (_cachePath == nil) {
42 | _cachePath = [self createCachesDirectory];
43 | }
44 | return _cachePath;
45 | }
46 |
47 | - (NSFileManager *)fileManager
48 | {
49 | @synchronized (_fileManager) {
50 | if (_fileManager == nil) {
51 | _fileManager = [NSFileManager defaultManager];
52 | }
53 | return _fileManager;
54 | }
55 | }
56 |
57 | - (NSString *)createCachesDirectory
58 | {
59 | NSString *cachePathDic = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0];
60 | NSString *cachePath = [cachePathDic stringByAppendingPathComponent:TYRequestManagerCacheDirectory];
61 | BOOL isDirectory;
62 | if (![self.fileManager fileExistsAtPath:cachePath isDirectory:&isDirectory]) {
63 | __autoreleasing NSError *error = nil;
64 | BOOL created = [self.fileManager createDirectoryAtPath:cachePath withIntermediateDirectories:YES attributes:nil error:&error];
65 | if (!created) {
66 | NSLog(@"<> - create cache directory failed with error:%@", error);
67 | }
68 | }
69 | return cachePath;
70 | }
71 |
72 | - (NSString *)md5String:(NSString *)str
73 | {
74 | const char *cStr = [str UTF8String];
75 | if (cStr == NULL) {
76 | cStr = "";
77 | }
78 | unsigned char result[CC_MD5_DIGEST_LENGTH];
79 | CC_MD5( cStr, (CC_LONG)strlen(cStr), result );
80 | return [NSString stringWithFormat:
81 | @"%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X%02X",
82 | result[0], result[1], result[2], result[3],
83 | result[4], result[5], result[6], result[7],
84 | result[8], result[9], result[10], result[11],
85 | result[12], result[13], result[14], result[15]
86 | ];
87 | }
88 |
89 | - (void)setObject:(id)object forKey:(NSString *)key
90 | {
91 | NSString *encodedKey = [self md5String:key];
92 | NSString *cachePath = self.cachePath;
93 | dispatch_async([self queue], ^{
94 | NSString *filePath = [cachePath stringByAppendingPathComponent:encodedKey];
95 | BOOL written = [NSKeyedArchiver archiveRootObject:object toFile:filePath];
96 | if (!written) {
97 | NSLog(@"<> - set object to file failed");
98 | }
99 | });
100 | }
101 |
102 | - (id )objectForKey:(NSString *)key
103 | {
104 | return [self objectForKey:key overdueDate:nil];
105 | }
106 |
107 | - (id)objectForKey:(NSString *)key overdueDate:(NSDate *)overdueDate
108 | {
109 | NSString *encodedKey = [self md5String:key];
110 | id object = nil;
111 | NSString *filePath = [self.cachePath stringByAppendingPathComponent:encodedKey];
112 |
113 | if ([self.fileManager fileExistsAtPath:filePath] ) {
114 | NSDate *modificationDate = [self cacheDateFilePath:filePath];
115 | if (!overdueDate || modificationDate.timeIntervalSince1970 - overdueDate.timeIntervalSince1970 >= 0) {
116 | object = [NSKeyedUnarchiver unarchiveObjectWithFile:filePath];
117 | }else {
118 | NSLog(@"file cache was overdue");
119 | }
120 | }
121 | return object;
122 | }
123 |
124 | - (void)removeObjectForKey:(NSString *)key
125 | {
126 | NSString *encodedKey = [self md5String:key];
127 | NSString *filePath = [self.cachePath stringByAppendingPathComponent:encodedKey];
128 | if ([self.fileManager fileExistsAtPath:filePath]) {
129 | __autoreleasing NSError *error = nil;
130 | BOOL removed = [self.fileManager removeItemAtPath:filePath error:&error];
131 | if (!removed) {
132 | NSLog(@"<> - remove item failed with error:%@", error);
133 | }
134 | }
135 | }
136 |
137 | - (void)removeAllObjects
138 | {
139 | __autoreleasing NSError *error;
140 | BOOL removed = [self.fileManager removeItemAtPath:self.cachePath error:&error];
141 | if (!removed) {
142 | NSLog(@" - remove cache directory failed with error:%@", error);
143 | }
144 | }
145 |
146 | #pragma mark - private
147 |
148 | - (NSDate *)cacheDateFilePath:(NSString *)path {
149 | // get file attribute
150 | NSError *attributesRetrievalError = nil;
151 | NSDictionary *attributes = [self.fileManager attributesOfItemAtPath:path
152 | error:&attributesRetrievalError];
153 | if (!attributes) {
154 | NSLog(@"Error get attributes for file at %@: %@", path, attributesRetrievalError);
155 | return nil;
156 | }
157 | return [attributes fileModificationDate];
158 | }
159 |
160 | - (void)trimToDate:(NSDate *)date
161 | {
162 | __autoreleasing NSError *error = nil;
163 | NSArray *files = [self.fileManager contentsOfDirectoryAtURL:[NSURL URLWithString:self.cachePath]
164 | includingPropertiesForKeys:@[NSURLContentModificationDateKey]
165 | options:NSDirectoryEnumerationSkipsHiddenFiles
166 | error:&error];
167 | if (error) {
168 | NSLog(@" - get files error:%@", error);
169 | }
170 |
171 | dispatch_async([self queue], ^{
172 | for (NSURL *fileURL in files) {
173 | NSDictionary *dictionary = [fileURL resourceValuesForKeys:@[NSURLContentModificationDateKey] error:nil];
174 | NSDate *modificationDate = [dictionary objectForKey:NSURLContentModificationDateKey];
175 | if (modificationDate.timeIntervalSince1970 - date.timeIntervalSince1970 < 0) {
176 | NSError *error = nil;
177 | if ([self.fileManager removeItemAtURL:fileURL error:&error]) {
178 | NSLog(@"delete cache yes");
179 | } else {
180 | NSLog(@"delete cache no %@",fileURL.absoluteString);
181 |
182 | }
183 |
184 | }
185 | }
186 | });
187 | }
188 |
189 | @end
190 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYHttpManager/TYHttpManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // TYHttpManager.m
3 | // TYHttpManagerDemo
4 | //
5 | // Created by tany on 16/5/23.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "TYHttpManager.h"
10 | #import "AFNetworking.h"
11 |
12 | @implementation TYHttpManager
13 |
14 | #pragma mark - init
15 |
16 | + (TYHttpManager *)sharedInstance {
17 | static id sharedInstance = nil;
18 | static dispatch_once_t onceToken;
19 | dispatch_once(&onceToken, ^{
20 | sharedInstance = [[self alloc] init];
21 | });
22 | return sharedInstance;
23 | }
24 |
25 | + (dispatch_queue_t)completeQueue {
26 | static dispatch_queue_t completeQueue = NULL;
27 | static dispatch_once_t onceToken;
28 | dispatch_once(&onceToken, ^{
29 | completeQueue = dispatch_queue_create("com.TYHttpManager.completeQueue", DISPATCH_QUEUE_SERIAL);
30 | dispatch_set_target_queue(completeQueue, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0));
31 | });
32 | return completeQueue;
33 | }
34 |
35 | - (instancetype)init
36 | {
37 | if (self = [super init]) {
38 | _requestConfiguration = [TYRequstConfigure sharedInstance];
39 | }
40 | return self;
41 | }
42 |
43 | #pragma maek - add request
44 |
45 | - (void)addRequest:(id)request
46 | {
47 | AFHTTPSessionManager *manager = [self defaultSessionManagerWithRequest:request];
48 |
49 | [self configureSessionManager:manager request:request];
50 |
51 | [self loadRequest:request sessionManager:manager];
52 | }
53 |
54 | - (void)cancleRequest:(id)request
55 | {
56 | [request cancle];
57 | }
58 |
59 | #pragma mark - configure http manager
60 |
61 | - (AFHTTPSessionManager *)defaultSessionManagerWithRequest:(id)request
62 | {
63 | TYRequstConfigure *requestConfiguration = [request configuration];
64 | if (requestConfiguration == nil) {
65 | requestConfiguration = self.requestConfiguration;
66 | }
67 |
68 | AFHTTPSessionManager *manager = nil;
69 | if (requestConfiguration.sessionConfiguration) {
70 | manager = [[AFHTTPSessionManager alloc]initWithBaseURL:[NSURL URLWithString:requestConfiguration.baseURL] sessionConfiguration:requestConfiguration.sessionConfiguration];
71 | }else {
72 | manager = [AFHTTPSessionManager manager];
73 | }
74 | manager.completionQueue = [[self class] completeQueue];
75 | return manager;
76 | }
77 |
78 | - (void)configureSessionManager:(AFHTTPSessionManager *)manager request:(id)request
79 | {
80 | if ([request serializerType] == TYRequestSerializerTypeJSON) {
81 | manager.requestSerializer = [AFJSONRequestSerializer serializer];
82 | }else if ([request serializerType] == TYRequestSerializerTypeString) {
83 | manager.requestSerializer = [AFJSONRequestSerializer serializer];
84 | manager.responseSerializer = [AFJSONResponseSerializer serializerWithReadingOptions:NSJSONReadingAllowFragments];
85 | }
86 |
87 | NSDictionary *headerFieldValue = [request headerFieldValues];
88 | if (headerFieldValue) {
89 | [headerFieldValue enumerateKeysAndObjectsUsingBlock:^(id key, id value, BOOL * stop) {
90 | if ([key isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) {
91 | [manager.requestSerializer setValue:value forHTTPHeaderField:key];
92 | }
93 | }];
94 | }
95 |
96 | manager.requestSerializer.cachePolicy = [request cachePolicy];
97 | manager.requestSerializer.timeoutInterval = [request timeoutInterval];
98 | manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/plain", @"text/javascript", @"text/json", @"text/html", nil];
99 | }
100 |
101 | - (NSString *)buildRequstURL:(id)request
102 | {
103 | NSString *URLPath = [request URLString];
104 | if ([URLPath hasPrefix:@"http:"] ) {
105 | return URLPath;
106 | }
107 |
108 | NSString *baseURL = request.baseURL.length > 0 ? request.baseURL : (request.configuration ? request.configuration.baseURL : [TYRequstConfigure sharedInstance].baseURL);
109 |
110 | return [NSString stringWithFormat:@"%@%@",baseURL?baseURL:@"",URLPath];
111 | }
112 |
113 | - (void)loadRequest:(id)request sessionManager:(AFHTTPSessionManager *)manager
114 | {
115 | NSString *URLString = [self buildRequstURL:request];
116 | NSDictionary *parameters = [request parameters];
117 |
118 | TYRequestMethod requestMethod = [request method];
119 | AFProgressBlock progressBlock = [request progressBlock];
120 |
121 | if (requestMethod == TYRequestMethodGet) {
122 |
123 | request.dataTask = [manager GET:URLString parameters:parameters progress:progressBlock success:^(NSURLSessionDataTask * task, id responseObject) {
124 | [request requestDidResponse:responseObject error:nil];
125 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
126 | [request requestDidResponse:nil error:error];
127 | }];
128 | }else if (requestMethod == TYRequestMethodPost) {
129 |
130 | AFConstructingBodyBlock constructingBodyBlock = [request constructingBodyBlock];
131 | if (constructingBodyBlock) {
132 | request.dataTask = [manager POST:URLString parameters:parameters constructingBodyWithBlock:constructingBodyBlock progress:progressBlock success:^(NSURLSessionDataTask * task, id responseObject) {
133 | [request requestDidResponse:responseObject error:nil];
134 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
135 | [request requestDidResponse:nil error:error];
136 | }];
137 | }else {
138 | request.dataTask = [manager POST:URLString parameters:parameters progress:progressBlock success:^(NSURLSessionDataTask * task, id responseObject) {
139 | [request requestDidResponse:responseObject error:nil];
140 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
141 | [request requestDidResponse:nil error:error];
142 | }];
143 | }
144 | }else if (requestMethod == TYRequestMethodHead) {
145 |
146 | request.dataTask = [manager HEAD:URLString parameters:parameters success:^(NSURLSessionDataTask * task) {
147 | [request requestDidResponse:nil error:nil];
148 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
149 | [request requestDidResponse:nil error:error];
150 | }];
151 | }else if (requestMethod == TYRequestMethodPut) {
152 |
153 | request.dataTask = [manager PUT:URLString parameters:parameters success:^(NSURLSessionDataTask * task, id responseObject) {
154 | [request requestDidResponse:responseObject error:nil];
155 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
156 | [request requestDidResponse:nil error:error];
157 | }];
158 | }else if (requestMethod == TYRequestMethodPatch) {
159 |
160 | request.dataTask = [manager PATCH:URLString parameters:parameters success:^(NSURLSessionDataTask * task, id responseObject) {
161 | [request requestDidResponse:responseObject error:nil];
162 | } failure:^(NSURLSessionDataTask * task, NSError * error) {
163 | [request requestDidResponse:nil error:error];
164 | }];
165 | }
166 | }
167 |
168 | @end
169 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFNetworkReachabilityManager.h:
--------------------------------------------------------------------------------
1 | // AFNetworkReachabilityManager.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #if !TARGET_OS_WATCH
25 | #import
26 |
27 | typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) {
28 | AFNetworkReachabilityStatusUnknown = -1,
29 | AFNetworkReachabilityStatusNotReachable = 0,
30 | AFNetworkReachabilityStatusReachableViaWWAN = 1,
31 | AFNetworkReachabilityStatusReachableViaWiFi = 2,
32 | };
33 |
34 | NS_ASSUME_NONNULL_BEGIN
35 |
36 | /**
37 | `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces.
38 |
39 | Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability.
40 |
41 | See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ )
42 |
43 | @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined.
44 | */
45 | @interface AFNetworkReachabilityManager : NSObject
46 |
47 | /**
48 | The current network reachability status.
49 | */
50 | @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
51 |
52 | /**
53 | Whether or not the network is currently reachable.
54 | */
55 | @property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable;
56 |
57 | /**
58 | Whether or not the network is currently reachable via WWAN.
59 | */
60 | @property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN;
61 |
62 | /**
63 | Whether or not the network is currently reachable via WiFi.
64 | */
65 | @property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi;
66 |
67 | ///---------------------
68 | /// @name Initialization
69 | ///---------------------
70 |
71 | /**
72 | Returns the shared network reachability manager.
73 | */
74 | + (instancetype)sharedManager;
75 |
76 | /**
77 | Creates and returns a network reachability manager with the default socket address.
78 |
79 | @return An initialized network reachability manager, actively monitoring the default socket address.
80 | */
81 | + (instancetype)manager;
82 |
83 | /**
84 | Creates and returns a network reachability manager for the specified domain.
85 |
86 | @param domain The domain used to evaluate network reachability.
87 |
88 | @return An initialized network reachability manager, actively monitoring the specified domain.
89 | */
90 | + (instancetype)managerForDomain:(NSString *)domain;
91 |
92 | /**
93 | Creates and returns a network reachability manager for the socket address.
94 |
95 | @param address The socket address (`sockaddr_in6`) used to evaluate network reachability.
96 |
97 | @return An initialized network reachability manager, actively monitoring the specified socket address.
98 | */
99 | + (instancetype)managerForAddress:(const void *)address;
100 |
101 | /**
102 | Initializes an instance of a network reachability manager from the specified reachability object.
103 |
104 | @param reachability The reachability object to monitor.
105 |
106 | @return An initialized network reachability manager, actively monitoring the specified reachability.
107 | */
108 | - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER;
109 |
110 | ///--------------------------------------------------
111 | /// @name Starting & Stopping Reachability Monitoring
112 | ///--------------------------------------------------
113 |
114 | /**
115 | Starts monitoring for changes in network reachability status.
116 | */
117 | - (void)startMonitoring;
118 |
119 | /**
120 | Stops monitoring for changes in network reachability status.
121 | */
122 | - (void)stopMonitoring;
123 |
124 | ///-------------------------------------------------
125 | /// @name Getting Localized Reachability Description
126 | ///-------------------------------------------------
127 |
128 | /**
129 | Returns a localized string representation of the current network reachability status.
130 | */
131 | - (NSString *)localizedNetworkReachabilityStatusString;
132 |
133 | ///---------------------------------------------------
134 | /// @name Setting Network Reachability Change Callback
135 | ///---------------------------------------------------
136 |
137 | /**
138 | Sets a callback to be executed when the network availability of the `baseURL` host changes.
139 |
140 | @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`.
141 | */
142 | - (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block;
143 |
144 | @end
145 |
146 | ///----------------
147 | /// @name Constants
148 | ///----------------
149 |
150 | /**
151 | ## Network Reachability
152 |
153 | The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses.
154 |
155 | enum {
156 | AFNetworkReachabilityStatusUnknown,
157 | AFNetworkReachabilityStatusNotReachable,
158 | AFNetworkReachabilityStatusReachableViaWWAN,
159 | AFNetworkReachabilityStatusReachableViaWiFi,
160 | }
161 |
162 | `AFNetworkReachabilityStatusUnknown`
163 | The `baseURL` host reachability is not known.
164 |
165 | `AFNetworkReachabilityStatusNotReachable`
166 | The `baseURL` host cannot be reached.
167 |
168 | `AFNetworkReachabilityStatusReachableViaWWAN`
169 | The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS.
170 |
171 | `AFNetworkReachabilityStatusReachableViaWiFi`
172 | The `baseURL` host can be reached via a Wi-Fi connection.
173 |
174 | ### Keys for Notification UserInfo Dictionary
175 |
176 | Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification.
177 |
178 | `AFNetworkingReachabilityNotificationStatusItem`
179 | A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification.
180 | The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status.
181 | */
182 |
183 | ///--------------------
184 | /// @name Notifications
185 | ///--------------------
186 |
187 | /**
188 | Posted when network reachability changes.
189 | This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability.
190 |
191 | @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`).
192 | */
193 | FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityDidChangeNotification;
194 | FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityNotificationStatusItem;
195 |
196 | ///--------------------
197 | /// @name Functions
198 | ///--------------------
199 |
200 | /**
201 | Returns a localized string representation of an `AFNetworkReachabilityStatus` value.
202 | */
203 | FOUNDATION_EXPORT NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status);
204 |
205 | NS_ASSUME_NONNULL_END
206 | #endif
207 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFNetworkReachabilityManager.m:
--------------------------------------------------------------------------------
1 | // AFNetworkReachabilityManager.m
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import "AFNetworkReachabilityManager.h"
23 | #if !TARGET_OS_WATCH
24 |
25 | #import
26 | #import
27 | #import
28 | #import
29 | #import
30 |
31 | NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change";
32 | NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem";
33 |
34 | typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status);
35 |
36 | NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) {
37 | switch (status) {
38 | case AFNetworkReachabilityStatusNotReachable:
39 | return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil);
40 | case AFNetworkReachabilityStatusReachableViaWWAN:
41 | return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil);
42 | case AFNetworkReachabilityStatusReachableViaWiFi:
43 | return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil);
44 | case AFNetworkReachabilityStatusUnknown:
45 | default:
46 | return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil);
47 | }
48 | }
49 |
50 | static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) {
51 | BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0);
52 | BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0);
53 | BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0));
54 | BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0);
55 | BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction));
56 |
57 | AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown;
58 | if (isNetworkReachable == NO) {
59 | status = AFNetworkReachabilityStatusNotReachable;
60 | }
61 | #if TARGET_OS_IPHONE
62 | else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) {
63 | status = AFNetworkReachabilityStatusReachableViaWWAN;
64 | }
65 | #endif
66 | else {
67 | status = AFNetworkReachabilityStatusReachableViaWiFi;
68 | }
69 |
70 | return status;
71 | }
72 |
73 | /**
74 | * Queue a status change notification for the main thread.
75 | *
76 | * This is done to ensure that the notifications are received in the same order
77 | * as they are sent. If notifications are sent directly, it is possible that
78 | * a queued notification (for an earlier status condition) is processed after
79 | * the later update, resulting in the listener being left in the wrong state.
80 | */
81 | static void AFPostReachabilityStatusChange(SCNetworkReachabilityFlags flags, AFNetworkReachabilityStatusBlock block) {
82 | AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags);
83 | dispatch_async(dispatch_get_main_queue(), ^{
84 | if (block) {
85 | block(status);
86 | }
87 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
88 | NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) };
89 | [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo];
90 | });
91 | }
92 |
93 | static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) {
94 | AFPostReachabilityStatusChange(flags, (__bridge AFNetworkReachabilityStatusBlock)info);
95 | }
96 |
97 |
98 | static const void * AFNetworkReachabilityRetainCallback(const void *info) {
99 | return Block_copy(info);
100 | }
101 |
102 | static void AFNetworkReachabilityReleaseCallback(const void *info) {
103 | if (info) {
104 | Block_release(info);
105 | }
106 | }
107 |
108 | @interface AFNetworkReachabilityManager ()
109 | @property (readonly, nonatomic, assign) SCNetworkReachabilityRef networkReachability;
110 | @property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus;
111 | @property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock;
112 | @end
113 |
114 | @implementation AFNetworkReachabilityManager
115 |
116 | + (instancetype)sharedManager {
117 | static AFNetworkReachabilityManager *_sharedManager = nil;
118 | static dispatch_once_t onceToken;
119 | dispatch_once(&onceToken, ^{
120 | _sharedManager = [self manager];
121 | });
122 |
123 | return _sharedManager;
124 | }
125 |
126 | + (instancetype)managerForDomain:(NSString *)domain {
127 | SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]);
128 |
129 | AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
130 |
131 | CFRelease(reachability);
132 |
133 | return manager;
134 | }
135 |
136 | + (instancetype)managerForAddress:(const void *)address {
137 | SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address);
138 | AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability];
139 |
140 | CFRelease(reachability);
141 |
142 | return manager;
143 | }
144 |
145 | + (instancetype)manager
146 | {
147 | #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 90000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 101100)
148 | struct sockaddr_in6 address;
149 | bzero(&address, sizeof(address));
150 | address.sin6_len = sizeof(address);
151 | address.sin6_family = AF_INET6;
152 | #else
153 | struct sockaddr_in address;
154 | bzero(&address, sizeof(address));
155 | address.sin_len = sizeof(address);
156 | address.sin_family = AF_INET;
157 | #endif
158 | return [self managerForAddress:&address];
159 | }
160 |
161 | - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability {
162 | self = [super init];
163 | if (!self) {
164 | return nil;
165 | }
166 |
167 | _networkReachability = CFRetain(reachability);
168 | self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown;
169 |
170 | return self;
171 | }
172 |
173 | - (instancetype)init NS_UNAVAILABLE
174 | {
175 | return nil;
176 | }
177 |
178 | - (void)dealloc {
179 | [self stopMonitoring];
180 |
181 | if (_networkReachability != NULL) {
182 | CFRelease(_networkReachability);
183 | }
184 | }
185 |
186 | #pragma mark -
187 |
188 | - (BOOL)isReachable {
189 | return [self isReachableViaWWAN] || [self isReachableViaWiFi];
190 | }
191 |
192 | - (BOOL)isReachableViaWWAN {
193 | return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN;
194 | }
195 |
196 | - (BOOL)isReachableViaWiFi {
197 | return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi;
198 | }
199 |
200 | #pragma mark -
201 |
202 | - (void)startMonitoring {
203 | [self stopMonitoring];
204 |
205 | if (!self.networkReachability) {
206 | return;
207 | }
208 |
209 | __weak __typeof(self)weakSelf = self;
210 | AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) {
211 | __strong __typeof(weakSelf)strongSelf = weakSelf;
212 |
213 | strongSelf.networkReachabilityStatus = status;
214 | if (strongSelf.networkReachabilityStatusBlock) {
215 | strongSelf.networkReachabilityStatusBlock(status);
216 | }
217 |
218 | };
219 |
220 | SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL};
221 | SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context);
222 | SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
223 |
224 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{
225 | SCNetworkReachabilityFlags flags;
226 | if (SCNetworkReachabilityGetFlags(self.networkReachability, &flags)) {
227 | AFPostReachabilityStatusChange(flags, callback);
228 | }
229 | });
230 | }
231 |
232 | - (void)stopMonitoring {
233 | if (!self.networkReachability) {
234 | return;
235 | }
236 |
237 | SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes);
238 | }
239 |
240 | #pragma mark -
241 |
242 | - (NSString *)localizedNetworkReachabilityStatusString {
243 | return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus);
244 | }
245 |
246 | #pragma mark -
247 |
248 | - (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block {
249 | self.networkReachabilityStatusBlock = block;
250 | }
251 |
252 | #pragma mark - NSKeyValueObserving
253 |
254 | + (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key {
255 | if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) {
256 | return [NSSet setWithObject:@"networkReachabilityStatus"];
257 | }
258 |
259 | return [super keyPathsForValuesAffectingValueForKey:key];
260 | }
261 |
262 | @end
263 | #endif
264 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFURLResponseSerialization.h:
--------------------------------------------------------------------------------
1 | // AFURLResponseSerialization.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 | #import
24 |
25 | NS_ASSUME_NONNULL_BEGIN
26 |
27 | /**
28 | The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data.
29 |
30 | For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object.
31 | */
32 | @protocol AFURLResponseSerialization
33 |
34 | /**
35 | The response object decoded from the data associated with a specified response.
36 |
37 | @param response The response to be processed.
38 | @param data The response data to be decoded.
39 | @param error The error that occurred while attempting to decode the response data.
40 |
41 | @return The object decoded from the specified response data.
42 | */
43 | - (nullable id)responseObjectForResponse:(nullable NSURLResponse *)response
44 | data:(nullable NSData *)data
45 | error:(NSError * _Nullable __autoreleasing *)error NS_SWIFT_NOTHROW;
46 |
47 | @end
48 |
49 | #pragma mark -
50 |
51 | /**
52 | `AFHTTPResponseSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation.
53 |
54 | Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPResponseSerializer` in order to ensure consistent default behavior.
55 | */
56 | @interface AFHTTPResponseSerializer : NSObject
57 |
58 | - (instancetype)init;
59 |
60 | /**
61 | The string encoding used to serialize data received from the server, when no string encoding is specified by the response. `NSUTF8StringEncoding` by default.
62 | */
63 | @property (nonatomic, assign) NSStringEncoding stringEncoding;
64 |
65 | /**
66 | Creates and returns a serializer with default configuration.
67 | */
68 | + (instancetype)serializer;
69 |
70 | ///-----------------------------------------
71 | /// @name Configuring Response Serialization
72 | ///-----------------------------------------
73 |
74 | /**
75 | The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation.
76 |
77 | See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
78 | */
79 | @property (nonatomic, copy, nullable) NSIndexSet *acceptableStatusCodes;
80 |
81 | /**
82 | The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation.
83 | */
84 | @property (nonatomic, copy, nullable) NSSet *acceptableContentTypes;
85 |
86 | /**
87 | Validates the specified response and data.
88 |
89 | In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks.
90 |
91 | @param response The response to be validated.
92 | @param data The data associated with the response.
93 | @param error The error that occurred while attempting to validate the response.
94 |
95 | @return `YES` if the response is valid, otherwise `NO`.
96 | */
97 | - (BOOL)validateResponse:(nullable NSHTTPURLResponse *)response
98 | data:(nullable NSData *)data
99 | error:(NSError * _Nullable __autoreleasing *)error;
100 |
101 | @end
102 |
103 | #pragma mark -
104 |
105 |
106 | /**
107 | `AFJSONResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes JSON responses.
108 |
109 | By default, `AFJSONResponseSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types:
110 |
111 | - `application/json`
112 | - `text/json`
113 | - `text/javascript`
114 | */
115 | @interface AFJSONResponseSerializer : AFHTTPResponseSerializer
116 |
117 | - (instancetype)init;
118 |
119 | /**
120 | Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default.
121 | */
122 | @property (nonatomic, assign) NSJSONReadingOptions readingOptions;
123 |
124 | /**
125 | Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`.
126 | */
127 | @property (nonatomic, assign) BOOL removesKeysWithNullValues;
128 |
129 | /**
130 | Creates and returns a JSON serializer with specified reading and writing options.
131 |
132 | @param readingOptions The specified JSON reading options.
133 | */
134 | + (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions;
135 |
136 | @end
137 |
138 | #pragma mark -
139 |
140 | /**
141 | `AFXMLParserResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects.
142 |
143 | By default, `AFXMLParserResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
144 |
145 | - `application/xml`
146 | - `text/xml`
147 | */
148 | @interface AFXMLParserResponseSerializer : AFHTTPResponseSerializer
149 |
150 | @end
151 |
152 | #pragma mark -
153 |
154 | #ifdef __MAC_OS_X_VERSION_MIN_REQUIRED
155 |
156 | /**
157 | `AFXMLDocumentResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
158 |
159 | By default, `AFXMLDocumentResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types:
160 |
161 | - `application/xml`
162 | - `text/xml`
163 | */
164 | @interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer
165 |
166 | - (instancetype)init;
167 |
168 | /**
169 | Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default.
170 | */
171 | @property (nonatomic, assign) NSUInteger options;
172 |
173 | /**
174 | Creates and returns an XML document serializer with the specified options.
175 |
176 | @param mask The XML document options.
177 | */
178 | + (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask;
179 |
180 | @end
181 |
182 | #endif
183 |
184 | #pragma mark -
185 |
186 | /**
187 | `AFPropertyListResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects.
188 |
189 | By default, `AFPropertyListResponseSerializer` accepts the following MIME types:
190 |
191 | - `application/x-plist`
192 | */
193 | @interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer
194 |
195 | - (instancetype)init;
196 |
197 | /**
198 | The property list format. Possible values are described in "NSPropertyListFormat".
199 | */
200 | @property (nonatomic, assign) NSPropertyListFormat format;
201 |
202 | /**
203 | The property list reading options. Possible values are described in "NSPropertyListMutabilityOptions."
204 | */
205 | @property (nonatomic, assign) NSPropertyListReadOptions readOptions;
206 |
207 | /**
208 | Creates and returns a property list serializer with a specified format, read options, and write options.
209 |
210 | @param format The property list format.
211 | @param readOptions The property list reading options.
212 | */
213 | + (instancetype)serializerWithFormat:(NSPropertyListFormat)format
214 | readOptions:(NSPropertyListReadOptions)readOptions;
215 |
216 | @end
217 |
218 | #pragma mark -
219 |
220 | /**
221 | `AFImageResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses.
222 |
223 | By default, `AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage:
224 |
225 | - `image/tiff`
226 | - `image/jpeg`
227 | - `image/gif`
228 | - `image/png`
229 | - `image/ico`
230 | - `image/x-icon`
231 | - `image/bmp`
232 | - `image/x-bmp`
233 | - `image/x-xbitmap`
234 | - `image/x-win-bitmap`
235 | */
236 | @interface AFImageResponseSerializer : AFHTTPResponseSerializer
237 |
238 | #if TARGET_OS_IOS || TARGET_OS_TV || TARGET_OS_WATCH
239 | /**
240 | The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance.
241 | */
242 | @property (nonatomic, assign) CGFloat imageScale;
243 |
244 | /**
245 | Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default.
246 | */
247 | @property (nonatomic, assign) BOOL automaticallyInflatesResponseImage;
248 | #endif
249 |
250 | @end
251 |
252 | #pragma mark -
253 |
254 | /**
255 | `AFCompoundSerializer` is a subclass of `AFHTTPResponseSerializer` that delegates the response serialization to the first `AFHTTPResponseSerializer` object that returns an object for `responseObjectForResponse:data:error:`, falling back on the default behavior of `AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer.
256 | */
257 | @interface AFCompoundResponseSerializer : AFHTTPResponseSerializer
258 |
259 | /**
260 | The component response serializers.
261 | */
262 | @property (readonly, nonatomic, copy) NSArray > *responseSerializers;
263 |
264 | /**
265 | Creates and returns a compound serializer comprised of the specified response serializers.
266 |
267 | @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`.
268 | */
269 | + (instancetype)compoundSerializerWithResponseSerializers:(NSArray > *)responseSerializers;
270 |
271 | @end
272 |
273 | ///----------------
274 | /// @name Constants
275 | ///----------------
276 |
277 | /**
278 | ## Error Domains
279 |
280 | The following error domain is predefined.
281 |
282 | - `NSString * const AFURLResponseSerializationErrorDomain`
283 |
284 | ### Constants
285 |
286 | `AFURLResponseSerializationErrorDomain`
287 | AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`.
288 | */
289 | FOUNDATION_EXPORT NSString * const AFURLResponseSerializationErrorDomain;
290 |
291 | /**
292 | ## User info dictionary keys
293 |
294 | These keys may exist in the user info dictionary, in addition to those defined for NSError.
295 |
296 | - `NSString * const AFNetworkingOperationFailingURLResponseErrorKey`
297 | - `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey`
298 |
299 | ### Constants
300 |
301 | `AFNetworkingOperationFailingURLResponseErrorKey`
302 | The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
303 |
304 | `AFNetworkingOperationFailingURLResponseDataErrorKey`
305 | The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`.
306 | */
307 | FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseErrorKey;
308 |
309 | FOUNDATION_EXPORT NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey;
310 |
311 | NS_ASSUME_NONNULL_END
312 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFSecurityPolicy.m:
--------------------------------------------------------------------------------
1 | // AFSecurityPolicy.m
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import "AFSecurityPolicy.h"
23 |
24 | #import
25 |
26 | #if !TARGET_OS_IOS && !TARGET_OS_WATCH && !TARGET_OS_TV
27 | static NSData * AFSecKeyGetData(SecKeyRef key) {
28 | CFDataRef data = NULL;
29 |
30 | __Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out);
31 |
32 | return (__bridge_transfer NSData *)data;
33 |
34 | _out:
35 | if (data) {
36 | CFRelease(data);
37 | }
38 |
39 | return nil;
40 | }
41 | #endif
42 |
43 | static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) {
44 | #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
45 | return [(__bridge id)key1 isEqual:(__bridge id)key2];
46 | #else
47 | return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)];
48 | #endif
49 | }
50 |
51 | static id AFPublicKeyForCertificate(NSData *certificate) {
52 | id allowedPublicKey = nil;
53 | SecCertificateRef allowedCertificate;
54 | SecCertificateRef allowedCertificates[1];
55 | CFArrayRef tempCertificates = nil;
56 | SecPolicyRef policy = nil;
57 | SecTrustRef allowedTrust = nil;
58 | SecTrustResultType result;
59 |
60 | allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate);
61 | __Require_Quiet(allowedCertificate != NULL, _out);
62 |
63 | allowedCertificates[0] = allowedCertificate;
64 | tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL);
65 |
66 | policy = SecPolicyCreateBasicX509();
67 | __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out);
68 | __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out);
69 |
70 | allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust);
71 |
72 | _out:
73 | if (allowedTrust) {
74 | CFRelease(allowedTrust);
75 | }
76 |
77 | if (policy) {
78 | CFRelease(policy);
79 | }
80 |
81 | if (tempCertificates) {
82 | CFRelease(tempCertificates);
83 | }
84 |
85 | if (allowedCertificate) {
86 | CFRelease(allowedCertificate);
87 | }
88 |
89 | return allowedPublicKey;
90 | }
91 |
92 | static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) {
93 | BOOL isValid = NO;
94 | SecTrustResultType result;
95 | __Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out);
96 |
97 | isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed);
98 |
99 | _out:
100 | return isValid;
101 | }
102 |
103 | static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) {
104 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust);
105 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount];
106 |
107 | for (CFIndex i = 0; i < certificateCount; i++) {
108 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i);
109 | [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)];
110 | }
111 |
112 | return [NSArray arrayWithArray:trustChain];
113 | }
114 |
115 | static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) {
116 | SecPolicyRef policy = SecPolicyCreateBasicX509();
117 | CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust);
118 | NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount];
119 | for (CFIndex i = 0; i < certificateCount; i++) {
120 | SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i);
121 |
122 | SecCertificateRef someCertificates[] = {certificate};
123 | CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL);
124 |
125 | SecTrustRef trust;
126 | __Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out);
127 |
128 | SecTrustResultType result;
129 | __Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out);
130 |
131 | [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)];
132 |
133 | _out:
134 | if (trust) {
135 | CFRelease(trust);
136 | }
137 |
138 | if (certificates) {
139 | CFRelease(certificates);
140 | }
141 |
142 | continue;
143 | }
144 | CFRelease(policy);
145 |
146 | return [NSArray arrayWithArray:trustChain];
147 | }
148 |
149 | #pragma mark -
150 |
151 | @interface AFSecurityPolicy()
152 | @property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode;
153 | @property (readwrite, nonatomic, strong) NSSet *pinnedPublicKeys;
154 | @end
155 |
156 | @implementation AFSecurityPolicy
157 |
158 | + (NSSet *)certificatesInBundle:(NSBundle *)bundle {
159 | NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."];
160 |
161 | NSMutableSet *certificates = [NSMutableSet setWithCapacity:[paths count]];
162 | for (NSString *path in paths) {
163 | NSData *certificateData = [NSData dataWithContentsOfFile:path];
164 | [certificates addObject:certificateData];
165 | }
166 |
167 | return [NSSet setWithSet:certificates];
168 | }
169 |
170 | + (NSSet *)defaultPinnedCertificates {
171 | static NSSet *_defaultPinnedCertificates = nil;
172 | static dispatch_once_t onceToken;
173 | dispatch_once(&onceToken, ^{
174 | NSBundle *bundle = [NSBundle bundleForClass:[self class]];
175 | _defaultPinnedCertificates = [self certificatesInBundle:bundle];
176 | });
177 |
178 | return _defaultPinnedCertificates;
179 | }
180 |
181 | + (instancetype)defaultPolicy {
182 | AFSecurityPolicy *securityPolicy = [[self alloc] init];
183 | securityPolicy.SSLPinningMode = AFSSLPinningModeNone;
184 |
185 | return securityPolicy;
186 | }
187 |
188 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode {
189 | return [self policyWithPinningMode:pinningMode withPinnedCertificates:[self defaultPinnedCertificates]];
190 | }
191 |
192 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates {
193 | AFSecurityPolicy *securityPolicy = [[self alloc] init];
194 | securityPolicy.SSLPinningMode = pinningMode;
195 |
196 | [securityPolicy setPinnedCertificates:pinnedCertificates];
197 |
198 | return securityPolicy;
199 | }
200 |
201 | - (instancetype)init {
202 | self = [super init];
203 | if (!self) {
204 | return nil;
205 | }
206 |
207 | self.validatesDomainName = YES;
208 |
209 | return self;
210 | }
211 |
212 | - (void)setPinnedCertificates:(NSSet *)pinnedCertificates {
213 | _pinnedCertificates = pinnedCertificates;
214 |
215 | if (self.pinnedCertificates) {
216 | NSMutableSet *mutablePinnedPublicKeys = [NSMutableSet setWithCapacity:[self.pinnedCertificates count]];
217 | for (NSData *certificate in self.pinnedCertificates) {
218 | id publicKey = AFPublicKeyForCertificate(certificate);
219 | if (!publicKey) {
220 | continue;
221 | }
222 | [mutablePinnedPublicKeys addObject:publicKey];
223 | }
224 | self.pinnedPublicKeys = [NSSet setWithSet:mutablePinnedPublicKeys];
225 | } else {
226 | self.pinnedPublicKeys = nil;
227 | }
228 | }
229 |
230 | #pragma mark -
231 |
232 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust
233 | forDomain:(NSString *)domain
234 | {
235 | if (domain && self.allowInvalidCertificates && self.validatesDomainName && (self.SSLPinningMode == AFSSLPinningModeNone || [self.pinnedCertificates count] == 0)) {
236 | // https://developer.apple.com/library/mac/documentation/NetworkingInternet/Conceptual/NetworkingTopics/Articles/OverridingSSLChainValidationCorrectly.html
237 | // According to the docs, you should only trust your provided certs for evaluation.
238 | // Pinned certificates are added to the trust. Without pinned certificates,
239 | // there is nothing to evaluate against.
240 | //
241 | // From Apple Docs:
242 | // "Do not implicitly trust self-signed certificates as anchors (kSecTrustOptionImplicitAnchors).
243 | // Instead, add your own (self-signed) CA certificate to the list of trusted anchors."
244 | NSLog(@"In order to validate a domain name for self signed certificates, you MUST use pinning.");
245 | return NO;
246 | }
247 |
248 | NSMutableArray *policies = [NSMutableArray array];
249 | if (self.validatesDomainName) {
250 | [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)];
251 | } else {
252 | [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()];
253 | }
254 |
255 | SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies);
256 |
257 | if (self.SSLPinningMode == AFSSLPinningModeNone) {
258 | return self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust);
259 | } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) {
260 | return NO;
261 | }
262 |
263 | switch (self.SSLPinningMode) {
264 | case AFSSLPinningModeNone:
265 | default:
266 | return NO;
267 | case AFSSLPinningModeCertificate: {
268 | NSMutableArray *pinnedCertificates = [NSMutableArray array];
269 | for (NSData *certificateData in self.pinnedCertificates) {
270 | [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)];
271 | }
272 | SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates);
273 |
274 | if (!AFServerTrustIsValid(serverTrust)) {
275 | return NO;
276 | }
277 |
278 | // obtain the chain after being validated, which *should* contain the pinned certificate in the last position (if it's the Root CA)
279 | NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust);
280 |
281 | for (NSData *trustChainCertificate in [serverCertificates reverseObjectEnumerator]) {
282 | if ([self.pinnedCertificates containsObject:trustChainCertificate]) {
283 | return YES;
284 | }
285 | }
286 |
287 | return NO;
288 | }
289 | case AFSSLPinningModePublicKey: {
290 | NSUInteger trustedPublicKeyCount = 0;
291 | NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust);
292 |
293 | for (id trustChainPublicKey in publicKeys) {
294 | for (id pinnedPublicKey in self.pinnedPublicKeys) {
295 | if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) {
296 | trustedPublicKeyCount += 1;
297 | }
298 | }
299 | }
300 | return trustedPublicKeyCount > 0;
301 | }
302 | }
303 |
304 | return NO;
305 | }
306 |
307 | #pragma mark - NSKeyValueObserving
308 |
309 | + (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys {
310 | return [NSSet setWithObject:@"pinnedCertificates"];
311 | }
312 |
313 | #pragma mark - NSSecureCoding
314 |
315 | + (BOOL)supportsSecureCoding {
316 | return YES;
317 | }
318 |
319 | - (instancetype)initWithCoder:(NSCoder *)decoder {
320 |
321 | self = [self init];
322 | if (!self) {
323 | return nil;
324 | }
325 |
326 | self.SSLPinningMode = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(SSLPinningMode))] unsignedIntegerValue];
327 | self.allowInvalidCertificates = [decoder decodeBoolForKey:NSStringFromSelector(@selector(allowInvalidCertificates))];
328 | self.validatesDomainName = [decoder decodeBoolForKey:NSStringFromSelector(@selector(validatesDomainName))];
329 | self.pinnedCertificates = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(pinnedCertificates))];
330 |
331 | return self;
332 | }
333 |
334 | - (void)encodeWithCoder:(NSCoder *)coder {
335 | [coder encodeObject:[NSNumber numberWithUnsignedInteger:self.SSLPinningMode] forKey:NSStringFromSelector(@selector(SSLPinningMode))];
336 | [coder encodeBool:self.allowInvalidCertificates forKey:NSStringFromSelector(@selector(allowInvalidCertificates))];
337 | [coder encodeBool:self.validatesDomainName forKey:NSStringFromSelector(@selector(validatesDomainName))];
338 | [coder encodeObject:self.pinnedCertificates forKey:NSStringFromSelector(@selector(pinnedCertificates))];
339 | }
340 |
341 | #pragma mark - NSCopying
342 |
343 | - (instancetype)copyWithZone:(NSZone *)zone {
344 | AFSecurityPolicy *securityPolicy = [[[self class] allocWithZone:zone] init];
345 | securityPolicy.SSLPinningMode = self.SSLPinningMode;
346 | securityPolicy.allowInvalidCertificates = self.allowInvalidCertificates;
347 | securityPolicy.validatesDomainName = self.validatesDomainName;
348 | securityPolicy.pinnedCertificates = [self.pinnedCertificates copyWithZone:zone];
349 |
350 | return securityPolicy;
351 | }
352 |
353 | @end
354 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/TYJSONModel/NSObject+TYJSONModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+TYJSONModel.m
3 | // TYJSONModelDemo
4 | //
5 | // Created by tany on 16/4/6.
6 | // Copyright © 2016年 tany. All rights reserved.
7 | //
8 |
9 | #import "NSObject+TYJSONModel.h"
10 | #import "TYClassInfo.h"
11 | #import
12 |
13 |
14 | @implementation NSObject (TYJSONModel)
15 |
16 | #pragma mark - json to model
17 |
18 | + (instancetype)ty_ModelWithJSON:(id)json
19 | {
20 | if (!json) {
21 | return nil;
22 | }
23 |
24 | NSDictionary *dic = nil;
25 | NSData *jsonData = nil;
26 | if ([json isKindOfClass:[NSDictionary class]]) {
27 | dic = json;
28 | } else if ([json isKindOfClass:[NSString class]]) {
29 | jsonData = [(NSString *)json dataUsingEncoding : NSUTF8StringEncoding];
30 | } else if ([json isKindOfClass:[NSData class]]) {
31 | jsonData = json;
32 | }
33 | if (jsonData) {
34 | // data to json
35 | dic = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:NULL];
36 | if (![dic isKindOfClass:[NSDictionary class]])
37 | dic = nil;
38 | }
39 |
40 | return [self ty_ModelWithDictonary:dic];
41 | }
42 |
43 | // dictonary to model
44 | + (instancetype)ty_ModelWithDictonary:(NSDictionary *)dic
45 | {
46 | if (!dic) {
47 | return nil;
48 | }
49 |
50 | NSObject *model = [[[self class]alloc]init];
51 |
52 | // dictonary to model
53 | [model ty_SetModelWithDictonary:dic];
54 |
55 | return model;
56 | }
57 |
58 | // dictonary to model
59 | - (void)ty_SetModelWithDictonary:(NSDictionary *)dic
60 | {
61 | if (!dic || ![dic isKindOfClass:[NSDictionary class]] || dic.count == 0) {
62 | return;
63 | }
64 |
65 | // 获取 当前类信息
66 | TYClassInfo *classInfo = [[TYClassInfo alloc]initWithClass:object_getClass(self)];
67 |
68 | // model in array or dictonary 映射
69 | NSDictionary *modelClassDic = nil;
70 | if ([[self class] respondsToSelector:@selector(modelClassInArrayOrDictonary)]) {
71 | modelClassDic = [[self class] modelClassInArrayOrDictonary];
72 | }
73 |
74 | // 属性 映射
75 | NSDictionary *propertyMapper = nil;
76 | if ([[self class] respondsToSelector:@selector(modelPropertyMapper)]) {
77 | propertyMapper = [[self class] modelPropertyMapper];
78 | }
79 |
80 | // 忽略 某些属性
81 | NSArray *ignoreProperties = nil;
82 | if ([[self class] respondsToSelector:@selector(ignoreModelProperties)]) {
83 | ignoreProperties = [[self class] ignoreModelProperties];
84 | }
85 |
86 | // 遍历当前类所有属性
87 | [classInfo.propertyInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, TYPropertyInfo *propertyInfo, BOOL * stop) {
88 |
89 | BOOL isIgnoreProperty = NO;
90 | id value = nil;
91 |
92 | if (ignoreProperties) {
93 | // 是否忽略这个属性
94 | isIgnoreProperty = [ignoreProperties containsObject:key];
95 | }
96 |
97 | if (!isIgnoreProperty) {
98 | NSString *maperKey = nil; //映射key
99 | if (propertyMapper) {
100 | maperKey = [propertyMapper objectForKey:key];
101 | }
102 |
103 | // 根据属性名key 获取 字典里的value
104 | value = [dic objectForKey:maperKey ? maperKey : key];
105 | }
106 |
107 | if (!isIgnoreProperty && value) {
108 | // 如果value有值
109 | if ([value isKindOfClass:[NSArray class]]) {
110 | // 校验 property 是否 数组类型
111 | if ([propertyInfo.typeClass isSubclassOfClass:[NSArray class]]) {
112 | Class class = nil;
113 | if (modelClassDic) {
114 | // 数组里是否包含模型
115 | class = [modelClassDic objectForKey:key];
116 | }
117 | if (class) {
118 | // 包含 就调用数组的 转模型方法
119 | value = [(NSArray *)value ty_ModelArrayWithClass:class];
120 | }
121 | }else {
122 | // property 不是数组类型 返回数据有误
123 | value = nil;
124 | }
125 | }else if([value isKindOfClass:[NSDictionary class]]){
126 | // property 是否是自定义模型
127 | if (propertyInfo.isCustomFondation) {
128 | // 字典 对应模型
129 | value = [propertyInfo.typeClass ty_ModelWithDictonary:value];
130 | }else if ([propertyInfo.typeClass isSubclassOfClass:[NSDictionary class]]) {
131 | // property 是 字典类型
132 | if (modelClassDic) {
133 | // 字典 里 是否包含模型
134 | Class class = [modelClassDic objectForKey:key];
135 | if (class) {
136 | // 包含 就调用字典的 转模型方法
137 | value = [(NSDictionary *)value ty_ModelDictionaryWithClass:class];
138 | }
139 | }
140 | }else {
141 | // property 不是 字典类型 返回数据有误
142 | value = nil;
143 | }
144 | }
145 |
146 | if ([value isEqual:[NSNull null]]) {
147 | // 去除 null
148 | value = nil;
149 | }
150 |
151 | if (propertyInfo.typeClass) {
152 | // 对象类型
153 | if ([propertyInfo.typeClass isSubclassOfClass:[NSString class]] && [value isKindOfClass:[NSNumber class]]) {
154 | // number 转 string
155 | value = [(NSNumber *)value stringValue];
156 | }else if (propertyInfo.typeClass == [NSValue class] || propertyInfo.typeClass == [NSDate class]) {
157 | // 不支持类型
158 | value = nil;
159 | }
160 | // 调用生成的 setter 方法 设置值
161 | [self setPropertyWithModel:self value:value setter:propertyInfo.setter];
162 | }else if(value) {
163 | // 基本类型
164 | if ([value isKindOfClass:[NSString class]]) {
165 | static NSNumberFormatter *s_numberFormatter;
166 | static dispatch_once_t onceToken;
167 | dispatch_once(&onceToken, ^{
168 | // NSString 转 NSNumber Formatter
169 | s_numberFormatter = [[NSNumberFormatter alloc]init];
170 | });
171 | // string 转 number
172 | value = [s_numberFormatter numberFromString:value];
173 | }
174 | // kvc 设置基本类型的值
175 | [self setValue:value forKey:key];
176 | }
177 | }
178 | }];
179 | }
180 |
181 | // model to dictonary
182 | - (NSDictionary *)ty_ModelToDictonary
183 | {
184 | if ([self isKindOfClass:[NSArray class]]) {
185 | return nil;
186 | }
187 |
188 | // 属性 映射
189 | NSDictionary *propertyMapper = nil;
190 | if ([[self class] respondsToSelector:@selector(modelPropertyMapper)]) {
191 | propertyMapper = [[self class] modelPropertyMapper];
192 | }
193 |
194 | // 忽略 某些属性
195 | NSArray *ignoreProperties = nil;
196 | if ([[self class] respondsToSelector:@selector(ignoreModelProperties)]) {
197 | ignoreProperties = [[self class] ignoreModelProperties];
198 | }
199 |
200 | // 获取 当前类信息
201 | TYClassInfo *classInfo = [[TYClassInfo alloc]initWithClass:object_getClass(self)];
202 | // 字典
203 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:classInfo.propertyInfo.count];
204 |
205 | [classInfo.propertyInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, TYPropertyInfo *propertyInfo, BOOL * stop) {
206 |
207 | BOOL isIgnoreProperty = NO;
208 | id value = nil;
209 |
210 | if (ignoreProperties) {
211 | // 是否忽略这个属性
212 | isIgnoreProperty = [ignoreProperties containsObject:key];
213 | }
214 |
215 | if (!isIgnoreProperty) {
216 | if (propertyInfo.typeClass) {
217 | // 对象类型 调用生成的 getter 方法 获取值
218 | value = [self propertyValueWithModel:self getter:propertyInfo.getter];
219 | }else {
220 | // 基本类型 使用kvc 获取值
221 | value = [self valueForKey:key];
222 | }
223 | }
224 |
225 | if (!isIgnoreProperty && value) {
226 | // 如果有值
227 | if ([value isKindOfClass:[NSArray class]]) {
228 | // 如果值是数组(可能包含模型) 调用model数组转dic数组方法
229 | value = [(NSArray *)value ty_ModelArrayToDicArray];
230 | }else if ([value isKindOfClass:[NSDictionary class]]) {
231 | // 如果值是字典(可能包含模型) 调用字典 model转dic方法
232 | value = [(NSDictionary *)value ty_ModelDictionaryToDictionary];
233 | }else if (propertyInfo.typeClass && propertyInfo.isCustomFondation) {
234 | value = [value ty_ModelToDictonary];
235 | }
236 |
237 | if (value) {
238 | NSString *maperKey = nil;
239 | if (propertyMapper) {
240 | //映射key
241 | maperKey = [propertyMapper objectForKey:key];
242 | }
243 | // 添加到字典
244 | dic[maperKey ? maperKey : key] = value;
245 | }
246 |
247 | }
248 |
249 | }];
250 |
251 | return [dic copy];
252 | }
253 |
254 | // dic array to model array
255 | + (NSArray *)ty_modelArrayWithDictionaryArray:(NSArray *)dicArray
256 | {
257 | return [dicArray ty_ModelArrayWithClass:[self class]];
258 | }
259 |
260 | #pragma mark - model to json
261 | // model to json
262 | - (id)ty_ModelToJSONObject
263 | {
264 | if ([self isKindOfClass:[NSArray class]]) {
265 | // 如果是数组
266 | return [(NSArray *)self ty_ModelArrayToDicArray];
267 | }
268 |
269 | return [self ty_ModelToDictonary];
270 | }
271 |
272 | - (NSData *)ty_ModelToJSONData
273 | {
274 | id jsonObject = [self ty_ModelToJSONObject];
275 | if (!jsonObject) return nil;
276 | return [NSJSONSerialization dataWithJSONObject:jsonObject options:0 error:NULL];
277 | }
278 |
279 | - (NSString *)ty_ModelToJSONString
280 | {
281 | NSData *jsonData = [self ty_ModelToJSONData];
282 | if (jsonData.length == 0) return nil;
283 | return [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
284 | }
285 |
286 | // model array to dic array
287 | + (NSArray *)ty_dictionaryArrayWithModelArray:(NSArray *)dicArray
288 | {
289 | return [dicArray ty_ModelArrayToDicArray];
290 | }
291 |
292 | #pragma mark - encode decode
293 | // encode
294 | - (void)ty_EncodeWithCoder:(NSCoder *)aCoder
295 | {
296 | TYClassInfo *classInfo = [[TYClassInfo alloc]initWithClass:object_getClass(self)];
297 |
298 | [classInfo.propertyInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, TYPropertyInfo *propertyInfo, BOOL * stop) {
299 |
300 | id value = nil;
301 |
302 | if (propertyInfo.typeClass) {
303 | value = [self propertyValueWithModel:self getter:propertyInfo.getter];
304 |
305 | }else {
306 | value = [self valueForKey:key];
307 | }
308 |
309 | if (value) {
310 | [aCoder encodeObject:value forKey:key];
311 | }
312 | }];
313 | }
314 |
315 | // decode
316 | - (instancetype)ty_InitWithCoder:(NSCoder *)aDecoder
317 | {
318 | if ([self init]) {
319 | TYClassInfo *classInfo = [[TYClassInfo alloc]initWithClass:object_getClass(self)];
320 |
321 | [classInfo.propertyInfo enumerateKeysAndObjectsUsingBlock:^(NSString *key, TYPropertyInfo *propertyInfo, BOOL * stop) {
322 |
323 | id value = [aDecoder decodeObjectForKey:key];
324 |
325 | if (value) {
326 | if (propertyInfo.typeClass) {
327 | [self setPropertyWithModel:self value:value setter:propertyInfo.setter];
328 | }else {
329 | [self setValue:value forKey:key];
330 | }
331 | }
332 | }];
333 | }
334 | return self;
335 | }
336 |
337 | #pragma mark - set get Property
338 |
339 | // set Property
340 | - (void)setPropertyWithModel:(id)model value:(id)value setter:(SEL)setter
341 | {
342 | if (!setter) {
343 | return;
344 | }
345 | ((void (*)(id, SEL, id))(void *) objc_msgSend)((id)model, setter, value);
346 | }
347 |
348 | // get Property
349 | - (id)propertyValueWithModel:(id)model getter:(SEL)getter
350 | {
351 | if (!getter) {
352 | return nil;
353 | }
354 | return ((id (*)(id, SEL))(void *) objc_msgSend)((id)model,getter);
355 | }
356 |
357 | @end
358 |
359 | @implementation NSArray (TYJSONModel)
360 |
361 | // 数组 to model 数组
362 | - (NSArray *)ty_ModelArrayWithClass:(Class)class
363 | {
364 | if (!class) {
365 | return self;
366 | }
367 | NSMutableArray *modelArray = [NSMutableArray array];
368 | // 遍历数组
369 | for (id value in self) {
370 |
371 | if ([value isKindOfClass:[NSDictionary class]]) {
372 | // value是字典 则 字典转模型
373 | NSObject *obj = [class ty_ModelWithDictonary:value];
374 | if (obj) {
375 | [modelArray addObject:obj];
376 | }
377 | }else if ([value isKindOfClass:[NSString class]]) {
378 | // value 是 NSString
379 | [modelArray addObject:value];
380 | }
381 | }
382 | return [modelArray copy];
383 | }
384 |
385 | // model 数组 to 数组
386 | - (NSArray *)ty_ModelArrayToDicArray
387 | {
388 | NSMutableArray *array = [NSMutableArray arrayWithCapacity:self.count];
389 | // 遍历数组
390 | for (id obj in self) {
391 | if (![TYPropertyInfo isClassFromFoundation:[obj class]]) {
392 | // obj 是 model 则 model 转 字典
393 | NSDictionary *dic = [obj ty_ModelToDictonary];
394 | if (dic) {
395 | [array addObject:dic];
396 | }
397 | }else {
398 | [array addObject:obj];
399 | }
400 | }
401 | return [array copy];
402 | }
403 |
404 | @end
405 |
406 | @implementation NSDictionary (TYJSONModel)
407 |
408 | // 字典 to model 字典
409 | - (NSDictionary *)ty_ModelDictionaryWithClass:(Class)class
410 | {
411 | if (!class) {
412 | return self;
413 | }
414 |
415 | NSMutableDictionary *dic = [NSMutableDictionary dictionary];
416 | // 遍历字典
417 | [self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL * stop) {
418 | if ([key isKindOfClass:[NSString class]]) {
419 | // 字典包含 obj字典 转 model
420 | NSObject *value = [class ty_ModelWithDictonary:obj];
421 | if (value) {
422 | dic[key] = value;
423 | }
424 | }
425 | }];
426 | return [dic copy];
427 |
428 | }
429 |
430 | // model 字典 to 字典
431 | - (NSDictionary *)ty_ModelDictionaryToDictionary
432 | {
433 | NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:self.count];
434 | // 遍历字典
435 | [self enumerateKeysAndObjectsUsingBlock:^(NSString *key, id obj, BOOL * stop) {
436 | if (![TYPropertyInfo isClassFromFoundation:[obj class]]) {
437 | // obj 是 模型 则 model to dic
438 | NSDictionary *objDic = [obj ty_ModelToDictonary];
439 | if (objDic) {
440 | dic[key] = objDic;
441 | }
442 | }else {
443 | dic[key] = obj;
444 | }
445 | }];
446 | return [dic copy];
447 | }
448 |
449 | @end
450 |
451 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFHTTPSessionManager.m:
--------------------------------------------------------------------------------
1 | // AFHTTPSessionManager.m
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import "AFHTTPSessionManager.h"
23 |
24 | #import "AFURLRequestSerialization.h"
25 | #import "AFURLResponseSerialization.h"
26 |
27 | #import
28 | #import
29 | #import
30 |
31 | #import
32 | #import
33 | #import
34 | #import
35 | #import
36 |
37 | #if TARGET_OS_IOS || TARGET_OS_TV
38 | #import
39 | #elif TARGET_OS_WATCH
40 | #import
41 | #endif
42 |
43 | @interface AFHTTPSessionManager ()
44 | @property (readwrite, nonatomic, strong) NSURL *baseURL;
45 | @end
46 |
47 | @implementation AFHTTPSessionManager
48 | @dynamic responseSerializer;
49 |
50 | + (instancetype)manager {
51 | return [[[self class] alloc] initWithBaseURL:nil];
52 | }
53 |
54 | - (instancetype)init {
55 | return [self initWithBaseURL:nil];
56 | }
57 |
58 | - (instancetype)initWithBaseURL:(NSURL *)url {
59 | return [self initWithBaseURL:url sessionConfiguration:nil];
60 | }
61 |
62 | - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration {
63 | return [self initWithBaseURL:nil sessionConfiguration:configuration];
64 | }
65 |
66 | - (instancetype)initWithBaseURL:(NSURL *)url
67 | sessionConfiguration:(NSURLSessionConfiguration *)configuration
68 | {
69 | self = [super initWithSessionConfiguration:configuration];
70 | if (!self) {
71 | return nil;
72 | }
73 |
74 | // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected
75 | if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
76 | url = [url URLByAppendingPathComponent:@""];
77 | }
78 |
79 | self.baseURL = url;
80 |
81 | self.requestSerializer = [AFHTTPRequestSerializer serializer];
82 | self.responseSerializer = [AFJSONResponseSerializer serializer];
83 |
84 | return self;
85 | }
86 |
87 | #pragma mark -
88 |
89 | - (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer {
90 | NSParameterAssert(requestSerializer);
91 |
92 | _requestSerializer = requestSerializer;
93 | }
94 |
95 | - (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer {
96 | NSParameterAssert(responseSerializer);
97 |
98 | [super setResponseSerializer:responseSerializer];
99 | }
100 |
101 | #pragma mark -
102 |
103 | - (NSURLSessionDataTask *)GET:(NSString *)URLString
104 | parameters:(id)parameters
105 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
106 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
107 | {
108 |
109 | return [self GET:URLString parameters:parameters progress:nil success:success failure:failure];
110 | }
111 |
112 | - (NSURLSessionDataTask *)GET:(NSString *)URLString
113 | parameters:(id)parameters
114 | progress:(void (^)(NSProgress * _Nonnull))downloadProgress
115 | success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
116 | failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
117 | {
118 |
119 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
120 | URLString:URLString
121 | parameters:parameters
122 | uploadProgress:nil
123 | downloadProgress:downloadProgress
124 | success:success
125 | failure:failure];
126 |
127 | [dataTask resume];
128 |
129 | return dataTask;
130 | }
131 |
132 | - (NSURLSessionDataTask *)HEAD:(NSString *)URLString
133 | parameters:(id)parameters
134 | success:(void (^)(NSURLSessionDataTask *task))success
135 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
136 | {
137 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:^(NSURLSessionDataTask *task, __unused id responseObject) {
138 | if (success) {
139 | success(task);
140 | }
141 | } failure:failure];
142 |
143 | [dataTask resume];
144 |
145 | return dataTask;
146 | }
147 |
148 | - (NSURLSessionDataTask *)POST:(NSString *)URLString
149 | parameters:(id)parameters
150 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
151 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
152 | {
153 | return [self POST:URLString parameters:parameters progress:nil success:success failure:failure];
154 | }
155 |
156 | - (NSURLSessionDataTask *)POST:(NSString *)URLString
157 | parameters:(id)parameters
158 | progress:(void (^)(NSProgress * _Nonnull))uploadProgress
159 | success:(void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
160 | failure:(void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
161 | {
162 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters uploadProgress:uploadProgress downloadProgress:nil success:success failure:failure];
163 |
164 | [dataTask resume];
165 |
166 | return dataTask;
167 | }
168 |
169 | - (NSURLSessionDataTask *)POST:(NSString *)URLString
170 | parameters:(nullable id)parameters
171 | constructingBodyWithBlock:(nullable void (^)(id _Nonnull))block
172 | success:(nullable void (^)(NSURLSessionDataTask * _Nonnull, id _Nullable))success
173 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable, NSError * _Nonnull))failure
174 | {
175 | return [self POST:URLString parameters:parameters constructingBodyWithBlock:block progress:nil success:success failure:failure];
176 | }
177 |
178 | - (NSURLSessionDataTask *)POST:(NSString *)URLString
179 | parameters:(id)parameters
180 | constructingBodyWithBlock:(void (^)(id formData))block
181 | progress:(nullable void (^)(NSProgress * _Nonnull))uploadProgress
182 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
183 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
184 | {
185 | NSError *serializationError = nil;
186 | NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError];
187 | if (serializationError) {
188 | if (failure) {
189 | dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
190 | failure(nil, serializationError);
191 | });
192 | }
193 |
194 | return nil;
195 | }
196 |
197 | __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:uploadProgress completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
198 | if (error) {
199 | if (failure) {
200 | failure(task, error);
201 | }
202 | } else {
203 | if (success) {
204 | success(task, responseObject);
205 | }
206 | }
207 | }];
208 |
209 | [task resume];
210 |
211 | return task;
212 | }
213 |
214 | - (NSURLSessionDataTask *)PUT:(NSString *)URLString
215 | parameters:(id)parameters
216 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
217 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
218 | {
219 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
220 |
221 | [dataTask resume];
222 |
223 | return dataTask;
224 | }
225 |
226 | - (NSURLSessionDataTask *)PATCH:(NSString *)URLString
227 | parameters:(id)parameters
228 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
229 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
230 | {
231 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
232 |
233 | [dataTask resume];
234 |
235 | return dataTask;
236 | }
237 |
238 | - (NSURLSessionDataTask *)DELETE:(NSString *)URLString
239 | parameters:(id)parameters
240 | success:(void (^)(NSURLSessionDataTask *task, id responseObject))success
241 | failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure
242 | {
243 | NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters uploadProgress:nil downloadProgress:nil success:success failure:failure];
244 |
245 | [dataTask resume];
246 |
247 | return dataTask;
248 | }
249 |
250 | - (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
251 | URLString:(NSString *)URLString
252 | parameters:(id)parameters
253 | uploadProgress:(nullable void (^)(NSProgress *uploadProgress)) uploadProgress
254 | downloadProgress:(nullable void (^)(NSProgress *downloadProgress)) downloadProgress
255 | success:(void (^)(NSURLSessionDataTask *, id))success
256 | failure:(void (^)(NSURLSessionDataTask *, NSError *))failure
257 | {
258 | NSError *serializationError = nil;
259 | NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
260 | if (serializationError) {
261 | if (failure) {
262 | dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
263 | failure(nil, serializationError);
264 | });
265 | }
266 |
267 | return nil;
268 | }
269 |
270 | __block NSURLSessionDataTask *dataTask = nil;
271 | dataTask = [self dataTaskWithRequest:request
272 | uploadProgress:uploadProgress
273 | downloadProgress:downloadProgress
274 | completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) {
275 | if (error) {
276 | if (failure) {
277 | failure(dataTask, error);
278 | }
279 | } else {
280 | if (success) {
281 | success(dataTask, responseObject);
282 | }
283 | }
284 | }];
285 |
286 | return dataTask;
287 | }
288 |
289 | #pragma mark - NSObject
290 |
291 | - (NSString *)description {
292 | return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue];
293 | }
294 |
295 | #pragma mark - NSSecureCoding
296 |
297 | + (BOOL)supportsSecureCoding {
298 | return YES;
299 | }
300 |
301 | - (instancetype)initWithCoder:(NSCoder *)decoder {
302 | NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))];
303 | NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"];
304 | if (!configuration) {
305 | NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"identifier"];
306 | if (configurationIdentifier) {
307 | #if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100)
308 | configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier];
309 | #else
310 | configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier];
311 | #endif
312 | }
313 | }
314 |
315 | self = [self initWithBaseURL:baseURL sessionConfiguration:configuration];
316 | if (!self) {
317 | return nil;
318 | }
319 |
320 | self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))];
321 | self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))];
322 | AFSecurityPolicy *decodedPolicy = [decoder decodeObjectOfClass:[AFSecurityPolicy class] forKey:NSStringFromSelector(@selector(securityPolicy))];
323 | if (decodedPolicy) {
324 | self.securityPolicy = decodedPolicy;
325 | }
326 |
327 | return self;
328 | }
329 |
330 | - (void)encodeWithCoder:(NSCoder *)coder {
331 | [super encodeWithCoder:coder];
332 |
333 | [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))];
334 | if ([self.session.configuration conformsToProtocol:@protocol(NSCoding)]) {
335 | [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"];
336 | } else {
337 | [coder encodeObject:self.session.configuration.identifier forKey:@"identifier"];
338 | }
339 | [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))];
340 | [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))];
341 | [coder encodeObject:self.securityPolicy forKey:NSStringFromSelector(@selector(securityPolicy))];
342 | }
343 |
344 | #pragma mark - NSCopying
345 |
346 | - (instancetype)copyWithZone:(NSZone *)zone {
347 | AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration];
348 |
349 | HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone];
350 | HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone];
351 | HTTPClient.securityPolicy = [self.securityPolicy copyWithZone:zone];
352 | return HTTPClient;
353 | }
354 |
355 | @end
356 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/MBProgressHUD/MBProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // MBProgressHUD.h
3 | // Version 0.9.2
4 | // Created by Matej Bukovinski on 2.4.09.
5 | //
6 |
7 | // This code is distributed under the terms and conditions of the MIT license.
8 |
9 | // Copyright (c) 2009-2015 Matej Bukovinski
10 | //
11 | // Permission is hereby granted, free of charge, to any person obtaining a copy
12 | // of this software and associated documentation files (the "Software"), to deal
13 | // in the Software without restriction, including without limitation the rights
14 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15 | // copies of the Software, and to permit persons to whom the Software is
16 | // furnished to do so, subject to the following conditions:
17 | //
18 | // The above copyright notice and this permission notice shall be included in
19 | // all copies or substantial portions of the Software.
20 | //
21 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27 | // THE SOFTWARE.
28 |
29 | #import
30 | #import
31 | #import
32 |
33 | @class MBBackgroundView;
34 | @protocol MBProgressHUDDelegate;
35 |
36 |
37 | extern CGFloat const MBProgressMaxOffset;
38 |
39 | typedef NS_ENUM(NSInteger, MBProgressHUDMode) {
40 | /// UIActivityIndicatorView.
41 | MBProgressHUDModeIndeterminate,
42 | /// A round, pie-chart like, progress view.
43 | MBProgressHUDModeDeterminate,
44 | /// Horizontal progress bar.
45 | MBProgressHUDModeDeterminateHorizontalBar,
46 | /// Ring-shaped progress view.
47 | MBProgressHUDModeAnnularDeterminate,
48 | /// Shows a custom view.
49 | MBProgressHUDModeCustomView,
50 | /// Shows only labels.
51 | MBProgressHUDModeText
52 | };
53 |
54 | typedef NS_ENUM(NSInteger, MBProgressHUDAnimation) {
55 | /// Opacity animation
56 | MBProgressHUDAnimationFade,
57 | /// Opacity + scale animation (zoom in when appearing zoom out when disappearing)
58 | MBProgressHUDAnimationZoom,
59 | /// Opacity + scale animation (zoom out style)
60 | MBProgressHUDAnimationZoomOut,
61 | /// Opacity + scale animation (zoom in style)
62 | MBProgressHUDAnimationZoomIn
63 | };
64 |
65 | typedef NS_ENUM(NSInteger, MBProgressHUDBackgroundStyle) {
66 | /// Solid color background
67 | MBProgressHUDBackgroundStyleSolidColor,
68 | /// UIVisualEffectView or UIToolbar.layer background view
69 | MBProgressHUDBackgroundStyleBlur
70 | };
71 |
72 |
73 | NS_ASSUME_NONNULL_BEGIN
74 |
75 |
76 | /**
77 | * Displays a simple HUD window containing a progress indicator and two optional labels for short messages.
78 | *
79 | * This is a simple drop-in class for displaying a progress HUD view similar to Apple's private UIProgressHUD class.
80 | * The MBProgressHUD window spans over the entire space given to it by the initWithFrame: constructor and catches all
81 | * user input on this region, thereby preventing the user operations on components below the view.
82 | *
83 | * @note To still allow touches to pass through the HUD, you can set hud.userInteractionEnabled = NO.
84 | * @attention MBProgressHUD is a UI class and should therefore only be accessed on the main thread.
85 | */
86 | @interface MBProgressHUD : UIView
87 |
88 | /**
89 | * Creates a new HUD, adds it to provided view and shows it. The counterpart to this method is hideHUDForView:animated:.
90 | *
91 | * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden.
92 | *
93 | * @param view The view that the HUD will be added to
94 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
95 | * animations while appearing.
96 | * @return A reference to the created HUD.
97 | *
98 | * @see hideHUDForView:animated:
99 | * @see animationType
100 | */
101 | + (instancetype)showHUDAddedTo:(UIView *)view animated:(BOOL)animated;
102 |
103 | /// @name Showing and hiding
104 |
105 | /**
106 | * Finds the top-most HUD subview and hides it. The counterpart to this method is showHUDAddedTo:animated:.
107 | *
108 | * @note This method sets removeFromSuperViewOnHide. The HUD will automatically be removed from the view hierarchy when hidden.
109 | *
110 | * @param view The view that is going to be searched for a HUD subview.
111 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
112 | * animations while disappearing.
113 | * @return YES if a HUD was found and removed, NO otherwise.
114 | *
115 | * @see showHUDAddedTo:animated:
116 | * @see animationType
117 | */
118 | + (BOOL)hideHUDForView:(UIView *)view animated:(BOOL)animated;
119 |
120 | /**
121 | * Finds the top-most HUD subview and returns it.
122 | *
123 | * @param view The view that is going to be searched.
124 | * @return A reference to the last HUD subview discovered.
125 | */
126 | + (nullable MBProgressHUD *)HUDForView:(UIView *)view;
127 |
128 | /**
129 | * A convenience constructor that initializes the HUD with the view's bounds. Calls the designated constructor with
130 | * view.bounds as the parameter.
131 | *
132 | * @param view The view instance that will provide the bounds for the HUD. Should be the same instance as
133 | * the HUD's superview (i.e., the view that the HUD will be added to).
134 | */
135 | - (instancetype)initWithView:(UIView *)view;
136 |
137 | /**
138 | * Displays the HUD.
139 | *
140 | * @note You need to make sure that the main thread completes its run loop soon after this method call so that
141 | * the user interface can be updated. Call this method when your task is already set up to be executed in a new thread
142 | * (e.g., when using something like NSOperation or making an asynchronous call like NSURLRequest).
143 | *
144 | * @param animated If set to YES the HUD will appear using the current animationType. If set to NO the HUD will not use
145 | * animations while appearing.
146 | *
147 | * @see animationType
148 | */
149 | - (void)showAnimated:(BOOL)animated;
150 |
151 | /**
152 | * Hides the HUD. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
153 | * hide the HUD when your task completes.
154 | *
155 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
156 | * animations while disappearing.
157 | *
158 | * @see animationType
159 | */
160 | - (void)hideAnimated:(BOOL)animated;
161 |
162 | /**
163 | * Hides the HUD after a delay. This still calls the hudWasHidden: delegate. This is the counterpart of the show: method. Use it to
164 | * hide the HUD when your task completes.
165 | *
166 | * @param animated If set to YES the HUD will disappear using the current animationType. If set to NO the HUD will not use
167 | * animations while disappearing.
168 | * @param delay Delay in seconds until the HUD is hidden.
169 | *
170 | * @see animationType
171 | */
172 | - (void)hideAnimated:(BOOL)animated afterDelay:(NSTimeInterval)delay;
173 |
174 | /**
175 | * The HUD delegate object. Receives HUD state notifications.
176 | */
177 | @property (weak, nonatomic) id delegate;
178 |
179 | /*
180 | * Grace period is the time (in seconds) that the invoked method may be run without
181 | * showing the HUD. If the task finishes before the grace time runs out, the HUD will
182 | * not be shown at all.
183 | * This may be used to prevent HUD display for very short tasks.
184 | * Defaults to 0 (no grace time).
185 | */
186 | @property (assign, nonatomic) NSTimeInterval graceTime;
187 |
188 | /**
189 | * The minimum time (in seconds) that the HUD is shown.
190 | * This avoids the problem of the HUD being shown and than instantly hidden.
191 | * Defaults to 0 (no minimum show time).
192 | */
193 | @property (assign, nonatomic) NSTimeInterval minShowTime;
194 |
195 | /**
196 | * Removes the HUD from its parent view when hidden.
197 | * Defaults to NO.
198 | */
199 | @property (assign, nonatomic) BOOL removeFromSuperViewOnHide;
200 |
201 | /// @name Appearance
202 |
203 | /**
204 | * MBProgressHUD operation mode. The default is MBProgressHUDModeIndeterminate.
205 | */
206 | @property (assign, nonatomic) MBProgressHUDMode mode;
207 |
208 | /**
209 | * A color that gets forwarded to all labels and supported indicators. Also sets the tintColor
210 | * for custom views on iOS 7+. Set to nil to manage color individually.
211 | * Defaults to semi-translucent black on iOS 7 and later and white on earlier iOS versions.
212 | */
213 | @property (strong, nonatomic, nullable) UIColor *contentColor UI_APPEARANCE_SELECTOR;
214 |
215 | /**
216 | * The animation type that should be used when the HUD is shown and hidden.
217 | */
218 | @property (assign, nonatomic) MBProgressHUDAnimation animationType UI_APPEARANCE_SELECTOR;
219 |
220 | /**
221 | * The bezel offset relative to the center of the view. You can use MBProgressMaxOffset
222 | * and -MBProgressMaxOffset to move the HUD all the way to the screen edge in each direction.
223 | * E.g., CGPointMake(0.f, MBProgressMaxOffset) would position the HUD centered on the bottom edge.
224 | */
225 | @property (assign, nonatomic) CGPoint offset UI_APPEARANCE_SELECTOR;
226 |
227 | /**
228 | * The amount of space between the HUD edge and the HUD elements (labels, indicators or custom views).
229 | * This also represents the minimum bezel distance to the edge of the HUD view.
230 | * Defaults to 20.f
231 | */
232 | @property (assign, nonatomic) CGFloat margin UI_APPEARANCE_SELECTOR;
233 |
234 | /**
235 | * The minimum size of the HUD bezel. Defaults to CGSizeZero (no minimum size).
236 | */
237 | @property (assign, nonatomic) CGSize minSize UI_APPEARANCE_SELECTOR;
238 |
239 | /**
240 | * Force the HUD dimensions to be equal if possible.
241 | */
242 | @property (assign, nonatomic, getter = isSquare) BOOL square UI_APPEARANCE_SELECTOR;
243 |
244 | /**
245 | * When enabled, the bezel center gets slightly affected by the device accelerometer data.
246 | * Has no effect on iOS < 7.0. Defaults to YES.
247 | */
248 | @property (assign, nonatomic, getter=areDefaultMotionEffectsEnabled) BOOL defaultMotionEffectsEnabled UI_APPEARANCE_SELECTOR;
249 |
250 | /// @name Progress
251 |
252 | /**
253 | * The progress of the progress indicator, from 0.0 to 1.0. Defaults to 0.0.
254 | */
255 | @property (assign, nonatomic) float progress;
256 |
257 | /// @name Views
258 |
259 | /**
260 | * The view containing the labels and indicator (or customView).
261 | */
262 | @property (strong, nonatomic, readonly) MBBackgroundView *bezelView;
263 |
264 | /**
265 | * View covering the entire HUD area, placed behind bezelView.
266 | */
267 | @property (strong, nonatomic, readonly) MBBackgroundView *backgroundView;
268 |
269 | /**
270 | * The UIView (e.g., a UIImageView) to be shown when the HUD is in MBProgressHUDModeCustomView.
271 | * The view should implement intrinsicContentSize for proper sizing. For best results use approximately 37 by 37 pixels.
272 | */
273 | @property (strong, nonatomic, nullable) UIView *customView;
274 |
275 | /**
276 | * A label that holds an optional short message to be displayed below the activity indicator. The HUD is automatically resized to fit
277 | * the entire text.
278 | */
279 | @property (strong, nonatomic, readonly) UILabel *label;
280 |
281 | /**
282 | * A label that holds an optional details message displayed below the labelText message. The details text can span multiple lines.
283 | */
284 | @property (strong, nonatomic, readonly) UILabel *detailsLabel;
285 |
286 | /**
287 | * A button that is placed below the labels. Visible only if a target / action is added.
288 | */
289 | @property (strong, nonatomic, readonly) UIButton *button;
290 |
291 | @end
292 |
293 |
294 | @protocol MBProgressHUDDelegate
295 |
296 | @optional
297 |
298 | /**
299 | * Called after the HUD was fully hidden from the screen.
300 | */
301 | - (void)hudWasHidden:(MBProgressHUD *)hud;
302 |
303 | @end
304 |
305 |
306 | /**
307 | * A progress view for showing definite progress by filling up a circle (pie chart).
308 | */
309 | @interface MBRoundProgressView : UIView
310 |
311 | /**
312 | * Progress (0.0 to 1.0)
313 | */
314 | @property (nonatomic, assign) float progress;
315 |
316 | /**
317 | * Indicator progress color.
318 | * Defaults to white [UIColor whiteColor].
319 | */
320 | @property (nonatomic, strong) UIColor *progressTintColor;
321 |
322 | /**
323 | * Indicator background (non-progress) color.
324 | * Only applicable on iOS versions older than iOS 7.
325 | * Defaults to translucent white (alpha 0.1).
326 | */
327 | @property (nonatomic, strong) UIColor *backgroundTintColor;
328 |
329 | /*
330 | * Display mode - NO = round or YES = annular. Defaults to round.
331 | */
332 | @property (nonatomic, assign, getter = isAnnular) BOOL annular;
333 |
334 | @end
335 |
336 |
337 | /**
338 | * A flat bar progress view.
339 | */
340 | @interface MBBarProgressView : UIView
341 |
342 | /**
343 | * Progress (0.0 to 1.0)
344 | */
345 | @property (nonatomic, assign) float progress;
346 |
347 | /**
348 | * Bar border line color.
349 | * Defaults to white [UIColor whiteColor].
350 | */
351 | @property (nonatomic, strong) UIColor *lineColor;
352 |
353 | /**
354 | * Bar background color.
355 | * Defaults to clear [UIColor clearColor];
356 | */
357 | @property (nonatomic, strong) UIColor *progressRemainingColor;
358 |
359 | /**
360 | * Bar progress color.
361 | * Defaults to white [UIColor whiteColor].
362 | */
363 | @property (nonatomic, strong) UIColor *progressColor;
364 |
365 | @end
366 |
367 |
368 | @interface MBBackgroundView : UIView
369 |
370 | /**
371 | * The background style.
372 | * Defaults to MBProgressHUDBackgroundStyleBlur on iOS 7 or later and MBProgressHUDBackgroundStyleSolidColor otherwise.
373 | * @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions.
374 | */
375 | @property (nonatomic) MBProgressHUDBackgroundStyle style;
376 |
377 | /**
378 | * The background color or the blur tint color.
379 | * @note Due to iOS 7 not supporting UIVisualEffectView, the blur effect differs slightly between iOS 7 and later versions.
380 | */
381 | @property (nonatomic, strong) UIColor *color;
382 |
383 | @end
384 |
385 | @interface MBProgressHUD (Deprecated)
386 |
387 | + (NSArray *)allHUDsForView:(UIView *)view __attribute__((deprecated("Store references when using more than one HUD per view.")));
388 | + (NSUInteger)hideAllHUDsForView:(UIView *)view animated:(BOOL)animated __attribute__((deprecated("Store references when using more than one HUD per view.")));
389 |
390 | - (id)initWithWindow:(UIWindow *)window __attribute__((deprecated("Use initWithView: instead.")));
391 |
392 | - (void)show:(BOOL)animated __attribute__((deprecated("Use showAnimated: instead.")));
393 | - (void)hide:(BOOL)animated __attribute__((deprecated("Use hideAnimated: instead.")));
394 | - (void)hide:(BOOL)animated afterDelay:(NSTimeInterval)delay __attribute__((deprecated("Use hideAnimated:afterDelay: instead.")));
395 |
396 | typedef void (^MBProgressHUDCompletionBlock)();
397 |
398 | - (void)showWhileExecuting:(SEL)method onTarget:(id)target withObject:(id)object animated:(BOOL)animated __attribute__((deprecated("Use GCD directly.")));
399 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block __attribute__((deprecated("Use GCD directly.")));
400 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly.")));
401 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue __attribute__((deprecated("Use GCD directly.")));
402 | - (void)showAnimated:(BOOL)animated whileExecutingBlock:(dispatch_block_t)block onQueue:(dispatch_queue_t)queue
403 | completionBlock:(nullable MBProgressHUDCompletionBlock)completion __attribute__((deprecated("Use GCD directly.")));
404 | @property (copy, nullable) MBProgressHUDCompletionBlock completionBlock __attribute__((deprecated("Use GCD directly.")));
405 | @property (assign) BOOL taskInProgress __attribute__((deprecated("No longer needed.")));
406 |
407 | @property (nonatomic, copy) NSString *labelText __attribute__((deprecated("Use label.text instead.")));
408 | @property (nonatomic, strong) UIFont *labelFont __attribute__((deprecated("Use label.font instead.")));
409 | @property (nonatomic, strong) UIColor *labelColor __attribute__((deprecated("Use label.textColor instead.")));
410 | @property (nonatomic, copy) NSString *detailsLabelText __attribute__((deprecated("Use detailsLabel.text instead.")));
411 | @property (nonatomic, strong) UIFont *detailsLabelFont __attribute__((deprecated("Use detailsLabel.font instead.")));
412 | @property (nonatomic, strong) UIColor *detailsLabelColor __attribute__((deprecated("Use detailsLabel.textColor instead.")));
413 | @property (assign, nonatomic) CGFloat opacity __attribute__((deprecated("Customize bezelView properties instead.")));
414 | @property (strong, nonatomic) UIColor *color __attribute__((deprecated("Customize the bezelView color instead.")));
415 | @property (assign, nonatomic) CGFloat xOffset __attribute__((deprecated("Set offset.x instead.")));
416 | @property (assign, nonatomic) CGFloat yOffset __attribute__((deprecated("Set offset.y instead.")));
417 | @property (assign, nonatomic) CGFloat cornerRadius __attribute__((deprecated("Set bezelView.layer.cornerRadius instead.")));
418 | @property (assign, nonatomic) BOOL dimBackground __attribute__((deprecated("Customize HUD background properties instead.")));
419 | @property (strong, nonatomic) UIColor *activityIndicatorColor __attribute__((deprecated("Use UIAppearance to customize UIActivityIndicatorView.")));
420 | @property (atomic, assign, readonly) CGSize size __attribute__((deprecated("Get the bezelView.frame.size instead.")));
421 |
422 | @end
423 |
424 | NS_ASSUME_NONNULL_END
425 |
--------------------------------------------------------------------------------
/TYHttpManagerDemo/AFNetworking/AFHTTPSessionManager.h:
--------------------------------------------------------------------------------
1 | // AFHTTPSessionManager.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 | #if !TARGET_OS_WATCH
24 | #import
25 | #endif
26 | #import
27 |
28 | #if TARGET_OS_IOS || TARGET_OS_WATCH || TARGET_OS_TV
29 | #import
30 | #else
31 | #import
32 | #endif
33 |
34 | #import "AFURLSessionManager.h"
35 |
36 | /**
37 | `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths.
38 |
39 | ## Subclassing Notes
40 |
41 | Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application.
42 |
43 | For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect.
44 |
45 | ## Methods to Override
46 |
47 | To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:`.
48 |
49 | ## Serialization
50 |
51 | Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``.
52 |
53 | Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to ``
54 |
55 | ## URL Construction Using Relative Paths
56 |
57 | For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`.
58 |
59 | Below are a few examples of how `baseURL` and relative paths interact:
60 |
61 | NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"];
62 | [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo
63 | [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz
64 | [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo
65 | [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo
66 | [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/
67 | [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/
68 |
69 | Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash.
70 |
71 | @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance.
72 | */
73 |
74 | NS_ASSUME_NONNULL_BEGIN
75 |
76 | @interface AFHTTPSessionManager : AFURLSessionManager
77 |
78 | /**
79 | The URL used to construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods.
80 | */
81 | @property (readonly, nonatomic, strong, nullable) NSURL *baseURL;
82 |
83 | /**
84 | Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies.
85 |
86 | @warning `requestSerializer` must not be `nil`.
87 | */
88 | @property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer;
89 |
90 | /**
91 | Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`.
92 |
93 | @warning `responseSerializer` must not be `nil`.
94 | */
95 | @property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer;
96 |
97 | ///---------------------
98 | /// @name Initialization
99 | ///---------------------
100 |
101 | /**
102 | Creates and returns an `AFHTTPSessionManager` object.
103 | */
104 | + (instancetype)manager;
105 |
106 | /**
107 | Initializes an `AFHTTPSessionManager` object with the specified base URL.
108 |
109 | @param url The base URL for the HTTP client.
110 |
111 | @return The newly-initialized HTTP client
112 | */
113 | - (instancetype)initWithBaseURL:(nullable NSURL *)url;
114 |
115 | /**
116 | Initializes an `AFHTTPSessionManager` object with the specified base URL.
117 |
118 | This is the designated initializer.
119 |
120 | @param url The base URL for the HTTP client.
121 | @param configuration The configuration used to create the managed session.
122 |
123 | @return The newly-initialized HTTP client
124 | */
125 | - (instancetype)initWithBaseURL:(nullable NSURL *)url
126 | sessionConfiguration:(nullable NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER;
127 |
128 | ///---------------------------
129 | /// @name Making HTTP Requests
130 | ///---------------------------
131 |
132 | /**
133 | Creates and runs an `NSURLSessionDataTask` with a `GET` request.
134 |
135 | @param URLString The URL string used to create the request URL.
136 | @param parameters The parameters to be encoded according to the client request serializer.
137 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
138 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
139 |
140 | @see -dataTaskWithRequest:completionHandler:
141 | */
142 | - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
143 | parameters:(nullable id)parameters
144 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
145 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
146 |
147 |
148 | /**
149 | Creates and runs an `NSURLSessionDataTask` with a `GET` request.
150 |
151 | @param URLString The URL string used to create the request URL.
152 | @param parameters The parameters to be encoded according to the client request serializer.
153 | @param downloadProgress A block object to be executed when the download progress is updated. Note this block is called on the session queue, not the main queue.
154 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
155 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
156 |
157 | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
158 | */
159 | - (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
160 | parameters:(nullable id)parameters
161 | progress:(nullable void (^)(NSProgress *downloadProgress))downloadProgress
162 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
163 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
164 |
165 | /**
166 | Creates and runs an `NSURLSessionDataTask` with a `HEAD` request.
167 |
168 | @param URLString The URL string used to create the request URL.
169 | @param parameters The parameters to be encoded according to the client request serializer.
170 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task.
171 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
172 |
173 | @see -dataTaskWithRequest:completionHandler:
174 | */
175 | - (nullable NSURLSessionDataTask *)HEAD:(NSString *)URLString
176 | parameters:(nullable id)parameters
177 | success:(nullable void (^)(NSURLSessionDataTask *task))success
178 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
179 |
180 | /**
181 | Creates and runs an `NSURLSessionDataTask` with a `POST` request.
182 |
183 | @param URLString The URL string used to create the request URL.
184 | @param parameters The parameters to be encoded according to the client request serializer.
185 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
186 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
187 |
188 | @see -dataTaskWithRequest:completionHandler:
189 | */
190 | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
191 | parameters:(nullable id)parameters
192 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
193 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
194 |
195 | /**
196 | Creates and runs an `NSURLSessionDataTask` with a `POST` request.
197 |
198 | @param URLString The URL string used to create the request URL.
199 | @param parameters The parameters to be encoded according to the client request serializer.
200 | @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
201 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
202 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
203 |
204 | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
205 | */
206 | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
207 | parameters:(nullable id)parameters
208 | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
209 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
210 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
211 |
212 | /**
213 | Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request.
214 |
215 | @param URLString The URL string used to create the request URL.
216 | @param parameters The parameters to be encoded according to the client request serializer.
217 | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol.
218 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
219 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
220 |
221 | @see -dataTaskWithRequest:completionHandler:
222 | */
223 | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
224 | parameters:(nullable id)parameters
225 | constructingBodyWithBlock:(nullable void (^)(id formData))block
226 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
227 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure DEPRECATED_ATTRIBUTE;
228 |
229 | /**
230 | Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request.
231 |
232 | @param URLString The URL string used to create the request URL.
233 | @param parameters The parameters to be encoded according to the client request serializer.
234 | @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol.
235 | @param uploadProgress A block object to be executed when the upload progress is updated. Note this block is called on the session queue, not the main queue.
236 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
237 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
238 |
239 | @see -dataTaskWithRequest:uploadProgress:downloadProgress:completionHandler:
240 | */
241 | - (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
242 | parameters:(nullable id)parameters
243 | constructingBodyWithBlock:(nullable void (^)(id formData))block
244 | progress:(nullable void (^)(NSProgress *uploadProgress))uploadProgress
245 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
246 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
247 |
248 | /**
249 | Creates and runs an `NSURLSessionDataTask` with a `PUT` request.
250 |
251 | @param URLString The URL string used to create the request URL.
252 | @param parameters The parameters to be encoded according to the client request serializer.
253 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
254 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
255 |
256 | @see -dataTaskWithRequest:completionHandler:
257 | */
258 | - (nullable NSURLSessionDataTask *)PUT:(NSString *)URLString
259 | parameters:(nullable id)parameters
260 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
261 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
262 |
263 | /**
264 | Creates and runs an `NSURLSessionDataTask` with a `PATCH` request.
265 |
266 | @param URLString The URL string used to create the request URL.
267 | @param parameters The parameters to be encoded according to the client request serializer.
268 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
269 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
270 |
271 | @see -dataTaskWithRequest:completionHandler:
272 | */
273 | - (nullable NSURLSessionDataTask *)PATCH:(NSString *)URLString
274 | parameters:(nullable id)parameters
275 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
276 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
277 |
278 | /**
279 | Creates and runs an `NSURLSessionDataTask` with a `DELETE` request.
280 |
281 | @param URLString The URL string used to create the request URL.
282 | @param parameters The parameters to be encoded according to the client request serializer.
283 | @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer.
284 | @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred.
285 |
286 | @see -dataTaskWithRequest:completionHandler:
287 | */
288 | - (nullable NSURLSessionDataTask *)DELETE:(NSString *)URLString
289 | parameters:(nullable id)parameters
290 | success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
291 | failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure;
292 |
293 | @end
294 |
295 | NS_ASSUME_NONNULL_END
296 |
--------------------------------------------------------------------------------