├── .DS_Store
├── HWDownloadDemo.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
│ └── xcuserdata
│ │ └── wangqibin.xcuserdatad
│ │ ├── UserInterfaceState.xcuserstate
│ │ └── WorkspaceSettings.xcsettings
├── xcshareddata
│ └── xcschemes
│ │ └── HWDownloadDemo.xcscheme
└── xcuserdata
│ └── wangqibin.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ └── xcschememanagement.plist
├── HWDownloadDemo
├── Categorys
│ ├── NSArray+Crash.h
│ ├── NSArray+Crash.m
│ ├── NSString+HW.h
│ ├── NSString+HW.m
│ ├── UIColor+HW.h
│ ├── UIColor+HW.m
│ ├── UIImage+HW.h
│ ├── UIImage+HW.m
│ ├── UIView+Extension.h
│ └── UIView+Extension.m
├── Common
│ ├── .DS_Store
│ ├── HWDownloadManager
│ │ ├── HWDataBaseManager.h
│ │ ├── HWDataBaseManager.m
│ │ ├── HWDownload.h
│ │ ├── HWDownloadManager.h
│ │ ├── HWDownloadManager.m
│ │ ├── HWDownloadModel.h
│ │ ├── HWDownloadModel.m
│ │ ├── NSURLSession+CorrectedResumeData.h
│ │ └── NSURLSession+CorrectedResumeData.m
│ ├── HWNetworkReachabilityManager.h
│ ├── HWNetworkReachabilityManager.m
│ ├── HWProgressHUD.h
│ ├── HWProgressHUD.m
│ ├── HWToolBox.h
│ ├── HWToolBox.m
│ └── SwizzlingDefine.h
├── Home
│ ├── HWPlayVC
│ │ └── Controller
│ │ │ ├── HWPlayVC.h
│ │ │ └── HWPlayVC.m
│ └── Home
│ │ ├── Controller
│ │ ├── HWHomeVC.h
│ │ └── HWHomeVC.m
│ │ └── View
│ │ ├── HWDownloadButton.h
│ │ ├── HWDownloadButton.m
│ │ ├── HWHomeCell.h
│ │ └── HWHomeCell.m
├── Main
│ ├── AppDelegate.h
│ ├── AppDelegate.m
│ ├── HWBaseViewController.h
│ ├── HWBaseViewController.m
│ ├── NavigationController
│ │ ├── HWNavigationController.h
│ │ ├── HWNavigationController.m
│ │ ├── UINavigationBar+Swizzling.h
│ │ ├── UINavigationBar+Swizzling.m
│ │ ├── UINavigationItem+Swizzling.h
│ │ └── UINavigationItem+Swizzling.m
│ └── TabBarController
│ │ ├── HWTabBarController.h
│ │ ├── HWTabBarController.m
│ │ ├── HWTabBarView.h
│ │ └── HWTabBarView.m
├── Me
│ ├── Cache
│ │ └── Controller
│ │ │ ├── HWCacheBaseVC.h
│ │ │ ├── HWCacheBaseVC.m
│ │ │ ├── HWCacheVC.h
│ │ │ ├── HWCacheVC.m
│ │ │ ├── HWDownloadingVC.h
│ │ │ └── HWDownloadingVC.m
│ ├── Me
│ │ └── Controller
│ │ │ ├── HWMeVC.h
│ │ │ └── HWMeVC.m
│ └── Setting
│ │ └── Controller
│ │ ├── HWSettingVC.h
│ │ └── HWSettingVC.m
├── Other
│ ├── Assets.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── GlobeConst.h
│ ├── GlobeConst.m
│ ├── GlobeHeader.h
│ ├── Images
│ │ └── Common
│ │ │ ├── com_download_default@2x.png
│ │ │ ├── com_download_default@3x.png
│ │ │ ├── com_download_error@2x.png
│ │ │ ├── com_download_error@3x.png
│ │ │ ├── com_download_finish@2x.png
│ │ │ ├── com_download_finish@3x.png
│ │ │ ├── com_download_pause@2x.png
│ │ │ ├── com_download_pause@3x.png
│ │ │ ├── com_download_waiting@2x.png
│ │ │ ├── com_download_waiting@3x.png
│ │ │ ├── com_loading01@2x.png
│ │ │ ├── com_loading02@2x.png
│ │ │ ├── com_loading03@2x.png
│ │ │ ├── com_loading04@2x.png
│ │ │ ├── com_loading05@2x.png
│ │ │ ├── com_loading06@2x.png
│ │ │ ├── com_loading07@2x.png
│ │ │ ├── com_loading08@2x.png
│ │ │ ├── nav_back@2x.png
│ │ │ ├── nav_back@3x.png
│ │ │ ├── nav_cancelBtn@2x.png
│ │ │ ├── nav_cancelBtn@3x.png
│ │ │ ├── nav_deleteBtn@2x.png
│ │ │ ├── nav_deleteBtn@3x.png
│ │ │ ├── tabbar_home_nor@2x.png
│ │ │ ├── tabbar_home_nor@3x.png
│ │ │ ├── tabbar_home_sel@2x.png
│ │ │ ├── tabbar_home_sel@3x.png
│ │ │ ├── tabbar_me_nor@2x.png
│ │ │ ├── tabbar_me_nor@3x.png
│ │ │ ├── tabbar_me_sel@2x.png
│ │ │ └── tabbar_me_sel@3x.png
│ ├── Info.plist
│ ├── PrefixHeader.pch
│ ├── main.m
│ └── testData.plist
└── Vender
│ ├── AFNetworking
│ ├── AFNetworking
│ │ ├── AFHTTPSessionManager.h
│ │ ├── AFHTTPSessionManager.m
│ │ ├── AFNetworkReachabilityManager.h
│ │ ├── AFNetworkReachabilityManager.m
│ │ ├── AFNetworking.h
│ │ ├── AFSecurityPolicy.h
│ │ ├── AFSecurityPolicy.m
│ │ ├── AFURLRequestSerialization.h
│ │ ├── AFURLRequestSerialization.m
│ │ ├── AFURLResponseSerialization.h
│ │ ├── AFURLResponseSerialization.m
│ │ ├── AFURLSessionManager.h
│ │ └── AFURLSessionManager.m
│ ├── LICENSE
│ ├── README.md
│ └── UIKit+AFNetworking
│ │ ├── AFAutoPurgingImageCache.h
│ │ ├── AFAutoPurgingImageCache.m
│ │ ├── AFImageDownloader.h
│ │ ├── AFImageDownloader.m
│ │ ├── AFNetworkActivityIndicatorManager.h
│ │ ├── AFNetworkActivityIndicatorManager.m
│ │ ├── UIActivityIndicatorView+AFNetworking.h
│ │ ├── UIActivityIndicatorView+AFNetworking.m
│ │ ├── UIButton+AFNetworking.h
│ │ ├── UIButton+AFNetworking.m
│ │ ├── UIImage+AFNetworking.h
│ │ ├── UIImageView+AFNetworking.h
│ │ ├── UIImageView+AFNetworking.m
│ │ ├── UIKit+AFNetworking.h
│ │ ├── UIProgressView+AFNetworking.h
│ │ ├── UIProgressView+AFNetworking.m
│ │ ├── UIRefreshControl+AFNetworking.h
│ │ ├── UIRefreshControl+AFNetworking.m
│ │ ├── UIWebView+AFNetworking.h
│ │ └── UIWebView+AFNetworking.m
│ ├── FMDB
│ ├── LICENSE.txt
│ ├── README.markdown
│ └── src
│ │ └── fmdb
│ │ ├── FMDB.h
│ │ ├── FMDatabase.h
│ │ ├── FMDatabase.m
│ │ ├── FMDatabaseAdditions.h
│ │ ├── FMDatabaseAdditions.m
│ │ ├── FMDatabasePool.h
│ │ ├── FMDatabasePool.m
│ │ ├── FMDatabaseQueue.h
│ │ ├── FMDatabaseQueue.m
│ │ ├── FMResultSet.h
│ │ └── FMResultSet.m
│ └── MJExtension
│ ├── LICENSE
│ ├── MJExtension
│ ├── MJExtension.h
│ ├── MJExtensionConst.h
│ ├── MJExtensionConst.m
│ ├── MJFoundation.h
│ ├── MJFoundation.m
│ ├── MJProperty.h
│ ├── MJProperty.m
│ ├── MJPropertyKey.h
│ ├── MJPropertyKey.m
│ ├── MJPropertyType.h
│ ├── MJPropertyType.m
│ ├── NSObject+MJClass.h
│ ├── NSObject+MJClass.m
│ ├── NSObject+MJCoding.h
│ ├── NSObject+MJCoding.m
│ ├── NSObject+MJKeyValue.h
│ ├── NSObject+MJKeyValue.m
│ ├── NSObject+MJProperty.h
│ ├── NSObject+MJProperty.m
│ ├── NSString+MJExtension.h
│ └── NSString+MJExtension.m
│ └── README.md
├── HWDownloadDemoTests
├── HWDownloadDemoTests.m
└── Info.plist
├── HWDownloadDemoUITests
├── HWDownloadDemoUITests.m
└── Info.plist
└── README.md
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/.DS_Store
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildSystemType
6 | Original
7 |
8 |
9 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/project.xcworkspace/xcuserdata/wangqibin.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo.xcodeproj/project.xcworkspace/xcuserdata/wangqibin.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/project.xcworkspace/xcuserdata/wangqibin.xcuserdatad/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | BuildLocationStyle
6 | UseAppPreferences
7 | CustomBuildLocationType
8 | RelativeToDerivedData
9 | DerivedDataLocationStyle
10 | Default
11 | EnabledFullIndexStoreVisibility
12 |
13 | IssueFilterStyle
14 | ShowActiveSchemeOnly
15 | LiveSourceIssuesEnabled
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/xcshareddata/xcschemes/HWDownloadDemo.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
89 |
90 |
91 |
92 |
93 |
94 |
100 |
102 |
108 |
109 |
110 |
111 |
113 |
114 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/xcuserdata/wangqibin.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/HWDownloadDemo.xcodeproj/xcuserdata/wangqibin.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | HWDownloadDemo.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 | HWDownloadDemo.xcscheme_^#shared#^_
13 |
14 | orderHint
15 | 0
16 |
17 |
18 | SuppressBuildableAutocreation
19 |
20 | 3DADAD6620B2BD70006D7FC8
21 |
22 | primary
23 |
24 |
25 | 3DADAD7E20B2BD70006D7FC8
26 |
27 | primary
28 |
29 |
30 | 3DADAD8920B2BD70006D7FC8
31 |
32 | primary
33 |
34 |
35 |
36 |
37 |
38 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/NSArray+Crash.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+Crash.h
3 | // SXEducation
4 | //
5 | // Created by sxmaps_w on 2017/11/24.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSArray (Crash)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/NSArray+Crash.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSArray+Crash.m
3 | // SXEducation
4 | //
5 | // Created by sxmaps_w on 2017/11/24.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 | #import "NSArray+Crash.h"
10 | #import
11 |
12 | @implementation NSArray (Crash)
13 |
14 | + (void)load
15 | {
16 | [super load];
17 |
18 | //替换不可变数组方法
19 | Method oldObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtIndex:));
20 | Method newObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayI"), @selector(objectAtSafeIndex:));
21 | method_exchangeImplementations(oldObjectAtIndex, newObjectAtIndex);
22 |
23 | //替换可变数组方法
24 | Method oldMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(objectAtIndex:));
25 | Method newMutableObjectAtIndex = class_getInstanceMethod(objc_getClass("__NSArrayM"), @selector(mutableObjectAtSafeIndex:));
26 | method_exchangeImplementations(oldMutableObjectAtIndex, newMutableObjectAtIndex);
27 | }
28 |
29 | - (id)objectAtSafeIndex:(NSUInteger)index
30 | {
31 | if (index > self.count - 1 || !self.count) {
32 | @try {
33 | return [self objectAtSafeIndex:index];
34 | }
35 | @catch (NSException *exception) {
36 | HWLog(@"exception: %@", exception.reason);
37 | return nil;
38 | }
39 |
40 | }else {
41 | return [self objectAtSafeIndex:index];
42 | }
43 | }
44 |
45 | - (id)mutableObjectAtSafeIndex:(NSUInteger)index
46 | {
47 | if (index > self.count - 1 || !self.count) {
48 | @try {
49 | return [self mutableObjectAtSafeIndex:index];
50 | }
51 | @catch (NSException *exception) {
52 | HWLog(@"exception: %@", exception.reason);
53 | return nil;
54 | }
55 |
56 | }else {
57 | return [self mutableObjectAtSafeIndex:index];
58 | }
59 | }
60 |
61 | @end
62 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/NSString+HW.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+HW.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface NSString (HW)
12 |
13 | // MD5加密
14 | - (NSString *)MD5;
15 |
16 | // 中文、特殊字符转码
17 | - (NSString *)transEncodingString;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/NSString+HW.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+HW.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "NSString+HW.h"
10 | #import
11 |
12 | @implementation NSString (HW)
13 |
14 | // MD5加密
15 | - (NSString *)MD5
16 | {
17 | const char *ptr = [self UTF8String];
18 |
19 | unsigned char md5Buffer[CC_MD5_DIGEST_LENGTH];
20 |
21 | CC_MD5(ptr, (unsigned int)strlen(ptr), md5Buffer);
22 |
23 | NSMutableString *output = [NSMutableString stringWithCapacity:CC_MD5_DIGEST_LENGTH *2];
24 | for (int i = 0; i
10 |
11 | @interface UIColor (HW)
12 |
13 | //16进制转化RGB
14 | + (UIColor *)colorWithHexString:(NSString *)string;
15 |
16 | //随即色
17 | + (UIColor *)randomColor;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/UIColor+HW.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIColor+HW.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "UIColor+HW.h"
10 |
11 | @implementation UIColor (HW)
12 |
13 | + (UIColor *)colorWithHexString:(NSString *)string
14 | {
15 | if ([string hasPrefix:@"#"]) string = [string substringFromIndex:1];
16 |
17 | // Separate into r, g, b substrings
18 | NSRange range;
19 | range.length = 2;
20 |
21 | range.location = 0;
22 | NSString *rString = [string substringWithRange:range];
23 |
24 | range.location = 2;
25 | NSString *gString = [string substringWithRange:range];
26 |
27 | range.location = 4;
28 | NSString *bString = [string substringWithRange:range];
29 |
30 | unsigned int r, g, b;
31 | [[NSScanner scannerWithString:rString] scanHexInt:&r];
32 | [[NSScanner scannerWithString:gString] scanHexInt:&g];
33 | [[NSScanner scannerWithString:bString] scanHexInt:&b];
34 |
35 | return [UIColor colorWithRed:((float)r/255.0f) green:((float)g/255.0f) blue:((float)b/255.0f) alpha:1];
36 | }
37 |
38 | + (UIColor *)randomColor
39 | {
40 | CGFloat red = arc4random_uniform(256);
41 | CGFloat green = arc4random_uniform(256);
42 | CGFloat blue = arc4random_uniform(256);
43 |
44 | return [UIColor colorWithRed:red/255.0 green:green/255.0 blue:blue/255.0 alpha:1];
45 | }
46 |
47 | @end
48 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/UIImage+HW.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+HW.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIImage (HW)
12 |
13 | //根据颜色返回图片
14 | + (UIImage *)imageWithColor:(UIColor *)color;
15 |
16 | //获取网络图片
17 | + (UIImage *)imageWithUrlString:(NSString *)urlString;
18 |
19 | //绘制图片圆角
20 | - (UIImage *)drawCornerInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/UIImage+HW.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+HW.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "UIImage+HW.h"
10 |
11 | @implementation UIImage (HW)
12 |
13 | //根据颜色返回图片
14 | + (UIImage *)imageWithColor:(UIColor *)color
15 | {
16 | CGRect rect = CGRectMake(0.0f, 0.0f, 1.0f, 1.0f);
17 | UIGraphicsBeginImageContext(rect.size);
18 | CGContextRef context = UIGraphicsGetCurrentContext();
19 | CGContextSetFillColorWithColor(context, [color CGColor]);
20 | CGContextFillRect(context, rect);
21 |
22 | UIImage *theImage = UIGraphicsGetImageFromCurrentImageContext();
23 | UIGraphicsEndImageContext();
24 |
25 | return theImage;
26 | }
27 |
28 | //获取网络图片
29 | + (UIImage *)imageWithUrlString:(NSString *)urlString
30 | {
31 | NSURL *url = [NSURL URLWithString:urlString];
32 |
33 | NSData *date = [NSData dataWithContentsOfURL:url];
34 |
35 | UIImage *image = [UIImage imageWithData:date];
36 |
37 | return image;
38 | }
39 |
40 | //绘制图片圆角
41 | - (UIImage *)drawCornerInRect:(CGRect)rect cornerRadius:(CGFloat)cornerRadius
42 | {
43 | UIBezierPath *bezierPath = [UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
44 | UIGraphicsBeginImageContextWithOptions(rect.size, false, [UIScreen mainScreen].scale);
45 | CGContextAddPath(UIGraphicsGetCurrentContext(), bezierPath.CGPath);
46 | CGContextClip(UIGraphicsGetCurrentContext());
47 | [self drawInRect:rect];
48 |
49 | CGContextDrawPath(UIGraphicsGetCurrentContext(), kCGPathFillStroke);
50 | UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
51 | UIGraphicsEndImageContext();
52 |
53 | return image;
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/UIView+Extension.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface UIView (Extension)
12 |
13 | @property (nonatomic, assign) CGFloat frameX;
14 | @property (nonatomic, assign) CGFloat frameY;
15 | @property (nonatomic, assign) CGFloat frameWidth;
16 | @property (nonatomic, assign) CGFloat frameHeight;
17 | @property (nonatomic, assign) CGPoint frameOrigin;
18 | @property (nonatomic, assign) CGSize frameSize;
19 | @property (nonatomic, assign) CGFloat boundsX;
20 | @property (nonatomic, assign) CGFloat boundsY;
21 | @property (nonatomic, assign) CGFloat boundsWidth;
22 | @property (nonatomic, assign) CGFloat boundsHeight;
23 | @property (nonatomic, assign) CGFloat centerX;
24 | @property (nonatomic, assign) CGFloat centerY;
25 |
26 | @end
27 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Categorys/UIView+Extension.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIView+Extension.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "UIView+Extension.h"
10 |
11 | @implementation UIView (Extension)
12 |
13 | - (CGFloat)frameX
14 | {
15 | return self.frame.origin.x;
16 | }
17 |
18 | - (void)setFrameX:(CGFloat)newX
19 | {
20 | self.frame = CGRectMake(newX, self.frame.origin.y, self.frame.size.width, self.frame.size.height);
21 | }
22 |
23 | - (CGFloat)frameY
24 | {
25 | return self.frame.origin.y;
26 | }
27 |
28 | - (void)setFrameY:(CGFloat)newY
29 | {
30 | self.frame = CGRectMake(self.frame.origin.x, newY, self.frame.size.width, self.frame.size.height);
31 | }
32 |
33 | - (CGFloat)frameWidth
34 | {
35 | return self.frame.size.width;
36 | }
37 |
38 | - (void)setFrameWidth:(CGFloat)newWidth
39 | {
40 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, newWidth, self.frame.size.height);
41 | }
42 |
43 | - (CGFloat)frameHeight
44 | {
45 | return self.frame.size.height;
46 | }
47 |
48 | - (void)setFrameHeight:(CGFloat)newHeight
49 | {
50 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, self.frame.size.width, newHeight);
51 | }
52 |
53 | - (CGPoint)frameOrigin
54 | {
55 | return self.frame.origin;
56 | }
57 |
58 | - (void)setFrameOrigin:(CGPoint)newOrigin
59 | {
60 | self.frame = CGRectMake(newOrigin.x, newOrigin.y, self.frame.size.width, self.frame.size.height);
61 | }
62 |
63 | - (CGSize)frameSize
64 | {
65 | return self.frame.size;
66 | }
67 |
68 | - (void)setFrameSize:(CGSize)newSize
69 | {
70 | self.frame = CGRectMake(self.frame.origin.x, self.frame.origin.y, newSize.width, newSize.height);
71 | }
72 |
73 | - (CGFloat)boundsX
74 | {
75 | return self.bounds.origin.x;
76 | }
77 |
78 | - (void)setBoundsX:(CGFloat)newX
79 | {
80 | self.bounds = CGRectMake(newX, self.bounds.origin.y, self.bounds.size.width, self.bounds.size.height);
81 | }
82 |
83 | - (CGFloat)boundsY
84 | {
85 | return self.bounds.origin.y;
86 | }
87 |
88 | - (void)setBoundsY:(CGFloat)newY
89 | {
90 | self.bounds = CGRectMake(self.bounds.origin.x, newY, self.bounds.size.width, self.bounds.size.height);
91 | }
92 |
93 | - (CGFloat)boundsWidth
94 | {
95 | return self.bounds.size.width;
96 | }
97 |
98 | - (void)setBoundsWidth:(CGFloat)newWidth
99 | {
100 | self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, newWidth, self.bounds.size.height);
101 | }
102 |
103 | - (CGFloat)boundsHeight
104 | {
105 | return self.bounds.size.height;
106 | }
107 |
108 | - (void)setBoundsHeight:(CGFloat)newHeight
109 | {
110 | self.bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, self.bounds.size.width, newHeight);
111 | }
112 |
113 | - (CGFloat)centerX
114 | {
115 | return self.center.x;
116 | }
117 |
118 | - (void)setCenterX:(CGFloat)newX
119 | {
120 | self.center = CGPointMake(newX, self.center.y);
121 | }
122 |
123 | - (CGFloat)centerY
124 | {
125 | return self.center.y;
126 | }
127 |
128 | - (void)setCenterY:(CGFloat)newY
129 | {
130 | self.center = CGPointMake(self.center.x, newY);
131 | }
132 |
133 | @end
134 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Common/.DS_Store
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/HWDataBaseManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDataBaseManager.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/25.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_OPTIONS(NSUInteger, HWDBUpdateOption) {
12 | HWDBUpdateOptionState = 1 << 0, // 更新状态
13 | HWDBUpdateOptionLastStateTime = 1 << 1, // 更新状态最后改变的时间
14 | HWDBUpdateOptionResumeData = 1 << 2, // 更新下载的数据
15 | HWDBUpdateOptionProgressData = 1 << 3, // 更新进度数据(包含tmpFileSize、totalFileSize、progress、intervalFileSize、lastSpeedTime)
16 | HWDBUpdateOptionAllParam = 1 << 4 // 更新全部数据
17 | };
18 |
19 | @interface HWDataBaseManager : NSObject
20 |
21 | // 获取单例
22 | + (instancetype)shareManager;
23 |
24 | // 插入数据
25 | - (void)insertModel:(HWDownloadModel *)model;
26 |
27 | // 获取数据
28 | - (HWDownloadModel *)getModelWithUrl:(NSString *)url; // 根据url获取数据
29 | - (HWDownloadModel *)getWaitingModel; // 获取第一条等待的数据
30 | - (HWDownloadModel *)getLastDownloadingModel; // 获取最后一条正在下载的数据
31 | - (NSArray *)getAllCacheData; // 获取所有数据
32 | - (NSArray *)getAllDownloadingData; // 根据lastStateTime倒叙获取所有正在下载的数据
33 | - (NSArray *)getAllDownloadedData; // 获取所有下载完成的数据
34 | - (NSArray *)getAllUnDownloadedData; // 获取所有未下载完成的数据(包含正在下载、等待、暂停、错误)
35 | - (NSArray *)getAllWaitingData; // 获取所有等待下载的数据
36 |
37 | // 更新数据
38 | - (void)updateWithModel:(HWDownloadModel *)model option:(HWDBUpdateOption)option;
39 |
40 | // 删除数据
41 | - (void)deleteModelWithUrl:(NSString *)url;
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/HWDownload.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownload.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #ifndef HWDownload_h
10 | #define HWDownload_h
11 |
12 | #import "HWDownloadManager.h"
13 | #import "HWDataBaseManager.h"
14 | #import "HWDownloadModel.h"
15 |
16 | #endif /* HWDownload_h */
17 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/HWDownloadManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadManager.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class HWDownloadModel;
12 |
13 | typedef NS_ENUM(NSInteger, HWDownloadState) {
14 | HWDownloadStateDefault = 0, // 默认
15 | HWDownloadStateDownloading, // 正在下载
16 | HWDownloadStateWaiting, // 等待
17 | HWDownloadStatePaused, // 暂停
18 | HWDownloadStateFinish, // 完成
19 | HWDownloadStateError, // 错误
20 | };
21 |
22 | @interface HWDownloadManager : NSObject
23 |
24 | // 初始化下载单例,若之前程序杀死时有正在下的任务,会自动恢复下载
25 | + (instancetype)shareManager;
26 |
27 | // 开始下载
28 | - (void)startDownloadTask:(HWDownloadModel *)model;
29 |
30 | // 暂停下载
31 | - (void)pauseDownloadTask:(HWDownloadModel *)model;
32 |
33 | // 删除下载任务及本地缓存
34 | - (void)deleteTaskAndCache:(HWDownloadModel *)model;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/HWDownloadModel.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadModel.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class FMResultSet;
12 |
13 | @interface HWDownloadModel : NSObject
14 |
15 | @property (nonatomic, copy) NSString *localPath; // 下载完成路径
16 | @property (nonatomic, copy) NSString *vid; // 文件唯一id标识
17 | @property (nonatomic, copy) NSString *fileName; // 文件名
18 | @property (nonatomic, copy) NSString *url; // url
19 | @property (nonatomic, strong) NSData *resumeData; // 下载的数据
20 | @property (nonatomic, assign) CGFloat progress; // 下载进度
21 | @property (nonatomic, assign) HWDownloadState state; // 下载状态
22 | @property (nonatomic, assign) NSUInteger totalFileSize; // 文件总大小
23 | @property (nonatomic, assign) NSUInteger tmpFileSize; // 下载大小
24 | @property (nonatomic, assign) NSUInteger speed; // 下载速度
25 | @property (nonatomic, assign) NSTimeInterval lastSpeedTime; // 上次计算速度时的时间戳
26 | @property (nonatomic, assign) NSUInteger intervalFileSize; // 计算速度时间内下载文件的大小
27 | @property (nonatomic, assign) NSUInteger lastStateTime; // 记录任务加入准备下载的时间(点击默认、暂停、失败状态),用于计算开始、停止任务的先后顺序
28 |
29 | // 根据数据库查询结果初始化
30 | - (instancetype)initWithFMResultSet:(FMResultSet *)resultSet;
31 |
32 | @end
33 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/HWDownloadModel.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadModel.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWDownloadModel.h"
10 |
11 | @implementation HWDownloadModel
12 |
13 | - (NSString *)localPath
14 | {
15 | if (!_localPath) {
16 | NSString *fileName = [_url substringFromIndex:[_url rangeOfString:@"/" options:NSBackwardsSearch].location + 1];
17 | NSString *str = [NSString stringWithFormat:@"%@_%@", _vid, fileName];
18 | _localPath = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:str];
19 | }
20 |
21 | return _localPath;
22 | }
23 |
24 | - (instancetype)initWithFMResultSet:(FMResultSet *)resultSet
25 | {
26 | if (!resultSet) return nil;
27 |
28 | _vid = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"vid"]];
29 | _url = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"url"]];
30 | _fileName = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"fileName"]];
31 | _totalFileSize = [[resultSet objectForColumn:@"totalFileSize"] integerValue];
32 | _tmpFileSize = [[resultSet objectForColumn:@"tmpFileSize"] integerValue];
33 | _progress = [[resultSet objectForColumn:@"progress"] floatValue];
34 | _state = [[resultSet objectForColumn:@"state"] integerValue];
35 | _lastSpeedTime = [resultSet doubleForColumn:@"lastSpeedTime"];
36 | _intervalFileSize = [[resultSet objectForColumn:@"intervalFileSize"] integerValue];
37 | _lastStateTime = [[resultSet objectForColumn:@"lastStateTime"] integerValue];
38 | _resumeData = [resultSet dataForColumn:@"resumeData"];
39 |
40 | return self;
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/NSURLSession+CorrectedResumeData.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLSession+CorrectedResumeData.h
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/25.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | // 用于修复iOS 10.0、10.1系统暂停后继续下载错误问题
8 |
9 | #import
10 |
11 | @interface NSURLSession (CorrectedResumeData)
12 |
13 | - (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWDownloadManager/NSURLSession+CorrectedResumeData.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSURLSession+CorrectedResumeData.m
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/25.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #import "NSURLSession+CorrectedResumeData.h"
10 |
11 | static NSString *const resumeCurrentRequest = @"NSURLSessionResumeCurrentRequest";
12 | static NSString *const resumeOriginalRequest = @"NSURLSessionResumeOriginalRequest";
13 |
14 | @implementation NSURLSession (CorrectedResumeData)
15 |
16 | - (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData
17 | {
18 | NSData *data = [self getCorrectResumeDataWithData:resumeData];
19 | data = data ? data : resumeData;
20 | NSURLSessionDownloadTask *task = [self downloadTaskWithResumeData:data];
21 | NSMutableDictionary *resumeDic = [self getResumeDictionaryWithData:data];
22 |
23 | if (resumeDic) {
24 | if (!task.originalRequest) {
25 | NSData *originalReqData = resumeDic[resumeOriginalRequest];
26 | NSURLRequest *originalRequest = [NSKeyedUnarchiver unarchiveObjectWithData:originalReqData];
27 | if (originalRequest) [task setValue:originalRequest forKey:@"originalRequest"];
28 | }
29 | if (!task.currentRequest) {
30 | NSData *currentReqData = resumeDic[resumeCurrentRequest];
31 | NSURLRequest *currentRequest = [NSKeyedUnarchiver unarchiveObjectWithData:currentReqData];
32 | if (currentRequest) [task setValue:currentRequest forKey:@"currentRequest"];
33 | }
34 | }
35 |
36 | return task;
37 | }
38 |
39 | - (NSData *)getCorrectResumeDataWithData:(NSData *)data
40 | {
41 | if (!data) return nil;
42 |
43 | NSMutableDictionary *resumeDictionary = [self getResumeDictionaryWithData:data];
44 | if (!resumeDictionary) return nil;
45 |
46 | resumeDictionary[resumeCurrentRequest] = [self getCorrectRequestDataWithData:resumeDictionary[resumeCurrentRequest]];
47 | resumeDictionary[resumeOriginalRequest] = [self getCorrectRequestDataWithData:resumeDictionary[resumeOriginalRequest]];
48 |
49 | return [NSPropertyListSerialization dataWithPropertyList:resumeDictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:nil];
50 | }
51 |
52 | - (NSMutableDictionary *)getResumeDictionaryWithData:(NSData *)data
53 | {
54 | return [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil];
55 | }
56 |
57 | - (NSData *)getCorrectRequestDataWithData:(NSData *)data
58 | {
59 | if (!data) return nil;
60 |
61 | if ([NSKeyedUnarchiver unarchiveObjectWithData:data]) return data;
62 |
63 | NSMutableDictionary *archive = [[NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil] mutableCopy];
64 | if (!archive) return nil;
65 |
66 | NSInteger i = 0;
67 | id objectss = archive[@"$objects"];
68 | while ([objectss[1] objectForKey:[NSString stringWithFormat:@"$%ld", i]]) {
69 | i++;
70 | }
71 |
72 | NSInteger j = 0;
73 | while ([archive[@"$objects"][1] objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]]) {
74 | NSMutableArray *array = archive[@"$objects"];
75 | NSMutableDictionary *dic = array[1];
76 | id obj = [dic objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]];
77 | if (obj) {
78 | [dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld", i + j]];
79 | [dic removeObjectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]];
80 | [array replaceObjectAtIndex:1 withObject:dic];
81 | archive[@"$objects"] = array;
82 | }
83 | j++;
84 | }
85 |
86 | if ([archive[@"$objects"][1] objectForKey:@"__nsurlrequest_proto_props"]) {
87 | NSMutableArray *array = archive[@"$objects"];
88 | NSMutableDictionary *dic = array[1];
89 | id obj = [dic objectForKey:@"__nsurlrequest_proto_props"];
90 | if (obj) {
91 | [dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld", i + j]];
92 | [dic removeObjectForKey:@"__nsurlrequest_proto_props"];
93 | [array replaceObjectAtIndex:1 withObject:dic];
94 | archive[@"$objects"] = array;
95 | }
96 | }
97 |
98 | if ([archive[@"$top"] objectForKey:@"NSKeyedArchiveRootObjectKey"]) {
99 | [archive[@"$top"] setObject:archive[@"$top"][@"NSKeyedArchiveRootObjectKey"] forKey: NSKeyedArchiveRootObjectKey];
100 | [archive[@"$top"] removeObjectForKey:@"NSKeyedArchiveRootObjectKey"];
101 | }
102 |
103 | return [NSPropertyListSerialization dataWithPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil];
104 | }
105 |
106 | @end
107 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWNetworkReachabilityManager.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWNetworkReachabilityManager.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/5/18.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "AFNetworkReachabilityManager.h"
10 |
11 | @interface HWNetworkReachabilityManager : NSObject
12 |
13 | // 当前网络状态
14 | @property (nonatomic, assign, readonly) AFNetworkReachabilityStatus networkReachabilityStatus;
15 |
16 | // 获取单例
17 | + (instancetype)shareManager;
18 |
19 | // 监听网络状态
20 | - (void)monitorNetworkStatus;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWNetworkReachabilityManager.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWNetworkReachabilityManager.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/5/18.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWNetworkReachabilityManager.h"
10 |
11 | @interface HWNetworkReachabilityManager ()
12 |
13 | @property (nonatomic, assign, readwrite) AFNetworkReachabilityStatus networkReachabilityStatus;
14 |
15 | @end
16 |
17 | @implementation HWNetworkReachabilityManager
18 |
19 | + (instancetype)shareManager
20 | {
21 | static HWNetworkReachabilityManager *manager = nil;
22 |
23 | static dispatch_once_t onceToken;
24 | dispatch_once(&onceToken, ^{
25 | manager = [[self alloc] init];
26 | });
27 |
28 | return manager;
29 | }
30 |
31 | // 监听网络状态
32 | - (void)monitorNetworkStatus
33 | {
34 | // 创建网络监听者
35 | AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
36 |
37 | [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
38 | switch (status) {
39 | case AFNetworkReachabilityStatusUnknown:
40 | // 未知网络
41 | HWLog(@"当前网络:未知网络");
42 | break;
43 |
44 | case AFNetworkReachabilityStatusNotReachable:
45 | // 无网络
46 | HWLog(@"当前网络:无网络");
47 | break;
48 |
49 | case AFNetworkReachabilityStatusReachableViaWWAN:
50 | // 蜂窝数据
51 | HWLog(@"当前网络:蜂窝数据");
52 | break;
53 |
54 | case AFNetworkReachabilityStatusReachableViaWiFi:
55 | // 无线网络
56 | HWLog(@"当前网络:无线网络");
57 | break;
58 |
59 | default:
60 | break;
61 | }
62 |
63 | if (_networkReachabilityStatus != status) {
64 | _networkReachabilityStatus = status;
65 | // 网络改变通知
66 | [[NSNotificationCenter defaultCenter] postNotificationName:HWNetworkingReachabilityDidChangeNotification object:[NSNumber numberWithInteger:status]];
67 | }
68 | }];
69 |
70 | // 开始监听
71 | [manager startMonitoring];
72 | }
73 |
74 | @end
75 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWProgressHUD.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWProgressHUD.h
3 | // HWProgressHUD
4 | //
5 | // Created by sxmaps_w on 2017/4/21.
6 | // Copyright © 2017年 wqb. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWProgressHUD : UIView
12 |
13 | // 显示转圈加载,调用dismiss、showMessage等方法隐藏,常用于已有视图上提交加载数据
14 | + (void)show;
15 |
16 | // 显示加载,在特定视图
17 | + (void)showInView:(UIView *)view;
18 |
19 | // 空页面显示加载动画,常用于未创建视图时加载数据,创建控件
20 | + (void)showWhilePushing;
21 |
22 | // 加载动画,传YES显示空页面显示加载动画,传NO显示转圈加载动画
23 | + (void)showWhilePushing:(BOOL)pushing;
24 |
25 | // 显示文字,默认两秒后消失
26 | + (void)showMessage:(NSString *)message;
27 |
28 | // 显示文字,默认两秒后消失,在特定视图
29 | + (void)showMessage:(NSString *)message inView:(UIView *)view;
30 |
31 | // 显示文字,设置显示时长
32 | + (void)showMessage:(NSString *)message duration:(NSTimeInterval)duration;
33 |
34 | // 显示文字,设置显示时长,在特定视图
35 | + (void)showMessage:(NSString *)message duration:(NSTimeInterval)duration inView:(UIView *)view;
36 |
37 | // 隐藏
38 | + (void)dismiss;
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/HWToolBox.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWToolBox.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWToolBox : NSObject
12 |
13 | // 根据字节大小返回文件大小字符KB、MB
14 | + (NSString *)stringFromByteCount:(long long)byteCount;
15 |
16 | // 时间转换为时间戳
17 | + (NSTimeInterval)getTimeStampWithDate:(NSDate *)date;
18 |
19 | // 时间戳转换为时间
20 | + (NSDate *)getDateWithTimeStamp:(NSTimeInterval)timeStamp;
21 |
22 | // 一个时间戳与当前时间的间隔(s)
23 | + (NSInteger)getIntervalsWithTimeStamp:(NSTimeInterval)timeStamp;
24 |
25 | //获得当前设备型号
26 | + (NSString *)getCurrentDeviceModel;
27 |
28 | //通过view获取控制器
29 | + (UIViewController *)findViewController:(UIView *)view;
30 |
31 | //获取当前控制器
32 | + (UIViewController *)getCurrentVC;
33 |
34 | //删除path路径下的文件
35 | + (void)clearCachesWithFilePath:(NSString *)path;
36 |
37 | //获取沙盒Library的文件目录
38 | + (NSString *)LibraryDirectory;
39 |
40 | //获取沙盒Document的文件目录
41 | + (NSString *)DocumentDirectory;
42 |
43 | //获取沙盒Preference的文件目录
44 | + (NSString *)PreferencePanesDirectory;
45 |
46 | // 获取沙盒Caches的文件目录
47 | + (NSString *)CachesDirectory;
48 |
49 | //验证是否是纯数字
50 | + (BOOL)isAllNumber:(NSString *)number;
51 |
52 | //验证手机号码
53 | + (BOOL)isMobileNumber:(NSString *)mobileNum;
54 |
55 | //验证身份证号码
56 | + (BOOL)isIdentityCardNumber:(NSString *)number;
57 |
58 | //验证香港身份证号码
59 | + (BOOL)isIdentityHKCardNumber:(NSString *)number;
60 |
61 | //验证密码格式(包含大写、小写、数字)
62 | + (BOOL)isConformSXPassword:(NSString *)password;
63 |
64 | //验证护照
65 | + (BOOL)isPassportNumber:(NSString *)number;
66 |
67 | //计算文字的长度
68 | + (CGSize)sizeWithText:(NSString *)text font:(UIFont *)font maxSize:(CGSize)maxSize;
69 |
70 | //去掉小数点后无效的零
71 | + (NSString *)deleteFailureZero:(NSString *)string;
72 |
73 | //得到中英文混合字符串长度
74 | + (int)lengthForText:(NSString *)text;
75 |
76 | //提示弹窗
77 | + (void)showAlertWithTitle:(NSString *)title sureMessage:(NSString *)sureMessage cancelMessage:(NSString *)cancelMessage warningMessage:(NSString *)warningMessage style:(UIAlertControllerStyle)UIAlertControllerStyle target:(id)target sureHandler:(void(^)(UIAlertAction *action))sureHandler cancelHandler:(void(^)(UIAlertAction *action))cancelHandler warningHandler:(void(^)(UIAlertAction *action))warningHandler;
78 |
79 | //获取当前时间
80 | + (NSString *)currentTime;
81 |
82 | // 获取当前时间(时分秒毫秒)
83 | + (NSString *)currentTimeCorrectToMillisecond;
84 |
85 | @end
86 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Common/SwizzlingDefine.h:
--------------------------------------------------------------------------------
1 | //
2 | // SwizzlingDefine.h
3 | // SXEducation
4 | //
5 | // Created by sxmaps on 2017/10/19.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 | #ifndef SwizzlingDefine_h
10 | #define SwizzlingDefine_h
11 | #import
12 |
13 | static inline void swizzling_exchangeMethod(Class clazz, SEL originalSelector, SEL swizzledSelector) {
14 | Method originalMethod = class_getInstanceMethod(clazz, originalSelector);
15 | Method swizzledMethod = class_getInstanceMethod(clazz, swizzledSelector);
16 |
17 | BOOL success = class_addMethod(clazz, originalSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
18 | if (success) {
19 | class_replaceMethod(clazz, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod));
20 | } else {
21 | method_exchangeImplementations(originalMethod, swizzledMethod);
22 | }
23 | }
24 |
25 | #endif /* SwizzlingDefine_h */
26 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/HWPlayVC/Controller/HWPlayVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWPlayVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/25.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 |
11 | @interface HWPlayVC : HWBaseViewController
12 |
13 | @property (nonatomic, strong) HWDownloadModel *model;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/HWPlayVC/Controller/HWPlayVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWPlayVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/25.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWPlayVC.h"
10 | #import
11 |
12 | @interface HWPlayVC ()
13 |
14 | @property (nonatomic, strong) AVPlayer *player;
15 |
16 | @end
17 |
18 | @implementation HWPlayVC
19 |
20 | - (void)viewDidLoad {
21 | [super viewDidLoad];
22 |
23 | self.navTitle = _model.fileName;
24 |
25 | [self creatControl];
26 | }
27 |
28 | - (void)creatControl
29 | {
30 | // 进度条
31 | UISlider *slider = [[UISlider alloc] initWithFrame:CGRectMake(50, KSuitFloat(400), KMainW - 100, 50)];
32 | [slider addTarget:self action:@selector(sliderValueChanged:) forControlEvents:UIControlEventValueChanged];
33 | [self.view addSubview:slider];
34 |
35 | // 创建播放器
36 | _player = [AVPlayer playerWithPlayerItem:[AVPlayerItem playerItemWithURL:[NSURL fileURLWithPath:_model.localPath]]];
37 |
38 | // 创建显示的图层
39 | AVPlayerLayer *playerLayer = [AVPlayerLayer playerLayerWithPlayer:_player];
40 | playerLayer.frame = CGRectMake(0, 0, KMainW, 400);
41 | [self.view.layer addSublayer:playerLayer];
42 |
43 | // 播放视频
44 | [_player play];
45 |
46 | // 进度回调
47 | weakify(self);
48 | [_player addPeriodicTimeObserverForInterval:CMTimeMake(1.0, 1.0) queue:dispatch_get_main_queue() usingBlock:^(CMTime time) {
49 | strongify(weakSelf);
50 | // 刷新slider
51 | slider.value = CMTimeGetSeconds(time) / CMTimeGetSeconds(strongSelf.player.currentItem.duration);
52 | }];
53 | }
54 |
55 | - (void)sliderValueChanged:(UISlider *)slider
56 | {
57 | // 计算时间
58 | float time = slider.value * CMTimeGetSeconds(_player.currentItem.duration);
59 |
60 | // 跳转到指定时间
61 | [_player seekToTime:CMTimeMake(time, 1.0)];
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/Controller/HWHomeVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWHomeVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 |
11 | @interface HWHomeVC : HWBaseViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/Controller/HWHomeVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWHomeVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWHomeVC.h"
10 | #import "HWHomeCell.h"
11 | #import "HWPlayVC.h"
12 |
13 | @interface HWHomeVC ()
14 |
15 | @property (nonatomic, strong) NSMutableArray *dataSource;
16 | @property (nonatomic, weak) UITableView *tableView;
17 |
18 | @end
19 |
20 | @implementation HWHomeVC
21 |
22 | - (NSMutableArray *)dataSource
23 | {
24 | if (!_dataSource) {
25 | _dataSource = [NSMutableArray array];
26 | }
27 |
28 | return _dataSource;
29 | }
30 |
31 | - (void)viewDidLoad {
32 | [super viewDidLoad];
33 |
34 | self.navTitle = @"首页";
35 |
36 | // 创建控件
37 | [self creatControl];
38 |
39 | // 添加通知
40 | [self addNotification];
41 | }
42 |
43 | - (void)viewWillAppear:(BOOL)animated
44 | {
45 | [super viewWillAppear:animated];
46 |
47 | // 获取网络数据
48 | [self getInfo];
49 |
50 | // 获取缓存
51 | [self getCacheData];
52 | }
53 |
54 | - (void)getInfo
55 | {
56 | // 模拟网络数据
57 | NSArray *testData = [NSArray arrayWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"testData.plist" ofType:nil]];
58 |
59 | // 转模型
60 | self.dataSource = [HWDownloadModel mj_objectArrayWithKeyValuesArray:testData];
61 | }
62 |
63 | - (void)getCacheData
64 | {
65 | // 获取已缓存数据
66 | NSArray *cacheData = [[HWDataBaseManager shareManager] getAllCacheData];
67 |
68 | // 这里是把本地缓存数据更新到网络请求的数据中,实际开发还是尽可能避免这样在两个地方取数据再整合
69 | for (int i = 0; i < self.dataSource.count; i++) {
70 | HWDownloadModel *model = self.dataSource[i];
71 | for (HWDownloadModel *downloadModel in cacheData) {
72 | if ([model.url isEqualToString:downloadModel.url]) {
73 | self.dataSource[i] = downloadModel;
74 | break;
75 | }
76 | }
77 | }
78 |
79 | [_tableView reloadData];
80 | }
81 |
82 | - (void)creatControl
83 | {
84 | // tableView
85 | UITableView *tableView = [[UITableView alloc] initWithFrame:CGRectMake(10, 0, KMainW - 20, KMainH - KNavHeight - KTabBarHeight)];
86 | tableView.showsVerticalScrollIndicator = NO;
87 | tableView.dataSource = self;
88 | tableView.delegate = self;
89 | tableView.rowHeight = 80.f;
90 | tableView.sectionHeaderHeight = 5.f;
91 | tableView.sectionFooterHeight = 5.f;
92 | tableView.backgroundColor = KWhiteColor;
93 | tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
94 | [self.view addSubview:tableView];
95 | _tableView = tableView;
96 | }
97 |
98 | - (void)addNotification
99 | {
100 | // 进度通知
101 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downLoadProgress:) name:HWDownloadProgressNotification object:nil];
102 | // 状态改变通知
103 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downLoadStateChange:) name:HWDownloadStateChangeNotification object:nil];
104 | }
105 |
106 | #pragma mark - UITableViewDataSource
107 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
108 | {
109 | return self.dataSource.count;
110 | }
111 |
112 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
113 | {
114 | HWHomeCell *cell = [HWHomeCell cellWithTableView:tableView];
115 |
116 | cell.model = self.dataSource[indexPath.row];
117 |
118 | return cell;
119 | }
120 |
121 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
122 | {
123 | HWDownloadModel *model = self.dataSource[indexPath.row];
124 |
125 | if (model.state == HWDownloadStateFinish) {
126 | HWPlayVC *vc = [[HWPlayVC alloc] init];
127 | vc.model = model;
128 | [self.navigationController pushViewController:vc animated:YES];
129 | }
130 | }
131 |
132 | - (UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
133 | {
134 | UIView *view = [[UIView alloc] init];
135 | view.backgroundColor = KClearColor;
136 |
137 | return view;
138 | }
139 |
140 | - (UIView *)tableView:(UITableView *)tableView viewForFooterInSection:(NSInteger)section
141 | {
142 | UIView *view = [[UIView alloc] init];
143 | view.backgroundColor = KClearColor;
144 |
145 | return view;
146 | }
147 |
148 | #pragma mark - HWDownloadNotification
149 | // 正在下载,进度回调
150 | - (void)downLoadProgress:(NSNotification *)notification
151 | {
152 | HWDownloadModel *downloadModel = notification.object;
153 |
154 | [self.dataSource enumerateObjectsUsingBlock:^(HWDownloadModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
155 | if ([model.url isEqualToString:downloadModel.url]) {
156 | // 主线程更新cell进度
157 | dispatch_async(dispatch_get_main_queue(), ^{
158 | HWHomeCell *cell = [_tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:idx inSection:0]];
159 | [cell updateViewWithModel:downloadModel];
160 | });
161 |
162 | *stop = YES;
163 | }
164 | }];
165 | }
166 |
167 | // 状态改变
168 | - (void)downLoadStateChange:(NSNotification *)notification
169 | {
170 | HWDownloadModel *downloadModel = notification.object;
171 |
172 | [self.dataSource enumerateObjectsUsingBlock:^(HWDownloadModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
173 | if ([model.url isEqualToString:downloadModel.url]) {
174 | // 更新数据源
175 | self.dataSource[idx] = downloadModel;
176 |
177 | // 主线程刷新cell
178 | dispatch_async(dispatch_get_main_queue(), ^{
179 | [_tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:idx inSection:0]] withRowAnimation:UITableViewRowAnimationNone];
180 | });
181 |
182 | *stop = YES;
183 | }
184 | }];
185 | }
186 |
187 | - (void)dealloc
188 | {
189 | [[NSNotificationCenter defaultCenter] removeObserver:self];
190 | }
191 |
192 | @end
193 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/View/HWDownloadButton.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadButton.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWDownloadButton : UIView
12 |
13 | @property (nonatomic, strong) HWDownloadModel *model; // 数据模型
14 | @property (nonatomic, assign) HWDownloadState state; // 下载状态
15 | @property (nonatomic, assign) CGFloat progress; // 下载进度
16 |
17 | // 添加点击方法
18 | - (void)addTarget:(id)target action:(SEL)action;
19 |
20 | @end
21 |
22 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/View/HWDownloadButton.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadButton.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/24.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWDownloadButton.h"
10 |
11 | @interface HWDownloadButton () {
12 | id _target;
13 | SEL _action;
14 | }
15 |
16 | @property (nonatomic, weak) UILabel *proLabel; // 进度标签
17 | @property (nonatomic, weak) UIImageView *imgView; // 状态视图
18 |
19 | @end
20 |
21 | @implementation HWDownloadButton
22 |
23 | - (instancetype)initWithFrame:(CGRect)frame
24 | {
25 | if (self = [super initWithFrame:frame]) {
26 | self.backgroundColor = KWhiteColor;
27 |
28 | // 百分比标签
29 | UILabel *proLabel = [[UILabel alloc] initWithFrame:self.bounds];
30 | proLabel.font = [UIFont boldSystemFontOfSize:15.0f];
31 | proLabel.textColor = [UIColor colorWithRed:0/255.0 green:191/255.0 blue:255/255.0 alpha:1];
32 | proLabel.textAlignment = NSTextAlignmentCenter;
33 | [self addSubview:proLabel];
34 | _proLabel = proLabel;
35 |
36 | // 状态视图
37 | UIImageView *imgView = [[UIImageView alloc] initWithFrame:self.bounds];
38 | imgView.backgroundColor = KWhiteColor;
39 | imgView.image = [UIImage imageNamed:@"com_download_default"];
40 | [self addSubview:imgView];
41 | _imgView = imgView;
42 | }
43 |
44 | return self;
45 | }
46 |
47 | - (void)setProgress:(CGFloat)progress
48 | {
49 | _progress = progress;
50 |
51 | _proLabel.text = [NSString stringWithFormat:@"%d%%", (int)floor(progress * 100)];
52 |
53 | [self setNeedsDisplay];
54 | }
55 |
56 | - (void)drawRect:(CGRect)rect
57 | {
58 | CGFloat lineWidth = 3.f;
59 |
60 | UIBezierPath *path = [[UIBezierPath alloc] init];
61 | path.lineWidth = lineWidth;
62 | [_proLabel.textColor set];
63 | path.lineCapStyle = kCGLineCapRound;
64 | path.lineJoinStyle = kCGLineJoinRound;
65 | CGFloat radius = (MIN(rect.size.width, rect.size.height) - lineWidth) * 0.5;
66 | // 画弧(参数:中心、半径、起始角度(3点钟方向为0)、结束角度、是否顺时针)
67 | [path addArcWithCenter:(CGPoint){rect.size.width * 0.5, rect.size.height * 0.5} radius:radius startAngle:M_PI * 1.5 endAngle:M_PI * 1.5 + M_PI * 2 * _progress clockwise:YES];
68 | [path stroke];
69 | }
70 |
71 | - (void)setModel:(HWDownloadModel *)model
72 | {
73 | _model = model;
74 |
75 | self.state = model.state;
76 | }
77 |
78 | - (void)setState:(HWDownloadState)state
79 | {
80 | _imgView.hidden = state == HWDownloadStateDownloading;
81 | _proLabel.hidden = !_imgView.hidden;
82 |
83 | switch (state) {
84 | case HWDownloadStateDefault:
85 | _imgView.image = [UIImage imageNamed:@"com_download_default"];
86 | break;
87 |
88 | case HWDownloadStateDownloading:
89 | break;
90 |
91 | case HWDownloadStateWaiting:
92 | _imgView.image = [UIImage imageNamed:@"com_download_waiting"];
93 | break;
94 |
95 | case HWDownloadStatePaused:
96 | _imgView.image = [UIImage imageNamed:@"com_download_pause"];
97 | break;
98 |
99 | case HWDownloadStateFinish:
100 | _imgView.image = [UIImage imageNamed:@"com_download_finish"];
101 | break;
102 |
103 | case HWDownloadStateError:
104 | _imgView.image = [UIImage imageNamed:@"com_download_error"];
105 | break;
106 |
107 | default:
108 | break;
109 | }
110 |
111 | _state = state;
112 | }
113 |
114 | - (void)addTarget:(id)target action:(SEL)action
115 | {
116 | _target = target;
117 | _action = action;
118 | }
119 |
120 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
121 | {
122 | if (_state == HWDownloadStateDefault || _state == HWDownloadStatePaused || _state == HWDownloadStateError) {
123 | // 点击默认、暂停、失败状态,调用开始下载
124 | [[HWDownloadManager shareManager] startDownloadTask:_model];
125 |
126 | }else if (_state == HWDownloadStateDownloading || _state == HWDownloadStateWaiting) {
127 | // 点击正在下载、等待状态,调用暂停下载
128 | [[HWDownloadManager shareManager] pauseDownloadTask:_model];
129 | }
130 |
131 | if (!_target || !_action) return;
132 | ((void (*)(id, SEL, id))[_target methodForSelector:_action])(_target, _action, self);
133 | }
134 |
135 | @end
136 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/View/HWHomeCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWHomeCell.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/23.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWHomeCell : UITableViewCell
12 |
13 | @property (nonatomic, strong) HWDownloadModel *model;
14 |
15 | + (instancetype)cellWithTableView:(UITableView *)tabelView;
16 |
17 | // 更新视图
18 | - (void)updateViewWithModel:(HWDownloadModel *)model;
19 |
20 | @end
21 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Home/Home/View/HWHomeCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWHomeCell.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/23.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWHomeCell.h"
10 | #import "HWDownloadButton.h"
11 |
12 | @interface HWHomeCell ()
13 |
14 | @property (nonatomic, weak) UILabel *titleLabel; // 标题
15 | @property (nonatomic, weak) UILabel *speedLabel; // 进度标签
16 | @property (nonatomic, weak) UILabel *fileSizeLabel; // 文件大小标签
17 | @property (nonatomic, weak) HWDownloadButton *downloadBtn; // 下载按钮
18 |
19 | @end
20 |
21 | @implementation HWHomeCell
22 |
23 | + (instancetype)cellWithTableView:(UITableView *)tabelView
24 | {
25 | static NSString *identifier = @"HWHomeCellIdentifier";
26 |
27 | HWHomeCell *cell = [tabelView dequeueReusableCellWithIdentifier:identifier];
28 | if (!cell) {
29 | cell = [[HWHomeCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
30 | cell.selectionStyle = UITableViewCellSelectionStyleNone;
31 | cell.backgroundColor = KWhiteColor;
32 |
33 | // 选中时cell背景色
34 | UIView *backgroundViews = [[UIView alloc] initWithFrame:cell.frame];
35 | backgroundViews.backgroundColor = [[UIColor colorWithHexString:@"#00CDCD"] colorWithAlphaComponent:0.5f];
36 | [cell setSelectedBackgroundView:backgroundViews];
37 | }
38 |
39 | return cell;
40 | }
41 |
42 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
43 | {
44 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
45 | // 底图
46 | CGFloat margin = 10.f;
47 | CGFloat backViewH = 70.f;
48 | UIView *backView = [[UIView alloc] initWithFrame:CGRectMake(0, margin * 0.5, KMainW - margin * 2, backViewH)];
49 | backView.backgroundColor = [UIColor colorWithHexString:@"#00CDCD"];
50 | [self.contentView addSubview:backView];
51 |
52 | // 下载按钮
53 | CGFloat btnW = 50.f;
54 | HWDownloadButton *downloadBtn = [[HWDownloadButton alloc] initWithFrame:CGRectMake(backView.frameWidth - btnW - margin, (backViewH - btnW) * 0.5, btnW, btnW)];
55 | [downloadBtn addTarget:self action:@selector(downBtnOnClick:)];
56 | [backView addSubview:downloadBtn];
57 | _downloadBtn = downloadBtn;
58 |
59 | // 标题
60 | UILabel *titleLabel = [[UILabel alloc] initWithFrame:CGRectMake(margin, 0, backView.frameWidth - margin * 3 - btnW, backViewH * 0.6)];
61 | titleLabel.font = [UIFont boldSystemFontOfSize:18.f];
62 | titleLabel.textColor = KWhiteColor;
63 | titleLabel.backgroundColor = backView.backgroundColor;
64 | titleLabel.layer.masksToBounds = YES;
65 | [backView addSubview:titleLabel];
66 | _titleLabel = titleLabel;
67 |
68 | // 进度标签
69 | UILabel *speedLable = [[UILabel alloc] initWithFrame:CGRectMake(margin, CGRectGetMaxY(titleLabel.frame), titleLabel.frameWidth * 0.36, backViewH * 0.4)];
70 | speedLable.font = [UIFont systemFontOfSize:14.f];
71 | speedLable.textColor = KWhiteColor;
72 | speedLable.textAlignment = NSTextAlignmentRight;
73 | speedLable.backgroundColor = backView.backgroundColor;
74 | speedLable.layer.masksToBounds = YES;
75 | [backView addSubview:speedLable];
76 | _speedLabel = speedLable;
77 |
78 | // 文件大小标签
79 | UILabel *fileSizeLabel = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(speedLable.frame), CGRectGetMaxY(titleLabel.frame), titleLabel.frameWidth - speedLable.frameWidth, backViewH * 0.4)];
80 | fileSizeLabel.font = [UIFont systemFontOfSize:14.f];
81 | fileSizeLabel.textColor = KWhiteColor;
82 | fileSizeLabel.textAlignment = NSTextAlignmentRight;
83 | fileSizeLabel.backgroundColor = backView.backgroundColor;
84 | fileSizeLabel.layer.masksToBounds = YES;
85 | [backView addSubview:fileSizeLabel];
86 | _fileSizeLabel = fileSizeLabel;
87 | }
88 |
89 | return self;
90 | }
91 |
92 | - (void)layoutSubviews
93 | {
94 | [super layoutSubviews];
95 |
96 | NSArray *subviews = ISIOS11 ? self.superview.subviews : self.subviews;
97 | NSString *classString = ISIOS11 ? @"UISwipeActionPullView" : @"UITableViewCellDeleteConfirmationView";
98 | for (UIView *view in subviews) {
99 | if ([view isKindOfClass:NSClassFromString(classString)]) {
100 | UIButton *deleteBtn = view.subviews.firstObject;
101 | view.backgroundColor = KClearColor;
102 | deleteBtn.frameY = 5;
103 | deleteBtn.frameHeight = 70;
104 | [deleteBtn setTitle:@"删除" forState:UIControlStateNormal];
105 | break;
106 | }
107 | }
108 | }
109 |
110 | - (void)setModel:(HWDownloadModel *)model
111 | {
112 | _model = model;
113 |
114 | _downloadBtn.model = model;
115 | _titleLabel.text = model.fileName;
116 | [self updateViewWithModel:model];
117 | }
118 |
119 | // 更新视图
120 | - (void)updateViewWithModel:(HWDownloadModel *)model
121 | {
122 | _downloadBtn.progress = model.progress;
123 |
124 | [self reloadLabelWithModel:model];
125 | }
126 |
127 | // 刷新标签
128 | - (void)reloadLabelWithModel:(HWDownloadModel *)model
129 | {
130 | NSString *totalSize = [HWToolBox stringFromByteCount:model.totalFileSize];
131 | NSString *tmpSize = [HWToolBox stringFromByteCount:model.tmpFileSize];
132 |
133 | if (model.state == HWDownloadStateFinish) {
134 | _fileSizeLabel.text = [NSString stringWithFormat:@"%@", totalSize];
135 |
136 | }else {
137 | _fileSizeLabel.text = [NSString stringWithFormat:@"%@ / %@", tmpSize, totalSize];
138 | }
139 | _fileSizeLabel.hidden = model.totalFileSize == 0;
140 |
141 | if (model.speed > 0) {
142 | _speedLabel.text = [NSString stringWithFormat:@"%@ / s", [HWToolBox stringFromByteCount:model.speed]];
143 | }
144 | _speedLabel.hidden = !(model.state == HWDownloadStateDownloading && model.totalFileSize > 0);
145 | }
146 |
147 | - (void)downBtnOnClick:(HWDownloadButton *)btn
148 | {
149 | // do something...
150 | }
151 |
152 | @end
153 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @property (nonatomic, copy) void (^ backgroundSessionCompletionHandler)(void); // 后台所有下载任务完成回调
16 |
17 | @end
18 |
19 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "HWTabBarController.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
19 | {
20 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
21 | self.window.backgroundColor = KWhiteColor;
22 | [self.window makeKeyAndVisible];
23 | self.window.rootViewController = [[HWTabBarController alloc] init];
24 |
25 | // 一次性代码
26 | [self projectOnceCode];
27 |
28 | // 开启网络监听
29 | [[HWNetworkReachabilityManager shareManager] monitorNetworkStatus];
30 |
31 | // 初始化下载单例,若之前程序杀死时有正在下的任务,会自动恢复下载
32 | [HWDownloadManager shareManager];
33 |
34 | return YES;
35 | }
36 |
37 | // 应用处于后台,所有下载任务完成调用
38 | - (void)application:(UIApplication *)application handleEventsForBackgroundURLSession:(NSString *)identifier completionHandler:(void (^)(void))completionHandler
39 | {
40 | _backgroundSessionCompletionHandler = completionHandler;
41 | }
42 |
43 | // 一次性代码
44 | - (void)projectOnceCode
45 | {
46 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
47 | NSString *onceKey = @"HWProjectOnceKey";
48 | if (![defaults boolForKey:onceKey]) {
49 | // 初始化下载最大并发数为1,不允许蜂窝网络下载
50 | [defaults setInteger:1 forKey:HWDownloadMaxConcurrentCountKey];
51 | [defaults setBool:NO forKey:HWDownloadAllowsCellularAccessKey];
52 | [defaults setBool:YES forKey:onceKey];
53 | }
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/HWBaseViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWBaseViewController.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWBaseViewController : UIViewController
12 |
13 | // 导航栏标题
14 | @property (nonatomic, copy) NSString *navTitle;
15 |
16 | // 是否允许二级页面屏幕左侧右滑返回,默认允许
17 | @property (nonatomic, assign) BOOL isAllowScrollBack;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/HWBaseViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWBaseViewController.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/9.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 | #import "HWTabBarController.h"
11 |
12 | @interface HWBaseViewController ()
13 |
14 | @end
15 |
16 | @implementation HWBaseViewController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | //默认视图背景色
22 | self.view.backgroundColor = KWhiteColor;
23 |
24 | //设置状态栏文字颜色为白色
25 | [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent animated:NO];
26 |
27 | //用以支持二级页面边缘右滑返回
28 | _isAllowScrollBack = YES;
29 | self.navigationController.interactivePopGestureRecognizer.delegate = (id)self;
30 |
31 | // 列表适配
32 | [self adaptiveView];
33 | }
34 |
35 | - (void)viewWillAppear:(BOOL)animated
36 | {
37 | [super viewWillAppear:animated];
38 |
39 | self.navigationController.interactivePopGestureRecognizer.enabled = _isAllowScrollBack;
40 |
41 | //一级页面显示tabBar
42 | if (self.navigationController.viewControllers.count == 1) {
43 | HWTabBarController *tabBarController = (HWTabBarController *)self.tabBarController;
44 | [tabBarController setTabBarShowWithAnimaition:YES];
45 | }
46 | }
47 |
48 | //设置导航栏标题
49 | - (void)setNavTitle:(NSString *)navTitle
50 | {
51 | _navTitle = navTitle;
52 |
53 | self.navigationItem.title = _navTitle;
54 | }
55 |
56 | // 列表适配
57 | - (void)adaptiveView
58 | {
59 | self.automaticallyAdjustsScrollViewInsets = NO;
60 | [UITableView appearance].estimatedRowHeight = 0;
61 | [UITableView appearance].estimatedSectionHeaderHeight = 0;
62 | [UITableView appearance].estimatedSectionFooterHeight = 0;
63 | // iOS 11 解决SafeArea的问题,同时能解决pop时上级页面scrollView抖动的问题
64 | if (@available(iOS 11, *)) [UIScrollView appearance].contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
65 | }
66 |
67 | @end
68 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/HWNavigationController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWNavigationController.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol BackButtonHandlerProtocol
12 |
13 | @optional
14 | /**
15 | 导航栏返回按钮点击事件,默认返回上一级,如有特殊操作可调用此方法
16 | */
17 | - (void)back;
18 |
19 | @end
20 |
21 | @interface UIViewController (customBackPopButton)
22 |
23 | @end
24 |
25 | @interface HWNavigationController : UINavigationController
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/HWNavigationController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWNavigationController.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWNavigationController.h"
10 | #import "HWTabBarController.h"
11 |
12 | @interface HWNavigationController ()
13 |
14 | @end
15 |
16 | @implementation HWNavigationController
17 |
18 | - (void)viewDidLoad {
19 | [super viewDidLoad];
20 |
21 | UIImage *navBackImage = [UIImage imageWithColor:[UIColor colorWithHexString:@"#009ACD"]];
22 | UINavigationBar *navBar = [UINavigationBar appearance];
23 | [navBar setShadowImage:[[UIImage alloc] init]];
24 | [navBar setBackgroundImage:navBackImage forBarMetrics:UIBarMetricsDefault];
25 | }
26 |
27 | - (void)pushViewController:(UIViewController *)viewController animated:(BOOL)animated
28 | {
29 | if (self.childViewControllers.count) {
30 | HWTabBarController *tabBarController = (HWTabBarController *)self.tabBarController;
31 | [tabBarController setTabBarHiddenWithAnimaition:YES];
32 |
33 | UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom];
34 | [button setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateNormal];
35 | [button setImage:[UIImage imageNamed:@"nav_back"] forState:UIControlStateHighlighted];
36 | [button sizeToFit];
37 | [button addTarget:self action:@selector(back) forControlEvents:UIControlEventTouchUpInside];
38 | viewController.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithCustomView:button];
39 | }
40 |
41 | if (![[super topViewController] isKindOfClass:[viewController class]]) {
42 | [super pushViewController:viewController animated:animated];
43 | }
44 | }
45 |
46 | - (void)back
47 | {
48 | if ([self.topViewController respondsToSelector:@selector(back)]) {
49 | [self.topViewController back];
50 |
51 | } else {
52 | [self popViewControllerAnimated:YES];
53 | }
54 | }
55 |
56 | @end
57 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/UINavigationBar+Swizzling.h:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationBar+Swizzling.h
3 | // SXEducation
4 | //
5 | // Created by sxmaps on 2017/10/19.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 |
10 |
11 | @interface UINavigationBar (Swizzling)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/UINavigationBar+Swizzling.m:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationBar+Swizzling.m
3 | // SXEducation
4 | //
5 | // Created by sxmaps on 2017/10/19.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 | #import "UINavigationBar+Swizzling.h"
10 | #import "SwizzlingDefine.h"
11 |
12 | @implementation UINavigationBar (Swizzling)
13 |
14 | + (void)load
15 | {
16 | static dispatch_once_t onceToken;
17 | dispatch_once(&onceToken, ^{
18 | swizzling_exchangeMethod([UINavigationBar class], @selector(layoutSubviews), @selector(swizzling_layoutSubViews));
19 | });
20 | }
21 |
22 | - (void)swizzling_layoutSubViews
23 | {
24 | UINavigationItem *navgationItem = [self topItem];
25 |
26 | if ([navgationItem.titleView isKindOfClass:[UILabel class]]) {
27 | UILabel *label = (UILabel *)navgationItem.titleView;
28 | UIFont *font = self.titleTextAttributes[NSFontAttributeName];
29 | if (font) {
30 | label.font = font;
31 | }
32 |
33 | UIColor *color = self.titleTextAttributes[NSForegroundColorAttributeName];
34 | if (color) {
35 | label.textColor = color;
36 | }
37 |
38 | [label sizeToFit];
39 | }
40 |
41 | if (!ISIOS11) {
42 | [self layoutLabel];
43 | }
44 | [self swizzling_layoutSubViews];
45 | }
46 |
47 | - (void)layoutLabel
48 | {
49 | UINavigationItem *navigationItem = [self topItem];
50 | UIView *view = navigationItem.titleView;
51 | view.centerX = self.frameWidth * .5f;
52 | view.centerY = self.frameHeight * .5f;
53 | }
54 |
55 | @end
56 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/UINavigationItem+Swizzling.h:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationItem+Swizzling.h
3 | // SXEducation
4 | //
5 | // Created by sxmaps on 2017/10/19.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 |
10 |
11 | @interface UINavigationItem (Swizzling)
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/NavigationController/UINavigationItem+Swizzling.m:
--------------------------------------------------------------------------------
1 | //
2 | // UINavigationItem+Swizzling.m
3 | // SXEducation
4 | //
5 | // Created by sxmaps on 2017/10/19.
6 | // Copyright © 2017年 sxmaps. All rights reserved.
7 | //
8 |
9 | #import "UINavigationItem+Swizzling.h"
10 | #import "SwizzlingDefine.h"
11 |
12 | #define KTitleLabelFont [UIFont boldSystemFontOfSize:18.f]
13 | #define KTitleLabelTextColor [UIColor colorWithHexString:@"#ffffff"]
14 |
15 | @implementation UINavigationItem (Swizzling)
16 |
17 | + (void)load
18 | {
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^{
21 | swizzling_exchangeMethod([UINavigationItem class], @selector(setTitle:), @selector(swizzling_setTitle:));
22 | swizzling_exchangeMethod([UINavigationItem class], @selector(title), @selector(swizzling_title));
23 | });
24 | }
25 |
26 | - (void)swizzling_setTitle:(NSString *)title
27 | {
28 | UILabel *titleLabel = (UILabel *)self.titleView;
29 | if (!titleLabel) {
30 | titleLabel = [[UILabel alloc] initWithFrame:CGRectZero];
31 | self.titleView = titleLabel;
32 | }
33 |
34 | if ([titleLabel isKindOfClass:[UILabel class]]) {
35 | titleLabel.font = KTitleLabelFont;
36 | titleLabel.textColor = KTitleLabelTextColor;
37 | titleLabel.text = title;
38 | }
39 |
40 | [titleLabel.superview layoutSubviews];
41 | }
42 |
43 | - (NSString *)swizzling_title
44 | {
45 | if ([self swizzling_title].length ) {
46 | return [self swizzling_title];
47 | }
48 |
49 | UILabel *titleLabel = (UILabel *)self.titleView;
50 | if ([titleLabel isKindOfClass:[UILabel class]]) {
51 | titleLabel.font = KTitleLabelFont;
52 | titleLabel.textColor = KTitleLabelTextColor;
53 |
54 | return titleLabel.text;
55 | }
56 |
57 | return nil;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/TabBarController/HWTabBarController.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWTabBarController.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWTabBarController : UITabBarController
12 |
13 | //隐藏TabBar
14 | - (void)setTabBarHiddenWithAnimaition:(BOOL)annimation;
15 |
16 | //显示TabBar
17 | - (void)setTabBarShowWithAnimaition:(BOOL)annimation;
18 |
19 | @end
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/TabBarController/HWTabBarController.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWTabBarController.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWTabBarController.h"
10 | #import "HWTabBarView.h"
11 | #import "HWNavigationController.h"
12 |
13 | @interface HWTabBarController ()
14 |
15 | @property (nonatomic, weak) HWTabBarView *tabBarView;
16 |
17 | @end
18 |
19 | @implementation HWTabBarController
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | //隐藏系统的tabbar
25 | self.tabBar.alpha = 0.0;
26 |
27 | [self creatControl];
28 |
29 | [self addViewControllers];
30 | }
31 |
32 | - (void)creatControl
33 | {
34 | //初始化tabBar视图
35 | HWTabBarView *tabBarView = [[HWTabBarView alloc] initWithFrame:(CGRect){0, KMainH - KTabBarHeight, KMainW, KTabBarHeight}];
36 | tabBarView.delegate = self;
37 | [self.view addSubview:tabBarView];
38 | _tabBarView = tabBarView;
39 | }
40 |
41 | - (void)addViewControllers
42 | {
43 | NSArray *classNameArray = @[@"HWHomeVC", @"HWMeVC"];
44 | NSMutableArray *array = [NSMutableArray array];
45 |
46 | for (int i = 0; i < classNameArray.count; i++) {
47 | UIViewController *vc = [[NSClassFromString(classNameArray[i]) alloc] init];
48 | HWNavigationController *nav = [[HWNavigationController alloc] initWithRootViewController:vc];
49 | [array addObject:nav];
50 | }
51 |
52 | self.viewControllers = array;
53 | self.selectedIndex = 0;
54 | }
55 |
56 | #pragma mark - HWTabBarViewDelegate
57 | - (void)SKTabBarView:(HWTabBarView *)tabBarView didClickMenuButton:(UIButton *)button
58 | {
59 | //让所有button归位成非选中状态
60 | for (int i = 0; i < 3; i ++) {
61 | UIButton *btn = (UIButton *) [_tabBarView viewWithTag:i + 100];
62 | [btn setSelected:NO];
63 | }
64 |
65 | //设置当前按钮为选中状态
66 | button.selected = YES;
67 |
68 | //设置当前tabBarController的选中页面
69 | [self setSelectedIndex:button.tag - 100];
70 | }
71 |
72 | //隐藏TabBar
73 | - (void)setTabBarHiddenWithAnimaition:(BOOL)annimation
74 | {
75 | [UIView animateWithDuration:annimation ? 0.25 : 0 animations:^{
76 | _tabBarView.frame = CGRectMake(0, KMainH + KTabBarHeight, KMainW, KTabBarHeight);
77 | }];
78 | }
79 |
80 | //显示TabBar
81 | - (void)setTabBarShowWithAnimaition:(BOOL)annimation
82 | {
83 | [UIView animateWithDuration:annimation ? 0.25 : 0 animations:^{
84 | _tabBarView.frame = CGRectMake(0, KMainH - KTabBarHeight, KMainW, KTabBarHeight);
85 | }];
86 | }
87 |
88 | @end
89 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/TabBarController/HWTabBarView.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWTabBarView.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @class HWTabBarView;
12 |
13 | @protocol HWTabBarViewDelegate
14 |
15 | /**
16 | 菜单按钮点击事件
17 |
18 | @param tabBarView HWTabBarView
19 | @param button 菜单按钮
20 | */
21 | - (void)SKTabBarView:(HWTabBarView *)tabBarView didClickMenuButton:(UIButton *)button;
22 |
23 | @end
24 |
25 | @interface HWTabBarView : UIView
26 |
27 | @property (nonatomic, weak) id delegate;
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Main/TabBarController/HWTabBarView.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWTabBarView.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWTabBarView.h"
10 |
11 | @implementation HWTabBarView
12 |
13 | - (id)initWithFrame:(CGRect)frame
14 | {
15 | if (self = [super initWithFrame:frame]) {
16 | //普通状态图片
17 | NSArray *imgNorArray = @[@"tabbar_home_nor", @"tabbar_me_nor"];
18 | //选中状态图片
19 | NSArray *imgSelArray = @[@"tabbar_home_sel", @"tabbar_me_sel"];
20 |
21 | //菜单按钮
22 | for (int i = 0; i < imgNorArray.count; i ++) {
23 | CGFloat btnW = KMainW / imgNorArray.count;
24 | CGFloat btnX = btnW * i;
25 | UIButton *btn = [[UIButton alloc] initWithFrame:CGRectMake(btnX, 0, btnW, 49)];
26 | btn.adjustsImageWhenHighlighted = NO;
27 | [btn setImage:[UIImage imageNamed:imgNorArray[i]] forState:UIControlStateNormal];
28 | [btn setImage:[UIImage imageNamed:imgSelArray[i]] forState:UIControlStateSelected];
29 | [btn setImage:[UIImage imageNamed:imgSelArray[i]] forState:UIControlStateSelected | UIControlStateHighlighted];
30 | btn.tag = i + 100;
31 | [btn setSelected:i == 0];
32 | [btn addTarget:self action:@selector(menuBtnOnClick:) forControlEvents:UIControlEventTouchUpInside];
33 | [self addSubview:btn];
34 | }
35 |
36 | //线
37 | UIView *line = [[UIView alloc] initWithFrame:CGRectMake(0, 0, KMainW, 0.5)];
38 | line.backgroundColor = [UIColor colorWithHexString:@"#a0a0a0"];
39 | line.alpha = 0.4f;
40 | [self addSubview:line];
41 |
42 | self.backgroundColor = KWhiteColor;
43 | }
44 |
45 | return self;
46 | }
47 |
48 | - (void)menuBtnOnClick:(UIButton *)btn
49 | {
50 | if (btn.selected) return;
51 |
52 | CAKeyframeAnimation *animation = [CAKeyframeAnimation animation];
53 | animation.keyPath = @"transform.scale";
54 | animation.values = @[@1.0, @1.2, @1.0];
55 | animation.duration = 0.25;
56 | animation.calculationMode = kCAAnimationCubic;
57 | [btn.imageView.layer addAnimation:animation forKey:nil];
58 |
59 | if (_delegate && [_delegate respondsToSelector:@selector(SKTabBarView:didClickMenuButton:)]) {
60 | [_delegate SKTabBarView:self didClickMenuButton:btn];
61 | }
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Cache/Controller/HWCacheBaseVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWCacheBaseVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/28.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 |
11 | @interface HWCacheBaseVC : HWBaseViewController
12 |
13 | @property (nonatomic, strong) NSMutableArray *dataSource; // 数据源
14 | @property (nonatomic, weak) UITableView *tableView; // 列表
15 | @property (nonatomic, assign, readonly, getter=isNavEditing) BOOL navEditing; // 是否是编辑删除状态
16 | @property (nonatomic, assign, readonly) CGFloat tabbarViewHeight; // 底部工具栏视图高度
17 |
18 | // 刷新列表
19 | - (void)reloadTableView;
20 |
21 | // 刷新一个cell
22 | - (void)reloadRowWithModel:(HWDownloadModel *)model index:(NSInteger)index;
23 |
24 | // 增加一条数据
25 | - (void)insertModel:(HWDownloadModel *)model;
26 |
27 | // 移除一条数据
28 | - (void)deleteRowAtIndex:(NSInteger)index;
29 |
30 | // 更新数据
31 | - (void)updateViewWithModel:(HWDownloadModel *)model index:(NSInteger)index;
32 |
33 | @end
34 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Cache/Controller/HWCacheVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWCacheVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/28.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWCacheBaseVC.h"
10 |
11 | @interface HWCacheVC : HWCacheBaseVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Cache/Controller/HWCacheVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWCacheVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/28.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWCacheVC.h"
10 | #import "HWDownloadingVC.h"
11 |
12 | @interface HWCacheVC ()
13 |
14 | @property (nonatomic, weak) UIButton *downloadingBtn;
15 | @property (nonatomic, assign) NSInteger downloadingCount;
16 |
17 | @end
18 |
19 | @implementation HWCacheVC
20 |
21 | - (void)viewDidLoad {
22 | [super viewDidLoad];
23 |
24 | self.navTitle = @"缓存";
25 |
26 | // 创建控件
27 | [self creatControl];
28 |
29 | // 添加通知
30 | [self addNotification];
31 | }
32 |
33 | - (void)viewWillAppear:(BOOL)animated
34 | {
35 | [super viewWillAppear:animated];
36 |
37 | // 获取缓存
38 | [self getCacheData];
39 | }
40 |
41 | - (void)creatControl
42 | {
43 | // 正在缓存按钮
44 | UIButton *downloadingBtn = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, KMainW, 50)];
45 | downloadingBtn.hidden = YES;
46 | downloadingBtn.backgroundColor = [UIColor lightGrayColor];
47 | [downloadingBtn addTarget:self action:@selector(downloadingBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
48 | [self.view addSubview:downloadingBtn];
49 | _downloadingBtn = downloadingBtn;
50 | }
51 |
52 | - (void)downloadingBtnOnClick
53 | {
54 | [self.navigationController pushViewController:[[HWDownloadingVC alloc] init] animated:YES];
55 | }
56 |
57 | - (void)addNotification
58 | {
59 | // 状态改变通知
60 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downLoadStateChange:) name:HWDownloadStateChangeNotification object:nil];
61 | }
62 |
63 | - (void)getCacheData
64 | {
65 | // 获取已缓存数据
66 | self.dataSource = [[[HWDataBaseManager shareManager] getAllDownloadedData] mutableCopy];
67 | [self reloadTableView];
68 |
69 | // 获取所有未下载完成的数据
70 | _downloadingCount = [[HWDataBaseManager shareManager] getAllUnDownloadedData].count;
71 | [self reloadCacheView];
72 | }
73 |
74 | // 刷新正在缓存提示视图
75 | - (void)reloadCacheView
76 | {
77 | _downloadingBtn.hidden = _downloadingCount == 0;
78 | [_downloadingBtn setTitle:[NSString stringWithFormat:@"%ld个文件正在缓存", _downloadingCount] forState:UIControlStateNormal];
79 |
80 | self.tableView.frameY = _downloadingCount == 0 ? 0 : _downloadingBtn.frameHeight;
81 | self.tableView.frameHeight = KMainH - KNavHeight - self.tableView.frameY - (self.isNavEditing ? self.tabbarViewHeight - self.tableView.sectionFooterHeight + 5 : 0);
82 | }
83 |
84 | // 状态改变
85 | - (void)downLoadStateChange:(NSNotification *)notification
86 | {
87 | HWDownloadModel *downloadModel = notification.object;
88 |
89 | if (downloadModel.state == HWDownloadStateFinish) {
90 | dispatch_async(dispatch_get_main_queue(), ^{
91 | [self insertModel:downloadModel];
92 | _downloadingCount--;
93 | [self reloadCacheView];
94 | });
95 | }
96 | }
97 |
98 | - (void)dealloc
99 | {
100 | [[NSNotificationCenter defaultCenter] removeObserver:self];
101 | }
102 |
103 | @end
104 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Cache/Controller/HWDownloadingVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadingVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/5/1.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWCacheBaseVC.h"
10 |
11 | @interface HWDownloadingVC : HWCacheBaseVC
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Cache/Controller/HWDownloadingVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadingVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/5/1.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWDownloadingVC.h"
10 |
11 | @interface HWDownloadingVC ()
12 |
13 | @end
14 |
15 | @implementation HWDownloadingVC
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 |
20 | self.navTitle = @"正在缓存";
21 |
22 | // 添加通知
23 | [self addNotification];
24 |
25 | // 获取缓存
26 | [self getCacheData];
27 | }
28 |
29 | - (void)addNotification
30 | {
31 | // 进度通知
32 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downLoadProgress:) name:HWDownloadProgressNotification object:nil];
33 | // 状态改变通知
34 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(downLoadStateChange:) name:HWDownloadStateChangeNotification object:nil];
35 | }
36 |
37 | - (void)getCacheData
38 | {
39 | // 获取所有未下载完成的数据
40 | self.dataSource = [[[HWDataBaseManager shareManager] getAllUnDownloadedData] mutableCopy];
41 | [self reloadTableView];
42 | }
43 |
44 | #pragma mark - HWDownloadNotification
45 | // 正在下载,进度回调
46 | - (void)downLoadProgress:(NSNotification *)notification
47 | {
48 | HWDownloadModel *downloadModel = notification.object;
49 |
50 | dispatch_async(dispatch_get_main_queue(), ^{
51 | [self.dataSource enumerateObjectsUsingBlock:^(HWDownloadModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
52 | if ([model.url isEqualToString:downloadModel.url]) {
53 | // 更新cell进度
54 | [self updateViewWithModel:downloadModel index:idx];
55 |
56 | *stop = YES;
57 | }
58 | }];
59 | });
60 | }
61 |
62 | // 状态改变
63 | - (void)downLoadStateChange:(NSNotification *)notification
64 | {
65 | HWDownloadModel *downloadModel = notification.object;
66 |
67 | dispatch_async(dispatch_get_main_queue(), ^{
68 | [self.dataSource enumerateObjectsUsingBlock:^(HWDownloadModel *model, NSUInteger idx, BOOL * _Nonnull stop) {
69 | if ([model.url isEqualToString:downloadModel.url]) {
70 | if (downloadModel.state == HWDownloadStateFinish) {
71 | // 下载完成,移除cell
72 | [self deleteRowAtIndex:idx];
73 |
74 | // 没有正在下载的数据,则返回
75 | if (self.dataSource.count == 0) [self.navigationController popViewControllerAnimated:YES];
76 |
77 | }else {
78 | // 刷新列表
79 | [self reloadRowWithModel:downloadModel index:idx];
80 | }
81 |
82 | *stop = YES;
83 | }
84 | }];
85 | });
86 | }
87 |
88 | - (void)dealloc
89 | {
90 | [[NSNotificationCenter defaultCenter] removeObserver:self];
91 | }
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Me/Controller/HWMeVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWMeVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 |
11 | @interface HWMeVC : HWBaseViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Me/Controller/HWMeVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWMeVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/10.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWMeVC.h"
10 | #import "HWCacheVC.h"
11 | #import "HWSettingVC.h"
12 |
13 | @interface HWMeVC ()
14 |
15 | @end
16 |
17 | @implementation HWMeVC
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 |
22 | self.navTitle = @"我的";
23 |
24 | [self creatControl];
25 | }
26 |
27 | - (void)creatControl
28 | {
29 | CGFloat controlX = 30;
30 | CGFloat controlYPadding = 50.f;
31 | CGFloat controlW = KMainW - controlX * 2;
32 | CGFloat controlH = 44.f;
33 |
34 | // 我的缓存
35 | UIButton *cacheBtn = [[UIButton alloc] initWithFrame:CGRectMake(controlX, controlYPadding, controlW, controlH)];
36 | [cacheBtn setTitle:@"我的缓存" forState:UIControlStateNormal];
37 | cacheBtn.backgroundColor = [UIColor lightGrayColor];
38 | [cacheBtn addTarget:self action:@selector(cacheBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
39 | [self.view addSubview:cacheBtn];
40 |
41 | // 设置
42 | UIButton *setBtn = [[UIButton alloc] initWithFrame:CGRectMake(controlX, CGRectGetMaxY(cacheBtn.frame) + controlYPadding, controlW, controlH)];
43 | [setBtn setTitle:@"设置" forState:UIControlStateNormal];
44 | setBtn.backgroundColor = [UIColor lightGrayColor];
45 | [setBtn addTarget:self action:@selector(setBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
46 | [self.view addSubview:setBtn];
47 | }
48 |
49 | - (void)cacheBtnOnClick
50 | {
51 | [self.navigationController pushViewController:[[HWCacheVC alloc] init] animated:YES];
52 | }
53 |
54 | - (void)setBtnOnClick
55 | {
56 | [self.navigationController pushViewController:[[HWSettingVC alloc] init] animated:YES];
57 | }
58 |
59 | @end
60 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Setting/Controller/HWSettingVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // HWSettingVC.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/26.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWBaseViewController.h"
10 |
11 | @interface HWSettingVC : HWBaseViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Me/Setting/Controller/HWSettingVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWSettingVC.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/26.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import "HWSettingVC.h"
10 |
11 | @interface HWSettingVC ()
12 |
13 | @property (nonatomic, weak) UITextField *textField;
14 |
15 | @end
16 |
17 | @implementation HWSettingVC
18 |
19 | - (void)viewDidLoad {
20 | [super viewDidLoad];
21 |
22 | self.navTitle = @"设置";
23 |
24 | [self creatControl];
25 | }
26 |
27 | - (void)creatControl
28 | {
29 | CGFloat controlX = 30.f;
30 | CGFloat controlYPadding = 50.f;
31 | CGFloat controlW = KMainW - controlX * 2;
32 | CGFloat controlH = 44.f;
33 |
34 | // 设置最大并发数
35 | UITextField *textField = [[UITextField alloc] initWithFrame:CGRectMake(controlX, controlYPadding, controlW, controlH)];
36 | UILabel *leftView = [[UILabel alloc] initWithFrame:CGRectMake(0, 0, 222, controlH)];
37 | leftView.text = @" 设置下载最大并发数(上限5):";
38 | leftView.textColor = KWhiteColor;
39 | textField.leftView = leftView;
40 | textField.leftViewMode = UITextFieldViewModeAlways;
41 | textField.text = [NSString stringWithFormat:@"%ld", [[NSUserDefaults standardUserDefaults] integerForKey:HWDownloadMaxConcurrentCountKey]];
42 | textField.textColor = [UIColor yellowColor];
43 | textField.font = [UIFont boldSystemFontOfSize:18.f];
44 | textField.backgroundColor = [UIColor lightGrayColor];
45 | textField.textAlignment = NSTextAlignmentCenter;
46 | textField.returnKeyType = UIReturnKeyDone;
47 | textField.keyboardType = UIKeyboardTypeNumbersAndPunctuation;
48 | [textField addTarget:self action:@selector(textFieldEditingChanged:) forControlEvents:UIControlEventEditingChanged];
49 | [textField addTarget:self action:@selector(done) forControlEvents:UIControlEventEditingDidEndOnExit];
50 | [self.view addSubview:textField];
51 | _textField = textField;
52 |
53 | // 是否允许蜂窝网络下载
54 | UILabel *accessLable = [[UILabel alloc] initWithFrame:CGRectMake(controlX, CGRectGetMaxY(textField.frame) + controlYPadding, controlW, controlH)];
55 | accessLable.text = @" 是否允许蜂窝网络下载";
56 | accessLable.textColor = KWhiteColor;
57 | accessLable.textAlignment = NSTextAlignmentLeft;
58 | accessLable.userInteractionEnabled = YES;
59 | accessLable.backgroundColor = [UIColor lightGrayColor];
60 | accessLable.layer.masksToBounds = YES;
61 | [self.view addSubview:accessLable];
62 |
63 | // 开关
64 | UISwitch *accessSwitch = [[UISwitch alloc] initWithFrame:CGRectMake(accessLable.frameWidth - 60, 6.5, 0, 0)];
65 | accessSwitch.on = [[NSUserDefaults standardUserDefaults] boolForKey:HWDownloadAllowsCellularAccessKey];
66 | [accessSwitch addTarget:self action:@selector(accessSwitchOnClick:) forControlEvents:UIControlEventValueChanged];
67 | [accessLable addSubview:accessSwitch];
68 |
69 | // 清空缓存
70 | UIButton *clearBtn = [[UIButton alloc] initWithFrame:CGRectMake(controlX, CGRectGetMaxY(accessLable.frame) + controlYPadding, controlW, controlH)];
71 | [clearBtn setTitle:@"清空缓存" forState:UIControlStateNormal];
72 | clearBtn.backgroundColor = [UIColor lightGrayColor];
73 | [clearBtn addTarget:self action:@selector(clearBtnOnClick) forControlEvents:UIControlEventTouchUpInside];
74 | [self.view addSubview:clearBtn];
75 | }
76 |
77 | - (void)textFieldEditingChanged:(UITextField *)textField
78 | {
79 | if (textField.text.length > 1) {
80 | textField.text = [textField.text substringToIndex:1];
81 |
82 | }else if (textField.text.length == 1) {
83 | NSCharacterSet *characterSet = [[NSCharacterSet characterSetWithCharactersInString:@"12345"] invertedSet];
84 | NSString *filtered = [[_textField.text componentsSeparatedByCharactersInSet:characterSet] componentsJoinedByString:@""];
85 | BOOL basicTest = [_textField.text isEqualToString:filtered];
86 | if (!basicTest) {
87 | UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"提示" message:@"请输入数字1~5" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil];
88 | [alert show];
89 | textField.text = @"";
90 | }
91 | }
92 | }
93 |
94 | - (void)done
95 | {
96 | if ([_textField.text isEqualToString:@""]) _textField.text = @"1";
97 |
98 | // 原并发数
99 | NSInteger oldCount = [[NSUserDefaults standardUserDefaults] integerForKey:HWDownloadMaxConcurrentCountKey];
100 | // 新并发数
101 | NSInteger newCount = [_textField.text integerValue];
102 |
103 | if (oldCount != newCount) {
104 | // 保存
105 | [[NSUserDefaults standardUserDefaults] setInteger:newCount forKey:HWDownloadMaxConcurrentCountKey];
106 |
107 | // 通知
108 | [[NSNotificationCenter defaultCenter] postNotificationName:HWDownloadMaxConcurrentCountChangeNotification object:[NSNumber numberWithInteger:newCount]];
109 | }
110 | }
111 |
112 | - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
113 | {
114 | [self.view endEditing:YES];
115 |
116 | [self done];
117 | }
118 |
119 | - (void)accessSwitchOnClick:(UISwitch *)accessSwitch
120 | {
121 | // 保存
122 | [[NSUserDefaults standardUserDefaults] setBool:accessSwitch.isOn forKey:HWDownloadAllowsCellularAccessKey];
123 |
124 | // 通知
125 | [[NSNotificationCenter defaultCenter] postNotificationName:HWDownloadAllowsCellularAccessChangeNotification object:[NSNumber numberWithBool:accessSwitch.isOn]];
126 | }
127 |
128 | - (void)clearBtnOnClick
129 | {
130 | [HWToolBox showAlertWithTitle:@"是否清空所有缓存?" sureMessage:@"确认" cancelMessage:@"取消" warningMessage:nil style:UIAlertControllerStyleAlert target:self sureHandler:^(UIAlertAction *action) {
131 | // 清空缓存
132 | [self clearLocalCache];
133 | } cancelHandler:nil warningHandler:nil];
134 | }
135 |
136 | - (void)clearLocalCache
137 | {
138 | dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
139 | dispatch_async(queue, ^{
140 | NSArray *array = [[HWDataBaseManager shareManager] getAllCacheData];
141 | for (HWDownloadModel *model in array) {
142 | [[HWDownloadManager shareManager] deleteTaskAndCache:model];
143 | }
144 | });
145 | }
146 |
147 | @end
148 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | }
88 | ],
89 | "info" : {
90 | "version" : 1,
91 | "author" : "xcode"
92 | }
93 | }
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/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 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/GlobeConst.h:
--------------------------------------------------------------------------------
1 | //
2 | // GlobeConst.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/20.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | /************************* 下载 *************************/
10 | UIKIT_EXTERN NSString * const HWDownloadProgressNotification; // 进度回调通知
11 | UIKIT_EXTERN NSString * const HWDownloadStateChangeNotification; // 状态改变通知
12 | UIKIT_EXTERN NSString * const HWDownloadMaxConcurrentCountKey; // 最大同时下载数量key
13 | UIKIT_EXTERN NSString * const HWDownloadMaxConcurrentCountChangeNotification; // 最大同时下载数量改变通知
14 | UIKIT_EXTERN NSString * const HWDownloadAllowsCellularAccessKey; // 是否允许蜂窝网络下载key
15 | UIKIT_EXTERN NSString * const HWDownloadAllowsCellularAccessChangeNotification; // 是否允许蜂窝网络下载改变通知
16 |
17 | /************************* 网络 *************************/
18 | UIKIT_EXTERN NSString * const HWNetworkingReachabilityDidChangeNotification; // 网络改变改变通知
19 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/GlobeConst.m:
--------------------------------------------------------------------------------
1 | //
2 | // GlobeConst.m
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/20.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /************************* 下载 *************************/
12 | NSString * const HWDownloadProgressNotification = @"HWDownloadProgressNotification";
13 | NSString * const HWDownloadStateChangeNotification = @"HWDownloadStateChangeNotification";
14 | NSString * const HWDownloadMaxConcurrentCountKey = @"HWDownloadMaxConcurrentCountKey";
15 | NSString * const HWDownloadMaxConcurrentCountChangeNotification = @"HWDownloadMaxConcurrentCountChangeNotification";
16 | NSString * const HWDownloadAllowsCellularAccessKey = @"HWDownloadAllowsCellularAccessKey";
17 | NSString * const HWDownloadAllowsCellularAccessChangeNotification = @"HWDownloadAllowsCellularAccessChangeNotification";
18 |
19 | /************************* 网络 *************************/
20 | NSString * const HWNetworkingReachabilityDidChangeNotification = @"HWNetworkingReachabilityDidChangeNotification";
21 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/GlobeHeader.h:
--------------------------------------------------------------------------------
1 | //
2 | // GlobeHeader.h
3 | // HWProject
4 | //
5 | // Created by wangqibin on 2018/4/20.
6 | // Copyright © 2018年 wangqibin. All rights reserved.
7 | //
8 |
9 | #ifndef GlobeHeader_h
10 | #define GlobeHeader_h
11 |
12 | /************************* system *************************/
13 | #import
14 |
15 | /************************* categorys *************************/
16 | #import "NSString+HW.h"
17 | #import "UIColor+HW.h"
18 | #import "UIImage+HW.h"
19 | #import "UIView+Extension.h"
20 |
21 | /************************* common *************************/
22 | #import "HWToolBox.h"
23 | #import "HWDownload.h"
24 | #import "HWNetworkReachabilityManager.h"
25 | #import "HWProgressHUD.h"
26 |
27 | /************************* vender *************************/
28 | #import "AFNetworking.h"
29 | #import "MJExtension.h"
30 | #import "FMDB.h"
31 |
32 | /************************* other *************************/
33 | #import "GlobeConst.h"
34 | #import "AppDelegate.h"
35 |
36 | #endif /* GlobeHeader_h */
37 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_default@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_default@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_default@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_default@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_error@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_error@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_error@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_error@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_finish@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_finish@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_finish@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_finish@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_pause@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_pause@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_pause@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_pause@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_waiting@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_waiting@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_download_waiting@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_download_waiting@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading01@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading01@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading02@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading02@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading03@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading03@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading04@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading04@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading05@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading05@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading06@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading06@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading07@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading07@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/com_loading08@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/com_loading08@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_back@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_back@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_back@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_back@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_cancelBtn@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_cancelBtn@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_cancelBtn@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_cancelBtn@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_deleteBtn@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_deleteBtn@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/nav_deleteBtn@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/nav_deleteBtn@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_home_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_home_nor@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_home_nor@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_home_nor@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_home_sel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_home_sel@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_home_sel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_home_sel@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_me_nor@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_me_nor@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_me_nor@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_me_nor@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_me_sel@2x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_me_sel@2x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Images/Common/tabbar_me_sel@3x.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HeroWqb/HWDownloadDemo/161bf067c492b8f378f52d0c306e6a3b7450946b/HWDownloadDemo/Other/Images/Common/tabbar_me_sel@3x.png
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | UIViewControllerBasedStatusBarAppearance
6 |
7 | CFBundleDevelopmentRegion
8 | $(DEVELOPMENT_LANGUAGE)
9 | CFBundleExecutable
10 | $(EXECUTABLE_NAME)
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 |
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/PrefixHeader.pch:
--------------------------------------------------------------------------------
1 | //
2 | // PrefixHeader.pch
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #ifndef PrefixHeader_pch
10 | #define PrefixHeader_pch
11 |
12 | #import "GlobeHeader.h"
13 |
14 | #define KWhiteColor [UIColor whiteColor]
15 | #define KClearColor [UIColor clearColor]
16 |
17 | #define KMainW [UIScreen mainScreen].bounds.size.width
18 | #define KMainH [UIScreen mainScreen].bounds.size.height
19 | #define KStatusBarHeight [[UIApplication sharedApplication] statusBarFrame].size.height
20 | #define KNavHeight (KStatusBarHeight + 44.f)
21 | #define KIsBangScreen (KStatusBarHeight > 20.1) // 刘海屏,状态栏44pt,底部留功能区34pt
22 | #define KTabBarHeight (KIsBangScreen ? 83.0f : 49.0f)
23 | #define KBottomSafeArea (KIsBangScreen ? 34.0f : 0.0f)
24 |
25 | #define IS_IPHONE_4 (KMainH == 480.0) // 320*480 3.5 @2x
26 | #define IS_IPHONE_5 (KMainH == 568.0) // 320*568 4.0 @2x
27 | #define IS_IPHONE_6 (KMainH == 667.0) // 375*667 4.7 @2x
28 | #define IS_IPHONE_6P (KMainH == 736.0) // 414*736 5.5 @3x
29 | #define IS_IPHONE_X (KMainH == 812.0) // 375*812 5.8 @3x iPhone X、Xs
30 | #define IS_IPHONE_XM (KMainH == 896.0) // 414*896 6.1 @2x iPhone Xr、6.5 @3x iPhone Xs Max
31 | #define ISIOS8 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 8.0 ? YES : NO)
32 | #define ISIOS9 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 9.0 ? YES : NO)
33 | #define ISIOS10 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 10.0 ? YES : NO)
34 | #define ISIOS11 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 11.0 ? YES : NO)
35 | #define ISIOS12 ([[[UIDevice currentDevice] systemVersion] floatValue] >= 12.0 ? YES : NO)
36 |
37 | #define KScreenRate (375 / KMainW)
38 | #define KSuitFloat(float) ((float) / KScreenRate)
39 | #define KSuitSize(width, height) CGSizeMake((width) / KScreenRate, (height) / KScreenRate)
40 | #define KSuitPoint(x, y) CGPointMake((x) / KScreenRate, (y) / KScreenRate)
41 | #define KSuitFrame(x, y, width, heigth) CGRectMake((x) / KScreenRate, (y) / KScreenRate, (width) / KScreenRate, (heigth) / KScreenRate)
42 |
43 | #define weakify(var) __weak typeof(var) weakSelf = var
44 | #define strongify(var) __strong typeof(var) strongSelf = var
45 |
46 | #define NSLog(...) printf("[%s] %s [第%d行] %s\n", [[HWToolBox currentTimeCorrectToMillisecond] UTF8String], __FUNCTION__, __LINE__, [[NSString stringWithFormat:__VA_ARGS__] UTF8String]);
47 |
48 | #ifdef DEBUG
49 | #define HWLog(format, ...) printf("[%s] %s [第%d行] %s\n", [[HWToolBox currentTimeCorrectToMillisecond] UTF8String], __FUNCTION__, __LINE__, [[NSString stringWithFormat:format, ## __VA_ARGS__] UTF8String]);
50 | #else
51 | #define HWLog(format, ...)
52 | #endif
53 |
54 | #endif /* PrefixHeader_pch */
55 |
56 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // HWDownloadDemo
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. 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 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Other/testData.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | vid
7 | 1
8 | fileName
9 | 网络视频文件 01
10 | url
11 | https://www.apple.com/105/media/cn/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/feature/iphone-x-feature-cn-20170912_1280x720h.mp4
12 |
13 |
14 | vid
15 | 2
16 | fileName
17 | 网络视频文件 02
18 | url
19 | https://images.apple.com/media/cn/macbook-pro/2016/b4a9efaa_6fe5_4075_a9d0_8e4592d6146c/films/design/macbook-pro-design-tft-cn-20161026_1536x640h.mp4
20 |
21 |
22 | vid
23 | 3
24 | fileName
25 | 网络视频文件 03
26 | url
27 | https://www.apple.com/105/media/cn/ipad-pro/how-to/2017/a0f629be_c30b_4333_942f_13a221fc44f3/films/dock/ipad-pro-dock-cn-20160907_1280x720h.mp4
28 |
29 |
30 | vid
31 | 4
32 | fileName
33 | 网络视频文件 04
34 | url
35 | https://www.apple.com/105/media/cn/ipad/2018/08716702_0a2f_4b2c_9fdd_e08394ae72f1/films/use-two-apps/ipad-use-two-apps-tpl-cn-20180404_1280x720h.mp4
36 |
37 |
38 | vid
39 | 5
40 | fileName
41 | 网络视频文件 05
42 | url
43 | https://www.apple.com/105/media/us/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/hero/large.mp4
44 |
45 |
46 | vid
47 | 6
48 | fileName
49 | 网络视频文件 06
50 | url
51 | https://www.apple.com/105/media/us/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/thumbnails/buck/large.mp4
52 |
53 |
54 | vid
55 | 7
56 | fileName
57 | 网络视频文件 07
58 | url
59 | https://www.apple.com/105/media/us/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/thumbnails/erin-sarofsky/large.mp4
60 |
61 |
62 | vid
63 | 8
64 | fileName
65 | 网络视频文件 08
66 | url
67 | https://www.apple.com/105/media/cn/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/films/buck/imac-pro-buck-tpl-cn-20180223_1280x720h.mp4
68 |
69 |
70 | vid
71 | 9
72 | fileName
73 | 网络视频文件 09
74 | url
75 | https://www.apple.com/105/media/cn/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/films/esteban-diacono/imac-pro-esteban-diacono-tpl-cn-20180223_1280x720h.mp4
76 |
77 |
78 | vid
79 | 10
80 | fileName
81 | 网络视频文件 10
82 | url
83 | https://www.apple.com/105/media/cn/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/films/luigi-honorat/imac-pro-luigi-honrat-tpl-cn-20180223_1280x720h.mp4
84 |
85 |
86 | vid
87 | 11
88 | fileName
89 | 网络视频文件 11
90 | url
91 | https://www.apple.com/105/media/cn/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/films/bts/luigi-honorat/imac-pro-luigi-honrat-bts-tpl-cn-20180223_1280x720h.mp4
92 |
93 |
94 | vid
95 | 12
96 | fileName
97 | 网络视频文件 12
98 | url
99 | https://www.apple.com/105/media/cn/imac-pro/2018/d0b63f9b_f0de_4dea_a993_62b4cb35ca96/films/michelle-dougherty/imac-pro-michelle-dougherty-tpl-cn-20180223_1280x720h.mp4
100 |
101 |
102 | vid
103 | 13
104 | fileName
105 | 网络视频文件 13
106 | url
107 | https://www.apple.com/105/media/cn/iphone-x/2018/5b64bc98_3bd3_4c12_9b3e_bae2df6b2d9d/films/new-light/iphone-x-new-light-tpl-cn-20180201_1280x720h.mp4
108 |
109 |
110 | vid
111 | 14
112 | fileName
113 | 网络视频文件 14
114 | url
115 | https://www.apple.com/105/media/cn/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/animoji/iphone-x-animoji-cn-20171205_1280x720h.mp4
116 |
117 |
118 | vid
119 | 15
120 | fileName
121 | 网络视频文件 15
122 | url
123 | https://www.apple.com/105/media/cn/ipad/2018/08716702_0a2f_4b2c_9fdd_e08394ae72f1/films/browse-files/ipad-browse-files-tpl-cn-20180404_1280x720h.mp4
124 |
125 |
126 | vid
127 | 16
128 | fileName
129 | 网络视频文件 16
130 | url
131 | https://www.apple.com/105/media/cn/iphone-x/2017/01df5b43-28e4-4848-bf20-490c34a926a7/films/face-id/iphone-x-face-id-cn-20171129_1280x720h.mp4
132 |
133 |
134 |
135 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/AFNetworking/AFNetworking.h:
--------------------------------------------------------------------------------
1 | // AFNetworking.h
2 | //
3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/)
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 | #import
25 | #import
26 |
27 | #ifndef _AFNETWORKING_
28 | #define _AFNETWORKING_
29 |
30 | #import "AFURLRequestSerialization.h"
31 | #import "AFURLResponseSerialization.h"
32 | #import "AFSecurityPolicy.h"
33 |
34 | #if !TARGET_OS_WATCH
35 | #import "AFNetworkReachabilityManager.h"
36 | #endif
37 |
38 | #import "AFURLSessionManager.h"
39 | #import "AFHTTPSessionManager.h"
40 |
41 | #endif /* _AFNETWORKING_ */
42 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2011–2016 Alamofire Software Foundation (http://alamofire.org/)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h:
--------------------------------------------------------------------------------
1 | // AFNetworkActivityIndicatorManager.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS
27 |
28 | #import
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 | /**
33 | `AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a session task has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero.
34 |
35 | You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code:
36 |
37 | [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES];
38 |
39 | By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself.
40 |
41 | See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information:
42 | http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44
43 | */
44 | NS_EXTENSION_UNAVAILABLE_IOS("Use view controller based solutions where appropriate instead.")
45 | @interface AFNetworkActivityIndicatorManager : NSObject
46 |
47 | /**
48 | A Boolean value indicating whether the manager is enabled.
49 |
50 | If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO.
51 | */
52 | @property (nonatomic, assign, getter = isEnabled) BOOL enabled;
53 |
54 | /**
55 | A Boolean value indicating whether the network activity indicator manager is currently active.
56 | */
57 | @property (readonly, nonatomic, assign, getter=isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible;
58 |
59 | /**
60 | A time interval indicating the minimum duration of networking activity that should occur before the activity indicator is displayed. The default value 1 second. If the network activity indicator should be displayed immediately when network activity occurs, this value should be set to 0 seconds.
61 |
62 | Apple's HIG describes the following:
63 |
64 | > Display the network activity indicator to provide feedback when your app accesses the network for more than a couple of seconds. If the operation finishes sooner than that, you don’t have to show the network activity indicator, because the indicator is likely to disappear before users notice its presence.
65 |
66 | */
67 | @property (nonatomic, assign) NSTimeInterval activationDelay;
68 |
69 | /**
70 | A time interval indicating the duration of time of no networking activity required before the activity indicator is disabled. This allows for continuous display of the network activity indicator across multiple requests. The default value is 0.17 seconds.
71 | */
72 |
73 | @property (nonatomic, assign) NSTimeInterval completionDelay;
74 |
75 | /**
76 | Returns the shared network activity indicator manager object for the system.
77 |
78 | @return The systemwide network activity indicator manager.
79 | */
80 | + (instancetype)sharedManager;
81 |
82 | /**
83 | Increments the number of active network requests. If this number was zero before incrementing, this will start animating the status bar network activity indicator.
84 | */
85 | - (void)incrementActivityCount;
86 |
87 | /**
88 | Decrements the number of active network requests. If this number becomes zero after decrementing, this will stop animating the status bar network activity indicator.
89 | */
90 | - (void)decrementActivityCount;
91 |
92 | /**
93 | Set the a custom method to be executed when the network activity indicator manager should be hidden/shown. By default, this is null, and the UIApplication Network Activity Indicator will be managed automatically. If this block is set, it is the responsiblity of the caller to manager the network activity indicator going forward.
94 |
95 | @param block A block to be executed when the network activity indicator status changes.
96 | */
97 | - (void)setNetworkingActivityActionWithBlock:(nullable void (^)(BOOL networkActivityIndicatorVisible))block;
98 |
99 | @end
100 |
101 | NS_ASSUME_NONNULL_END
102 |
103 | #endif
104 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIActivityIndicatorView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import
29 |
30 | /**
31 | This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a session task.
32 | */
33 | @interface UIActivityIndicatorView (AFNetworking)
34 |
35 | ///----------------------------------
36 | /// @name Animating for Session Tasks
37 | ///----------------------------------
38 |
39 | /**
40 | Binds the animating state to the state of the specified task.
41 |
42 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
43 | */
44 | - (void)setAnimatingWithStateOfTask:(nullable NSURLSessionTask *)task;
45 |
46 | @end
47 |
48 | #endif
49 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m:
--------------------------------------------------------------------------------
1 | // UIActivityIndicatorView+AFNetworking.m
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import "UIActivityIndicatorView+AFNetworking.h"
23 | #import
24 |
25 | #if TARGET_OS_IOS || TARGET_OS_TV
26 |
27 | #import "AFURLSessionManager.h"
28 |
29 | @interface AFActivityIndicatorViewNotificationObserver : NSObject
30 | @property (readonly, nonatomic, weak) UIActivityIndicatorView *activityIndicatorView;
31 | - (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView;
32 |
33 | - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task;
34 |
35 | @end
36 |
37 | @implementation UIActivityIndicatorView (AFNetworking)
38 |
39 | - (AFActivityIndicatorViewNotificationObserver *)af_notificationObserver {
40 | AFActivityIndicatorViewNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver));
41 | if (notificationObserver == nil) {
42 | notificationObserver = [[AFActivityIndicatorViewNotificationObserver alloc] initWithActivityIndicatorView:self];
43 | objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
44 | }
45 | return notificationObserver;
46 | }
47 |
48 | - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
49 | [[self af_notificationObserver] setAnimatingWithStateOfTask:task];
50 | }
51 |
52 | @end
53 |
54 | @implementation AFActivityIndicatorViewNotificationObserver
55 |
56 | - (instancetype)initWithActivityIndicatorView:(UIActivityIndicatorView *)activityIndicatorView
57 | {
58 | self = [super init];
59 | if (self) {
60 | _activityIndicatorView = activityIndicatorView;
61 | }
62 | return self;
63 | }
64 |
65 | - (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task {
66 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
67 |
68 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
69 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
70 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
71 |
72 | if (task) {
73 | if (task.state != NSURLSessionTaskStateCompleted) {
74 |
75 | #pragma clang diagnostic push
76 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
77 | #pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
78 | if (task.state == NSURLSessionTaskStateRunning) {
79 | [self.activityIndicatorView startAnimating];
80 | } else {
81 | [self.activityIndicatorView stopAnimating];
82 | }
83 | #pragma clang diagnostic pop
84 |
85 | [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task];
86 | [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task];
87 | [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidSuspendNotification object:task];
88 | }
89 | }
90 | }
91 |
92 | #pragma mark -
93 |
94 | - (void)af_startAnimating {
95 | dispatch_async(dispatch_get_main_queue(), ^{
96 | #pragma clang diagnostic push
97 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
98 | [self.activityIndicatorView startAnimating];
99 | #pragma clang diagnostic pop
100 | });
101 | }
102 |
103 | - (void)af_stopAnimating {
104 | dispatch_async(dispatch_get_main_queue(), ^{
105 | #pragma clang diagnostic push
106 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
107 | [self.activityIndicatorView stopAnimating];
108 | #pragma clang diagnostic pop
109 | });
110 | }
111 |
112 | #pragma mark -
113 |
114 | - (void)dealloc {
115 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
116 |
117 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
118 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
119 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
120 | }
121 |
122 | @end
123 |
124 | #endif
125 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIImage+AFNetworking.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIImage+AFNetworking.h
3 | //
4 | //
5 | // Created by Paulo Ferreira on 08/07/15.
6 | //
7 | // Permission is hereby granted, free of charge, to any person obtaining a copy
8 | // of this software and associated documentation files (the "Software"), to deal
9 | // in the Software without restriction, including without limitation the rights
10 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11 | // copies of the Software, and to permit persons to whom the Software is
12 | // furnished to do so, subject to the following conditions:
13 | //
14 | // The above copyright notice and this permission notice shall be included in
15 | // all copies or substantial portions of the Software.
16 | //
17 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23 | // THE SOFTWARE.
24 |
25 | #if TARGET_OS_IOS || TARGET_OS_TV
26 |
27 | #import
28 |
29 | @interface UIImage (AFNetworking)
30 |
31 | + (UIImage*) safeImageWithData:(NSData*)data;
32 |
33 | @end
34 |
35 | #endif
36 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIImageView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 | @class AFImageDownloader;
33 |
34 | /**
35 | This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL.
36 | */
37 | @interface UIImageView (AFNetworking)
38 |
39 | ///------------------------------------
40 | /// @name Accessing the Image Downloader
41 | ///------------------------------------
42 |
43 | /**
44 | Set the shared image downloader used to download images.
45 |
46 | @param imageDownloader The shared image downloader used to download images.
47 | */
48 | + (void)setSharedImageDownloader:(AFImageDownloader *)imageDownloader;
49 |
50 | /**
51 | The shared image downloader used to download images.
52 | */
53 | + (AFImageDownloader *)sharedImageDownloader;
54 |
55 | ///--------------------
56 | /// @name Setting Image
57 | ///--------------------
58 |
59 | /**
60 | Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled.
61 |
62 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished.
63 |
64 | By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:`
65 |
66 | @param url The URL used for the image request.
67 | */
68 | - (void)setImageWithURL:(NSURL *)url;
69 |
70 | /**
71 | Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled.
72 |
73 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished.
74 |
75 | By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:`
76 |
77 | @param url The URL used for the image request.
78 | @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes.
79 | */
80 | - (void)setImageWithURL:(NSURL *)url
81 | placeholderImage:(nullable UIImage *)placeholderImage;
82 |
83 | /**
84 | Asynchronously downloads an image from the specified URL request, and sets it once the request is finished. Any previous image request for the receiver will be cancelled.
85 |
86 | If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished.
87 |
88 | If a success block is specified, it is the responsibility of the block to set the image of the image view before returning. If no success block is specified, the default behavior of setting the image with `self.image = image` is applied.
89 |
90 | @param urlRequest The URL request used for the image request.
91 | @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes.
92 | @param success A block to be executed when the image data task finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the response parameter will be `nil`.
93 | @param failure A block object to be executed when the image data task finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred.
94 | */
95 | - (void)setImageWithURLRequest:(NSURLRequest *)urlRequest
96 | placeholderImage:(nullable UIImage *)placeholderImage
97 | success:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, UIImage *image))success
98 | failure:(nullable void (^)(NSURLRequest *request, NSHTTPURLResponse * _Nullable response, NSError *error))failure;
99 |
100 | /**
101 | Cancels any executing image operation for the receiver, if one exists.
102 | */
103 | - (void)cancelImageDownloadTask;
104 |
105 | @end
106 |
107 | NS_ASSUME_NONNULL_END
108 |
109 | #endif
110 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIKit+AFNetworking.h
2 | //
3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #if TARGET_OS_IOS || TARGET_OS_TV
24 | #import
25 |
26 | #ifndef _UIKIT_AFNETWORKING_
27 | #define _UIKIT_AFNETWORKING_
28 |
29 | #if TARGET_OS_IOS
30 | #import "AFAutoPurgingImageCache.h"
31 | #import "AFImageDownloader.h"
32 | #import "AFNetworkActivityIndicatorManager.h"
33 | #import "UIRefreshControl+AFNetworking.h"
34 | #import "UIWebView+AFNetworking.h"
35 | #endif
36 |
37 | #import "UIActivityIndicatorView+AFNetworking.h"
38 | #import "UIButton+AFNetworking.h"
39 | #import "UIImageView+AFNetworking.h"
40 | #import "UIProgressView+AFNetworking.h"
41 | #endif /* _UIKIT_AFNETWORKING_ */
42 | #endif
43 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIProgressView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 |
33 | /**
34 | This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task.
35 | */
36 | @interface UIProgressView (AFNetworking)
37 |
38 | ///------------------------------------
39 | /// @name Setting Session Task Progress
40 | ///------------------------------------
41 |
42 | /**
43 | Binds the progress to the upload progress of the specified session task.
44 |
45 | @param task The session task.
46 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
47 | */
48 | - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
49 | animated:(BOOL)animated;
50 |
51 | /**
52 | Binds the progress to the download progress of the specified session task.
53 |
54 | @param task The session task.
55 | @param animated `YES` if the change should be animated, `NO` if the change should happen immediately.
56 | */
57 | - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
58 | animated:(BOOL)animated;
59 |
60 | @end
61 |
62 | NS_ASSUME_NONNULL_END
63 |
64 | #endif
65 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m:
--------------------------------------------------------------------------------
1 | // UIProgressView+AFNetworking.m
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import "UIProgressView+AFNetworking.h"
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS || TARGET_OS_TV
27 |
28 | #import "AFURLSessionManager.h"
29 |
30 | static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext;
31 | static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext;
32 |
33 | #pragma mark -
34 |
35 | @implementation UIProgressView (AFNetworking)
36 |
37 | - (BOOL)af_uploadProgressAnimated {
38 | return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_uploadProgressAnimated)) boolValue];
39 | }
40 |
41 | - (void)af_setUploadProgressAnimated:(BOOL)animated {
42 | objc_setAssociatedObject(self, @selector(af_uploadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
43 | }
44 |
45 | - (BOOL)af_downloadProgressAnimated {
46 | return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_downloadProgressAnimated)) boolValue];
47 | }
48 |
49 | - (void)af_setDownloadProgressAnimated:(BOOL)animated {
50 | objc_setAssociatedObject(self, @selector(af_downloadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
51 | }
52 |
53 | #pragma mark -
54 |
55 | - (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task
56 | animated:(BOOL)animated
57 | {
58 | [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext];
59 | [task addObserver:self forKeyPath:@"countOfBytesSent" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext];
60 |
61 | [self af_setUploadProgressAnimated:animated];
62 | }
63 |
64 | - (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task
65 | animated:(BOOL)animated
66 | {
67 | [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
68 | [task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext];
69 |
70 | [self af_setDownloadProgressAnimated:animated];
71 | }
72 |
73 | #pragma mark - NSKeyValueObserving
74 |
75 | - (void)observeValueForKeyPath:(NSString *)keyPath
76 | ofObject:(id)object
77 | change:(__unused NSDictionary *)change
78 | context:(void *)context
79 | {
80 | if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) {
81 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) {
82 | if ([object countOfBytesExpectedToSend] > 0) {
83 | dispatch_async(dispatch_get_main_queue(), ^{
84 | [self setProgress:[object countOfBytesSent] / ([object countOfBytesExpectedToSend] * 1.0f) animated:self.af_uploadProgressAnimated];
85 | });
86 | }
87 | }
88 |
89 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) {
90 | if ([object countOfBytesExpectedToReceive] > 0) {
91 | dispatch_async(dispatch_get_main_queue(), ^{
92 | [self setProgress:[object countOfBytesReceived] / ([object countOfBytesExpectedToReceive] * 1.0f) animated:self.af_downloadProgressAnimated];
93 | });
94 | }
95 | }
96 |
97 | if ([keyPath isEqualToString:NSStringFromSelector(@selector(state))]) {
98 | if ([(NSURLSessionTask *)object state] == NSURLSessionTaskStateCompleted) {
99 | @try {
100 | [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state))];
101 |
102 | if (context == AFTaskCountOfBytesSentContext) {
103 | [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))];
104 | }
105 |
106 | if (context == AFTaskCountOfBytesReceivedContext) {
107 | [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))];
108 | }
109 | }
110 | @catch (NSException * __unused exception) {}
111 | }
112 | }
113 | }
114 | }
115 |
116 | @end
117 |
118 | #endif
119 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIRefreshControl+AFNetworking.m
2 | //
3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import
24 |
25 | #import
26 |
27 | #if TARGET_OS_IOS
28 |
29 | #import
30 |
31 | NS_ASSUME_NONNULL_BEGIN
32 |
33 | /**
34 | This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically beginning and ending refreshing depending on the loading state of a session task.
35 | */
36 | @interface UIRefreshControl (AFNetworking)
37 |
38 | ///-----------------------------------
39 | /// @name Refreshing for Session Tasks
40 | ///-----------------------------------
41 |
42 | /**
43 | Binds the refreshing state to the state of the specified task.
44 |
45 | @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled.
46 | */
47 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
48 |
49 | @end
50 |
51 | NS_ASSUME_NONNULL_END
52 |
53 | #endif
54 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m:
--------------------------------------------------------------------------------
1 | // UIRefreshControl+AFNetworking.m
2 | //
3 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
4 | //
5 | // Permission is hereby granted, free of charge, to any person obtaining a copy
6 | // of this software and associated documentation files (the "Software"), to deal
7 | // in the Software without restriction, including without limitation the rights
8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | // copies of the Software, and to permit persons to whom the Software is
10 | // furnished to do so, subject to the following conditions:
11 | //
12 | // The above copyright notice and this permission notice shall be included in
13 | // all copies or substantial portions of the Software.
14 | //
15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21 | // THE SOFTWARE.
22 |
23 | #import "UIRefreshControl+AFNetworking.h"
24 | #import
25 |
26 | #if TARGET_OS_IOS
27 |
28 | #import "AFURLSessionManager.h"
29 |
30 | @interface AFRefreshControlNotificationObserver : NSObject
31 | @property (readonly, nonatomic, weak) UIRefreshControl *refreshControl;
32 | - (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl;
33 |
34 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task;
35 |
36 | @end
37 |
38 | @implementation UIRefreshControl (AFNetworking)
39 |
40 | - (AFRefreshControlNotificationObserver *)af_notificationObserver {
41 | AFRefreshControlNotificationObserver *notificationObserver = objc_getAssociatedObject(self, @selector(af_notificationObserver));
42 | if (notificationObserver == nil) {
43 | notificationObserver = [[AFRefreshControlNotificationObserver alloc] initWithActivityRefreshControl:self];
44 | objc_setAssociatedObject(self, @selector(af_notificationObserver), notificationObserver, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
45 | }
46 | return notificationObserver;
47 | }
48 |
49 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
50 | [[self af_notificationObserver] setRefreshingWithStateOfTask:task];
51 | }
52 |
53 | @end
54 |
55 | @implementation AFRefreshControlNotificationObserver
56 |
57 | - (instancetype)initWithActivityRefreshControl:(UIRefreshControl *)refreshControl
58 | {
59 | self = [super init];
60 | if (self) {
61 | _refreshControl = refreshControl;
62 | }
63 | return self;
64 | }
65 |
66 | - (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task {
67 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
68 |
69 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
70 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
71 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
72 |
73 | if (task) {
74 | #pragma clang diagnostic push
75 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
76 | #pragma clang diagnostic ignored "-Warc-repeated-use-of-weak"
77 | if (task.state == NSURLSessionTaskStateRunning) {
78 | [self.refreshControl beginRefreshing];
79 |
80 | [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task];
81 | [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task];
82 | [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task];
83 | } else {
84 | [self.refreshControl endRefreshing];
85 | }
86 | #pragma clang diagnostic pop
87 | }
88 | }
89 |
90 | #pragma mark -
91 |
92 | - (void)af_beginRefreshing {
93 | dispatch_async(dispatch_get_main_queue(), ^{
94 | #pragma clang diagnostic push
95 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
96 | [self.refreshControl beginRefreshing];
97 | #pragma clang diagnostic pop
98 | });
99 | }
100 |
101 | - (void)af_endRefreshing {
102 | dispatch_async(dispatch_get_main_queue(), ^{
103 | #pragma clang diagnostic push
104 | #pragma clang diagnostic ignored "-Wreceiver-is-weak"
105 | [self.refreshControl endRefreshing];
106 | #pragma clang diagnostic pop
107 | });
108 | }
109 |
110 | #pragma mark -
111 |
112 | - (void)dealloc {
113 | NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter];
114 |
115 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil];
116 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil];
117 | [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil];
118 | }
119 |
120 | @end
121 |
122 | #endif
123 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h:
--------------------------------------------------------------------------------
1 | // UIWebView+AFNetworking.h
2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ )
3 | //
4 | // Permission is hereby granted, free of charge, to any person obtaining a copy
5 | // of this software and associated documentation files (the "Software"), to deal
6 | // in the Software without restriction, including without limitation the rights
7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 | // copies of the Software, and to permit persons to whom the Software is
9 | // furnished to do so, subject to the following conditions:
10 | //
11 | // The above copyright notice and this permission notice shall be included in
12 | // all copies or substantial portions of the Software.
13 | //
14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 | // THE SOFTWARE.
21 |
22 | #import
23 |
24 | #import
25 |
26 | #if TARGET_OS_IOS
27 |
28 | #import
29 |
30 | NS_ASSUME_NONNULL_BEGIN
31 |
32 | @class AFHTTPSessionManager;
33 |
34 | /**
35 | This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling.
36 |
37 | @discussion When using these category methods, make sure to assign `delegate` for the web view, which implements `–webView:shouldStartLoadWithRequest:navigationType:` appropriately. This allows for tapped links to be loaded through AFNetworking, and can ensure that `canGoBack` & `canGoForward` update their values correctly.
38 | */
39 | @interface UIWebView (AFNetworking)
40 |
41 | /**
42 | The session manager used to download all requests.
43 | */
44 | @property (nonatomic, strong) AFHTTPSessionManager *sessionManager;
45 |
46 | /**
47 | Asynchronously loads the specified request.
48 |
49 | @param request A URL request identifying the location of the content to load. This must not be `nil`.
50 | @param progress A progress object monitoring the current download progress.
51 | @param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string.
52 | @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
53 | */
54 | - (void)loadRequest:(NSURLRequest *)request
55 | progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
56 | success:(nullable NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success
57 | failure:(nullable void (^)(NSError *error))failure;
58 |
59 | /**
60 | Asynchronously loads the data associated with a particular request with a specified MIME type and text encoding.
61 |
62 | @param request A URL request identifying the location of the content to load. This must not be `nil`.
63 | @param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified.
64 | @param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified.
65 | @param progress A progress object monitoring the current download progress.
66 | @param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data.
67 | @param failure A block object to be executed when the data task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred.
68 | */
69 | - (void)loadRequest:(NSURLRequest *)request
70 | MIMEType:(nullable NSString *)MIMEType
71 | textEncodingName:(nullable NSString *)textEncodingName
72 | progress:(NSProgress * _Nullable __autoreleasing * _Nullable)progress
73 | success:(nullable NSData * (^)(NSHTTPURLResponse *response, NSData *data))success
74 | failure:(nullable void (^)(NSError *error))failure;
75 |
76 | @end
77 |
78 | NS_ASSUME_NONNULL_END
79 |
80 | #endif
81 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/FMDB/LICENSE.txt:
--------------------------------------------------------------------------------
1 | If you are using FMDB in your project, I'd love to hear about it. Let Gus know
2 | by sending an email to gus@flyingmeat.com.
3 |
4 | And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you
5 | might consider purchasing a drink of their choosing if FMDB has been useful to
6 | you.
7 |
8 | Finally, and shortly, this is the MIT License.
9 |
10 | Copyright (c) 2008-2014 Flying Meat Inc.
11 |
12 | Permission is hereby granted, free of charge, to any person obtaining a copy
13 | of this software and associated documentation files (the "Software"), to deal
14 | in the Software without restriction, including without limitation the rights
15 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
16 | copies of the Software, and to permit persons to whom the Software is
17 | furnished to do so, subject to the following conditions:
18 |
19 | The above copyright notice and this permission notice shall be included in
20 | all copies or substantial portions of the Software.
21 |
22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
23 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
24 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
25 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
26 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
27 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
28 | THE SOFTWARE.
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/FMDB/src/fmdb/FMDB.h:
--------------------------------------------------------------------------------
1 | #import
2 |
3 | FOUNDATION_EXPORT double FMDBVersionNumber;
4 | FOUNDATION_EXPORT const unsigned char FMDBVersionString[];
5 |
6 | #import "FMDatabase.h"
7 | #import "FMResultSet.h"
8 | #import "FMDatabaseAdditions.h"
9 | #import "FMDatabaseQueue.h"
10 | #import "FMDatabasePool.h"
11 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2013-2015 MJExtension (https://github.com/CoderMJLee/MJExtension)
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJExtension.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | // 代码地址:https://github.com/CoderMJLee/MJExtension
8 | // 代码地址:http://code4app.com/ios/%E5%AD%97%E5%85%B8-JSON-%E4%B8%8E%E6%A8%A1%E5%9E%8B%E7%9A%84%E8%BD%AC%E6%8D%A2/5339992a933bf062608b4c57
9 |
10 | #import "NSObject+MJCoding.h"
11 | #import "NSObject+MJProperty.h"
12 | #import "NSObject+MJClass.h"
13 | #import "NSObject+MJKeyValue.h"
14 | #import "NSString+MJExtension.h"
15 | #import "MJExtensionConst.h"
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJExtensionConst.h:
--------------------------------------------------------------------------------
1 |
2 | #ifndef __MJExtensionConst__H__
3 | #define __MJExtensionConst__H__
4 |
5 | #import
6 |
7 | // 过期
8 | #define MJExtensionDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead)
9 |
10 | // 构建错误
11 | #define MJExtensionBuildError(clazz, msg) \
12 | NSError *error = [NSError errorWithDomain:msg code:250 userInfo:nil]; \
13 | [clazz setMj_error:error];
14 |
15 | // 日志输出
16 | #ifdef DEBUG
17 | #define MJExtensionLog(...) NSLog(__VA_ARGS__)
18 | #else
19 | #define MJExtensionLog(...)
20 | #endif
21 |
22 | /**
23 | * 断言
24 | * @param condition 条件
25 | * @param returnValue 返回值
26 | */
27 | #define MJExtensionAssertError(condition, returnValue, clazz, msg) \
28 | [clazz setMj_error:nil]; \
29 | if ((condition) == NO) { \
30 | MJExtensionBuildError(clazz, msg); \
31 | return returnValue;\
32 | }
33 |
34 | #define MJExtensionAssert2(condition, returnValue) \
35 | if ((condition) == NO) return returnValue;
36 |
37 | /**
38 | * 断言
39 | * @param condition 条件
40 | */
41 | #define MJExtensionAssert(condition) MJExtensionAssert2(condition, )
42 |
43 | /**
44 | * 断言
45 | * @param param 参数
46 | * @param returnValue 返回值
47 | */
48 | #define MJExtensionAssertParamNotNil2(param, returnValue) \
49 | MJExtensionAssert2((param) != nil, returnValue)
50 |
51 | /**
52 | * 断言
53 | * @param param 参数
54 | */
55 | #define MJExtensionAssertParamNotNil(param) MJExtensionAssertParamNotNil2(param, )
56 |
57 | /**
58 | * 打印所有的属性
59 | */
60 | #define MJLogAllIvars \
61 | -(NSString *)description \
62 | { \
63 | return [self mj_keyValues].description; \
64 | }
65 | #define MJExtensionLogAllProperties MJLogAllIvars
66 |
67 | /**
68 | * 类型(属性类型)
69 | */
70 | extern NSString *const MJPropertyTypeInt;
71 | extern NSString *const MJPropertyTypeShort;
72 | extern NSString *const MJPropertyTypeFloat;
73 | extern NSString *const MJPropertyTypeDouble;
74 | extern NSString *const MJPropertyTypeLong;
75 | extern NSString *const MJPropertyTypeLongLong;
76 | extern NSString *const MJPropertyTypeChar;
77 | extern NSString *const MJPropertyTypeBOOL1;
78 | extern NSString *const MJPropertyTypeBOOL2;
79 | extern NSString *const MJPropertyTypePointer;
80 |
81 | extern NSString *const MJPropertyTypeIvar;
82 | extern NSString *const MJPropertyTypeMethod;
83 | extern NSString *const MJPropertyTypeBlock;
84 | extern NSString *const MJPropertyTypeClass;
85 | extern NSString *const MJPropertyTypeSEL;
86 | extern NSString *const MJPropertyTypeId;
87 |
88 | #endif
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJExtensionConst.m:
--------------------------------------------------------------------------------
1 | #ifndef __MJExtensionConst__M__
2 | #define __MJExtensionConst__M__
3 |
4 | #import
5 |
6 | /**
7 | * 成员变量类型(属性类型)
8 | */
9 | NSString *const MJPropertyTypeInt = @"i";
10 | NSString *const MJPropertyTypeShort = @"s";
11 | NSString *const MJPropertyTypeFloat = @"f";
12 | NSString *const MJPropertyTypeDouble = @"d";
13 | NSString *const MJPropertyTypeLong = @"l";
14 | NSString *const MJPropertyTypeLongLong = @"q";
15 | NSString *const MJPropertyTypeChar = @"c";
16 | NSString *const MJPropertyTypeBOOL1 = @"c";
17 | NSString *const MJPropertyTypeBOOL2 = @"b";
18 | NSString *const MJPropertyTypePointer = @"*";
19 |
20 | NSString *const MJPropertyTypeIvar = @"^{objc_ivar=}";
21 | NSString *const MJPropertyTypeMethod = @"^{objc_method=}";
22 | NSString *const MJPropertyTypeBlock = @"@?";
23 | NSString *const MJPropertyTypeClass = @"#";
24 | NSString *const MJPropertyTypeSEL = @":";
25 | NSString *const MJPropertyTypeId = @"@";
26 |
27 | #endif
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJFoundation.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJFoundation.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 14/7/16.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface MJFoundation : NSObject
12 | + (BOOL)isClassFromFoundation:(Class)c;
13 | @end
14 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJFoundation.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJFoundation.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 14/7/16.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJFoundation.h"
10 | #import "MJExtensionConst.h"
11 | #import
12 |
13 | static NSSet *foundationClasses_;
14 |
15 | @implementation MJFoundation
16 |
17 | + (NSSet *)foundationClasses
18 | {
19 | if (foundationClasses_ == nil) {
20 | // 集合中没有NSObject,因为几乎所有的类都是继承自NSObject,具体是不是NSObject需要特殊判断
21 | foundationClasses_ = [NSSet setWithObjects:
22 | [NSURL class],
23 | [NSDate class],
24 | [NSValue class],
25 | [NSData class],
26 | [NSError class],
27 | [NSArray class],
28 | [NSDictionary class],
29 | [NSString class],
30 | [NSAttributedString class], nil];
31 | }
32 | return foundationClasses_;
33 | }
34 |
35 | + (BOOL)isClassFromFoundation:(Class)c
36 | {
37 | if (c == [NSObject class] || c == [NSManagedObject class]) return YES;
38 |
39 | __block BOOL result = NO;
40 | [[self foundationClasses] enumerateObjectsUsingBlock:^(Class foundationClass, BOOL *stop) {
41 | if ([c isSubclassOfClass:foundationClass]) {
42 | result = YES;
43 | *stop = YES;
44 | }
45 | }];
46 | return result;
47 | }
48 | @end
49 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJProperty.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | // 包装一个成员属性
8 |
9 | #import
10 | #import
11 | #import "MJPropertyType.h"
12 | #import "MJPropertyKey.h"
13 |
14 | /**
15 | * 包装一个成员
16 | */
17 | @interface MJProperty : NSObject
18 | /** 成员属性 */
19 | @property (nonatomic, assign) objc_property_t property;
20 | /** 成员属性的名字 */
21 | @property (nonatomic, readonly) NSString *name;
22 |
23 | /** 成员属性的类型 */
24 | @property (nonatomic, readonly) MJPropertyType *type;
25 | /** 成员属性来源于哪个类(可能是父类) */
26 | @property (nonatomic, assign) Class srcClass;
27 |
28 | /**** 同一个成员属性 - 父类和子类的行为可能不一致(originKey、propertyKeys、objectClassInArray) ****/
29 | /** 设置最原始的key */
30 | - (void)setOriginKey:(id)originKey forClass:(Class)c;
31 | /** 对应着字典中的多级key(里面存放的数组,数组里面都是MJPropertyKey对象) */
32 | - (NSArray *)propertyKeysForClass:(Class)c;
33 |
34 | /** 模型数组中的模型类型 */
35 | - (void)setObjectClassInArray:(Class)objectClass forClass:(Class)c;
36 | - (Class)objectClassInArrayForClass:(Class)c;
37 | /**** 同一个成员变量 - 父类和子类的行为可能不一致(key、keys、objectClassInArray) ****/
38 |
39 | /**
40 | * 设置object的成员变量值
41 | */
42 | - (void)setValue:(id)value forObject:(id)object;
43 | /**
44 | * 得到object的成员属性值
45 | */
46 | - (id)valueForObject:(id)object;
47 |
48 | /**
49 | * 初始化
50 | */
51 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property;
52 |
53 | @end
54 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJProperty.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJProperty.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJProperty.h"
10 | #import "MJFoundation.h"
11 | #import "MJExtensionConst.h"
12 | #import
13 |
14 | @interface MJProperty()
15 | @property (strong, nonatomic) NSMutableDictionary *propertyKeysDict;
16 | @property (strong, nonatomic) NSMutableDictionary *objectClassInArrayDict;
17 | @end
18 |
19 | @implementation MJProperty
20 |
21 | #pragma mark - 初始化
22 | - (instancetype)init
23 | {
24 | if (self = [super init]) {
25 | _propertyKeysDict = [NSMutableDictionary dictionary];
26 | _objectClassInArrayDict = [NSMutableDictionary dictionary];
27 | }
28 | return self;
29 | }
30 |
31 | #pragma mark - 缓存
32 | + (instancetype)cachedPropertyWithProperty:(objc_property_t)property
33 | {
34 | MJProperty *propertyObj = objc_getAssociatedObject(self, property);
35 | if (propertyObj == nil) {
36 | propertyObj = [[self alloc] init];
37 | propertyObj.property = property;
38 | objc_setAssociatedObject(self, property, propertyObj, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
39 | }
40 | return propertyObj;
41 | }
42 |
43 | #pragma mark - 公共方法
44 | - (void)setProperty:(objc_property_t)property
45 | {
46 | _property = property;
47 |
48 | MJExtensionAssertParamNotNil(property);
49 |
50 | // 1.属性名
51 | _name = @(property_getName(property));
52 |
53 | // 2.成员类型
54 | NSString *attrs = @(property_getAttributes(property));
55 | NSUInteger dotLoc = [attrs rangeOfString:@","].location;
56 | NSString *code = nil;
57 | NSUInteger loc = 1;
58 | if (dotLoc == NSNotFound) { // 没有,
59 | code = [attrs substringFromIndex:loc];
60 | } else {
61 | code = [attrs substringWithRange:NSMakeRange(loc, dotLoc - loc)];
62 | }
63 | _type = [MJPropertyType cachedTypeWithCode:code];
64 | }
65 |
66 | /**
67 | * 获得成员变量的值
68 | */
69 | - (id)valueForObject:(id)object
70 | {
71 | if (self.type.KVCDisabled) return [NSNull null];
72 | return [object valueForKey:self.name];
73 | }
74 |
75 | /**
76 | * 设置成员变量的值
77 | */
78 | - (void)setValue:(id)value forObject:(id)object
79 | {
80 | if (self.type.KVCDisabled || value == nil) return;
81 | [object setValue:value forKey:self.name];
82 | }
83 |
84 | /**
85 | * 通过字符串key创建对应的keys
86 | */
87 | - (NSArray *)propertyKeysWithStringKey:(NSString *)stringKey
88 | {
89 | if (stringKey.length == 0) return nil;
90 |
91 | NSMutableArray *propertyKeys = [NSMutableArray array];
92 | // 如果有多级映射
93 | NSArray *oldKeys = [stringKey componentsSeparatedByString:@"."];
94 |
95 | for (NSString *oldKey in oldKeys) {
96 | NSUInteger start = [oldKey rangeOfString:@"["].location;
97 | if (start != NSNotFound) { // 有索引的key
98 | NSString *prefixKey = [oldKey substringToIndex:start];
99 | NSString *indexKey = prefixKey;
100 | if (prefixKey.length) {
101 | MJPropertyKey *propertyKey = [[MJPropertyKey alloc] init];
102 | propertyKey.name = prefixKey;
103 | [propertyKeys addObject:propertyKey];
104 |
105 | indexKey = [oldKey stringByReplacingOccurrencesOfString:prefixKey withString:@""];
106 | }
107 |
108 | /** 解析索引 **/
109 | // 元素
110 | NSArray *cmps = [[indexKey stringByReplacingOccurrencesOfString:@"[" withString:@""] componentsSeparatedByString:@"]"];
111 | for (NSInteger i = 0; i
10 |
11 | typedef enum {
12 | MJPropertyKeyTypeDictionary = 0, // 字典的key
13 | MJPropertyKeyTypeArray // 数组的key
14 | } MJPropertyKeyType;
15 |
16 | /**
17 | * 属性的key
18 | */
19 | @interface MJPropertyKey : NSObject
20 | /** key的名字 */
21 | @property (copy, nonatomic) NSString *name;
22 | /** key的种类,可能是@"10",可能是@"age" */
23 | @property (assign, nonatomic) MJPropertyKeyType type;
24 |
25 | /**
26 | * 根据当前的key,也就是name,从object(字典或者数组)中取值
27 | */
28 | - (id)valueInObject:(id)object;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJPropertyKey.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJPropertyKey.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/8/11.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJPropertyKey.h"
10 |
11 | @implementation MJPropertyKey
12 |
13 | - (id)valueInObject:(id)object
14 | {
15 | if ([object isKindOfClass:[NSDictionary class]] && self.type == MJPropertyKeyTypeDictionary) {
16 | return object[self.name];
17 | } else if ([object isKindOfClass:[NSArray class]] && self.type == MJPropertyKeyTypeArray) {
18 | NSArray *array = object;
19 | NSUInteger index = self.name.intValue;
20 | if (index < array.count) return array[index];
21 | return nil;
22 | }
23 | return nil;
24 | }
25 | @end
26 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJPropertyType.h:
--------------------------------------------------------------------------------
1 | //
2 | // MJPropertyType.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | // 包装一种类型
8 |
9 | #import
10 |
11 | /**
12 | * 包装一种类型
13 | */
14 | @interface MJPropertyType : NSObject
15 | /** 类型标识符 */
16 | @property (nonatomic, copy) NSString *code;
17 |
18 | /** 是否为id类型 */
19 | @property (nonatomic, readonly, getter=isIdType) BOOL idType;
20 |
21 | /** 是否为基本数字类型:int、float等 */
22 | @property (nonatomic, readonly, getter=isNumberType) BOOL numberType;
23 |
24 | /** 是否为BOOL类型 */
25 | @property (nonatomic, readonly, getter=isBoolType) BOOL boolType;
26 |
27 | /** 对象类型(如果是基本数据类型,此值为nil) */
28 | @property (nonatomic, readonly) Class typeClass;
29 |
30 | /** 类型是否来自于Foundation框架,比如NSString、NSArray */
31 | @property (nonatomic, readonly, getter = isFromFoundation) BOOL fromFoundation;
32 | /** 类型是否不支持KVC */
33 | @property (nonatomic, readonly, getter = isKVCDisabled) BOOL KVCDisabled;
34 |
35 | /**
36 | * 获得缓存的类型对象
37 | */
38 | + (instancetype)cachedTypeWithCode:(NSString *)code;
39 | @end
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/MJPropertyType.m:
--------------------------------------------------------------------------------
1 | //
2 | // MJPropertyType.m
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "MJPropertyType.h"
10 | #import "MJExtension.h"
11 | #import "MJFoundation.h"
12 | #import "MJExtensionConst.h"
13 |
14 | @implementation MJPropertyType
15 |
16 | static NSMutableDictionary *types_;
17 | + (void)initialize
18 | {
19 | types_ = [NSMutableDictionary dictionary];
20 | }
21 |
22 | + (instancetype)cachedTypeWithCode:(NSString *)code
23 | {
24 | MJExtensionAssertParamNotNil2(code, nil);
25 | @synchronized (self) {
26 | MJPropertyType *type = types_[code];
27 | if (type == nil) {
28 | type = [[self alloc] init];
29 | type.code = code;
30 | types_[code] = type;
31 | }
32 | return type;
33 | }
34 | }
35 |
36 | #pragma mark - 公共方法
37 | - (void)setCode:(NSString *)code
38 | {
39 | _code = code;
40 |
41 | MJExtensionAssertParamNotNil(code);
42 |
43 | if ([code isEqualToString:MJPropertyTypeId]) {
44 | _idType = YES;
45 | } else if (code.length == 0) {
46 | _KVCDisabled = YES;
47 | } else if (code.length > 3 && [code hasPrefix:@"@\""]) {
48 | // 去掉@"和",截取中间的类型名称
49 | _code = [code substringWithRange:NSMakeRange(2, code.length - 3)];
50 | _typeClass = NSClassFromString(_code);
51 | _fromFoundation = [MJFoundation isClassFromFoundation:_typeClass];
52 | _numberType = [_typeClass isSubclassOfClass:[NSNumber class]];
53 |
54 | } else if ([code isEqualToString:MJPropertyTypeSEL] ||
55 | [code isEqualToString:MJPropertyTypeIvar] ||
56 | [code isEqualToString:MJPropertyTypeMethod]) {
57 | _KVCDisabled = YES;
58 | }
59 |
60 | // 是否为数字类型
61 | NSString *lowerCode = _code.lowercaseString;
62 | NSArray *numberTypes = @[MJPropertyTypeInt, MJPropertyTypeShort, MJPropertyTypeBOOL1, MJPropertyTypeBOOL2, MJPropertyTypeFloat, MJPropertyTypeDouble, MJPropertyTypeLong, MJPropertyTypeLongLong, MJPropertyTypeChar];
63 | if ([numberTypes containsObject:lowerCode]) {
64 | _numberType = YES;
65 |
66 | if ([lowerCode isEqualToString:MJPropertyTypeBOOL1]
67 | || [lowerCode isEqualToString:MJPropertyTypeBOOL2]) {
68 | _boolType = YES;
69 | }
70 | }
71 | }
72 | @end
73 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSObject+MJClass.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJClass.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/8/11.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | /**
12 | * 遍历所有类的block(父类)
13 | */
14 | typedef void (^MJClassesEnumeration)(Class c, BOOL *stop);
15 |
16 | /** 这个数组中的属性名才会进行字典和模型的转换 */
17 | typedef NSArray * (^MJAllowedPropertyNames)();
18 | /** 这个数组中的属性名才会进行归档 */
19 | typedef NSArray * (^MJAllowedCodingPropertyNames)();
20 |
21 | /** 这个数组中的属性名将会被忽略:不进行字典和模型的转换 */
22 | typedef NSArray * (^MJIgnoredPropertyNames)();
23 | /** 这个数组中的属性名将会被忽略:不进行归档 */
24 | typedef NSArray * (^MJIgnoredCodingPropertyNames)();
25 |
26 | /**
27 | * 类相关的扩展
28 | */
29 | @interface NSObject (MJClass)
30 | /**
31 | * 遍历所有的类
32 | */
33 | + (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration;
34 | + (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration;
35 |
36 | #pragma mark - 属性白名单配置
37 | /**
38 | * 这个数组中的属性名才会进行字典和模型的转换
39 | *
40 | * @param allowedPropertyNames 这个数组中的属性名才会进行字典和模型的转换
41 | */
42 | + (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
43 |
44 | /**
45 | * 这个数组中的属性名才会进行字典和模型的转换
46 | */
47 | + (NSMutableArray *)mj_totalAllowedPropertyNames;
48 |
49 | #pragma mark - 属性黑名单配置
50 | /**
51 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
52 | *
53 | * @param ignoredPropertyNames 这个数组中的属性名将会被忽略:不进行字典和模型的转换
54 | */
55 | + (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames;
56 |
57 | /**
58 | * 这个数组中的属性名将会被忽略:不进行字典和模型的转换
59 | */
60 | + (NSMutableArray *)mj_totalIgnoredPropertyNames;
61 |
62 | #pragma mark - 归档属性白名单配置
63 | /**
64 | * 这个数组中的属性名才会进行归档
65 | *
66 | * @param allowedCodingPropertyNames 这个数组中的属性名才会进行归档
67 | */
68 | + (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames;
69 |
70 | /**
71 | * 这个数组中的属性名才会进行字典和模型的转换
72 | */
73 | + (NSMutableArray *)mj_totalAllowedCodingPropertyNames;
74 |
75 | #pragma mark - 归档属性黑名单配置
76 | /**
77 | * 这个数组中的属性名将会被忽略:不进行归档
78 | *
79 | * @param ignoredCodingPropertyNames 这个数组中的属性名将会被忽略:不进行归档
80 | */
81 | + (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames;
82 |
83 | /**
84 | * 这个数组中的属性名将会被忽略:不进行归档
85 | */
86 | + (NSMutableArray *)mj_totalIgnoredCodingPropertyNames;
87 |
88 | #pragma mark - 内部使用
89 | + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key;
90 | @end
91 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSObject+MJClass.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJClass.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/8/11.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSObject+MJClass.h"
10 | #import "NSObject+MJCoding.h"
11 | #import "NSObject+MJKeyValue.h"
12 | #import "MJFoundation.h"
13 | #import
14 |
15 | static const char MJAllowedPropertyNamesKey = '\0';
16 | static const char MJIgnoredPropertyNamesKey = '\0';
17 | static const char MJAllowedCodingPropertyNamesKey = '\0';
18 | static const char MJIgnoredCodingPropertyNamesKey = '\0';
19 |
20 | static NSMutableDictionary *allowedPropertyNamesDict_;
21 | static NSMutableDictionary *ignoredPropertyNamesDict_;
22 | static NSMutableDictionary *allowedCodingPropertyNamesDict_;
23 | static NSMutableDictionary *ignoredCodingPropertyNamesDict_;
24 |
25 | @implementation NSObject (MJClass)
26 |
27 | + (void)load
28 | {
29 | allowedPropertyNamesDict_ = [NSMutableDictionary dictionary];
30 | ignoredPropertyNamesDict_ = [NSMutableDictionary dictionary];
31 | allowedCodingPropertyNamesDict_ = [NSMutableDictionary dictionary];
32 | ignoredCodingPropertyNamesDict_ = [NSMutableDictionary dictionary];
33 | }
34 |
35 | + (NSMutableDictionary *)dictForKey:(const void *)key
36 | {
37 | @synchronized (self) {
38 | if (key == &MJAllowedPropertyNamesKey) return allowedPropertyNamesDict_;
39 | if (key == &MJIgnoredPropertyNamesKey) return ignoredPropertyNamesDict_;
40 | if (key == &MJAllowedCodingPropertyNamesKey) return allowedCodingPropertyNamesDict_;
41 | if (key == &MJIgnoredCodingPropertyNamesKey) return ignoredCodingPropertyNamesDict_;
42 | return nil;
43 | }
44 | }
45 |
46 | + (void)mj_enumerateClasses:(MJClassesEnumeration)enumeration
47 | {
48 | // 1.没有block就直接返回
49 | if (enumeration == nil) return;
50 |
51 | // 2.停止遍历的标记
52 | BOOL stop = NO;
53 |
54 | // 3.当前正在遍历的类
55 | Class c = self;
56 |
57 | // 4.开始遍历每一个类
58 | while (c && !stop) {
59 | // 4.1.执行操作
60 | enumeration(c, &stop);
61 |
62 | // 4.2.获得父类
63 | c = class_getSuperclass(c);
64 |
65 | if ([MJFoundation isClassFromFoundation:c]) break;
66 | }
67 | }
68 |
69 | + (void)mj_enumerateAllClasses:(MJClassesEnumeration)enumeration
70 | {
71 | // 1.没有block就直接返回
72 | if (enumeration == nil) return;
73 |
74 | // 2.停止遍历的标记
75 | BOOL stop = NO;
76 |
77 | // 3.当前正在遍历的类
78 | Class c = self;
79 |
80 | // 4.开始遍历每一个类
81 | while (c && !stop) {
82 | // 4.1.执行操作
83 | enumeration(c, &stop);
84 |
85 | // 4.2.获得父类
86 | c = class_getSuperclass(c);
87 | }
88 | }
89 |
90 | #pragma mark - 属性黑名单配置
91 | + (void)mj_setupIgnoredPropertyNames:(MJIgnoredPropertyNames)ignoredPropertyNames
92 | {
93 | [self mj_setupBlockReturnValue:ignoredPropertyNames key:&MJIgnoredPropertyNamesKey];
94 | }
95 |
96 | + (NSMutableArray *)mj_totalIgnoredPropertyNames
97 | {
98 | return [self mj_totalObjectsWithSelector:@selector(mj_ignoredPropertyNames) key:&MJIgnoredPropertyNamesKey];
99 | }
100 |
101 | #pragma mark - 归档属性黑名单配置
102 | + (void)mj_setupIgnoredCodingPropertyNames:(MJIgnoredCodingPropertyNames)ignoredCodingPropertyNames
103 | {
104 | [self mj_setupBlockReturnValue:ignoredCodingPropertyNames key:&MJIgnoredCodingPropertyNamesKey];
105 | }
106 |
107 | + (NSMutableArray *)mj_totalIgnoredCodingPropertyNames
108 | {
109 | return [self mj_totalObjectsWithSelector:@selector(mj_ignoredCodingPropertyNames) key:&MJIgnoredCodingPropertyNamesKey];
110 | }
111 |
112 | #pragma mark - 属性白名单配置
113 | + (void)mj_setupAllowedPropertyNames:(MJAllowedPropertyNames)allowedPropertyNames;
114 | {
115 | [self mj_setupBlockReturnValue:allowedPropertyNames key:&MJAllowedPropertyNamesKey];
116 | }
117 |
118 | + (NSMutableArray *)mj_totalAllowedPropertyNames
119 | {
120 | return [self mj_totalObjectsWithSelector:@selector(mj_allowedPropertyNames) key:&MJAllowedPropertyNamesKey];
121 | }
122 |
123 | #pragma mark - 归档属性白名单配置
124 | + (void)mj_setupAllowedCodingPropertyNames:(MJAllowedCodingPropertyNames)allowedCodingPropertyNames
125 | {
126 | [self mj_setupBlockReturnValue:allowedCodingPropertyNames key:&MJAllowedCodingPropertyNamesKey];
127 | }
128 |
129 | + (NSMutableArray *)mj_totalAllowedCodingPropertyNames
130 | {
131 | return [self mj_totalObjectsWithSelector:@selector(mj_allowedCodingPropertyNames) key:&MJAllowedCodingPropertyNamesKey];
132 | }
133 | #pragma mark - block和方法处理:存储block的返回值
134 | + (void)mj_setupBlockReturnValue:(id (^)())block key:(const char *)key
135 | {
136 | if (block) {
137 | objc_setAssociatedObject(self, key, block(), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
138 | } else {
139 | objc_setAssociatedObject(self, key, nil, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
140 | }
141 |
142 | // 清空数据
143 | [[self dictForKey:key] removeAllObjects];
144 | }
145 |
146 | + (NSMutableArray *)mj_totalObjectsWithSelector:(SEL)selector key:(const char *)key
147 | {
148 | NSMutableArray *array = [self dictForKey:key][NSStringFromClass(self)];
149 | if (array) return array;
150 |
151 | // 创建、存储
152 | [self dictForKey:key][NSStringFromClass(self)] = array = [NSMutableArray array];
153 |
154 | if ([self respondsToSelector:selector]) {
155 | #pragma clang diagnostic push
156 | #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
157 | NSArray *subArray = [self performSelector:selector];
158 | #pragma clang diagnostic pop
159 | if (subArray) {
160 | [array addObjectsFromArray:subArray];
161 | }
162 | }
163 |
164 | [self mj_enumerateAllClasses:^(__unsafe_unretained Class c, BOOL *stop) {
165 | NSArray *subArray = objc_getAssociatedObject(c, key);
166 | [array addObjectsFromArray:subArray];
167 | }];
168 | return array;
169 | }
170 | @end
171 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSObject+MJCoding.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJCoding.h
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJExtensionConst.h"
11 |
12 | /**
13 | * Codeing协议
14 | */
15 | @protocol MJCoding
16 | @optional
17 | /**
18 | * 这个数组中的属性名才会进行归档
19 | */
20 | + (NSArray *)mj_allowedCodingPropertyNames;
21 | /**
22 | * 这个数组中的属性名将会被忽略:不进行归档
23 | */
24 | + (NSArray *)mj_ignoredCodingPropertyNames;
25 | @end
26 |
27 | @interface NSObject (MJCoding)
28 | /**
29 | * 解码(从文件中解析对象)
30 | */
31 | - (void)mj_decode:(NSCoder *)decoder;
32 | /**
33 | * 编码(将对象写入文件中)
34 | */
35 | - (void)mj_encode:(NSCoder *)encoder;
36 | @end
37 |
38 | /**
39 | 归档的实现
40 | */
41 | #define MJCodingImplementation \
42 | - (id)initWithCoder:(NSCoder *)decoder \
43 | { \
44 | if (self = [super init]) { \
45 | [self mj_decode:decoder]; \
46 | } \
47 | return self; \
48 | } \
49 | \
50 | - (void)encodeWithCoder:(NSCoder *)encoder \
51 | { \
52 | [self mj_encode:encoder]; \
53 | }
54 |
55 | #define MJExtensionCodingImplementation MJCodingImplementation
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSObject+MJCoding.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJCoding.m
3 | // MJExtension
4 | //
5 | // Created by mj on 14-1-15.
6 | // Copyright (c) 2014年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSObject+MJCoding.h"
10 | #import "NSObject+MJClass.h"
11 | #import "NSObject+MJProperty.h"
12 | #import "MJProperty.h"
13 |
14 | @implementation NSObject (MJCoding)
15 |
16 | - (void)mj_encode:(NSCoder *)encoder
17 | {
18 | Class clazz = [self class];
19 |
20 | NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames];
21 | NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames];
22 |
23 | [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
24 | // 检测是否被忽略
25 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
26 | if ([ignoredCodingPropertyNames containsObject:property.name]) return;
27 |
28 | id value = [property valueForObject:self];
29 | if (value == nil) return;
30 | [encoder encodeObject:value forKey:property.name];
31 | }];
32 | }
33 |
34 | - (void)mj_decode:(NSCoder *)decoder
35 | {
36 | Class clazz = [self class];
37 |
38 | NSArray *allowedCodingPropertyNames = [clazz mj_totalAllowedCodingPropertyNames];
39 | NSArray *ignoredCodingPropertyNames = [clazz mj_totalIgnoredCodingPropertyNames];
40 |
41 | [clazz mj_enumerateProperties:^(MJProperty *property, BOOL *stop) {
42 | // 检测是否被忽略
43 | if (allowedCodingPropertyNames.count && ![allowedCodingPropertyNames containsObject:property.name]) return;
44 | if ([ignoredCodingPropertyNames containsObject:property.name]) return;
45 |
46 | id value = [decoder decodeObjectForKey:property.name];
47 | if (value == nil) { // 兼容以前的MJExtension版本
48 | value = [decoder decodeObjectForKey:[@"_" stringByAppendingString:property.name]];
49 | }
50 | if (value == nil) return;
51 | [property setValue:value forObject:self];
52 | }];
53 | }
54 | @end
55 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSObject+MJProperty.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSObject+MJProperty.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/4/17.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJExtensionConst.h"
11 |
12 | @class MJProperty;
13 |
14 | /**
15 | * 遍历成员变量用的block
16 | *
17 | * @param property 成员的包装对象
18 | * @param stop YES代表停止遍历,NO代表继续遍历
19 | */
20 | typedef void (^MJPropertiesEnumeration)(MJProperty *property, BOOL *stop);
21 |
22 | /** 将属性名换为其他key去字典中取值 */
23 | typedef NSDictionary * (^MJReplacedKeyFromPropertyName)();
24 | typedef id (^MJReplacedKeyFromPropertyName121)(NSString *propertyName);
25 | /** 数组中需要转换的模型类 */
26 | typedef NSDictionary * (^MJObjectClassInArray)();
27 | /** 用于过滤字典中的值 */
28 | typedef id (^MJNewValueFromOldValue)(id object, id oldValue, MJProperty *property);
29 |
30 | /**
31 | * 成员属性相关的扩展
32 | */
33 | @interface NSObject (MJProperty)
34 | #pragma mark - 遍历
35 | /**
36 | * 遍历所有的成员
37 | */
38 | + (void)mj_enumerateProperties:(MJPropertiesEnumeration)enumeration;
39 |
40 | #pragma mark - 新值配置
41 | /**
42 | * 用于过滤字典中的值
43 | *
44 | * @param newValueFormOldValue 用于过滤字典中的值
45 | */
46 | + (void)mj_setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue;
47 | + (id)mj_getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property;
48 |
49 | #pragma mark - key配置
50 | /**
51 | * 将属性名换为其他key去字典中取值
52 | *
53 | * @param replacedKeyFromPropertyName 将属性名换为其他key去字典中取值
54 | */
55 | + (void)mj_setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName;
56 | /**
57 | * 将属性名换为其他key去字典中取值
58 | *
59 | * @param replacedKeyFromPropertyName121 将属性名换为其他key去字典中取值
60 | */
61 | + (void)mj_setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121;
62 |
63 | #pragma mark - array model class配置
64 | /**
65 | * 数组中需要转换的模型类
66 | *
67 | * @param objectClassInArray 数组中需要转换的模型类
68 | */
69 | + (void)mj_setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray;
70 | @end
71 |
72 | @interface NSObject (MJPropertyDeprecated_v_2_5_16)
73 | + (void)enumerateProperties:(MJPropertiesEnumeration)enumeration MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
74 | + (void)setupNewValueFromOldValue:(MJNewValueFromOldValue)newValueFormOldValue MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
75 | + (id)getNewValueFromObject:(__unsafe_unretained id)object oldValue:(__unsafe_unretained id)oldValue property:(__unsafe_unretained MJProperty *)property MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
76 | + (void)setupReplacedKeyFromPropertyName:(MJReplacedKeyFromPropertyName)replacedKeyFromPropertyName MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
77 | + (void)setupReplacedKeyFromPropertyName121:(MJReplacedKeyFromPropertyName121)replacedKeyFromPropertyName121 MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
78 | + (void)setupObjectClassInArray:(MJObjectClassInArray)objectClassInArray MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
79 | @end
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSString+MJExtension.h:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MJExtension.h
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/6/7.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "MJExtensionConst.h"
11 |
12 | @interface NSString (MJExtension)
13 | /**
14 | * 驼峰转下划线(loveYou -> love_you)
15 | */
16 | - (NSString *)mj_underlineFromCamel;
17 | /**
18 | * 下划线转驼峰(love_you -> loveYou)
19 | */
20 | - (NSString *)mj_camelFromUnderline;
21 | /**
22 | * 首字母变大写
23 | */
24 | - (NSString *)mj_firstCharUpper;
25 | /**
26 | * 首字母变小写
27 | */
28 | - (NSString *)mj_firstCharLower;
29 |
30 | - (BOOL)mj_isPureInt;
31 |
32 | - (NSURL *)mj_url;
33 | @end
34 |
35 | @interface NSString (MJExtensionDeprecated_v_2_5_16)
36 | - (NSString *)underlineFromCamel MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
37 | - (NSString *)camelFromUnderline MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
38 | - (NSString *)firstCharUpper MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
39 | - (NSString *)firstCharLower MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
40 | - (BOOL)isPureInt MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
41 | - (NSURL *)url MJExtensionDeprecated("请在方法名前面加上mj_前缀,使用mj_***");
42 | @end
43 |
--------------------------------------------------------------------------------
/HWDownloadDemo/Vender/MJExtension/MJExtension/NSString+MJExtension.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+MJExtension.m
3 | // MJExtensionExample
4 | //
5 | // Created by MJ Lee on 15/6/7.
6 | // Copyright (c) 2015年 小码哥. All rights reserved.
7 | //
8 |
9 | #import "NSString+MJExtension.h"
10 |
11 | @implementation NSString (MJExtension)
12 | - (NSString *)mj_underlineFromCamel
13 | {
14 | if (self.length == 0) return self;
15 | NSMutableString *string = [NSMutableString string];
16 | for (NSUInteger i = 0; i= 2) [string appendString:[cmp substringFromIndex:1]];
40 | } else {
41 | [string appendString:cmp];
42 | }
43 | }
44 | return string;
45 | }
46 |
47 | - (NSString *)mj_firstCharLower
48 | {
49 | if (self.length == 0) return self;
50 | NSMutableString *string = [NSMutableString string];
51 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].lowercaseString];
52 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
53 | return string;
54 | }
55 |
56 | - (NSString *)mj_firstCharUpper
57 | {
58 | if (self.length == 0) return self;
59 | NSMutableString *string = [NSMutableString string];
60 | [string appendString:[NSString stringWithFormat:@"%c", [self characterAtIndex:0]].uppercaseString];
61 | if (self.length >= 2) [string appendString:[self substringFromIndex:1]];
62 | return string;
63 | }
64 |
65 | - (BOOL)mj_isPureInt
66 | {
67 | NSScanner *scan = [NSScanner scannerWithString:self];
68 | int val;
69 | return [scan scanInt:&val] && [scan isAtEnd];
70 | }
71 |
72 | - (NSURL *)mj_url
73 | {
74 | // [self stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet characterSetWithCharactersInString:@"!$&'()*+,-./:;=?@_~%#[]"]];
75 | #pragma clang diagnostic push
76 | #pragma clang diagnostic ignored"-Wdeprecated-declarations"
77 | return [NSURL URLWithString:(NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (CFStringRef)self, (CFStringRef)@"!$&'()*+,-./:;=?@_~%#[]", NULL,kCFStringEncodingUTF8))];
78 | #pragma clang diagnostic pop
79 | }
80 | @end
81 |
82 | @implementation NSString (MJExtensionDeprecated_v_2_5_16)
83 | - (NSString *)underlineFromCamel
84 | {
85 | return self.mj_underlineFromCamel;
86 | }
87 |
88 | - (NSString *)camelFromUnderline
89 | {
90 | return self.mj_camelFromUnderline;
91 | }
92 |
93 | - (NSString *)firstCharLower
94 | {
95 | return self.mj_firstCharLower;
96 | }
97 |
98 | - (NSString *)firstCharUpper
99 | {
100 | return self.mj_firstCharUpper;
101 | }
102 |
103 | - (BOOL)isPureInt
104 | {
105 | return self.mj_isPureInt;
106 | }
107 |
108 | - (NSURL *)url
109 | {
110 | return self.mj_url;
111 | }
112 | @end
113 |
--------------------------------------------------------------------------------
/HWDownloadDemoTests/HWDownloadDemoTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadDemoTests.m
3 | // HWDownloadDemoTests
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWDownloadDemoTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation HWDownloadDemoTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/HWDownloadDemoTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/HWDownloadDemoUITests/HWDownloadDemoUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // HWDownloadDemoUITests.m
3 | // HWDownloadDemoUITests
4 | //
5 | // Created by wangqibin on 2018/5/21.
6 | // Copyright © 2018年 hero. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface HWDownloadDemoUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation HWDownloadDemoUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/HWDownloadDemoUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # HWDownloadDemo
2 | 文件下载功能,包含大文件下载,后台下载,杀死进程,重新启动时继续下载,设置下载并发数,监听网络改变等。
3 | CSDN博客:https://blog.csdn.net/hero_wqb/article/details/80407478
4 |
--------------------------------------------------------------------------------