├── .gitignore
├── AJNetworking.podspec
├── AJNetworking.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ └── contents.xcworkspacedata
├── AJNetworking.xcworkspace
└── contents.xcworkspacedata
├── AJNetworking
├── AppDelegate.h
├── AppDelegate.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── testImg.imageset
│ │ ├── Contents.json
│ │ └── testImg@2x.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── Classes
│ ├── AJCacheOptions.h
│ ├── AJCacheOptions.m
│ ├── AJError.h
│ ├── AJError.m
│ ├── AJHubProtocol.h
│ ├── AJNetworkConfig.h
│ ├── AJNetworkConfig.m
│ ├── AJNetworkLog.h
│ ├── AJNetworkLog.m
│ ├── AJNetworkManager.h
│ ├── AJNetworkManager.m
│ ├── AJNetworkStatus.h
│ ├── AJNetworkStatus.m
│ ├── AJNetworking.h
│ ├── Model
│ │ ├── AJRequestBeanBase.h
│ │ ├── AJRequestBeanBase.m
│ │ ├── AJRequestBeanDownloadTaskBase.h
│ │ ├── AJRequestBeanDownloadTaskBase.m
│ │ ├── AJRequestBeanProtocol.h
│ │ ├── AJResponseBeanBase.h
│ │ ├── AJResponseBeanBase.m
│ │ └── AJResponseBeanProtocol.h
│ └── Utils
│ │ ├── MD5Util.h
│ │ └── MD5Util.m
├── Demo
│ ├── BViewController.h
│ ├── BViewController.m
│ ├── RequestBeanDemoBase.h
│ ├── RequestBeanDemoBase.m
│ ├── RequestBeanDemoFilm.h
│ ├── RequestBeanDemoFilm.m
│ ├── RequestBeanDemoLogin.h
│ ├── RequestBeanDemoLogin.m
│ ├── RequestBeanDemoNews.h
│ ├── RequestBeanDemoNews.m
│ ├── RequestBeanDemoRegister.h
│ ├── RequestBeanDemoRegister.m
│ ├── RequestBeanVersion.h
│ ├── RequestBeanVersion.m
│ ├── RequestConfig.h
│ ├── RequestConfig.m
│ ├── RequestConfig.plist
│ ├── ResponseBeanDemo.h
│ ├── ResponseBeanDemo.m
│ ├── ResponseBeanDemoFilm.h
│ ├── ResponseBeanDemoFilm.m
│ ├── ResponseBeanDemoLogin.h
│ ├── ResponseBeanDemoLogin.m
│ ├── ResponseBeanDemoNews.h
│ ├── ResponseBeanDemoNews.m
│ ├── ResponseBeanDemoRegister.h
│ ├── ResponseBeanDemoRegister.m
│ ├── User.h
│ ├── User.m
│ ├── ViewController.h
│ └── ViewController.m
├── Example
│ ├── Certificate
│ │ └── client_test_local.p12
│ ├── LoginViewController.h
│ ├── LoginViewController.m
│ ├── Model
│ │ ├── AlipayConfigBean.h
│ │ ├── AlipayConfigBean.m
│ │ ├── CompanyBean.h
│ │ ├── CompanyBean.m
│ │ ├── RequestBeanAlipayConfig.h
│ │ ├── RequestBeanAlipayConfig.m
│ │ ├── RequestBeanDownloadFile.h
│ │ ├── RequestBeanDownloadFile.m
│ │ ├── RequestBeanLogin.h
│ │ ├── RequestBeanLogin.m
│ │ ├── RequestBeanUploadAvatar.h
│ │ ├── RequestBeanUploadAvatar.m
│ │ ├── ResponseBeanAlipayConfig.h
│ │ ├── ResponseBeanAlipayConfig.m
│ │ ├── ResponseBeanDownloadFile.h
│ │ ├── ResponseBeanDownloadFile.m
│ │ ├── ResponseBeanExample.h
│ │ ├── ResponseBeanExample.m
│ │ ├── ResponseBeanLogin.h
│ │ ├── ResponseBeanLogin.m
│ │ ├── ResponseBeanUploadAvatar.h
│ │ └── ResponseBeanUploadAvatar.m
│ └── Utils
│ │ ├── Base64
│ │ ├── Base64.h
│ │ └── Base64.m
│ │ ├── NSData+Base64.h
│ │ ├── NSData+Base64.m
│ │ ├── TripleDESEncrypt.h
│ │ └── TripleDESEncrypt.m
├── Info.plist
├── NetworkHub.h
├── NetworkHub.m
├── client.p12
└── main.m
├── LICENSE
├── Podfile
├── Podfile.lock
├── README.md
└── StructureFlow.png
/.gitignore:
--------------------------------------------------------------------------------
1 | # Xcode
2 | #
3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
4 |
5 | ## Build generated
6 | build/
7 | DerivedData
8 |
9 | ## Various settings
10 | *.pbxuser
11 | !default.pbxuser
12 | *.mode1v3
13 | !default.mode1v3
14 | *.mode2v3
15 | !default.mode2v3
16 | *.perspectivev3
17 | !default.perspectivev3
18 | xcuserdata
19 |
20 | ## Other
21 | *.xccheckout
22 | *.moved-aside
23 | *.xcuserstate
24 | *.xcscmblueprint
25 |
26 | ## Obj-C/Swift specific
27 | *.hmap
28 | *.ipa
29 |
30 | # CocoaPods
31 | #
32 | # We recommend against adding the Pods directory to your .gitignore. However
33 | # you should judge for yourself, the pros and cons are mentioned at:
34 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control
35 | #
36 | Pods/
37 |
38 | # Carthage
39 | #
40 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
41 | # Carthage/Checkouts
42 |
43 | Carthage/Build
44 |
45 | # fastlane
46 | #
47 | # It is recommended to not store the screenshots in the git repo. Instead, use fastlane to re-generate the
48 | # screenshots whenever they are needed.
49 | # For more information about the recommended setup visit:
50 | # https://github.com/fastlane/fastlane/blob/master/docs/Gitignore.md
51 |
52 | fastlane/report.xml
53 | fastlane/screenshots
54 |
--------------------------------------------------------------------------------
/AJNetworking.podspec:
--------------------------------------------------------------------------------
1 |
2 | Pod::Spec.new do |s|
3 |
4 | s.name = "AJNetworking"
5 | s.version = "3.2.0"
6 | s.summary = "AJNetworking是对AFNetworking 3.x 版本的封装,内部集成缓存和JSON转化."
7 |
8 | s.description = <<-DESC
9 | AJNetworking是对网络层的封装,将网络请求、JSON数据转化和数据缓存合三为一,上层可以更专注于业务的处理。
10 | DESC
11 |
12 | s.homepage = "https://github.com/AbooJan/AJNetworking"
13 |
14 | s.license = "MIT"
15 | s.license = { :type => "MIT", :file => "LICENSE" }
16 | s.author = { "AbooJan" => "aboojaner@gmail.com" }
17 |
18 | s.platform = :ios
19 | s.platform = :ios, "7.0"
20 | s.ios.deployment_target = "7.0"
21 |
22 | s.source = { :git => "https://github.com/AbooJan/AJNetworking.git", :tag => "#{s.version}" }
23 | s.source_files = "AJNetworking/Classes/*.{h,m}","AJNetworking/Classes/Model/*.{h,m}","AJNetworking/Classes/Utils/*.{h,m}"
24 |
25 | s.frameworks = "UIKit","Foundation","Security"
26 | s.requires_arc = true
27 |
28 | s.dependency "AFNetworking"
29 | s.dependency "MJExtension"
30 | s.dependency "SPTPersistentCache"
31 |
32 | end
33 |
--------------------------------------------------------------------------------
/AJNetworking.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/AJNetworking.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/AJNetworking/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/3/19.
6 | // Copyright © 2016年 aboojan. 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 |
--------------------------------------------------------------------------------
/AJNetworking/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/3/19.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "AJNetworking.h"
11 | #import "NetworkHub.h"
12 |
13 | @interface AppDelegate ()
14 | @property (nonatomic, strong) NetworkHub *hub;
15 | @end
16 |
17 | @implementation AppDelegate
18 |
19 |
20 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
21 |
22 | NSString *documentsPath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
23 | AJLog(@"%@", documentsPath);
24 |
25 | self.hub = [[NetworkHub alloc] init];
26 |
27 | // 网络配置
28 | AJNetworkConfig *networkConfig = [AJNetworkConfig shareInstance];
29 | networkConfig.hostUrl = @"localhost:3000";
30 | // networkConfig.hostUrl = @"192.168.1.10:80";
31 | networkConfig.httpsCertificatePassword = CFSTR("666666");
32 | networkConfig.httpsCertificatePath = [[NSBundle mainBundle] pathForResource:@"client" ofType:@"p12"];
33 | networkConfig.hubDelegate = self.hub;
34 |
35 | // 网络缓存配置
36 | AJCacheOptions *cacheOptions = [AJCacheOptions new];
37 | cacheOptions.cachePath = [documentsPath stringByAppendingPathComponent:@"aj_network_cache"];
38 | cacheOptions.openCacheGC = YES;
39 | cacheOptions.globalCacheExpirationSecond = 60;
40 | cacheOptions.globalCacheGCSecond = 2 * 60;
41 | networkConfig.cacheOptions = cacheOptions;
42 |
43 | return YES;
44 | }
45 |
46 | - (void)applicationWillResignActive:(UIApplication *)application {
47 | // 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.
48 | // 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.
49 | }
50 |
51 | - (void)applicationDidEnterBackground:(UIApplication *)application {
52 | // 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.
53 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
54 | }
55 |
56 | - (void)applicationWillEnterForeground:(UIApplication *)application {
57 | // 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.
58 | }
59 |
60 | - (void)applicationDidBecomeActive:(UIApplication *)application {
61 | // 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.
62 | }
63 |
64 | - (void)applicationWillTerminate:(UIApplication *)application {
65 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/AJNetworking/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 | "idiom" : "ipad",
65 | "size" : "83.5x83.5",
66 | "scale" : "2x"
67 | }
68 | ],
69 | "info" : {
70 | "version" : 1,
71 | "author" : "xcode"
72 | }
73 | }
--------------------------------------------------------------------------------
/AJNetworking/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/AJNetworking/Assets.xcassets/testImg.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "testImg@2x.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/AJNetworking/Assets.xcassets/testImg.imageset/testImg@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbooJan/AJNetworking/cb06bcd954c40a84c40ef7e99eb1443fef5eb55b/AJNetworking/Assets.xcassets/testImg.imageset/testImg@2x.png
--------------------------------------------------------------------------------
/AJNetworking/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 |
--------------------------------------------------------------------------------
/AJNetworking/Base.lproj/Main.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 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
100 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
137 |
144 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
218 |
219 |
220 |
221 |
222 |
223 |
224 |
225 |
226 |
238 |
250 |
262 |
274 |
286 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
313 |
314 |
315 |
316 |
317 |
318 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJCacheOptions.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJCacheOptions.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/4/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | extern const NSUInteger AJCacheDefaultExpirationSecond;
13 | extern const NSUInteger AJCacheDefaultGCSecond;
14 |
15 |
16 | @interface AJCacheOptions : NSObject
17 |
18 | /**
19 | * @author aboojan
20 | *
21 | * @brief 缓存存放路径
22 | */
23 | @property (nonatomic, copy) NSString *cachePath;
24 |
25 | /**
26 | * @author aboojan
27 | *
28 | * @brief 是否开启缓存自动回收,默认关闭
29 | */
30 | @property (nonatomic,assign) BOOL openCacheGC;
31 |
32 | /**
33 | * @author aboojan
34 | *
35 | * @brief 缓存过期时间,最小不能小于60s
36 | */
37 | @property (nonatomic, assign) NSUInteger globalCacheExpirationSecond;
38 |
39 | /**
40 | * @author aboojan
41 | *
42 | * @brief 缓存自动回收时间,最小不能小于60s(开启自动回收之后才有效)
43 | */
44 | @property (nonatomic, assign) NSUInteger globalCacheGCSecond;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJCacheOptions.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJCacheOptions.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/4/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJCacheOptions.h"
10 |
11 |
12 | const NSUInteger AJCacheDefaultExpirationSecond = 10 * 60;
13 | const NSUInteger AJCacheDefaultGCSecond = 6 * 60 + 3;
14 |
15 |
16 | @implementation AJCacheOptions
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJError.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJError.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/24.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, AJErrorCode)
12 | {
13 | AJErrorCodeDefault = 0,
14 | AJErrorCodeNoCache = 101,
15 | AJErrorCodeCacheInvalid = 102,
16 | AJErrorCodeNoNetwork = 103,
17 | AJErrorCodeNoResponse = 104
18 | };
19 |
20 | @interface AJError : NSObject
21 |
22 | @property (nonatomic,assign) NSInteger code;
23 | @property (copy, nonatomic) NSString *message;
24 |
25 | + (AJError *)defaultError;
26 | - (instancetype)initWithCode:(NSInteger)code message:(NSString *)message;
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJError.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJError.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/24.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJError.h"
10 |
11 | @implementation AJError
12 |
13 | + (AJError *)defaultError
14 | {
15 | AJError *err = [[AJError alloc] initWithCode:AJErrorCodeDefault message:@"error"];
16 | return err;
17 | }
18 |
19 | - (instancetype)initWithCode:(NSInteger)code message:(NSString *)message
20 | {
21 | self = [super init];
22 | if (self) {
23 | self.code = code;
24 | self.message = message;
25 | }
26 | return self;
27 | }
28 |
29 | - (NSString *)description
30 | {
31 | return [NSString stringWithFormat:@"code:%ld \n message:%@", self.code, self.message];
32 | }
33 |
34 | @end
35 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJHubProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJHubProtocol.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/9/24.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol AJHubProtocol
12 |
13 | /**
14 | * 显示Hub
15 | *
16 | @param tip hub文案
17 | */
18 | - (void)showHub:(nullable NSString *)tip;
19 |
20 |
21 | /**
22 | * 隐藏Hub
23 | */
24 | - (void)dismissHub;
25 | @end
26 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkConfig.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import "AJCacheOptions.h"
10 | #import
11 | #import
12 | #import "AJHubProtocol.h"
13 |
14 | #ifdef DEBUG
15 | # define AJLog(fmt, ...) NSLog((@"%s [Line %d] " fmt), __PRETTY_FUNCTION__, __LINE__, ##__VA_ARGS__);
16 | #else
17 | # define AJLog(...)
18 | #endif
19 |
20 | #define AJConstructingBlockDefine ^(id formData)
21 |
22 | typedef void (^AFConstructingBlock)(id formData);
23 |
24 | typedef NS_ENUM(NSInteger, HTTP_REQUEST_SERIALIZATION)
25 | {
26 | /// Content-Type:application/x-www-form-urlencoded
27 | HTTP_REQUEST_SERIALIZATION_FORM,
28 | /// Content-Type:application/json
29 | HTTP_REQUEST_SERIALIZATION_JSON,
30 | /// Content-Type:application/x-plist
31 | HTTP_REQUEST_SERIALIZATION_PROPERTY_LIST
32 | };
33 |
34 | typedef NS_ENUM(NSInteger, HTTP_METHOD)
35 | {
36 | HTTP_METHOD_GET,
37 | HTTP_METHOD_POST,
38 | HTTP_METHOD_HEAD,
39 | HTTP_METHOD_PUT,
40 | HTTP_METHOD_DELETE,
41 | HTTP_METHOD_PATCH
42 | };
43 |
44 | typedef NS_ENUM(NSInteger, HTTP_SCHEME)
45 | {
46 | HTTP_SCHEME_HTTP,
47 | HTTP_SCHEME_HTTPS
48 | };
49 |
50 | @interface AJNetworkConfig : NSObject
51 |
52 | + (AJNetworkConfig *)shareInstance;
53 |
54 | - (SPTPersistentCache *)globalHttpCache;
55 |
56 | /// 服务器域名
57 | @property (nonatomic, copy) NSString *hostUrl;
58 | /// HTTPS 证书密码
59 | @property (nonatomic, assign) CFStringRef httpsCertificatePassword;
60 | /// HTTPS 证书路径
61 | @property (nonatomic, copy) NSString *httpsCertificatePath;
62 | /// 缓存配置
63 | @property (nonatomic, strong) AJCacheOptions *cacheOptions;
64 | /// Hub显示代理
65 | @property (nonatomic, weak) id hubDelegate;
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkConfig.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import "AJNetworkConfig.h"
10 | #import "AJNetworkStatus.h"
11 |
12 | #define kBundleID [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleIdentifier"]
13 |
14 |
15 | @interface AJNetworkConfig ()
16 | /// 网络缓存
17 | @property (nonatomic, strong) SPTPersistentCache *httpCache;
18 | @end
19 |
20 | @implementation AJNetworkConfig
21 |
22 | + (AJNetworkConfig *)shareInstance
23 | {
24 | static AJNetworkConfig * instance;
25 | static dispatch_once_t onceToken;
26 | dispatch_once(&onceToken, ^{
27 | instance = [[AJNetworkConfig alloc] init];
28 |
29 | // 开启网络状态监听
30 | [AJNetworkStatus shareInstance];
31 | });
32 |
33 | return instance;
34 | }
35 |
36 | - (SPTPersistentCache *)globalHttpCache
37 | {
38 | if (!_httpCache) {
39 |
40 | NSString *cacheIdentifier = [NSString stringWithFormat:@"%@.cache", kBundleID];
41 |
42 | // 缓存配置
43 | SPTPersistentCacheOptions *options = [[SPTPersistentCacheOptions alloc]
44 | initWithCachePath:self.cacheOptions.cachePath
45 | identifier:cacheIdentifier
46 | defaultExpirationInterval:self.cacheOptions.globalCacheExpirationSecond
47 | garbageCollectorInterval:self.cacheOptions.globalCacheGCSecond
48 | debug:^(NSString * _Nonnull string) {
49 |
50 | AJLog(@"###SPTPersistentCache###: %@", string);
51 | }];
52 |
53 | _httpCache = [[SPTPersistentCache alloc] initWithOptions:options];
54 |
55 | // 开启缓存自动回收
56 | if (self.cacheOptions.openCacheGC) {
57 | [_httpCache scheduleGarbageCollector];
58 | }
59 |
60 | }
61 |
62 | return _httpCache;
63 | }
64 |
65 | - (AJCacheOptions *)cacheOptions
66 | {
67 | if (!_cacheOptions){
68 |
69 | _cacheOptions = [[AJCacheOptions alloc] init];
70 |
71 | _cacheOptions.cachePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", kBundleID]];
72 | _cacheOptions.globalCacheExpirationSecond = AJCacheDefaultExpirationSecond;
73 | _cacheOptions.globalCacheGCSecond = AJCacheDefaultGCSecond;
74 | }
75 |
76 | if( (_cacheOptions.cachePath == nil) || [_cacheOptions.cachePath isEqualToString:@""] )
77 | {
78 | _cacheOptions.cachePath = [NSTemporaryDirectory() stringByAppendingPathComponent:[NSString stringWithFormat:@"%@", kBundleID]];
79 | }
80 |
81 | if (_cacheOptions.globalCacheExpirationSecond < 60) {
82 | _cacheOptions.globalCacheExpirationSecond = AJCacheDefaultExpirationSecond;
83 | }
84 |
85 | if (_cacheOptions.globalCacheGCSecond < 60) {
86 | _cacheOptions.globalCacheGCSecond = AJCacheDefaultGCSecond;
87 | }
88 |
89 | return _cacheOptions;
90 | }
91 |
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkLog.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkLog.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJRequestBeanBase.h"
11 | #import "AJResponseBeanBase.h"
12 |
13 | @interface AJNetworkLog : NSObject
14 | + (void)logWithRequestBean:(__kindof AJRequestBeanBase *)requestBean;
15 | + (void)logWithRequestBean:(__kindof AJRequestBeanBase *)requestBean json:(id)responseJSON;
16 | + (void)logWithContent:(NSString *)logContent;
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkLog.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkLog.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJNetworkLog.h"
10 | #import "MJExtension.h"
11 |
12 |
13 | @implementation AJNetworkLog
14 |
15 | + (NSString *)createPostURL:(NSDictionary *)params
16 | {
17 | NSString *postString = @"";
18 | for (NSString *key in params.allKeys) {
19 | NSString *value = [params objectForKey:key];
20 | postString = [postString stringByAppendingFormat:@"%@=%@&",key,value];
21 | }
22 | if ([postString length]>1) {
23 | postString=[postString substringToIndex:[postString length]-1];
24 | }
25 | return postString;
26 | }
27 |
28 | + (void)logWithRequestBean:(__kindof AJRequestBeanBase *)requestBean
29 | {
30 | NSString *hostStr = [requestBean apiHost];
31 | NSString *apiStr = [requestBean apiPath];
32 |
33 | BOOL loseConfigHost = (hostStr == nil) || [hostStr isEqualToString:@""];
34 | NSCAssert(!loseConfigHost, @"找不到Host!");
35 |
36 | BOOL loseConfigApi = (apiStr == nil) || [apiStr isEqualToString:@""];
37 | NSCAssert(!loseConfigApi, @"找不到Api路径!");
38 |
39 |
40 | NSMutableString *logString = [NSMutableString stringWithString:@"\n\n"];
41 | [logString appendFormat:@"**************************************************************\n"];
42 | [logString appendFormat:@"* Request Start *\n"];
43 | [logString appendFormat:@"**************************************************************\n\n"];
44 | [logString appendFormat:@"请求:\n%@?%@\n\n", [requestBean requestUrl], [self createPostURL:[requestBean mj_keyValues]]];
45 | [logString appendFormat:@"%@", [requestBean mj_keyValues]];
46 | [logString appendFormat:@"\n\n"];
47 | [logString appendFormat:@"**************************************************************\n"];
48 | [logString appendFormat:@"* Request End *\n"];
49 | [logString appendFormat:@"**************************************************************\n\n"];
50 |
51 | AJLog(@"%@", logString);
52 | }
53 |
54 | + (void)logWithRequestBean:(__kindof AJRequestBeanBase *)requestBean json:(id)responseJSON
55 | {
56 | NSMutableString *logString = [NSMutableString stringWithString:@"\n\n"];
57 | [logString appendFormat:@"==============================================================\n"];
58 | [logString appendFormat:@"= API Response =\n"];
59 | [logString appendFormat:@"==============================================================\n\n"];
60 | [logString appendFormat:@"URL: %@\n\n", [requestBean requestUrl]];
61 | [logString appendFormat:@"%@", responseJSON];
62 | [logString appendFormat:@"\n\n"];
63 | [logString appendFormat:@"==============================================================\n"];
64 | [logString appendFormat:@"= Response End =\n"];
65 | [logString appendFormat:@"==============================================================\n\n\n"];
66 |
67 | AJLog(@"%@", logString);
68 | }
69 |
70 | + (void)logWithContent:(NSString *)logContent
71 | {
72 | NSMutableString *logStr = [NSMutableString stringWithString:@"\n\n"];
73 | [logStr appendFormat:@"################################################################\n"];
74 | [logStr appendFormat:@"# Error #\n"];
75 | [logStr appendFormat:@"################################################################\n\n"];
76 | [logStr appendFormat:@"%@\n\n", logContent];
77 | [logStr appendFormat:@"################################################################\n\n\n"];
78 |
79 | AJLog(@"%@", logStr);
80 | }
81 |
82 | @end
83 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkManager.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 AbooJan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJNetworkConfig.h"
11 | #import "AJRequestBeanBase.h"
12 | #import "AJResponseBeanBase.h"
13 | #import "AJRequestBeanDownloadTaskBase.h"
14 | #import "AJError.h"
15 |
16 | /**
17 | * @author aboojan
18 | *
19 | * @brief 结果回调
20 | *
21 | * @param responseBean 数据Bean,可能是缓存或网络数据
22 | * @param err 错误,如果为nil,回调成功,否则失败
23 | */
24 | typedef void(^AJRequestCallBack)(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err);
25 |
26 | typedef void(^AJDownloadProgressCallBack)(int64_t totalUnitCount, int64_t completedUnitCount, double progressRate);
27 | typedef void(^AJDownloadCompletionCallBack)(NSURL * _Nullable filePath, NSError * _Nullable error);
28 |
29 |
30 | @interface AJNetworkManager : NSObject
31 |
32 | /**
33 | * @author aboojan
34 | *
35 | * @brief 发请网络请求,没有缓存
36 | *
37 | * @param requestBean 网络请求参数模型Bean
38 | * @param callBack 网络请求结果回调
39 | */
40 | + (void)requestWithBean:(__kindof AJRequestBeanBase * _Nonnull)requestBean
41 | callBack:(AJRequestCallBack _Nonnull)callBack;
42 |
43 | /**
44 | * @author aboojan
45 | *
46 | * @brief 发起网络请求,有缓存
47 | *
48 | * @param requestBean 网络请求参数模式Bean
49 | * @param cacheCallBack 缓存读取回调
50 | * @param httpCallBack 网络请求结果回调
51 | */
52 | + (void)requestWithBean:(__kindof AJRequestBeanBase * _Nonnull)requestBean
53 | cacheCallBack:(AJRequestCallBack _Nonnull)cacheCallBack
54 | httpCallBack:(AJRequestCallBack _Nonnull)httpCallBack;
55 |
56 |
57 | /**
58 | * @author aboojan
59 | *
60 | * @brief 文件下载
61 | *
62 | * @param requestBean 文件下载请求Bean
63 | * @param progressCallBack 下载进度回调
64 | * @param completionCallBack 完成回调
65 | *
66 | * @return 当前下载任务线程
67 | */
68 | + ( NSURLSessionDownloadTask * _Nullable )downloadTaskWithBean:(__kindof AJRequestBeanDownloadTaskBase * _Nonnull)requestBean progress:(AJDownloadProgressCallBack _Nullable )progressCallBack completion:(AJDownloadCompletionCallBack _Nullable)completionCallBack;
69 |
70 | /**
71 | * @author aboojan
72 | *
73 | * @brief 读取缓存
74 | *
75 | * @param requestBean 请求Bean
76 | * @param callBack 读取缓存回调
77 | */
78 | + (void)cacheWithRequestWithBean:(__kindof AJRequestBeanBase * _Nonnull)requestBean callBack:(AJRequestCallBack _Nonnull)callBack;
79 |
80 | /**
81 | 根据 taskKey 结束目标网络请求任务
82 |
83 | @param taskKeyArray 任务Key数组
84 | */
85 | + (void)stopRequestTaskWithTaskKey:(NSArray<__kindof NSString *> * _Nonnull)taskKeyArray;
86 |
87 | @end
88 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkManager.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 AbooJan. All rights reserved.
7 | //
8 |
9 | #import "AJNetworkManager.h"
10 | #import "MJExtension.h"
11 | #import "AJNetworkLog.h"
12 | #import
13 | #import "MD5Util.h"
14 | #import "AJNetworkStatus.h"
15 |
16 | @interface AJNetworkManager()
17 | @property (nonatomic, strong) NSMutableDictionary<__kindof NSString *, __kindof NSURLSessionTask *> *taskStack;
18 | @end
19 |
20 | @implementation AJNetworkManager
21 |
22 | #pragma mark - <基本信息>
23 |
24 | + (AJNetworkManager *)shareInstance
25 | {
26 | static AJNetworkManager *instance;
27 | static dispatch_once_t onceToken;
28 | dispatch_once(&onceToken, ^{
29 | instance = [[AJNetworkManager alloc] init];
30 | instance.taskStack = [NSMutableDictionary dictionary];
31 | });
32 |
33 | return instance;
34 | }
35 |
36 | + (AFHTTPSessionManager *)httpsSessionManager {
37 |
38 | AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
39 | AFSecurityPolicy *securityPolicy = [AFSecurityPolicy defaultPolicy];
40 | securityPolicy.allowInvalidCertificates = YES;
41 | securityPolicy.validatesDomainName = NO;
42 | manager.securityPolicy = securityPolicy;
43 |
44 | __weak __typeof(&*self) weakSelf = self;
45 | [manager setSessionDidReceiveAuthenticationChallengeBlock:^NSURLSessionAuthChallengeDisposition(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential *__autoreleasing *credential) {
46 |
47 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
48 |
49 | if (challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust) {
50 |
51 | *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
52 | return NSURLSessionAuthChallengeUseCredential;
53 |
54 | }else if(challenge.protectionSpace.authenticationMethod == NSURLAuthenticationMethodClientCertificate) {
55 |
56 | NSData *PKCS12Data = [[NSData alloc] initWithContentsOfFile:[AJNetworkConfig shareInstance].httpsCertificatePath];
57 | CFDataRef inPKCS12Data = (__bridge CFDataRef)PKCS12Data;
58 | SecIdentityRef identity = NULL;
59 | [strongSelf extractIdentity :inPKCS12Data :&identity];
60 | SecCertificateRef certificate = NULL;
61 | SecIdentityCopyCertificate (identity, &certificate);
62 |
63 | *credential = [NSURLCredential credentialWithIdentity:identity certificates:nil persistence:NSURLCredentialPersistencePermanent];
64 |
65 | return NSURLSessionAuthChallengeUseCredential;
66 |
67 | }else{
68 | return NSURLSessionAuthChallengeUseCredential;
69 | }
70 | }];
71 |
72 | return manager;
73 | }
74 |
75 | #pragma mark 设置加密信息
76 | + (OSStatus)extractIdentity:(CFDataRef)inP12Data :(SecIdentityRef*)identity
77 | {
78 | OSStatus securityError = errSecSuccess;
79 | CFStringRef password = [AJNetworkConfig shareInstance].httpsCertificatePassword;
80 | const void *keys[] = { kSecImportExportPassphrase };
81 | const void *values[] = { password };
82 |
83 | CFDictionaryRef options = CFDictionaryCreate(NULL, keys, values, 1, NULL, NULL);
84 | CFArrayRef items = CFArrayCreate(NULL, 0, 0, NULL);
85 | securityError = SecPKCS12Import(inP12Data, options, &items);
86 |
87 | if (securityError == 0)
88 | {
89 | CFDictionaryRef ident = CFArrayGetValueAtIndex(items,0);
90 | const void *tempIdentity = NULL;
91 | tempIdentity = CFDictionaryGetValue(ident, kSecImportItemIdentity);
92 | *identity = (SecIdentityRef)tempIdentity;
93 | }
94 |
95 | if (options)
96 | {
97 | CFRelease(options);
98 | }
99 |
100 | return securityError;
101 | }
102 |
103 |
104 | + (Class)responseClassWithRequestBean:(__kindof AJRequestBeanBase *) requestBean
105 | {
106 | NSString *responseBeanNameStr = [requestBean responseBeanClassName];
107 | if (!responseBeanNameStr) {
108 | responseBeanNameStr = @"AJResponseBeanBase";
109 | }
110 |
111 | const char *responseBeanName = [responseBeanNameStr UTF8String];
112 |
113 | Class responseBeanClass = objc_getClass(responseBeanName);
114 |
115 | NSAssert([responseBeanClass isSubclassOfClass:[AJResponseBeanBase class]], @"Response Bean Class must be subclass of AJResponseBeanBase");
116 |
117 | return responseBeanClass;
118 | }
119 |
120 |
121 | #pragma mark - <请求处理>
122 |
123 | #pragma mark - private
124 |
125 | + (__kindof AFHTTPRequestSerializer *)requestSerializerWithRequestBean:(__kindof AJRequestBeanBase *)requestBean
126 | {
127 | __kindof AFHTTPRequestSerializer *requestSerializer;
128 | switch ([requestBean requestSerialization]) {
129 | case HTTP_REQUEST_SERIALIZATION_FORM:
130 | requestSerializer = [AFHTTPRequestSerializer serializer];
131 | break;
132 |
133 | case HTTP_REQUEST_SERIALIZATION_JSON:
134 | requestSerializer = [AFJSONRequestSerializer serializer];
135 | break;
136 |
137 | case HTTP_REQUEST_SERIALIZATION_PROPERTY_LIST:
138 | requestSerializer = [AFPropertyListRequestSerializer serializer];
139 | break;
140 |
141 | default:
142 | requestSerializer = [AFHTTPRequestSerializer serializer];;
143 | break;
144 | }
145 | requestSerializer.timeoutInterval = [requestBean timeout];
146 |
147 | return requestSerializer;
148 | }
149 |
150 | + (void)configHttpHeaderWithRequestBean:(__kindof AJRequestBeanBase *)requestBean requestSerializer:(__kindof AFHTTPRequestSerializer *)requestSerializer
151 | {
152 | NSDictionary *headerFieldValueDictionary = [requestBean httpHeader];
153 | if (headerFieldValueDictionary != nil) {
154 | for (id httpHeaderField in headerFieldValueDictionary.allKeys) {
155 | id value = headerFieldValueDictionary[httpHeaderField];
156 | if ([httpHeaderField isKindOfClass:[NSString class]] && [value isKindOfClass:[NSString class]]) {
157 | [requestSerializer setValue:(NSString *)value forHTTPHeaderField:(NSString *)httpHeaderField];
158 | } else {
159 | AJLog(@"Error, class of key/value in headerFieldValueDictionary should be NSString.");
160 | }
161 | }
162 | }
163 |
164 | }
165 |
166 | #pragma mark - public
167 |
168 | + (void)requestWithBean:(__kindof AJRequestBeanBase *)requestBean callBack:(AJRequestCallBack)callBack
169 | {
170 | // 网络检测
171 | if (![[AJNetworkStatus shareInstance] canReachable]) {
172 |
173 | AJError *err = [[AJError alloc] initWithCode:AJErrorCodeNoNetwork message:@"network can not reach"];
174 | callBack(nil, err);
175 |
176 | return;
177 | }
178 |
179 | // 检查当前是否已经有请求在跑
180 | NSURLSessionTask *oldTask = [[self shareInstance].taskStack objectForKey:[requestBean taskKey]];
181 | if (oldTask) {
182 | // 如果已有旧的请求在跑,不进行新的请求
183 | return;
184 | }
185 |
186 | // 发起请求
187 | NSString *requestUrl = [requestBean requestUrl];
188 | NSDictionary *params = [requestBean mj_keyValues];
189 |
190 | __kindof AFHTTPRequestSerializer *requestSerializer = [self requestSerializerWithRequestBean:requestBean];
191 |
192 | // Http Header
193 | [self configHttpHeaderWithRequestBean:requestBean requestSerializer:requestSerializer];
194 |
195 | // 序列化
196 | AFJSONResponseSerializer *responseSerializer = [AFJSONResponseSerializer serializer];
197 | responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/html", @"text/plain", @"application/msexcel", nil];
198 |
199 | AFHTTPSessionManager *manager = [AFHTTPSessionManager manager];
200 | if ([requestBean httpScheme] == HTTP_SCHEME_HTTPS) {
201 | manager = [self httpsSessionManager];
202 | }
203 | manager.requestSerializer = requestSerializer;
204 | manager.responseSerializer = responseSerializer;
205 |
206 | // LOG
207 | [AJNetworkLog logWithRequestBean:requestBean];
208 |
209 | //Hub
210 | [self showHub:requestBean];
211 |
212 | NSURLSessionTask *requestTask = nil;
213 | __weak __typeof__(self) weakSelf = self;
214 |
215 |
216 | // Request Success Callback
217 | void(^SuccessBlock)(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject) = ^(NSURLSessionDataTask * _Nonnull task, id _Nullable responseObject){
218 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
219 |
220 | [strongSelf dismissHub:requestBean];
221 | [strongSelf handleSuccessWithRequestBean:requestBean response:responseObject callBack:callBack];
222 | [strongSelf stopRequestTaskWithTaskKey:@[[requestBean taskKey]]];
223 | };
224 |
225 | // Request Fail Callback
226 | void (^FailBlock)(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) = ^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
227 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
228 |
229 | [strongSelf dismissHub:requestBean];
230 | [strongSelf handleFailureWithError:error callBack:callBack];
231 | [strongSelf stopRequestTaskWithTaskKey:@[[requestBean taskKey]]];
232 | };
233 |
234 |
235 | switch ([requestBean httpMethod]) {
236 |
237 | case HTTP_METHOD_GET:
238 | {
239 | requestTask = [manager GET:requestUrl parameters:params progress:nil success:SuccessBlock failure:FailBlock];
240 | break;
241 | }
242 |
243 | case HTTP_METHOD_POST:
244 | {
245 |
246 | if ([requestBean constructingBodyBlock] != nil) {
247 |
248 | // 文件等富文本内容
249 | requestTask = [manager POST:requestUrl parameters:params constructingBodyWithBlock:[requestBean constructingBodyBlock] progress:nil success:SuccessBlock failure:FailBlock];
250 |
251 | }else{
252 |
253 | requestTask = [manager POST:requestUrl parameters:params progress:nil success:SuccessBlock failure:FailBlock];
254 | }
255 |
256 | break;
257 | }
258 |
259 | case HTTP_METHOD_HEAD:
260 | {
261 | requestTask = [manager HEAD:requestUrl parameters:params success:^(NSURLSessionDataTask * _Nonnull task) {
262 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
263 |
264 | [strongSelf dismissHub:requestBean];
265 | [strongSelf handleSuccessWithRequestBean:requestBean response:task callBack:callBack];
266 | [strongSelf stopRequestTaskWithTaskKey:@[[requestBean taskKey]]];
267 |
268 | } failure:FailBlock];
269 |
270 | break;
271 | }
272 |
273 | case HTTP_METHOD_PUT:
274 | {
275 | requestTask = [manager PUT:requestUrl parameters:params success:SuccessBlock failure:FailBlock];
276 |
277 | break;
278 | }
279 |
280 | case HTTP_METHOD_PATCH:
281 | {
282 | requestTask = [manager PATCH:requestUrl parameters:params success:SuccessBlock failure:FailBlock];
283 |
284 | break;
285 | }
286 |
287 | case HTTP_METHOD_DELETE:
288 | {
289 | requestTask = [manager DELETE:requestUrl parameters:params success:SuccessBlock failure:FailBlock];
290 |
291 | break;
292 | }
293 |
294 | default:
295 | NSLog(@"unknow http method");
296 | break;
297 | }
298 |
299 | // 任务队列
300 | if (requestTask != nil
301 | && requestBean != nil
302 | && [requestBean taskKey] !=nil) {
303 |
304 | [[self shareInstance].taskStack setObject:requestTask forKey:[requestBean taskKey]];
305 | }
306 | }
307 |
308 | + (void)requestWithBean:(__kindof AJRequestBeanBase *)requestBean cacheCallBack:(AJRequestCallBack)cacheCallBack httpCallBack:(AJRequestCallBack)httpCallBack
309 | {
310 | __weak __typeof__(self) weakSelf = self;
311 | [self cacheWithRequestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
312 |
313 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
314 |
315 | // 缓存结果回调
316 | cacheCallBack(responseBean, err);
317 |
318 | if (err != nil) {
319 |
320 | // 没有缓存,发起网络请求
321 | [strongSelf requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
322 | httpCallBack(responseBean, err);
323 | }];
324 |
325 | }else{
326 |
327 | if ([requestBean cacheLiveSecond] == 0) {
328 |
329 | // 缓存长期有效,需要发起网络请求
330 | [strongSelf requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
331 | httpCallBack(responseBean, err);
332 | }];
333 |
334 | }else{
335 | // 缓存短期有效,无需网络请求
336 | }
337 | }
338 | }];
339 | }
340 |
341 | + (NSURLSessionDownloadTask *)downloadTaskWithBean:(__kindof AJRequestBeanDownloadTaskBase *)requestBean progress:(AJDownloadProgressCallBack)progressCallBack completion:(AJDownloadCompletionCallBack)completionCallBack
342 | {
343 | // 如果已存在,则不下载
344 | NSString *saveFilePath = [requestBean.saveFilePath stringByAppendingPathComponent:requestBean.saveFileName];
345 | NSURL *saveFileUrl = [NSURL fileURLWithPath:saveFilePath];
346 | NSFileManager *fileManager = [NSFileManager defaultManager];
347 | if ([fileManager fileExistsAtPath:saveFilePath]) {
348 | completionCallBack(saveFileUrl, nil);
349 | return nil;
350 | }
351 |
352 |
353 | NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
354 | AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration];
355 |
356 | NSURL *URL = [NSURL URLWithString:requestBean.fileUrl];
357 | NSURLRequest *request = [NSURLRequest requestWithURL:URL];
358 |
359 | NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
360 |
361 | if (progressCallBack) {
362 | progressCallBack(downloadProgress.totalUnitCount, downloadProgress.completedUnitCount, (downloadProgress.completedUnitCount * 1.0) / (downloadProgress.totalUnitCount * 1.0));
363 | }
364 |
365 | } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
366 |
367 | return saveFileUrl;
368 |
369 | } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
370 |
371 | if (completionCallBack) {
372 | completionCallBack(filePath, error);
373 | }
374 |
375 | }];
376 |
377 | [downloadTask resume];
378 |
379 | return downloadTask;
380 | }
381 |
382 | + (void)cacheWithRequestWithBean:(__kindof AJRequestBeanBase *)requestBean callBack:(AJRequestCallBack)callBack
383 | {
384 | if ([requestBean cacheResponse]) {
385 |
386 | SPTPersistentCache *httpCache = [[AJNetworkConfig shareInstance] globalHttpCache];
387 | NSString *cacheKey = [requestBean taskKey];
388 |
389 | __weak __typeof(&*self) weakSelf = self;
390 | [httpCache loadDataForKey:cacheKey withCallback:^(SPTPersistentCacheResponse * _Nonnull response) {
391 |
392 | __strong __typeof__(weakSelf) strongSelf = weakSelf;
393 |
394 | if (response.result == SPTPersistentCacheResponseCodeOperationSucceeded) {
395 | NSData *cacheData = response.record.data;
396 | NSDictionary *jsonDic = [cacheData mj_keyValues];
397 |
398 | Class responseClass = [strongSelf responseClassWithRequestBean:requestBean];
399 | AJResponseBeanBase *responseBean = [responseClass mj_objectWithKeyValues:jsonDic];
400 | responseBean.rawData = jsonDic;
401 |
402 | callBack(responseBean, nil);
403 |
404 | }else{
405 |
406 | AJError *err = [[AJError alloc] initWithCode:AJErrorCodeCacheInvalid message:@"cache invalid"];
407 | callBack(nil, err);
408 | }
409 |
410 | } onQueue:dispatch_get_main_queue()];
411 |
412 | }else{
413 |
414 | AJError *err = [[AJError alloc] initWithCode:AJErrorCodeNoCache message:@"no cache"];
415 | callBack(nil, err);
416 | }
417 | }
418 |
419 | + (void)stopRequestTaskWithTaskKey:(NSArray<__kindof NSString *> *)taskKeyArray
420 | {
421 | if (!taskKeyArray) {
422 | return;
423 | }
424 |
425 | for (NSString *taskKey in taskKeyArray) {
426 |
427 | NSURLSessionTask *task = [[self shareInstance].taskStack objectForKey:taskKey];
428 | if (task) {
429 |
430 | // 任务取消
431 | if (task.state == NSURLSessionTaskStateRunning) {
432 | [task cancel];
433 | }
434 |
435 | // 从任务队列中移除
436 | [[self shareInstance].taskStack removeObjectForKey:taskKey];
437 | }
438 | }
439 | }
440 |
441 | #pragma mark - <结果处理>
442 |
443 | + (void)handleSuccessWithRequestBean:(__kindof AJRequestBeanBase *)requestBean response:(id _Nullable) responseObject callBack:(AJRequestCallBack)callBack
444 | {
445 | [AJNetworkLog logWithRequestBean:requestBean json:responseObject];
446 |
447 |
448 | //TODO: HEAD 请求结果处理有待补充
449 | if ([requestBean httpMethod] == HTTP_METHOD_HEAD) {
450 | callBack(nil, [AJError defaultError]);
451 | return;
452 | }
453 |
454 | if (!responseObject) {
455 |
456 | AJError *err = [[AJError alloc] initWithCode:AJErrorCodeNoResponse message:@"no response data"];
457 | callBack(nil, err);
458 | [AJNetworkLog logWithContent:@"请求失败:没有数据返回!"];
459 | return;
460 | }
461 |
462 | Class responseClass = [self responseClassWithRequestBean:requestBean];
463 | AJResponseBeanBase *responseBean = [responseClass mj_objectWithKeyValues:responseObject];
464 | responseBean.rawData = responseObject;
465 |
466 | if ([responseBean checkSuccess]) {
467 |
468 | // 缓存
469 | if ([requestBean cacheResponse]) {
470 | [self saveCacheWithRequestBean:requestBean responseObj:responseObject];
471 | }
472 |
473 | // 成功
474 | callBack(responseBean, nil);
475 |
476 | }else{
477 | // 失败
478 | NSString *errMsg = [NSString stringWithFormat:@"错误码:%ld", (long)[responseBean statusCode]];
479 | NSString *responseMsg = [responseBean responseMessage];
480 | if ((responseMsg != nil) && ![responseMsg isEqualToString:@""] ) {
481 | errMsg = [NSString stringWithFormat:@"%@ -- %@", errMsg, responseMsg];
482 | }
483 |
484 | [AJNetworkLog logWithContent:[NSString stringWithFormat:@"请求失败:%@", errMsg]];
485 |
486 | AJError *err = [[AJError alloc] initWithCode:[responseBean statusCode] message:errMsg];
487 | callBack(responseBean, err);
488 | }
489 | }
490 |
491 | + (void)handleFailureWithError:(NSError *)error callBack:(AJRequestCallBack)callBack
492 | {
493 | [AJNetworkLog logWithContent:[NSString stringWithFormat:@"请求失败:%@", [error description]]];
494 |
495 | AJError *err = [[AJError alloc] initWithCode:error.code message:error.description];
496 | callBack(nil, err);
497 | }
498 |
499 |
500 | + (void)saveCacheWithRequestBean:(__kindof AJRequestBeanBase *) requestBean responseObj:(id _Nullable) responseObject
501 | {
502 | SPTPersistentCache *httpCache = [[AJNetworkConfig shareInstance] globalHttpCache];
503 |
504 | NSData *cacheData = [responseObject mj_JSONData];
505 | NSString *cacheKey = [requestBean taskKey];
506 | NSTimeInterval ttl = [requestBean cacheLiveSecond];
507 |
508 | [httpCache storeData:cacheData forKey:cacheKey ttl:ttl locked:NO withCallback:^(SPTPersistentCacheResponse * _Nonnull response) {
509 |
510 | if (response.result == SPTPersistentCacheResponseCodeOperationSucceeded) {
511 | AJLog(@"#cache data success#: %@", cacheKey);
512 | }else{
513 | AJLog(@"#cache fail#: %@", [response.error description]);
514 | }
515 |
516 | } onQueue:dispatch_get_main_queue()];
517 | }
518 |
519 | #pragma mark Hub
520 | + (void)showHub:(AJRequestBeanBase *)requestBean
521 | {
522 | if ([requestBean isShowHub]) {
523 |
524 | id delegate = [AJNetworkConfig shareInstance].hubDelegate;
525 | if ([delegate respondsToSelector:@selector(showHub:)]) {
526 | [delegate showHub:[requestBean hubTips]];
527 | }
528 | }
529 | }
530 |
531 | + (void)dismissHub:(AJRequestBeanBase *)requestBean
532 | {
533 | if ([requestBean isShowHub]) {
534 |
535 | id delegate = [AJNetworkConfig shareInstance].hubDelegate;
536 | if ([delegate respondsToSelector:@selector(dismissHub)]) {
537 | [delegate dismissHub];
538 | }
539 | }
540 | }
541 |
542 | @end
543 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkStatus.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkStatus.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/10.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, AJNetworkReachabilityStatus)
12 | {
13 | AJNetworkReachabilityStatusUnknown,
14 | AJNetworkReachabilityStatusNotReachable,
15 | AJNetworkReachabilityStatusWWAN,
16 | AJNetworkReachabilityStatusWiFi
17 | };
18 |
19 | @interface AJNetworkStatus : NSObject
20 |
21 | + (AJNetworkStatus *)shareInstance;
22 |
23 | - (AJNetworkReachabilityStatus)currentStatus;
24 |
25 | - (BOOL)canReachable;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworkStatus.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworkStatus.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/10.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJNetworkStatus.h"
10 | #import "AFNetworkReachabilityManager.h"
11 |
12 | @interface AJNetworkStatus()
13 | @property (nonatomic, strong) AFNetworkReachabilityManager *networkManager;
14 | @end
15 |
16 | @implementation AJNetworkStatus
17 |
18 | + (AJNetworkStatus *)shareInstance
19 | {
20 | static AJNetworkStatus *instance;
21 | static dispatch_once_t onceToken;
22 | dispatch_once(&onceToken, ^{
23 | instance = [[AJNetworkStatus alloc] init];
24 |
25 | instance.networkManager = [AFNetworkReachabilityManager manager];
26 | [instance.networkManager startMonitoring];
27 | });
28 |
29 | return instance;
30 | }
31 |
32 | - (AJNetworkReachabilityStatus)currentStatus
33 | {
34 | switch (self.networkManager.networkReachabilityStatus) {
35 |
36 | case AFNetworkReachabilityStatusUnknown: {
37 | return AJNetworkReachabilityStatusUnknown;
38 | }
39 |
40 | case AFNetworkReachabilityStatusNotReachable: {
41 | return AJNetworkReachabilityStatusNotReachable;
42 | }
43 |
44 | case AFNetworkReachabilityStatusReachableViaWWAN: {
45 | return AJNetworkReachabilityStatusWWAN;
46 | }
47 |
48 | case AFNetworkReachabilityStatusReachableViaWiFi: {
49 | return AJNetworkReachabilityStatusWiFi;
50 | }
51 |
52 | default:
53 | return AJNetworkReachabilityStatusUnknown;
54 | }
55 | }
56 |
57 | - (BOOL)canReachable
58 | {
59 | return self.networkManager.reachable;
60 | }
61 |
62 | @end
63 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/AJNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJNetworking.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #ifndef AJNetworking_h
10 | #define AJNetworking_h
11 |
12 | #import "AJNetworkConfig.h"
13 | #import "AJNetworkManager.h"
14 | #import "AJRequestBeanBase.h"
15 | #import "AJResponseBeanBase.h"
16 | #import "AJRequestBeanDownloadTaskBase.h"
17 | #import "AJRequestBeanProtocol.h"
18 | #import "AJResponseBeanProtocol.h"
19 | #import "AJCacheOptions.h"
20 | #import "AJNetworkStatus.h"
21 | #import "AJError.h"
22 | #import "AJHubProtocol.h"
23 |
24 | #endif /* AJNetworking_h */
25 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJRequestBeanBase.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJRequestBeanBase.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJRequestBeanProtocol.h"
11 |
12 | @interface AJRequestBeanBase : NSObject
13 | @property (copy, nonatomic, readonly) NSString *taskKey;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJRequestBeanBase.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJRequestBeanBase.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 | #import
11 | #import "MJExtension.h"
12 | #import "MD5Util.h"
13 |
14 | static const NSTimeInterval DEFAULT_TIMEOUT = 30.0;
15 |
16 | @implementation AJRequestBeanBase
17 |
18 | - (HTTP_SCHEME)httpScheme
19 | {
20 | return HTTP_SCHEME_HTTP;
21 | }
22 |
23 | - (HTTP_METHOD)httpMethod
24 | {
25 | return HTTP_METHOD_GET;
26 | }
27 |
28 | - (NSTimeInterval)timeout
29 | {
30 | return DEFAULT_TIMEOUT;
31 | }
32 |
33 | - (NSString *)apiHost
34 | {
35 | return [AJNetworkConfig shareInstance].hostUrl;
36 | }
37 |
38 | - (NSString *)apiPath
39 | {
40 | return @"";
41 | }
42 |
43 | - (NSDictionary *)httpHeader
44 | {
45 | return nil;
46 | }
47 |
48 | - (NSString *)requestUrl
49 | {
50 | NSString *scheme = @"http";
51 | if ([self httpScheme] == HTTP_SCHEME_HTTPS) {
52 | scheme = @"https";
53 | }
54 |
55 | NSString *baseUrl = [self apiHost];
56 | NSString *apiPath = [self apiPath];
57 | NSString *requestUrl = [NSString stringWithFormat:@"%@://%@%@", scheme, baseUrl, apiPath];
58 |
59 | return requestUrl;
60 | }
61 |
62 | - (AFConstructingBlock)constructingBodyBlock
63 | {
64 | return nil;
65 | }
66 |
67 | - (BOOL)cacheResponse
68 | {
69 | return NO;
70 | }
71 |
72 | - (NSUInteger)cacheLiveSecond
73 | {
74 | return 0;
75 | }
76 |
77 | + (NSArray *)ignoredPropertyNames
78 | {
79 | return @[];
80 | }
81 |
82 | + (NSArray *)mj_ignoredPropertyNames
83 | {
84 | NSMutableArray *ignoreArray = [NSMutableArray arrayWithArray:[self ignoredPropertyNames]];
85 |
86 | [ignoreArray addObject:@"taskKey"];
87 |
88 | // 解决MJExtension最新版本的BUG
89 | [ignoreArray addObject:@"debugDescription"];
90 | [ignoreArray addObject:@"description"];
91 | [ignoreArray addObject:@"hash"];
92 | [ignoreArray addObject:@"superclass"];
93 |
94 | return ignoreArray;
95 | }
96 |
97 | - (BOOL)isShowHub
98 | {
99 | return NO;
100 | }
101 |
102 | - (NSString *)hubTips
103 | {
104 | return nil;
105 | }
106 |
107 | - (NSString *)responseBeanClassName
108 | {
109 | const char *requestClassName = class_getName([self class]);
110 | NSString *responseBeanNameStr = [[NSString stringWithUTF8String:requestClassName] stringByReplacingOccurrencesOfString:@"Request" withString:@"Response"];
111 | return responseBeanNameStr;
112 | }
113 |
114 | - (NSString *)taskKey
115 | {
116 | NSString *cacheInfoStr = [NSString stringWithFormat:@"URL:%@ PARAMS:%@", [self requestUrl], [self mj_keyValues]];
117 |
118 | NSString *key = [MD5Util md5WithoutEncryptionFactor:cacheInfoStr];
119 |
120 | return key;
121 | }
122 |
123 | - (HTTP_REQUEST_SERIALIZATION)requestSerialization
124 | {
125 | return HTTP_REQUEST_SERIALIZATION_FORM;
126 | }
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJRequestBeanDownloadTaskBase.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDownloadTaskBase.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface AJRequestBeanDownloadTaskBase : AJRequestBeanBase
12 |
13 | @property (nonatomic, copy) NSString *fileUrl;
14 | @property (nonatomic, copy) NSString *saveFilePath;
15 | @property (nonatomic, copy) NSString *saveFileName;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJRequestBeanDownloadTaskBase.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDownloadTaskBase.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanDownloadTaskBase.h"
10 |
11 | @implementation AJRequestBeanDownloadTaskBase
12 |
13 | + (NSArray *)ignoredPropertyNames
14 | {
15 | return @[@"fileUrl", @"saveFilePath", @"saveFileName"];
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJRequestBeanProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJRequestBeanProtocol.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/22.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJNetworkConfig.h"
11 |
12 | @protocol AJRequestBeanProtocol
13 |
14 | /**
15 | * @author aboojan
16 | *
17 | * @brief HTTP协议
18 | *
19 | * @return HTTP or HTTPS
20 | */
21 | - (HTTP_SCHEME)httpScheme;
22 |
23 | /**
24 | * @author aboojan
25 | *
26 | * @brief HTTP请求方法
27 | *
28 | * @return GET / POST ...
29 | */
30 | - (HTTP_METHOD)httpMethod;
31 |
32 | /**
33 | * @author aboojan
34 | *
35 | * @brief 请求超时
36 | *
37 | * @return 超时时长
38 | */
39 | - (NSTimeInterval)timeout;
40 |
41 | /**
42 | * @author aboojan
43 | *
44 | * @brief Api的主域名
45 | *
46 | * @return 域名或IP
47 | */
48 | - (NSString *)apiHost;
49 |
50 | /**
51 | * @author aboojan
52 | *
53 | * @brief 请求API路径
54 | *
55 | * @return api路径
56 | */
57 | - (NSString *)apiPath;
58 |
59 | /**
60 | * @author aboojan
61 | *
62 | * @brief HTTP 请求 header
63 | *
64 | * @return 字典型,如果没有返回nil
65 | */
66 | - (NSDictionary *)httpHeader;
67 |
68 | /**
69 | * @author aboojan
70 | *
71 | * @brief 发起请求的完整链接
72 | *
73 | * @return 完整请求链接
74 | */
75 | - (NSString *)requestUrl;
76 |
77 | /**
78 | * @author aboojan
79 | *
80 | * @brief 当POST的内容带有文件等富文本时使用
81 | *
82 | * @return MultipartFormData Block
83 | */
84 | - (AFConstructingBlock)constructingBodyBlock;
85 |
86 | /**
87 | * @author aboojan
88 | *
89 | * @brief 是否缓存请求结果,默认不缓存
90 | *
91 | * @return YES,缓存;NO,不缓存
92 | */
93 | - (BOOL)cacheResponse;
94 |
95 | /**
96 | * @author aboojan
97 | *
98 | * @brief 缓存有效时间,单位为秒, 默认为0,即长期有效;
99 | *
100 | * @return 有效时间
101 | */
102 | - (NSUInteger)cacheLiveSecond;
103 |
104 | /**
105 | * @author aboojan
106 | *
107 | * @brief 忽略的请求参数名称数组
108 | *
109 | * @return 忽略参数数组,如:@[@"param1", @"param2"]
110 | */
111 | + (NSArray<__kindof NSString *> *)ignoredPropertyNames;
112 |
113 |
114 | /**
115 | * @author aboojan
116 | *
117 | * @brief 是否需要显示Loading,默认不显示
118 | *
119 | * @return YES,显示;NO,不显示
120 | */
121 | - (BOOL)isShowHub;
122 |
123 |
124 | /**
125 | * @author aboojan
126 | *
127 | * @brief Hub提示文案,isShowHub设置为YES时才会生效
128 | *
129 | * @return 提示文案
130 | */
131 | - (NSString *)hubTips;
132 |
133 |
134 | /**
135 | * @author aboojan
136 | *
137 | * @brief 用于Response JSON解析的目标类名,默认为根据RequestBean解析名称。
138 | * 如果返回nil,则解析为`AJResponseBeanBase`。
139 | * 类名对应的类必须继承自`AJResponseBeanBase`。
140 | *
141 | @return Response JSON解析的目标类名
142 | */
143 | - (NSString *)responseBeanClassName;
144 |
145 | /**
146 | 网络请求数据序列化格式
147 |
148 | @return HTTP_REQUEST_SERIALIZATION ENUM, 默认是HTTP_REQUEST_SERIALIZATION_FORM
149 | */
150 | - (HTTP_REQUEST_SERIALIZATION)requestSerialization;
151 |
152 | @end
153 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJResponseBeanBase.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJResponseBeanBase.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJResponseBeanProtocol.h"
11 | #import "AJNetworkConfig.h"
12 |
13 | @interface AJResponseBeanBase : NSObject
14 | @property (nonatomic, strong) id rawData;
15 | @end
16 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJResponseBeanBase.m:
--------------------------------------------------------------------------------
1 | //
2 | // AJResponseBeanBase.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/18.
6 | // Copyright © 2016年 Joiway. All rights reserved.
7 | //
8 |
9 | #import "AJResponseBeanBase.h"
10 |
11 | @implementation AJResponseBeanBase
12 |
13 | - (NSInteger)statusCode
14 | {
15 | return 0;
16 | }
17 |
18 | - (NSString *)responseMessage
19 | {
20 | return nil;
21 | }
22 |
23 | - (BOOL)checkSuccess
24 | {
25 | return NO;
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Model/AJResponseBeanProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // AJResponseBeanProtocol.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/22.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol AJResponseBeanProtocol
12 |
13 | /**
14 | * @author zhongbaojian
15 | *
16 | * @brief 请求结果状态码
17 | *
18 | * @return 状态码
19 | */
20 | - (NSInteger)statusCode;
21 |
22 | /**
23 | * @author zhongbaojian
24 | *
25 | * @brief 返回提示信息
26 | *
27 | * @return 提示信息
28 | */
29 | - (NSString *)responseMessage;
30 |
31 | /**
32 | * @author aboojan, 16-03-20 10:03:57
33 | *
34 | * @brief 根据自定义的状态码校验返回结果是否正确
35 | *
36 | * @return YES,正确;NO,错误
37 | */
38 | - (BOOL)checkSuccess;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Utils/MD5Util.h:
--------------------------------------------------------------------------------
1 | //
2 | // MD5Util.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 |
12 | @interface MD5Util : NSObject
13 |
14 | /**
15 | * @author aboojan
16 | *
17 | * @brief 使用默认加密因子进行MD5加密
18 | *
19 | * @param targetContent 需要加密的内容
20 | *
21 | * @return 经过MD5之后的内容
22 | */
23 | + (NSString *)md5WithDefaultEncryptionFactor:(NSString *) targetContent;
24 |
25 | /**
26 | * @author aboojan
27 | *
28 | * @brief 使用目标加密因子进行MD5加密
29 | *
30 | * @param targetContent 需要加密的内容
31 | * @param factor 加密因子
32 | *
33 | * @return MD5之后的内容
34 | */
35 | + (NSString *)md5WithContent:(NSString *) targetContent encryptionFactor:(NSString *) factor;
36 |
37 | /**
38 | * @author aboojan
39 | *
40 | * @brief 普通MD5加密
41 | *
42 | * @param targetContent 需要加密的内容
43 | *
44 | * @return MD5之后的内容
45 | */
46 | + (NSString *)md5WithoutEncryptionFactor:(NSString *) targetContent;
47 |
48 | /**
49 | * @author aboojan
50 | *
51 | * @brief 对NSDictionary数据进行MD5
52 | *
53 | * @param targetDictionary 需要进行MD5的Dictionary
54 | * @param factor 加密因子,如果没有加密因子则使用默认加密因子
55 | *
56 | * @return MD5之后的内容
57 | */
58 | + (NSString *)md5WithDictionary:(NSDictionary *)targetDictionary encryptionFactor:(NSString *)factor;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/AJNetworking/Classes/Utils/MD5Util.m:
--------------------------------------------------------------------------------
1 | //
2 | // MD5Util.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "MD5Util.h"
10 | #import
11 | #include
12 |
13 | // MD5加密因子
14 | #define MD5_DEFAULT_ENCRYPTION_FACTOR @"123456789"
15 |
16 | @implementation MD5Util
17 |
18 | + (NSString *)md5WithDefaultEncryptionFactor:(NSString *) targetContent
19 | {
20 |
21 | NSString *s1 = [self md5WithoutEncryptionFactor:[targetContent stringByAppendingString:MD5_DEFAULT_ENCRYPTION_FACTOR]];
22 | NSString *s2 = [self md5WithoutEncryptionFactor:s1];
23 | return s2;
24 | }
25 |
26 | + (NSString *)md5WithContent:(NSString *) targetContent encryptionFactor:(NSString *) factor
27 | {
28 |
29 | if (factor == nil || [factor isEqualToString:@""]) {
30 | factor = MD5_DEFAULT_ENCRYPTION_FACTOR;
31 | }
32 |
33 | NSString *s1 = [self md5WithoutEncryptionFactor:[targetContent stringByAppendingString:factor]];
34 | NSString *s2 = [self md5WithoutEncryptionFactor:s1];
35 | return s2;
36 | }
37 |
38 |
39 | + (NSString *)md5WithoutEncryptionFactor:(NSString *) targetContent
40 | {
41 | const char *cStr = [targetContent UTF8String];
42 | unsigned char result[16];
43 | CC_MD5(cStr, (CC_LONG)strlen(cStr), result);
44 | NSString *md5Str = [NSString stringWithFormat:
45 | @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
46 | result[0], result[1], result[2], result[3],
47 | result[4], result[5], result[6], result[7],
48 | result[8], result[9], result[10], result[11],
49 | result[12], result[13], result[14], result[15]
50 | ];
51 |
52 | return md5Str;
53 | }
54 |
55 | NSInteger letterSorted(id string1,id string2, void *context){
56 | if (string1&&string2) {
57 | return [string1 compare:string2];
58 | }else{
59 | return 0;
60 | }
61 |
62 | }
63 |
64 | + (NSString *)md5WithDictionary:(NSDictionary *) targetDictionary encryptionFactor:(NSString *) factor
65 | {
66 | if ( (targetDictionary != nil) && (targetDictionary.allKeys.count > 0) ) {
67 |
68 | NSArray *keys = targetDictionary.allKeys;
69 | NSArray *sortedKeys = [keys sortedArrayUsingFunction:letterSorted context:NULL];
70 | NSMutableString *sortedValueString = [[NSMutableString alloc] init];
71 |
72 | for (NSString *key in sortedKeys) {
73 |
74 | id value = [targetDictionary objectForKey:key];
75 |
76 | if (value && ![value isEqual:[NSNull null]]) {
77 |
78 | NSString *valueString = @"";
79 |
80 | Class numberClass = objc_getClass("__NSCFNumber");
81 | Class boolClass = objc_getClass("__NSCFBoolean");
82 |
83 | if ([value class] == numberClass || [value class] == boolClass) {
84 |
85 | valueString = [value stringValue];
86 |
87 | }else{
88 |
89 | valueString = value;
90 | }
91 |
92 | [sortedValueString appendString:valueString];
93 | }
94 |
95 | }
96 |
97 | return [self md5WithContent:sortedValueString encryptionFactor:factor];
98 | }
99 |
100 | return @"";
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/BViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // BViewController.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/11/24.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 |
11 | @interface BViewController : ViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/BViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // BViewController.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/11/24.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "BViewController.h"
10 | #import "AJNetworkManager.h"
11 | #import "RequestBeanDemoRegister.h"
12 | #import "ResponseBeanDemoRegister.h"
13 |
14 | @interface BViewController ()
15 | @property (nonatomic, strong) NSMutableArray *taskKeyArray;
16 | @end
17 |
18 | @implementation BViewController
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 | self.view.backgroundColor = [UIColor orangeColor];
23 | self.taskKeyArray = [NSMutableArray array];
24 |
25 | [self performSelector:@selector(closePage) withObject:nil afterDelay:1.0];
26 | [self sendRequest];
27 | }
28 |
29 | - (void)closePage
30 | {
31 | [self dismissViewControllerAnimated:YES completion:^{
32 | // 结束网络请求也可以放到这里
33 | }];
34 | }
35 |
36 | - (void)dealloc
37 | {
38 | // 可以在控制器释放的时候结束正在进行着的网络请求
39 | // 可以写一个控制器基类,暴露出一个taskKey数组,然后统一在页面关闭时结束网络请求
40 | [AJNetworkManager stopRequestTaskWithTaskKey:self.taskKeyArray];
41 |
42 | AJLog(@"dealloc");
43 | }
44 |
45 | - (void)sendRequest
46 | {
47 | [self request1];
48 | [self request2];
49 | }
50 |
51 | - (void)request1
52 | {
53 | RequestBeanDemoRegister *requestBean = [RequestBeanDemoRegister new];
54 | requestBean.userName = @"Github";
55 | requestBean.pw = @"123456";
56 |
57 | [self.taskKeyArray addObject:[requestBean taskKey]];
58 |
59 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
60 |
61 | AJLog(@"#request1 Callback#: %@", err);
62 | }];
63 | }
64 |
65 | - (void)request2
66 | {
67 | RequestBeanDemoRegister *requestBean = [RequestBeanDemoRegister new];
68 | requestBean.userName = @"Google";
69 | requestBean.pw = @"123456";
70 |
71 | [self.taskKeyArray addObject:[requestBean taskKey]];
72 |
73 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
74 |
75 | AJLog(@"#request2 Callback#: %@", err);
76 | }];
77 | }
78 |
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoBase.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoBase.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface RequestBeanDemoBase : AJRequestBeanBase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoBase.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoBase.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 | #import "RequestConfig.h"
11 |
12 | @implementation RequestBeanDemoBase
13 |
14 | - (NSString *)apiPath
15 | {
16 | return [[RequestConfig shareInstance] apiPathWithRequestClass:[self class]];
17 | }
18 |
19 | - (HTTP_SCHEME)httpScheme
20 | {
21 | return [[RequestConfig shareInstance] httpSchemeWithRequestClass:[self class]];
22 | }
23 |
24 | - (HTTP_METHOD)httpMethod
25 | {
26 | return [[RequestConfig shareInstance] httpMethodWithRequestClass:[self class]];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoFilm.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoFilm.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/27.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 |
11 | @interface RequestBeanDemoFilm : RequestBeanDemoBase
12 | /// 测试码,用于控制返回结果
13 | @property (nonatomic,assign) NSInteger testCode;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoFilm.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoFilm.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/27.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoFilm.h"
10 |
11 | @implementation RequestBeanDemoFilm
12 |
13 | - (BOOL)cacheResponse
14 | {
15 | return YES;
16 | }
17 |
18 | - (BOOL)isShowHub
19 | {
20 | return YES;
21 | }
22 |
23 | - (NSString *)hubTips
24 | {
25 | return @"加载中...";
26 | }
27 |
28 | @end
29 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoLogin.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoLogin.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 |
11 | @interface RequestBeanDemoLogin : RequestBeanDemoBase
12 | @property (copy, nonatomic) NSString *account;
13 | @property (copy, nonatomic) NSString *pw;
14 |
15 | // 测试参数忽略
16 | @property (copy, nonatomic) NSString *name;
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoLogin.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoLogin.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoLogin.h"
10 |
11 | @implementation RequestBeanDemoLogin
12 | + (NSArray *)ignoredPropertyNames
13 | {
14 | return @[@"name"];
15 | }
16 | @end
17 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoNews.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoNews.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 |
11 | @interface RequestBeanDemoNews : RequestBeanDemoBase
12 | @property (copy, nonatomic) NSString *userId;
13 | @property (copy, nonatomic) NSString *dateTime;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoNews.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoNews.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoNews.h"
10 |
11 | @implementation RequestBeanDemoNews
12 |
13 | - (BOOL)cacheResponse
14 | {
15 | return YES;
16 | }
17 |
18 | - (NSUInteger)cacheLiveSecond
19 | {
20 | return 80;
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoRegister.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoRegister.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 |
11 | @interface RequestBeanDemoRegister : RequestBeanDemoBase
12 |
13 | @property (copy, nonatomic) NSString *userName;
14 | @property (copy, nonatomic) NSString *pw;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanDemoRegister.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDemoRegister.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoRegister.h"
10 |
11 | @implementation RequestBeanDemoRegister
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanVersion.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanVersion.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/11/13.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDemoBase.h"
10 |
11 | @interface RequestBeanVersion : RequestBeanDemoBase
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestBeanVersion.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanVersion.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/11/13.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanVersion.h"
10 |
11 | @implementation RequestBeanVersion
12 | - (NSString *)responseBeanClassName
13 | {
14 | // 可以定义一个通用的Response类
15 | return @"ResponseBeanDemo";
16 | }
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestConfig.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJNetworking.h"
11 |
12 |
13 | @interface RequestConfig : NSObject
14 |
15 | +(RequestConfig *)shareInstance;
16 |
17 | - (NSString *)apiPathWithRequestClass:(Class)requestClass;
18 | - (HTTP_SCHEME)httpSchemeWithRequestClass:(Class)requestClass;
19 | - (HTTP_METHOD)httpMethodWithRequestClass:(Class)requestClass;
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestConfig.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestConfig.h"
10 |
11 | static NSString * const KEY_API = @"api";
12 | static NSString * const KEY_SCHEME = @"scheme";
13 | static NSString * const KEY_METHOD = @"method";
14 |
15 | @interface RequestConfig()
16 | @property (nonatomic,strong) NSDictionary *config;
17 | @end
18 |
19 | @implementation RequestConfig
20 |
21 | + (RequestConfig *)shareInstance
22 | {
23 | static RequestConfig *instance;
24 | static dispatch_once_t onceToken;
25 |
26 | dispatch_once(&onceToken, ^{
27 | instance = [[RequestConfig alloc] init];
28 |
29 | NSString *configPath = [[NSBundle mainBundle] pathForResource:@"RequestConfig" ofType:@"plist"];
30 | instance.config = [NSDictionary dictionaryWithContentsOfFile:configPath];
31 |
32 | });
33 |
34 | return instance;
35 | }
36 |
37 | - (NSString *)apiPathWithRequestClass:(Class)requestClass
38 | {
39 | NSString *apiPath = self.config[NSStringFromClass(requestClass)][KEY_API];
40 | return apiPath;
41 | }
42 |
43 | - (HTTP_SCHEME)httpSchemeWithRequestClass:(Class)requestClass
44 | {
45 | NSString *httpScheme = self.config[NSStringFromClass(requestClass)][KEY_SCHEME];
46 | if ([httpScheme isEqualToString:@"HTTPS"]) {
47 | return HTTP_SCHEME_HTTPS;
48 | }else{
49 | return HTTP_SCHEME_HTTP;
50 | }
51 | }
52 |
53 | - (HTTP_METHOD)httpMethodWithRequestClass:(Class)requestClass
54 | {
55 | NSString *httpMethod = self.config[NSStringFromClass(requestClass)][KEY_METHOD];
56 | if ([httpMethod isEqualToString:@"GET"]) {
57 | return HTTP_METHOD_GET;
58 |
59 | }else if ([httpMethod isEqualToString:@"POST"]){
60 | return HTTP_METHOD_POST;
61 |
62 | }else if ([httpMethod isEqualToString:@"HEAD"]){
63 | return HTTP_METHOD_HEAD;
64 |
65 | }else if ([httpMethod isEqualToString:@"PUT"]){
66 | return HTTP_METHOD_PUT;
67 |
68 | }else if ([httpMethod isEqualToString:@"DELETE"]){
69 | return HTTP_METHOD_DELETE;
70 |
71 | }else{
72 | return HTTP_METHOD_PATCH;
73 | }
74 | }
75 |
76 |
77 | @end
78 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/RequestConfig.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | RequestBeanDemoLogin
6 |
7 | api
8 | /login
9 | scheme
10 | HTTP
11 | method
12 | GET
13 | desc
14 | 接口描述:登陆
15 |
16 | RequestBeanDemoRegister
17 |
18 | api
19 | /register
20 | scheme
21 | HTTP
22 | method
23 | POST
24 | desc
25 | 接口描述:注册
26 |
27 | RequestBeanDemoNews
28 |
29 | api
30 | /news
31 | scheme
32 | HTTP
33 | method
34 | GET
35 | desc
36 | 获取新闻列表
37 |
38 | RequestBeanDemoFilm
39 |
40 | api
41 | /film
42 | scheme
43 | HTTP
44 | method
45 | GET
46 | desc
47 | 接口描述:电影列表
48 |
49 | RequestBeanVersion
50 |
51 | api
52 | /version
53 | scheme
54 | HTTP
55 | method
56 | GET
57 | desc
58 | 接口描述:版本号
59 |
60 |
61 |
62 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemo.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemo.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/22.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJResponseBeanBase.h"
10 |
11 | @interface ResponseBeanDemo : AJResponseBeanBase
12 | @property (nonatomic,strong) NSString *msg;
13 | @property (nonatomic,assign) NSInteger code;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemo.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemo.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/22.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemo.h"
10 |
11 | @implementation ResponseBeanDemo
12 | - (NSInteger)statusCode
13 | {
14 | return self.code;
15 | }
16 |
17 | - (NSString *)responseMessage
18 | {
19 | return self.msg;
20 | }
21 |
22 | - (BOOL)checkSuccess
23 | {
24 | if (self.code == 1) {
25 | return YES;
26 | }else{
27 | return NO;
28 | }
29 | }
30 |
31 | @end
32 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoFilm.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoFilm.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/27.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemo.h"
10 |
11 | @interface Film : NSObject
12 | @property (copy, nonatomic) NSString *name;
13 | @property (copy, nonatomic) NSString *type;
14 | @end
15 |
16 |
17 | @interface ResponseBeanDemoFilm : ResponseBeanDemo
18 | @property (nonatomic,strong) NSArray<__kindof Film *> *data;
19 | @end
20 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoFilm.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoFilm.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/27.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemoFilm.h"
10 |
11 | @implementation Film
12 | @end
13 |
14 | @implementation ResponseBeanDemoFilm
15 | + (NSDictionary *)mj_objectClassInArray
16 | {
17 | return @{@"data":@"Film"};
18 | }
19 | @end
20 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoLogin.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoLogin.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemo.h"
10 | #import "User.h"
11 |
12 | @interface ResponseBeanDemoLogin : ResponseBeanDemo
13 | @property (nonatomic,strong) User *data;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoLogin.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoLogin.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemoLogin.h"
10 |
11 | @implementation ResponseBeanDemoLogin
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoNews.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoNews.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemo.h"
10 |
11 | @interface News : NSObject
12 | @property (copy, nonatomic) NSString *title;
13 | @property (copy, nonatomic) NSString *content;
14 | @property (copy, nonatomic) NSString *author;
15 | @end
16 |
17 | @interface ResponseBeanDemoNews : ResponseBeanDemo
18 | @property (nonatomic,strong) NSArray<__kindof News *> *data;
19 | @end
20 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoNews.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoNews.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemoNews.h"
10 |
11 | @implementation News
12 |
13 | @end
14 |
15 | @implementation ResponseBeanDemoNews
16 |
17 | + (NSDictionary *)mj_objectClassInArray
18 | {
19 | return @{@"data":@"News"};
20 | }
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoRegister.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoRegister.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemo.h"
10 |
11 | @interface RegisterUser : NSObject
12 | @property (copy, nonatomic) NSString *userId;
13 | @end
14 |
15 | @interface ResponseBeanDemoRegister : ResponseBeanDemo
16 | @property (nonatomic,strong) RegisterUser *data;
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ResponseBeanDemoRegister.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDemoRegister.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDemoRegister.h"
10 |
11 | @implementation RegisterUser
12 |
13 | @end
14 |
15 | @implementation ResponseBeanDemoRegister
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/User.h:
--------------------------------------------------------------------------------
1 | //
2 | // User.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface User : NSObject
12 |
13 | @property (copy, nonatomic) NSString *userId;
14 | @property (copy, nonatomic) NSString *name;
15 | @property (nonatomic,assign) NSInteger age;
16 | @property (copy, nonatomic) NSString *gender;
17 | @property (copy, nonatomic) NSString *job;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/User.m:
--------------------------------------------------------------------------------
1 | //
2 | // User.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/8/6.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "User.h"
10 |
11 | @implementation User
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/3/19.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/AJNetworking/Demo/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/3/19.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import "AJNetworkManager.h"
11 | #import "RequestBeanDemoLogin.h"
12 | #import "ResponseBeanDemoLogin.h"
13 | #import "RequestBeanDemoRegister.h"
14 | #import "ResponseBeanDemoRegister.h"
15 | #import "RequestBeanDemoNews.h"
16 | #import "ResponseBeanDemoNews.h"
17 | #import "RequestBeanDemoFilm.h"
18 | #import "ResponseBeanDemoFilm.h"
19 | #import "RequestBeanVersion.h"
20 | #import "MJExtension.h"
21 | #import "BViewController.h"
22 |
23 | @interface ViewController ()
24 |
25 | @property (weak, nonatomic) IBOutlet UITextField *accountTF;
26 | @property (weak, nonatomic) IBOutlet UITextField *pwTF;
27 | - (IBAction)loginBtnClick:(UIButton *)sender;
28 |
29 |
30 | @property (weak, nonatomic) IBOutlet UITextField *userNameTF;
31 | @property (weak, nonatomic) IBOutlet UITextField *pwTF1;
32 | - (IBAction)registerBtnClick:(id)sender;
33 |
34 |
35 | @property (weak, nonatomic) IBOutlet UITextField *userIdTF;
36 | @property (weak, nonatomic) IBOutlet UITextField *dateTimeTF;
37 | - (IBAction)readNewsBtnClick:(id)sender;
38 |
39 |
40 | @property (weak, nonatomic) IBOutlet UISegmentedControl *statusSegment;
41 | - (IBAction)filmBtnClick:(id)sender;
42 |
43 | - (IBAction)jumpToPage:(id)sender;
44 |
45 | @end
46 |
47 | @implementation ViewController
48 |
49 | - (void)viewDidLoad {
50 | [super viewDidLoad];
51 | }
52 |
53 | #pragma mark 自定义Response Bean 示例
54 | - (IBAction)customResponseBeanClassBtnClick:(id)sender
55 | {
56 | RequestBeanVersion *requestBean = [[RequestBeanVersion alloc] init];
57 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
58 | if (!err) {
59 | AJLog(@"%@", responseBean);
60 | }else{
61 | AJLog(@"%@", [err description]);
62 | }
63 | }];
64 | }
65 |
66 |
67 | #pragma mark GET请求示例
68 | - (IBAction)loginBtnClick:(UIButton *)sender
69 | {
70 | [self.view endEditing:YES];
71 |
72 | RequestBeanDemoLogin *requestBean = [[RequestBeanDemoLogin alloc] init];
73 | requestBean.account = self.accountTF.text;
74 | requestBean.pw = self.pwTF.text;
75 |
76 | //test
77 | requestBean.name = @"aboo";
78 |
79 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
80 |
81 | if (!err) {
82 |
83 | // 返回结果处理
84 | ResponseBeanDemoLogin *response = responseBean;
85 | AJLog(@"user: %@", response.data);
86 |
87 | }else{
88 |
89 | if (responseBean) {
90 | AJLog(@"请求错误:%ld -- %@", responseBean.statusCode, responseBean.responseMessage);
91 | }else{
92 | AJLog(@"网络错误,稍后重试");
93 | }
94 | }
95 | }];
96 | }
97 |
98 | #pragma mark POST请求示例
99 | - (IBAction)registerBtnClick:(id)sender
100 | {
101 | [self.view endEditing:YES];
102 |
103 | RequestBeanDemoRegister *requestBean = [RequestBeanDemoRegister new];
104 | requestBean.userName = self.userNameTF.text;
105 | requestBean.pw = self.pwTF1.text;
106 |
107 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
108 |
109 | if (!err) {
110 |
111 | // 结果处理
112 | ResponseBeanDemoRegister *response = responseBean;
113 | AJLog(@"userId:%@", response.data.userId);
114 | }
115 | }];
116 |
117 | }
118 |
119 | #pragma mark 短期缓存示例
120 | - (IBAction)readNewsBtnClick:(id)sender
121 | {
122 | [self.view endEditing:YES];
123 |
124 | RequestBeanDemoNews *requestBean = [RequestBeanDemoNews new];
125 | requestBean.userId = self.userIdTF.text;
126 | requestBean.dateTime = self.dateTimeTF.text;
127 |
128 | [AJNetworkManager requestWithBean:requestBean cacheCallBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
129 |
130 | if (!err) {
131 |
132 | // 读取缓存
133 | AJLog(@"###来自缓存###");
134 | [self handleNews:responseBean];
135 |
136 | }else{
137 | // 读取缓存失败
138 | AJLog(@"%@", [err description]);
139 | }
140 |
141 | } httpCallBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
142 |
143 | if (!err) {
144 |
145 | // 网络请求成功
146 | AJLog(@"###来自网络###");
147 | [self handleNews:responseBean];
148 |
149 | }else{
150 | // 网络请求失败
151 | AJLog(@"%@", [err description]);
152 | }
153 |
154 | }];
155 |
156 | }
157 |
158 | - (void)handleNews:(ResponseBeanDemoNews *)news
159 | {
160 | for (News *page in news.data) {
161 | AJLog(@"%@ -- %@ -- %@", page.title, page.content, page.author);
162 | }
163 | }
164 |
165 | #pragma mark 长期缓存示例
166 | - (IBAction)filmBtnClick:(id)sender
167 | {
168 | NSInteger testCode = self.statusSegment.selectedSegmentIndex;
169 |
170 | RequestBeanDemoFilm *reqeustBean = [[RequestBeanDemoFilm alloc] init];
171 | reqeustBean.testCode = testCode;
172 |
173 | /*
174 | * 对于服务器增量更新的设计,可以先读取缓存显示出来,然后根据http请求结果来判断是否更新页面。
175 | */
176 |
177 | [AJNetworkManager requestWithBean:reqeustBean cacheCallBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
178 |
179 | if (!err) {
180 |
181 | AJLog(@"---来自缓存---");
182 | [self handleFilm:responseBean];
183 | }
184 |
185 | } httpCallBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
186 |
187 | if (!err) {
188 |
189 | AJLog(@"---来自网络---");
190 | [self handleFilm:responseBean];
191 | }
192 |
193 | }];
194 | }
195 |
196 | - (void)handleFilm:(ResponseBeanDemoFilm *)films
197 | {
198 | for (Film *film in films.data) {
199 | AJLog(@"%@ -- %@", film.name, film.type);
200 | }
201 | }
202 |
203 | #pragma mark
204 | - (IBAction)jumpToPage:(id)sender
205 | {
206 | BViewController *bPage = [[BViewController alloc] init];
207 | [self presentViewController:bPage animated:YES completion:^{
208 | //
209 | }];
210 | }
211 |
212 | @end
213 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Certificate/client_test_local.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbooJan/AJNetworking/cb06bcd954c40a84c40ef7e99eb1443fef5eb55b/AJNetworking/Example/Certificate/client_test_local.p12
--------------------------------------------------------------------------------
/AJNetworking/Example/LoginViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // LoginViewController.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface LoginViewController : UIViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/LoginViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // LoginViewController.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "LoginViewController.h"
10 | #import "RequestBeanLogin.h"
11 | #import "ResponseBeanLogin.h"
12 | #import "AJNetworkManager.h"
13 | #import "TripleDESEncrypt.h"
14 | #import "ResponseBeanAlipayConfig.h"
15 | #import "RequestBeanAlipayConfig.h"
16 | #import "RequestBeanUploadAvatar.h"
17 | #import "ResponseBeanUploadAvatar.h"
18 | #import "ResponseBeanDownloadFile.h"
19 | #import "RequestBeanDownloadFile.h"
20 | #import "AJRequestBeanDownloadTaskBase.h"
21 | #import "MD5Util.h"
22 |
23 |
24 | @interface LoginViewController ()
25 | @property (weak, nonatomic) IBOutlet UITextField *accountTF;
26 | @property (weak, nonatomic) IBOutlet UITextField *passwordTF;
27 |
28 | - (IBAction)loginBtnClick:(id)sender;
29 | - (IBAction)httpsTestBtnClick:(id)sender;
30 | - (IBAction)uploadBtnClick:(id)sender;
31 |
32 | - (IBAction)downloadBtnClick:(id)sender;
33 | - (IBAction)suspendDownloadBtnClick:(id)sender;
34 | - (IBAction)cancelDownloadBtnClick:(id)sender;
35 |
36 | @property (nonatomic, strong) NSURLSessionDownloadTask *downloadTask;
37 | @property (nonatomic, assign) BOOL isDownloading;
38 |
39 | @end
40 |
41 | @implementation LoginViewController
42 |
43 | - (void)viewDidLoad {
44 | [super viewDidLoad];
45 | }
46 |
47 | - (IBAction)loginBtnClick:(id)sender
48 | {
49 | [self.view endEditing:YES];
50 |
51 | NSString *accountStr = self.accountTF.text;
52 | NSString *pwStr = self.passwordTF.text;
53 |
54 | RequestBeanLogin *requestBean = [[RequestBeanLogin alloc] init];
55 | requestBean.phone = [TripleDESEncrypt tripleDES:accountStr encryptOrDecrypt:kCCEncrypt];
56 | requestBean.pwd = [TripleDESEncrypt tripleDES:pwStr encryptOrDecrypt:kCCEncrypt];
57 |
58 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
59 |
60 | if (!err) {
61 | ResponseBeanLogin *response = responseBean;
62 | AJLog(@"#: %@", response.rawData);
63 | }
64 |
65 | }];
66 | }
67 |
68 | - (IBAction)httpsTestBtnClick:(id)sender
69 | {
70 | // https 测试
71 |
72 | RequestBeanAlipayConfig *requestBean = [[RequestBeanAlipayConfig alloc] init];
73 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
74 |
75 | if (!err) {
76 | ResponseBeanAlipayConfig *response = responseBean;
77 | AlipayConfigBean *configBean = response.obj;
78 |
79 | }
80 | }];
81 | }
82 |
83 | - (IBAction)uploadBtnClick:(id)sender
84 | {
85 | RequestBeanUploadAvatar *requestBean = [[RequestBeanUploadAvatar alloc] init];
86 | requestBean.compid = @"1702487";
87 | requestBean.avatar = [UIImage imageNamed:@"testImg"];
88 |
89 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
90 |
91 | if (!err) {
92 | ResponseBeanUploadAvatar *response = responseBean;
93 | }
94 | }];
95 | }
96 |
97 | - (IBAction)downloadBtnClick:(id)sender
98 | {
99 | // NSString *fileUrl = @"http://temp.26923.com/2016/pic/000/378/032ad9af805a8e83d8323f515d1d6645.jpg";
100 | NSString *fileUrl = @"http://125.89.74.165/10/m/m/j/a/mmjazvfnzomddhahggpebnswqfeutw/hc.yinyuetai.com/026601346FEFC3079F2136B68B0ECFD7.flv?sc=5927e705d66bde7b&br=717";
101 | NSString *fileMD5 = [MD5Util md5WithoutEncryptionFactor:fileUrl];
102 |
103 | AJRequestBeanDownloadTaskBase *downloadRequest = [[AJRequestBeanDownloadTaskBase alloc] init];
104 |
105 | downloadRequest.fileUrl = fileUrl;
106 | // downloadRequest.saveFileName = [NSString stringWithFormat:@"%@.jpg", fileMD5];
107 |
108 | downloadRequest.saveFileName = [NSString stringWithFormat:@"%@.mp4", fileMD5];
109 |
110 | downloadRequest.saveFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
111 |
112 | self.downloadTask = [AJNetworkManager downloadTaskWithBean:downloadRequest progress:^(int64_t totalUnitCount, int64_t completedUnitCount, double progressRate) {
113 |
114 | AJLog(@"下载进度:%lf", progressRate);
115 |
116 | } completion:^(NSURL *filePath, NSError *error) {
117 |
118 | if (error) {
119 | AJLog(@"下载失败:%@", [error description]);
120 | }else{
121 | AJLog(@"下载成功:%@", [filePath description]);
122 | }
123 |
124 | }];
125 |
126 | self.isDownloading = YES;
127 | }
128 |
129 | - (IBAction)suspendDownloadBtnClick:(UIButton *)sender
130 | {
131 | // 暂停下载
132 | if (self.downloadTask) {
133 |
134 | if (self.isDownloading) {
135 |
136 | [self.downloadTask suspend];
137 | [sender setTitle:@"继续下载" forState:UIControlStateNormal];
138 |
139 | self.isDownloading = NO;
140 |
141 | }else{
142 |
143 | [self.downloadTask resume];
144 | [sender setTitle:@"暂停下载" forState:UIControlStateNormal];
145 |
146 | self.isDownloading = YES;
147 | }
148 | }
149 | }
150 |
151 | - (IBAction)cancelDownloadBtnClick:(id)sender
152 | {
153 | // 取消下载
154 | if (self.downloadTask) {
155 | [self.downloadTask cancel];
156 | }
157 | }
158 | @end
159 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/AlipayConfigBean.h:
--------------------------------------------------------------------------------
1 | //
2 | // AlipayConfigBean.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AlipayConfigBean : NSObject
12 | @property (nonatomic,strong) NSString *alipayPubKey;
13 | @property (nonatomic,strong) NSString *partnerPrivKey;
14 | @property (nonatomic,strong) NSString *sellerID;
15 | @property (nonatomic,strong) NSString *partnerID;
16 | @end
17 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/AlipayConfigBean.m:
--------------------------------------------------------------------------------
1 | //
2 | // AlipayConfigBean.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AlipayConfigBean.h"
10 | #import "TripleDESEncrypt.h"
11 |
12 | @implementation AlipayConfigBean
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/CompanyBean.h:
--------------------------------------------------------------------------------
1 | //
2 | // CompanyBean.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface CompanyBean : NSObject
12 |
13 | @property (nonatomic, copy) NSString *province;
14 | @property (nonatomic, copy) NSString *city;
15 | @property (nonatomic, copy) NSString *area;
16 | @property (nonatomic, copy) NSString *user_id;
17 | @property (nonatomic, copy) NSString *email;
18 | @property (nonatomic, copy) NSString *name;
19 | @property (nonatomic, copy) NSString *img;
20 | @property (nonatomic, copy) NSString *introduce;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/CompanyBean.m:
--------------------------------------------------------------------------------
1 | //
2 | // CompanyBean.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "CompanyBean.h"
10 |
11 | @implementation CompanyBean
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanAlipayConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanAlipayConfig.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface RequestBeanAlipayConfig : AJRequestBeanBase
12 | @property (nonatomic,assign) NSInteger device;
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanAlipayConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanAlipayConfig.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanAlipayConfig.h"
10 |
11 | @implementation RequestBeanAlipayConfig
12 |
13 | - (HTTP_METHOD)httpMethod
14 | {
15 | return HTTP_METHOD_POST;
16 | }
17 |
18 | - (HTTP_SCHEME)httpScheme
19 | {
20 | return HTTP_SCHEME_HTTPS;
21 | }
22 |
23 | - (NSString *)apiPath
24 | {
25 | return @"/pay/getKey";
26 | }
27 |
28 | - (NSInteger)device
29 | {
30 | return 1;
31 | }
32 |
33 | - (NSTimeInterval)timeout
34 | {
35 | return 35.0;
36 | }
37 |
38 | @end
39 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanDownloadFile.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDownloadFile.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface RequestBeanDownloadFile : AJRequestBeanBase
12 | @property (nonatomic, copy) NSString *compid;
13 | @property (nonatomic,strong) NSString *job_id;
14 | @property (nonatomic, copy) NSString *timestamp;
15 | @property (nonatomic, assign) NSInteger system;
16 | @property (nonatomic, copy) NSString *versions;
17 | @end
18 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanDownloadFile.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanDownloadFile.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanDownloadFile.h"
10 |
11 | @implementation RequestBeanDownloadFile
12 |
13 | - (HTTP_METHOD)httpMethod
14 | {
15 | return HTTP_METHOD_POST;
16 | }
17 |
18 | - (NSString *)apiPath
19 | {
20 | return @"/apply/exportBalance";
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanLogin.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanLogin.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface RequestBeanLogin : AJRequestBeanBase
12 | @property (nonatomic, copy) NSString *phone;
13 | @property (nonatomic, copy) NSString *pwd;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanLogin.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanLogin.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanLogin.h"
10 |
11 | @implementation RequestBeanLogin
12 |
13 | - (HTTP_METHOD)httpMethod
14 | {
15 | return HTTP_METHOD_POST;
16 | }
17 |
18 | - (NSString *)apiPath
19 | {
20 | return @"/company/login";
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanUploadAvatar.h:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanUploadAvatar.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/29.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJRequestBeanBase.h"
10 |
11 | @interface RequestBeanUploadAvatar : AJRequestBeanBase
12 |
13 | @property (nonatomic, copy) NSString *compid;
14 |
15 | @property (nonatomic, strong) UIImage *avatar;
16 | @end
17 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/RequestBeanUploadAvatar.m:
--------------------------------------------------------------------------------
1 | //
2 | // RequestBeanUploadAvatar.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/29.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "RequestBeanUploadAvatar.h"
10 |
11 | @implementation RequestBeanUploadAvatar
12 |
13 | - (NSString *)apiPath
14 | {
15 | return @"/company/updateLogo";
16 | }
17 |
18 | - (HTTP_METHOD)httpMethod
19 | {
20 | return HTTP_METHOD_POST;
21 | }
22 |
23 | - (NSTimeInterval)timeout
24 | {
25 | return 30.0;
26 | }
27 |
28 | + (NSArray *)mj_ignoredPropertyNames
29 | {
30 | return @[@"avatar"];
31 | }
32 |
33 | - (AFConstructingBlock)constructingBodyBlock
34 | {
35 | NSData *data = UIImageJPEGRepresentation(self.avatar, 0.8);
36 | NSString *name = @"img";
37 | NSString *formKey = @"img";
38 | NSString *type = @"applicaton/octet-stream";
39 |
40 | return AJConstructingBlockDefine {
41 | [formData appendPartWithFileData:data name:formKey fileName:name mimeType:type];
42 | };
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanAlipayConfig.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanAlipayConfig.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanExample.h"
10 | #import "AlipayConfigBean.h"
11 |
12 | @interface ResponseBeanAlipayConfig : ResponseBeanExample
13 | @property (nonatomic,strong) AlipayConfigBean *obj;
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanAlipayConfig.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanAlipayConfig.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanAlipayConfig.h"
10 |
11 | @implementation ResponseBeanAlipayConfig
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanDownloadFile.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDownloadFile.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanExample.h"
10 |
11 | @interface ResponseBeanDownloadFile : ResponseBeanExample
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanDownloadFile.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanDownloadFile.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/30.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanDownloadFile.h"
10 |
11 | @implementation ResponseBeanDownloadFile
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanExample.h:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanExample.h
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "AJResponseBeanBase.h"
10 |
11 | @interface ResponseBeanExample : AJResponseBeanBase
12 | ///提示语
13 | @property (nonatomic,strong) NSString *msg;
14 | ///状态值
15 | @property (nonatomic,assign) NSInteger status;
16 | @end
17 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Model/ResponseBeanExample.m:
--------------------------------------------------------------------------------
1 | //
2 | // ResponseBeanExample.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/26.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "ResponseBeanExample.h"
10 | #import
11 |
12 | #define kDataName @"data."
13 |
14 | @implementation ResponseBeanExample
15 |
16 | - (NSInteger)statusCode
17 | {
18 | return self.status;
19 | }
20 |
21 | - (NSString *)responseMessage
22 | {
23 | return self.msg;
24 | }
25 |
26 | - (BOOL)checkSuccess
27 | {
28 | if (self.status == 0) {
29 | return YES;
30 | }else{
31 | return NO;
32 | }
33 | }
34 |
35 | + (NSDictionary *)replacedKeyFromPropertyName
36 | {
37 | unsigned int propCount;
38 | objc_property_t* properties = class_copyPropertyList([self class], &propCount);
39 |
40 | NSMutableDictionary *parmas = [[NSMutableDictionary alloc] initWithCapacity:propCount];
41 |
42 | for (int i=0; i
34 |
35 |
36 | @interface NSData (Base64)
37 |
38 | + (NSData *)dataWithBase64EncodedString:(NSString *)string;
39 | - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
40 | - (NSString *)base64EncodedString;
41 |
42 | @end
43 |
44 |
45 | @interface NSString (Base64)
46 |
47 | + (NSString *)stringWithBase64EncodedString:(NSString *)string;
48 | - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth;
49 | - (NSString *)base64EncodedString;
50 | - (NSString *)base64DecodedString;
51 | - (NSData *)base64DecodedData;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Utils/Base64/Base64.m:
--------------------------------------------------------------------------------
1 | //
2 | // Base64.m
3 | //
4 | // Version 1.2
5 | //
6 | // Created by Nick Lockwood on 12/01/2012.
7 | // Copyright (C) 2012 Charcoal Design
8 | //
9 | // Distributed under the permissive zlib License
10 | // Get the latest version from here:
11 | //
12 | // https://github.com/nicklockwood/Base64
13 | //
14 | // This software is provided 'as-is', without any express or implied
15 | // warranty. In no event will the authors be held liable for any damages
16 | // arising from the use of this software.
17 | //
18 | // Permission is granted to anyone to use this software for any purpose,
19 | // including commercial applications, and to alter it and redistribute it
20 | // freely, subject to the following restrictions:
21 | //
22 | // 1. The origin of this software must not be misrepresented; you must not
23 | // claim that you wrote the original software. If you use this software
24 | // in a product, an aacknowledgment in the product documentation would be
25 | // appreciated but is not required.
26 | //
27 | // 2. Altered source versions must be plainly marked as such, and must not be
28 | // misrepresented as being the original software.
29 | //
30 | // 3. This notice may not be removed or altered from any source distribution.
31 | //
32 |
33 | #import "Base64.h"
34 |
35 |
36 | #pragma GCC diagnostic ignored "-Wselector"
37 |
38 |
39 | #import
40 | #if !__has_feature(objc_arc)
41 | #error This library requires automatic reference counting
42 | #endif
43 |
44 |
45 | @implementation NSData (Base64)
46 |
47 | + (NSData *)dataWithBase64EncodedString:(NSString *)string
48 | {
49 | if (![string length]) return nil;
50 |
51 | NSData *decoded = nil;
52 |
53 | #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
54 |
55 | if (![NSData instancesRespondToSelector:@selector(initWithBase64EncodedString:options:)])
56 | {
57 | decoded = [[self alloc] initWithBase64Encoding:[string stringByReplacingOccurrencesOfString:@"[^A-Za-z0-9+/=]" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, [string length])]];
58 | }
59 | else
60 |
61 | #endif
62 |
63 | {
64 | decoded = [[self alloc] initWithBase64EncodedString:string options:NSDataBase64DecodingIgnoreUnknownCharacters];
65 | }
66 |
67 | return [decoded length]? decoded: nil;
68 | }
69 |
70 | - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
71 | {
72 | if (![self length]) return nil;
73 |
74 | NSString *encoded = nil;
75 |
76 | #if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 || __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_7_0
77 |
78 | if (![NSData instancesRespondToSelector:@selector(base64EncodedStringWithOptions:)])
79 | {
80 | encoded = [self base64Encoding];
81 | }
82 | else
83 |
84 | #endif
85 |
86 | {
87 | switch (wrapWidth)
88 | {
89 | case 64:
90 | {
91 | return [self base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
92 | }
93 | case 76:
94 | {
95 | return [self base64EncodedStringWithOptions:NSDataBase64Encoding76CharacterLineLength];
96 | }
97 | default:
98 | {
99 | encoded = [self base64EncodedStringWithOptions:(NSDataBase64EncodingOptions)0];
100 | }
101 | }
102 | }
103 |
104 | if (!wrapWidth || wrapWidth >= [encoded length])
105 | {
106 | return encoded;
107 | }
108 |
109 | wrapWidth = (wrapWidth / 4) * 4;
110 | NSMutableString *result = [NSMutableString string];
111 | for (NSUInteger i = 0; i < [encoded length]; i+= wrapWidth)
112 | {
113 | if (i + wrapWidth >= [encoded length])
114 | {
115 | [result appendString:[encoded substringFromIndex:i]];
116 | break;
117 | }
118 | [result appendString:[encoded substringWithRange:NSMakeRange(i, wrapWidth)]];
119 | [result appendString:@"\r\n"];
120 | }
121 |
122 | return result;
123 | }
124 |
125 | - (NSString *)base64EncodedString
126 | {
127 | return [self base64EncodedStringWithWrapWidth:0];
128 | }
129 |
130 | @end
131 |
132 |
133 | @implementation NSString (Base64)
134 |
135 | + (NSString *)stringWithBase64EncodedString:(NSString *)string
136 | {
137 | NSData *data = [NSData dataWithBase64EncodedString:string];
138 | if (data)
139 | {
140 | return [[self alloc] initWithData:data encoding:NSUTF8StringEncoding];
141 | }
142 | return nil;
143 | }
144 |
145 | - (NSString *)base64EncodedStringWithWrapWidth:(NSUInteger)wrapWidth
146 | {
147 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
148 | return [data base64EncodedStringWithWrapWidth:wrapWidth];
149 | }
150 |
151 | - (NSString *)base64EncodedString
152 | {
153 | NSData *data = [self dataUsingEncoding:NSUTF8StringEncoding allowLossyConversion:YES];
154 | return [data base64EncodedString];
155 | }
156 |
157 | - (NSString *)base64DecodedString
158 | {
159 | return [NSString stringWithBase64EncodedString:self];
160 | }
161 |
162 | - (NSData *)base64DecodedData
163 | {
164 | return [NSData dataWithBase64EncodedString:self];
165 | }
166 |
167 | @end
168 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Utils/NSData+Base64.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSData+Base64.h
3 | // base64
4 | //
5 | // Created by Matt Gallagher on 2009/06/03.
6 | // Copyright 2009 Matt Gallagher. All rights reserved.
7 | //
8 | // This software is provided 'as-is', without any express or implied
9 | // warranty. In no event will the authors be held liable for any damages
10 | // arising from the use of this software. Permission is granted to anyone to
11 | // use this software for any purpose, including commercial applications, and to
12 | // alter it and redistribute it freely, subject to the following restrictions:
13 | //
14 | // 1. The origin of this software must not be misrepresented; you must not
15 | // claim that you wrote the original software. If you use this software
16 | // in a product, an acknowledgment in the product documentation would be
17 | // appreciated but is not required.
18 | // 2. Altered source versions must be plainly marked as such, and must not be
19 | // misrepresented as being the original software.
20 | // 3. This notice may not be removed or altered from any source
21 | // distribution.
22 | //
23 |
24 | #import
25 |
26 | void *NewBase64Decode(
27 | const char *inputBuffer,
28 | size_t length,
29 | size_t *outputLength);
30 |
31 | char *NewBase64Encode(
32 | const void *inputBuffer,
33 | size_t length,
34 | bool separateLines,
35 | size_t *outputLength);
36 |
37 | @interface NSData (Base64)
38 |
39 | + (NSData *)dataFromBase64String:(NSString *)aString;
40 | - (NSString *)base64EncodedString;
41 |
42 | @end
43 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Utils/NSData+Base64.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSData+Base64.m
3 | // base64
4 | //
5 | // Created by Matt Gallagher on 2009/06/03.
6 | // Copyright 2009 Matt Gallagher. All rights reserved.
7 | //
8 | // This software is provided 'as-is', without any express or implied
9 | // warranty. In no event will the authors be held liable for any damages
10 | // arising from the use of this software. Permission is granted to anyone to
11 | // use this software for any purpose, including commercial applications, and to
12 | // alter it and redistribute it freely, subject to the following restrictions:
13 | //
14 | // 1. The origin of this software must not be misrepresented; you must not
15 | // claim that you wrote the original software. If you use this software
16 | // in a product, an acknowledgment in the product documentation would be
17 | // appreciated but is not required.
18 | // 2. Altered source versions must be plainly marked as such, and must not be
19 | // misrepresented as being the original software.
20 | // 3. This notice may not be removed or altered from any source
21 | // distribution.
22 | //
23 |
24 | #import "NSData+Base64.h"
25 |
26 | //
27 | // Mapping from 6 bit pattern to ASCII character.
28 | //
29 | static unsigned char base64EncodeLookup[65] =
30 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
31 |
32 | //
33 | // Definition for "masked-out" areas of the base64DecodeLookup mapping
34 | //
35 | #define xx 65
36 |
37 | //
38 | // Mapping from ASCII character to 6 bit pattern.
39 | //
40 | static unsigned char base64DecodeLookup[256] =
41 | {
42 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
43 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
44 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, 62, xx, xx, xx, 63,
45 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, xx, xx, xx, xx, xx, xx,
46 | xx, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
47 | 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, xx, xx, xx, xx, xx,
48 | xx, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
49 | 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, xx, xx, xx, xx, xx,
50 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
51 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
52 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
53 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
54 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
55 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
56 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
57 | xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx, xx,
58 | };
59 |
60 | //
61 | // Fundamental sizes of the binary and base64 encode/decode units in bytes
62 | //
63 | #define BINARY_UNIT_SIZE 3
64 | #define BASE64_UNIT_SIZE 4
65 |
66 | //
67 | // NewBase64Decode
68 | //
69 | // Decodes the base64 ASCII string in the inputBuffer to a newly malloced
70 | // output buffer.
71 | //
72 | // inputBuffer - the source ASCII string for the decode
73 | // length - the length of the string or -1 (to specify strlen should be used)
74 | // outputLength - if not-NULL, on output will contain the decoded length
75 | //
76 | // returns the decoded buffer. Must be free'd by caller. Length is given by
77 | // outputLength.
78 | //
79 | void *NewBase64Decode(
80 | const char *inputBuffer,
81 | size_t length,
82 | size_t *outputLength)
83 | {
84 | if (length == -1)
85 | {
86 | length = strlen(inputBuffer);
87 | }
88 |
89 | size_t outputBufferSize =
90 | ((length+BASE64_UNIT_SIZE-1) / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE;
91 | unsigned char *outputBuffer = (unsigned char *)malloc(outputBufferSize);
92 |
93 | size_t i = 0;
94 | size_t j = 0;
95 | while (i < length)
96 | {
97 | //
98 | // Accumulate 4 valid characters (ignore everything else)
99 | //
100 | unsigned char accumulated[BASE64_UNIT_SIZE];
101 | size_t accumulateIndex = 0;
102 | while (i < length)
103 | {
104 | unsigned char decode = base64DecodeLookup[inputBuffer[i++]];
105 | if (decode != xx)
106 | {
107 | accumulated[accumulateIndex] = decode;
108 | accumulateIndex++;
109 |
110 | if (accumulateIndex == BASE64_UNIT_SIZE)
111 | {
112 | break;
113 | }
114 | }
115 | }
116 |
117 | //
118 | // Store the 6 bits from each of the 4 characters as 3 bytes
119 | //
120 | // (Uses improved bounds checking suggested by Alexandre Colucci)
121 | //
122 | if(accumulateIndex >= 2)
123 | outputBuffer[j] = (accumulated[0] << 2) | (accumulated[1] >> 4);
124 | if(accumulateIndex >= 3)
125 | outputBuffer[j + 1] = (accumulated[1] << 4) | (accumulated[2] >> 2);
126 | if(accumulateIndex >= 4)
127 | outputBuffer[j + 2] = (accumulated[2] << 6) | accumulated[3];
128 | j += accumulateIndex - 1;
129 | }
130 |
131 | if (outputLength)
132 | {
133 | *outputLength = j;
134 | }
135 | return outputBuffer;
136 | }
137 |
138 | //
139 | // NewBase64Encode
140 | //
141 | // Encodes the arbitrary data in the inputBuffer as base64 into a newly malloced
142 | // output buffer.
143 | //
144 | // inputBuffer - the source data for the encode
145 | // length - the length of the input in bytes
146 | // separateLines - if zero, no CR/LF characters will be added. Otherwise
147 | // a CR/LF pair will be added every 64 encoded chars.
148 | // outputLength - if not-NULL, on output will contain the encoded length
149 | // (not including terminating 0 char)
150 | //
151 | // returns the encoded buffer. Must be free'd by caller. Length is given by
152 | // outputLength.
153 | //
154 | char *NewBase64Encode(
155 | const void *buffer,
156 | size_t length,
157 | bool separateLines,
158 | size_t *outputLength)
159 | {
160 | const unsigned char *inputBuffer = (const unsigned char *)buffer;
161 |
162 | #define MAX_NUM_PADDING_CHARS 2
163 | #define OUTPUT_LINE_LENGTH 64
164 | #define INPUT_LINE_LENGTH ((OUTPUT_LINE_LENGTH / BASE64_UNIT_SIZE) * BINARY_UNIT_SIZE)
165 | #define CR_LF_SIZE 2
166 |
167 | //
168 | // Byte accurate calculation of final buffer size
169 | //
170 | size_t outputBufferSize =
171 | ((length / BINARY_UNIT_SIZE)
172 | + ((length % BINARY_UNIT_SIZE) ? 1 : 0))
173 | * BASE64_UNIT_SIZE;
174 | if (separateLines)
175 | {
176 | outputBufferSize +=
177 | (outputBufferSize / OUTPUT_LINE_LENGTH) * CR_LF_SIZE;
178 | }
179 |
180 | //
181 | // Include space for a terminating zero
182 | //
183 | outputBufferSize += 1;
184 |
185 | //
186 | // Allocate the output buffer
187 | //
188 | char *outputBuffer = (char *)malloc(outputBufferSize);
189 | if (!outputBuffer)
190 | {
191 | return NULL;
192 | }
193 |
194 | size_t i = 0;
195 | size_t j = 0;
196 | const size_t lineLength = separateLines ? INPUT_LINE_LENGTH : length;
197 | size_t lineEnd = lineLength;
198 |
199 | while (true)
200 | {
201 | if (lineEnd > length)
202 | {
203 | lineEnd = length;
204 | }
205 |
206 | for (; i + BINARY_UNIT_SIZE - 1 < lineEnd; i += BINARY_UNIT_SIZE)
207 | {
208 | //
209 | // Inner loop: turn 48 bytes into 64 base64 characters
210 | //
211 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
212 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4)
213 | | ((inputBuffer[i + 1] & 0xF0) >> 4)];
214 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i + 1] & 0x0F) << 2)
215 | | ((inputBuffer[i + 2] & 0xC0) >> 6)];
216 | outputBuffer[j++] = base64EncodeLookup[inputBuffer[i + 2] & 0x3F];
217 | }
218 |
219 | if (lineEnd == length)
220 | {
221 | break;
222 | }
223 |
224 | //
225 | // Add the newline
226 | //
227 | outputBuffer[j++] = '\r';
228 | outputBuffer[j++] = '\n';
229 | lineEnd += lineLength;
230 | }
231 |
232 | if (i + 1 < length)
233 | {
234 | //
235 | // Handle the single '=' case
236 | //
237 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
238 | outputBuffer[j++] = base64EncodeLookup[((inputBuffer[i] & 0x03) << 4)
239 | | ((inputBuffer[i + 1] & 0xF0) >> 4)];
240 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i + 1] & 0x0F) << 2];
241 | outputBuffer[j++] = '=';
242 | }
243 | else if (i < length)
244 | {
245 | //
246 | // Handle the double '=' case
247 | //
248 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0xFC) >> 2];
249 | outputBuffer[j++] = base64EncodeLookup[(inputBuffer[i] & 0x03) << 4];
250 | outputBuffer[j++] = '=';
251 | outputBuffer[j++] = '=';
252 | }
253 | outputBuffer[j] = 0;
254 |
255 | //
256 | // Set the output length and return the buffer
257 | //
258 | if (outputLength)
259 | {
260 | *outputLength = j;
261 | }
262 | return outputBuffer;
263 | }
264 |
265 | @implementation NSData (Base64)
266 |
267 | //
268 | // dataFromBase64String:
269 | //
270 | // Creates an NSData object containing the base64 decoded representation of
271 | // the base64 string 'aString'
272 | //
273 | // Parameters:
274 | // aString - the base64 string to decode
275 | //
276 | // returns the autoreleased NSData representation of the base64 string
277 | //
278 | + (NSData *)dataFromBase64String:(NSString *)aString
279 | {
280 | NSData *data = [aString dataUsingEncoding:NSASCIIStringEncoding];
281 | size_t outputLength;
282 | void *outputBuffer = NewBase64Decode([data bytes], [data length], &outputLength);
283 | NSData *result = [NSData dataWithBytes:outputBuffer length:outputLength];
284 | free(outputBuffer);
285 | return result;
286 | }
287 |
288 | //
289 | // base64EncodedString
290 | //
291 | // Creates an NSString object that contains the base 64 encoding of the
292 | // receiver's data. Lines are broken at 64 characters long.
293 | //
294 | // returns an autoreleased NSString being the base 64 representation of the
295 | // receiver.
296 | //
297 | - (NSString *)base64EncodedString
298 | {
299 | size_t outputLength = 0;
300 | char *outputBuffer =
301 | NewBase64Encode([self bytes], [self length], true, &outputLength);
302 |
303 | NSString *result = [[NSString alloc]initWithBytes:outputBuffer
304 | length:outputLength
305 | encoding:NSASCIIStringEncoding];
306 | free(outputBuffer);
307 | return result;
308 | }
309 |
310 | @end
311 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Utils/TripleDESEncrypt.h:
--------------------------------------------------------------------------------
1 | //
2 | // TripleDESEncrypt.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import
11 | #import
12 | #import
13 |
14 | @interface TripleDESEncrypt : NSObject
15 |
16 | /**
17 | * 内容加密解密
18 | *
19 | * @param plainText 需要加密的内容
20 | * @param encryptOrDecrypt 加密/解密
21 | *
22 | * @return 加密/解密后的内容
23 | */
24 | + (NSString*)tripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/AJNetworking/Example/Utils/TripleDESEncrypt.m:
--------------------------------------------------------------------------------
1 | //
2 | // TripleDESEncrypt.m
3 | // AJNetworking
4 | //
5 | // Created by 钟宝健 on 16/3/28.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "TripleDESEncrypt.h"
10 | #import "NSData+Base64.h"
11 |
12 | #define kChosenDigestLength CC_SHA1_DIGEST_LENGTH
13 |
14 | #define DESKEY @"12345678912312312"
15 |
16 | @implementation TripleDESEncrypt
17 |
18 | + (NSString*)tripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt
19 | {
20 | const void *vkey = (const void *)[DESKEY UTF8String];
21 | NSString *result = [self tripleDES:plainText encryptOrDecrypt:encryptOrDecrypt vkey:vkey];
22 |
23 | return result;
24 | }
25 |
26 | + (NSString*)tripleDES:(NSString*)plainText encryptOrDecrypt:(CCOperation)encryptOrDecrypt vkey:(const void *)vkey
27 | {
28 | const void *vplainText;
29 | size_t plainTextBufferSize;
30 |
31 | if (encryptOrDecrypt == kCCDecrypt)//解密
32 | {
33 |
34 | NSData *EncryptData = [NSData dataFromBase64String:plainText];
35 | plainTextBufferSize = [EncryptData length];
36 | vplainText = [EncryptData bytes];
37 | }
38 | else //加密
39 | {
40 | NSData* data = [plainText dataUsingEncoding:NSUTF8StringEncoding];
41 | plainTextBufferSize = [data length];
42 | vplainText = (const void *)[data bytes];
43 | }
44 |
45 | CCCryptorStatus ccStatus;
46 | uint8_t *bufferPtr = NULL;
47 | size_t bufferPtrSize = 0;
48 | size_t movedBytes = 0;
49 |
50 | bufferPtrSize = (plainTextBufferSize + kCCBlockSize3DES) & ~(kCCBlockSize3DES - 1);
51 | bufferPtr = malloc( bufferPtrSize * sizeof(uint8_t));
52 | memset((void *)bufferPtr, 0x0, bufferPtrSize);
53 |
54 | ccStatus = CCCrypt(encryptOrDecrypt,
55 | kCCAlgorithm3DES,
56 | kCCOptionPKCS7Padding | kCCOptionECBMode,
57 | vkey,
58 | kCCKeySize3DES,
59 | nil,
60 | vplainText,
61 | plainTextBufferSize,
62 | (void *)bufferPtr,
63 | bufferPtrSize,
64 | &movedBytes);
65 |
66 | NSString *result;
67 |
68 | if (encryptOrDecrypt == kCCDecrypt)
69 | {
70 | result = [[NSString alloc] initWithData:[NSData dataWithBytes:(const void *)bufferPtr
71 | length:(NSUInteger)movedBytes]
72 | encoding:NSUTF8StringEncoding];
73 | }
74 | else
75 | {
76 | NSData *myData = [NSData dataWithBytes:(const void *)bufferPtr length:(NSUInteger)movedBytes];
77 | result = [myData base64EncodedString];
78 | }
79 | free(bufferPtr);
80 |
81 | return result;
82 | }
83 |
84 | @end
85 |
--------------------------------------------------------------------------------
/AJNetworking/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 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | NSAppTransportSecurity
30 |
31 | NSAllowsArbitraryLoads
32 |
33 |
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 |
--------------------------------------------------------------------------------
/AJNetworking/NetworkHub.h:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkHub.h
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/9/25.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AJNetworking.h"
11 |
12 | @interface NetworkHub : NSObject
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/AJNetworking/NetworkHub.m:
--------------------------------------------------------------------------------
1 | //
2 | // NetworkHub.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 2016/9/25.
6 | // Copyright © 2016年 aboojan. All rights reserved.
7 | //
8 |
9 | #import "NetworkHub.h"
10 |
11 | @implementation NetworkHub
12 |
13 | - (void)showHub:(NSString *)tip
14 | {
15 | AJLog(@"显示Hub: %@", tip);
16 | }
17 |
18 | - (void)dismissHub
19 | {
20 | AJLog(@"隐藏Hub");
21 | }
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/AJNetworking/client.p12:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbooJan/AJNetworking/cb06bcd954c40a84c40ef7e99eb1443fef5eb55b/AJNetworking/client.p12
--------------------------------------------------------------------------------
/AJNetworking/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // AJNetworking
4 | //
5 | // Created by aboojan on 16/3/19.
6 | // Copyright © 2016年 aboojan. 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 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 AbooJan
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 all
13 | 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 THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Podfile:
--------------------------------------------------------------------------------
1 | platform :ios, "7.0"
2 |
3 | target "AJNetworking" do
4 |
5 | pod "AFNetworking"
6 | pod "MJExtension"
7 | pod "SPTPersistentCache"
8 |
9 | end
--------------------------------------------------------------------------------
/Podfile.lock:
--------------------------------------------------------------------------------
1 | PODS:
2 | - AFNetworking (3.1.0):
3 | - AFNetworking/NSURLSession (= 3.1.0)
4 | - AFNetworking/Reachability (= 3.1.0)
5 | - AFNetworking/Security (= 3.1.0)
6 | - AFNetworking/Serialization (= 3.1.0)
7 | - AFNetworking/UIKit (= 3.1.0)
8 | - AFNetworking/NSURLSession (3.1.0):
9 | - AFNetworking/Reachability
10 | - AFNetworking/Security
11 | - AFNetworking/Serialization
12 | - AFNetworking/Reachability (3.1.0)
13 | - AFNetworking/Security (3.1.0)
14 | - AFNetworking/Serialization (3.1.0)
15 | - AFNetworking/UIKit (3.1.0):
16 | - AFNetworking/NSURLSession
17 | - MJExtension (3.0.13)
18 | - SPTPersistentCache (1.0.0)
19 |
20 | DEPENDENCIES:
21 | - AFNetworking
22 | - MJExtension
23 | - SPTPersistentCache
24 |
25 | SPEC CHECKSUMS:
26 | AFNetworking: 5e0e199f73d8626b11e79750991f5d173d1f8b67
27 | MJExtension: 5932755f451458eefa24239358817f8d291240c7
28 | SPTPersistentCache: c2ab4542796647387441169e352ba5f812128153
29 |
30 | PODFILE CHECKSUM: 1b33c742b248a87bfb2d7c2345e0ce888cea54ce
31 |
32 | COCOAPODS: 1.0.1
33 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AJNetworking
2 |
3 | [](https://cocoapods.org/?q=AJNetworking)
4 | [](https://ghit.me/repo/AbooJan/AJNetworking)
5 |
6 | AFNetworking 3.0 版本的封装,结合MJExtension框架处理JSON序列化问题
7 |
8 | 项目中使用的网络请求服务器代码使用 `Node.js` 编写:[NetworkTest](https://github.com/AbooJan/NetworkTest)
9 |
10 |
11 | * 网络请求结构图
12 |
13 | 
14 |
15 |
16 | ## 安装
17 |
18 | ```
19 | pod 'AJNetworking'
20 | ```
21 |
22 |
23 | ## 使用方法
24 |
25 | #### 一、 网络配置
26 | 1. 全局网络配置,需要使用类 `AJNetworkConfig` 在 `AppDelegate` 中配置.
27 |
28 | ```objective-c
29 | /// 服务器域名
30 | @property (nonatomic, copy) NSString *hostUrl;
31 | /// HTTPS 证书密码
32 | @property (nonatomic, assign) CFStringRef httpsCertificatePassword;
33 | /// HTTPS 证书路径
34 | @property (nonatomic, copy) NSString *httpsCertificatePath;
35 | ```
36 |
37 | --
38 |
39 | #### 二、 发起请求
40 |
41 | 1. 新建一个请求类继承自 `AJRequestBeanBase` , 一个响应类继承自 `AJResponseBeanBase` 。
42 |
43 | > #### 命名规则
44 |
45 | > 1. 请求类: `RequestBean` + `业务名称`
46 |
47 | > 2. 响应类: `ResponseBean` + `业务名称`
48 |
49 | > 3. 默认请求类跟响应类的 `业务名称` 必须相同
50 |
51 | > 4. 例如一个登录请求,请求类为:`RequestBeanLogin` , 响应类为:`ResponseBeanLogin`
52 |
53 | > 5. 如果请求类实现了方法:`- (NSString *)responseBeanClassName` , 则可以自定义响应类,名称可以不同,但依然需要继承自 `AJResponseBeanBase` 类。
54 |
55 |
56 |
57 | 2. 请求类里面的成员变量即为发起请求的入参,响应类里面的成员变量即为返回参数。
58 |
59 | 3. 请求类需要遵循协议:`AJRequestBeanProtocol` . 响应类需要遵循协议:`AJResponseBeanProtocol`
60 |
61 | 4. 网络请求的相关配置通过实现协议 `AJRequestBeanProtocol` 的方法。
62 |
63 | 5. 发起请求由类 `AJNetworkManager` 管理,里面负责网络的请求和返回数据的处理,示例:
64 |
65 | ```objective-c
66 | RequestBeanDemoRegister *requestBean = [RequestBeanDemoRegister new];
67 | requestBean.userName = self.userNameTF.text;
68 | requestBean.pw = self.pwTF1.text;
69 |
70 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
71 |
72 | if (!err) {
73 |
74 | // 结果处理
75 | ResponseBeanDemoRegister *response = responseBean;
76 | AJLog(@"userId:%@", response.data.userId);
77 | }
78 | }];
79 | ```
80 |
81 | --
82 |
83 | #### 三、 文件上传
84 |
85 | 1. 请求类需要实现协议 `AJRequestBeanProtocol` 中的方法, 这个参考了 `YTKNetwork` 框架:
86 |
87 | ```objective-c
88 | /**
89 | * @author aboojan
90 | *
91 | * @brief 当POST的内容带有文件等富文本时使用
92 | *
93 | * @return MultipartFormData Block
94 | */
95 | - (AFConstructingBlock)constructingBodyBlock;
96 | ```
97 |
98 | 2. 方法实现示例:
99 |
100 | ```objective-c
101 | - (AFConstructingBlock)constructingBodyBlock
102 | {
103 | NSData *data = UIImageJPEGRepresentation(self.avatar, 0.8);
104 | NSString *name = @"img";
105 | NSString *formKey = @"img";
106 | NSString *type = @"applicaton/octet-stream";
107 |
108 | return AJConstructingBlockDefine {
109 | [formData appendPartWithFileData:data name:formKey fileName:name mimeType:type];
110 | };
111 | }
112 | ```
113 |
114 | 3. 文件上传请求示例,跟发起普通请求一样:
115 |
116 | ```objective-c
117 | RequestBeanUploadAvatar *requestBean = [[RequestBeanUploadAvatar alloc] init];
118 | requestBean.compid = @"1702487";
119 | requestBean.avatar = [UIImage imageNamed:@"testImg"];
120 |
121 | [AJNetworkManager requestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
122 |
123 | if (!err) {
124 | ResponseBeanUploadAvatar *response = responseBean;
125 | }
126 | }];
127 | ```
128 |
129 | --
130 |
131 | #### 四、文件下载
132 |
133 | 1. 文件下载跟普通请求不同,需要使用类 `AJNetworkManager` 中的以下方法:
134 |
135 | ```objective-c
136 | /**
137 | * @author aboojan
138 | *
139 | * @brief 文件下载
140 | *
141 | * @param requestBean 文件下载请求Bean
142 | * @param progressCallBack 下载进度回调
143 | * @param completionCallBack 完成回调
144 | *
145 | * @return 当前下载任务线程
146 | */
147 | + ( NSURLSessionDownloadTask * _Nullable )downloadTaskWithBean:(__kindof RequestBeanDownloadTaskBase * _Nonnull)requestBean progress:(AJDownloadProgressCallBack _Nullable )progressCallBack completion:(AJDownloadCompletionCallBack _Nullable)completionCallBack;;
148 | ```
149 |
150 | 2. 文件下载请求类使用 `RequestBeanDownloadTaskBase`,使用示例:
151 |
152 | ```objective-c
153 | RequestBeanDownloadTaskBase *downloadRequest = [[RequestBeanDownloadTaskBase alloc] init];
154 | downloadRequest.fileUrl = @"http://temp.26923.com/2016/pic/000/378/032ad9af805a8e83d8323f515d1d6645.jpg";
155 | downloadRequest.saveFileName = @"desktop.jpg";
156 | downloadRequest.saveFilePath = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject];
157 |
158 | [AJNetworkManager downloadTaskWithBean:downloadRequest progress:^(int64_t totalUnitCount, int64_t completedUnitCount, double progressRate) {
159 |
160 | AJLog(@"下载进度:%lf", progressRate);
161 |
162 | } completion:^(NSURL *filePath, NSError *error) {
163 |
164 | if (error) {
165 | AJLog(@"下载失败:%@", [error description]);
166 | }else{
167 | AJLog(@"下载成功:%@", [filePath description]);
168 | }
169 |
170 | }];
171 | ```
172 |
173 |
174 | 3. 下载任务控制, 通过下载请求返回的 `NSURLSessionDownloadTask` 实例来处理。
175 |
176 | ```objective-c
177 | // 暂停任务
178 | [self.downloadTask suspend];
179 |
180 | // 继续下载
181 | [self.downloadTask resume];
182 |
183 | // 取消下载
184 | [self.downloadTask cancel];
185 | ```
186 |
187 | --
188 |
189 | #### 五、缓存
190 |
191 | 1. 读取已缓存数据跟发起普通请求类似,使用 `AJNetworkManager` 的以下方法:
192 |
193 | ```objective-c
194 | /**
195 | * @author aboojan
196 | *
197 | * @brief 读取缓存
198 | *
199 | * @param requestBean 请求Bean
200 | * @param callBack 读取缓存回调
201 | */
202 | + (void)cacheWithRequestWithBean:(__kindof AJRequestBeanBase * _Nonnull)requestBean callBack:(AJRequestCallBack _Nonnull)callBack
203 | ```
204 |
205 | 2. 如果要缓存请求数据,需要请求类实现协议 `AJRequestBeanProtocol` 的以下方法:
206 |
207 | ```objective-c
208 | /**
209 | * @author aboojan
210 | *
211 | * @brief 是否缓存请求结果,默认不缓存
212 | *
213 | * @return YES,缓存;NO,不缓存
214 | */
215 | - (BOOL)cacheResponse;
216 | ```
217 |
218 | 3. 默认缓存是长期有效的,如果需要控制缓存的有效时间,需要请求类实现协议 `AJRequestBeanProtocol` 的以下方法:
219 |
220 | ```objective-c
221 | /**
222 | * @author aboojan
223 | *
224 | * @brief 缓存有效时间,单位为秒, 默认为0,即长期有效;
225 | *
226 | * @return 有效时间
227 | */
228 | - (NSUInteger)cacheLiveSecond;
229 | ```
230 |
231 | 4. 发起请求的时候可以先读取缓存,当缓存不存在或已失效的时候才真正发起请求:
232 |
233 | ```objective-c
234 | [AJNetworkManager cacheWithRequestWithBean:requestBean callBack:^(__kindof AJResponseBeanBase * _Nullable responseBean, AJError * _Nullable err) {
235 |
236 | if (!err) {
237 |
238 | // 读取缓存
239 | [self handleReponse:response];
240 |
241 | }else{
242 |
243 | // 发起网络请求
244 | [self readFromNetwork];
245 | }
246 | }];
247 | ```
248 |
249 | 5. 目前已把缓存和网络请求结合在了一起,如果设置的是短期缓存,在有效期内不会发起真正的网络请求;如果是长期有效缓存,则会先读取缓存,然后发起网络请求。使用详情可以参考Demo
250 |
251 | ```objective-c
252 | /**
253 | * @author aboojan
254 | *
255 | * @brief 发起网络请求,有缓存
256 | *
257 | * @param requestBean 网络请求参数模式Bean
258 | * @param cacheCallBack 缓存读取回调
259 | * @param httpCallBack 网络请求结果回调
260 | */
261 | + (void)requestWithBean:(__kindof AJRequestBeanBase * _Nonnull)requestBean
262 | cacheCallBack:(AJRequestCallBack _Nonnull)cacheCallBack
263 | httpCallBack:(AJRequestCallBack _Nonnull)httpCallBack;
264 | ```
265 |
266 |
267 | --
268 |
269 | #### 六、全局缓存配置
270 | 1. 缓存配置类 `AJCacheOptions` , 提供3个可选配置项:
271 |
272 | ```objective-c
273 | /**
274 | * @author aboojan
275 | *
276 | * @brief 缓存存放路径
277 | */
278 | @property (nonatomic, copy) NSString *cachePath;
279 |
280 | /**
281 | * @author aboojan
282 | *
283 | * @brief 是否开启缓存自动回收,默认关闭
284 | */
285 | @property (nonatomic,assign) BOOL openCacheGC;
286 |
287 | /**
288 | * @author aboojan
289 | *
290 | * @brief 缓存过期时间,最小不能小于60s
291 | */
292 | @property (nonatomic, assign) NSUInteger globalCacheExpirationSecond;
293 |
294 | /**
295 | * @author aboojan
296 | *
297 | * @brief 缓存自动回收时间,最小不能小于60s
298 | */
299 | @property (nonatomic, assign) NSUInteger globalCacheGCSecond;
300 | ```
301 |
302 |
303 | 2. 缓存配置跟网络配置一样,通过类 `AJNetworkConfig` 类设置,例如:
304 |
305 | ```objective-c
306 | AJCacheOptions *cacheOptions = [AJCacheOptions new];
307 | cacheOptions.cachePath = [documentsPath stringByAppendingPathComponent:@"aj_network_cache"];
308 | cacheOptions.openCacheGC = YES;
309 | cacheOptions.globalCacheExpirationSecond = 60;
310 | cacheOptions.globalCacheGCSecond = 2 * 60;
311 | networkConfig.cacheOptions = cacheOptions;
312 | ```
313 |
314 |
315 | --
316 |
317 |
318 | #### 七、网络状态
319 | 通过类 `AJNetworkStatus` 获取当前网络状态,框架本身在网络配置完之后即开启网络监测。
320 |
321 | ```
322 | - (AJNetworkReachabilityStatus)currentStatus;
323 | - (BOOL)canReachable;
324 | ```
325 |
326 |
327 | ---
328 |
329 |
330 | #### 八、网络请求Hub支持
331 | 1. 在 `RequestBean` 中实现以下方法
332 |
333 | ```
334 | /**
335 | * @author aboojan
336 | *
337 | * @brief 是否需要显示Loading,默认不显示
338 | *
339 | * @return YES,显示;NO,不显示
340 | */
341 | - (BOOL)isShowHub;
342 |
343 | /**
344 | * @author aboojan
345 | *
346 | * @brief Hub提示文案,isShowHub设置为YES时才会生效
347 | *
348 | @return 提示文案
349 | */
350 | - (NSString *)hubTips;
351 | ```
352 |
353 | 2. 通过类 `AJNetworkConfig` 类设置 `hubDelegate` ,然后在 `delegate` 中实现hub的显示。
354 |
355 | ```
356 | /**
357 | * 显示Hub
358 | *
359 | @param tip hub文案
360 | */
361 | - (void)showHub:(nullable NSString *)tip;
362 |
363 | /**
364 | * 隐藏Hub
365 | */
366 | - (void)dismissHub;
367 | ```
368 |
369 |
370 | ---
371 |
372 |
373 | #### 九、结束网络请求
374 | 1. 通过 `AJNetworkManager` 类的以下方法实现结束网络请求任务
375 |
376 | ```
377 | /**
378 | 根据 taskKey 结束目标网络请求任务
379 |
380 | @param taskKeyArray 任务Key数组
381 | */
382 | + (void)stopRequestTaskWithTaskKey:(NSArray<__kindof NSString *> * _Nonnull)taskKeyArray
383 | ```
384 |
385 | 2. 继承自 `AJRequestBeanBase` 请求数据Bean新增了一个获取 `taskKey` 的成员变量,在Bean赋值后可以获取。
386 |
387 | 3. 这样可以在控制器基类中暴露一个存放 `taskKey` 的数组,然后在通用的页面关闭方法或 `dealloc` 方法中把网络请求结束掉,减少资源占用。
388 |
389 | ---
390 |
391 | ## 感谢
392 |
393 | 依赖框架 |
394 | ------------ |
395 | [AFNetwoking](https://github.com/AFNetworking/AFNetworking) |
396 | [MJExtension](https://github.com/CoderMJLee/MJExtension) |
397 | [SPTPersistentCache](https://github.com/spotify/SPTPersistentCache) |
398 |
--------------------------------------------------------------------------------
/StructureFlow.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AbooJan/AJNetworking/cb06bcd954c40a84c40ef7e99eb1443fef5eb55b/StructureFlow.png
--------------------------------------------------------------------------------