Commit 57857b20dcf0fd071b2b2dc1d04924a599faf825
1 parent
df2d2fde
0.0.1
Showing
42 changed files
with
3019 additions
and
0 deletions
.gitignore
0 → 100644
| 1 | +# OS X | ||
| 2 | +.DS_Store | ||
| 3 | + | ||
| 4 | +# Xcode | ||
| 5 | +build/ | ||
| 6 | +Products/ | ||
| 7 | +*.pbxuser | ||
| 8 | +!default.pbxuser | ||
| 9 | +*.mode1v3 | ||
| 10 | +!default.mode1v3 | ||
| 11 | +*.mode2v3 | ||
| 12 | +!default.mode2v3 | ||
| 13 | +*.perspectivev3 | ||
| 14 | +!default.perspectivev3 | ||
| 15 | +xcuserdata/ | ||
| 16 | +*.xccheckout | ||
| 17 | +profile | ||
| 18 | +*.moved-aside | ||
| 19 | +DerivedData | ||
| 20 | +*.hmap | ||
| 21 | +*.ipa | ||
| 22 | + | ||
| 23 | +# Bundler | ||
| 24 | +.bundle | ||
| 25 | + | ||
| 26 | +# Add this line if you want to avoid checking in source code from Carthage dependencies. | ||
| 27 | +# Carthage/Checkouts | ||
| 28 | + | ||
| 29 | +Carthage/Build | ||
| 30 | + | ||
| 31 | +# We recommend against adding the Pods directory to your .gitignore. However | ||
| 32 | +# you should judge for yourself, the pros and cons are mentioned at: | ||
| 33 | +# https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control | ||
| 34 | +# | ||
| 35 | +# Note: if you ignore the Pods directory, make sure to uncomment | ||
| 36 | +# `pod install` in .travis.yml | ||
| 37 | +# | ||
| 38 | +# Pods/ |
.travis.yml
0 → 100644
| 1 | +# references: | ||
| 2 | +# * https://www.objc.io/issues/6-build-tools/travis-ci/ | ||
| 3 | +# * https://github.com/supermarin/xcpretty#usage | ||
| 4 | + | ||
| 5 | +osx_image: xcode7.3 | ||
| 6 | +language: objective-c | ||
| 7 | +# cache: cocoapods | ||
| 8 | +# podfile: Example/Podfile | ||
| 9 | +# before_install: | ||
| 10 | +# - gem install cocoapods # Since Travis is not always on latest version | ||
| 11 | +# - pod install --project-directory=Example | ||
| 12 | +script: | ||
| 13 | +- set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Example/CNLiveDownloadManager.xcworkspace -scheme CNLiveDownloadManager-Example -sdk iphonesimulator9.3 ONLY_ACTIVE_ARCH=NO | xcpretty | ||
| 14 | +- pod lib lint |
CNLiveDownloadManager.podspec
0 → 100644
| 1 | + | ||
| 2 | +Pod::Spec.new do |s| | ||
| 3 | + s.name = 'CNLiveDownloadManager' | ||
| 4 | + s.version = '0.0.1' | ||
| 5 | + s.summary = '下载管理器' | ||
| 6 | + | ||
| 7 | + s.description = <<-DESC | ||
| 8 | +TODO: Add long description of the pod here. | ||
| 9 | + DESC | ||
| 10 | + | ||
| 11 | + s.homepage = 'http://bj.gitlab.cnlive.com/ios-team/CNLiveDownloadManager' | ||
| 12 | + # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2' | ||
| 13 | + s.license = { :type => 'MIT', :file => 'LICENSE' } | ||
| 14 | + s.author = { '殷巧娟' => '1427945373@qq.com' } | ||
| 15 | + s.source = { :git => 'http://bj.gitlab.cnlive.com/ios-team/CNLiveDownloadManager.git', :tag => s.version.to_s } | ||
| 16 | + # s.social_media_url = 'https://twitter.com/<TWITTER_USERNAME>' | ||
| 17 | + | ||
| 18 | + s.ios.deployment_target = '9.0' | ||
| 19 | + | ||
| 20 | + # s.source_files = 'CNLiveDownloadManager/Classes/**/*' | ||
| 21 | + | ||
| 22 | + # s.resource_bundles = { | ||
| 23 | + # 'CNLiveDownloadManager' => ['CNLiveDownloadManager/Assets/*.png'] | ||
| 24 | + # } | ||
| 25 | + | ||
| 26 | + # s.public_header_files = 'Pod/Classes/**/*.h' | ||
| 27 | + s.subspec 'Model' do |model| | ||
| 28 | + model.dependency 'CNLiveBaseKit' | ||
| 29 | + model.dependency 'CNLiveTripartiteManagement/FMDB' | ||
| 30 | + model.source_files = 'CNLiveDownloadManager/Classes/Model/*.{h,m}' | ||
| 31 | + end | ||
| 32 | + s.subspec 'ViewModel' do |viewModel| | ||
| 33 | + viewModel.dependency 'CNLiveTripartiteManagement/FMDB' | ||
| 34 | + viewModel.source_files = 'CNLiveDownloadManager/Classes/ViewModel/*.{h,m}' | ||
| 35 | + viewModel.dependency 'CNLiveDownloadManager/Model' | ||
| 36 | + viewModel.dependency 'CNLiveBaseTools' | ||
| 37 | + viewModel.dependency 'CNLiveEnvironmentConfiguration' | ||
| 38 | + viewModel.dependency 'CNLiveBusinessTools' | ||
| 39 | + viewModel.dependency 'CNLiveBaseKit' | ||
| 40 | + viewModel.dependency 'CNLiveRequestBastKit' | ||
| 41 | + viewModel.dependency 'CNLiveTripartiteManagement/QMUIKit' | ||
| 42 | + end | ||
| 43 | + s.frameworks = 'UIKit', 'Foundation' | ||
| 44 | + # s.dependency 'CNLiveTripartiteManagement/FMDB' | ||
| 45 | + # s.dependency 'CNLiveBaseKit' | ||
| 46 | + # s.dependency 'CNLiveTripartiteManagement/MJExtension' | ||
| 47 | +end |
CNLiveDownloadManager/Assets/.gitkeep
0 → 100644
CNLiveDownloadManager/Classes/Model/CNLiveAlbumAudioListModel.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAlbumAudioListModel.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | +#import "CNLiveAlbumMsgModel.h" | ||
| 10 | +#import <FMDB/FMDB.h> | ||
| 11 | +NS_ASSUME_NONNULL_BEGIN | ||
| 12 | +typedef NS_ENUM(NSInteger, CNDownloadState) { | ||
| 13 | + CNDownloadStateDefault = 0, // 默认 | ||
| 14 | + CNDownloadStateDownloading, // 正在下载 | ||
| 15 | + CNDownloadStateWaiting, // 等待 | ||
| 16 | + CNDownloadStatePaused, // 暂停 | ||
| 17 | + CNDownloadStateFinish, // 完成 | ||
| 18 | + CNDownloadStateError, // 错误 | ||
| 19 | + CNDownloadStatePausedNoNetwork, //无网的时候暂停和退到后台暂停 | ||
| 20 | +}; | ||
| 21 | +@interface CNLiveAlbumAudioListModel : NSObject | ||
| 22 | +@property (nonatomic, copy) NSString *activityId; //活动ID | ||
| 23 | +@property (nonatomic, copy) NSString *title; //标题名称 | ||
| 24 | +@property (nonatomic, copy) NSString *albumId; //专辑ID | ||
| 25 | +@property (nonatomic, copy) NSString *albumName; //专辑名称 | ||
| 26 | +@property (nonatomic, copy) NSString *actor; //作者 | ||
| 27 | +@property (nonatomic, copy) NSString *modelId; //类型ID,5是音频 | ||
| 28 | +@property (nonatomic, copy) NSString *time; | ||
| 29 | +@property (nonatomic, copy) NSString *img; | ||
| 30 | +@property (nonatomic, copy) NSString *counts; //后面标题号 | ||
| 31 | +@property (nonatomic, copy) NSString *viewCounts; //人数 | ||
| 32 | +@property (nonatomic, copy) NSString *schedule; //播放长度 | ||
| 33 | +@property (nonatomic, copy) NSString *comments; //评论数 | ||
| 34 | +@property (nonatomic, copy) NSString *contentId; | ||
| 35 | +@property (nonatomic, copy) NSString *duration; //时长 | ||
| 36 | +@property (nonatomic, copy) NSString *shareUrl; | ||
| 37 | +@property (nonatomic, copy) NSString * aid; //专辑ID | ||
| 38 | +@property (nonatomic, copy) NSString * poster; //封面图 | ||
| 39 | +@property (nonatomic, copy) NSString * channelName; // | ||
| 40 | + // 播放详情接口 | ||
| 41 | +@property (nonatomic, strong) CNLiveAlbumMsgModel * album; //专辑 | ||
| 42 | +@property (nonatomic, copy) NSString * desc; //描述 | ||
| 43 | +@property (nonatomic, copy) NSString * model; // | ||
| 44 | +@property (nonatomic, copy) NSString * publishTime; // | ||
| 45 | +@property (nonatomic, copy) NSString * siteId; // | ||
| 46 | +@property (nonatomic, copy) NSString * subTitle; | ||
| 47 | +@property (nonatomic, copy) NSString *isSelected; //是否被播放过 | ||
| 48 | + // 历史记录 | ||
| 49 | +@property (nonatomic, copy) NSString *recordId; | ||
| 50 | +@property (nonatomic, copy) NSString *activeId; | ||
| 51 | +@property (nonatomic, copy) NSString *recent; | ||
| 52 | +@property (nonatomic, copy) NSString *sid; | ||
| 53 | +@property (nonatomic, copy) NSString *albumImg; | ||
| 54 | +@property (nonatomic, copy) NSString *number; //展示前面的数字,自己加的 | ||
| 55 | +@property (nonatomic, copy) NSString *isCellSelected; //cell是否被选中 | ||
| 56 | + //下载的数据 | ||
| 57 | +@property (nonatomic, copy) NSString *localPath; // 下载完成路径 | ||
| 58 | +@property (nonatomic, copy) NSString *url; // url | ||
| 59 | +@property (nonatomic, strong) NSData *resumeData; // 下载的数据 | ||
| 60 | +@property (nonatomic, assign) CGFloat progress; // 下载进度 | ||
| 61 | +@property (nonatomic, assign) CNDownloadState state; // 下载状态 | ||
| 62 | +@property (nonatomic, assign) NSUInteger totalFileSize; // 文件总大小 | ||
| 63 | +@property (nonatomic, assign) NSUInteger tmpFileSize; // 下载大小 | ||
| 64 | +@property (nonatomic, assign) NSUInteger speed; // 下载速度 | ||
| 65 | +@property (nonatomic, assign) NSTimeInterval lastSpeedTime; // 上次计算速度时的时间戳 | ||
| 66 | +@property (nonatomic, assign) NSUInteger intervalFileSize; // 计算速度时间内下载文件的大小 | ||
| 67 | +@property (nonatomic, assign) NSUInteger lastStateTime; // 记录任务加入准备下载的时间(点击默认、暂停、失败状态),用于计算开始、停止任务的先后顺序 | ||
| 68 | +@property (nonatomic, copy) NSString *fileSize; //服务器返的文件大小 | ||
| 69 | + | ||
| 70 | + // 根据数据库查询结果初始化 | ||
| 71 | +- (instancetype)initWithFMResultSet:(FMResultSet *)resultSet; | ||
| 72 | +@end | ||
| 73 | + | ||
| 74 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/Model/CNLiveAlbumAudioListModel.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAlbumAudioListModel.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveAlbumAudioListModel.h" | ||
| 9 | +#import "MJExtension.h" | ||
| 10 | +@implementation CNLiveAlbumAudioListModel | ||
| 11 | ++ (NSDictionary *)mj_replacedKeyFromPropertyName | ||
| 12 | +{ | ||
| 13 | + return @{ | ||
| 14 | + @"recordId":@"id", | ||
| 15 | + }; | ||
| 16 | +} | ||
| 17 | +- (NSString *)localPath { | ||
| 18 | + if (!_localPath) { | ||
| 19 | + if (_url && ![_url isEqualToString:@"<null>"]) { | ||
| 20 | + NSString *fileName = [_url substringFromIndex:[_url rangeOfString:@"/" options:NSBackwardsSearch].location + 1]; | ||
| 21 | + NSString *str = [NSString stringWithFormat:@"%@_%@", _activityId, fileName]; | ||
| 22 | + NSString *fileCacheDireCtory = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"albumAudioList_%@",_albumId]]; | ||
| 23 | + _localPath = [fileCacheDireCtory stringByAppendingPathComponent:str]; | ||
| 24 | + } | ||
| 25 | + } | ||
| 26 | + | ||
| 27 | + return _localPath ? _localPath: @""; | ||
| 28 | +} | ||
| 29 | +- (instancetype)initWithFMResultSet:(FMResultSet *)resultSet { | ||
| 30 | + if (!resultSet) return nil; | ||
| 31 | + _activityId = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"activityId"]]; | ||
| 32 | + _contentId = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"contentId"]]; | ||
| 33 | + _title = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"title"]]; | ||
| 34 | + _albumName = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"albumName"]]; | ||
| 35 | + _albumId = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"albumId"]]; | ||
| 36 | + _img = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"img"]]; | ||
| 37 | + _shareUrl = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"shareUrl"]]; | ||
| 38 | + _counts = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"counts"]]; | ||
| 39 | + _viewCounts = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"viewCounts"]]; | ||
| 40 | + _actor = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"actor"]]; | ||
| 41 | + _duration = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"duration"]]; | ||
| 42 | + _modelId = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"modelId"]]; | ||
| 43 | + _schedule = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"schedule"]]; | ||
| 44 | + _channelName = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"channelName"]]; | ||
| 45 | + _time = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"time"]]; | ||
| 46 | + _url = [NSString stringWithFormat:@"%@", [resultSet objectForColumn:@"url"]]; | ||
| 47 | + _resumeData = [resultSet dataForColumn:@"resumeData"]; | ||
| 48 | + _totalFileSize = [[resultSet objectForColumn:@"totalFileSize"] integerValue]; | ||
| 49 | + _tmpFileSize = [[resultSet objectForColumn:@"tmpFileSize"] integerValue]; | ||
| 50 | + _state = [[resultSet objectForColumn:@"state"] integerValue]; | ||
| 51 | + _progress = [[resultSet objectForColumn:@"progress"] floatValue]; | ||
| 52 | + _lastSpeedTime = [resultSet doubleForColumn:@"lastSpeedTime"]; | ||
| 53 | + _intervalFileSize = [[resultSet objectForColumn:@"intervalFileSize"] integerValue]; | ||
| 54 | + _lastStateTime = [[resultSet objectForColumn:@"lastStateTime"] integerValue]; | ||
| 55 | + _fileSize = [NSString stringWithFormat:@"%@",[resultSet objectForColumn:@"fileSize"]]; | ||
| 56 | + | ||
| 57 | + return self; | ||
| 58 | +} | ||
| 59 | + | ||
| 60 | +@end |
CNLiveDownloadManager/Classes/Model/CNLiveAlbumMsgModel.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAlbumMsgModel.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | +@class CNLiveAlbumMsgSpModel; | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface CNLiveAlbumMsgModel : NSObject | ||
| 13 | +@property (nonatomic, copy) NSString *albumId; | ||
| 14 | +@property (nonatomic, copy) NSString *albumImg; //图片地址 | ||
| 15 | +@property (nonatomic, copy) NSString *albumName; //标题 | ||
| 16 | +@property (nonatomic, copy) NSString *desc; //描述 | ||
| 17 | +@property (nonatomic, copy) NSString *actor; | ||
| 18 | +@property (nonatomic, copy) NSString *time; //时间戳 | ||
| 19 | +@property (nonatomic, copy) NSString *episodeNow; //总集数 | ||
| 20 | +@property (nonatomic, strong) CNLiveAlbumMsgSpModel *sp; //下面简介 | ||
| 21 | +@property (nonatomic, copy) NSString *subscriptions; | ||
| 22 | +@property (nonatomic, copy) NSString *subscribe; | ||
| 23 | +@property (nonatomic, copy) NSString *episodeLast; //最后一次播放的章节数 | ||
| 24 | +@property (nonatomic, copy) NSString *contentIdLast; | ||
| 25 | +- (CGFloat)setRowHeight; | ||
| 26 | +@end | ||
| 27 | +@interface CNLiveAlbumMsgSpModel : NSObject | ||
| 28 | +@property (nonatomic, copy) NSString *spName; // | ||
| 29 | +@property (nonatomic, copy) NSString *spId; // | ||
| 30 | +@property (nonatomic, copy) NSString *spIcon; // | ||
| 31 | +@property (nonatomic, copy) NSString *desc; // | ||
| 32 | +@property (nonatomic, copy) NSString *subscriptions; // | ||
| 33 | +@property (nonatomic, copy) NSString *subscribe; // | ||
| 34 | +@end | ||
| 35 | + | ||
| 36 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/Model/CNLiveAlbumMsgModel.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAlbumMsgModel.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveAlbumMsgModel.h" | ||
| 9 | +#import <CNLiveBaseKit/CNLiveDefinesHeader.h> | ||
| 10 | +@implementation CNLiveAlbumMsgModel | ||
| 11 | ++ (NSDictionary *)mj_objectClassInArray{ | ||
| 12 | + return @{ | ||
| 13 | + @"sp" : @"CNLiveAlbumMsgSpModel" | ||
| 14 | + }; | ||
| 15 | +} | ||
| 16 | +- (CGFloat)setRowHeight { | ||
| 17 | + NSDictionary *descAttr = @{NSFontAttributeName:UIFontCNMake(16)}; | ||
| 18 | + CGFloat descHeight = [self.desc boundingRectWithSize:CGSizeMake(KScreenWidth - 20, MAXFLOAT) options:NSStringDrawingUsesLineFragmentOrigin attributes:descAttr context:nil].size.height; | ||
| 19 | + return descHeight; | ||
| 20 | +} | ||
| 21 | +@end | ||
| 22 | +@implementation CNLiveAlbumMsgSpModel | ||
| 23 | + | ||
| 24 | +@end | ||
| 25 | + |
CNLiveDownloadManager/Classes/ViewModel/CNLiveDataBaseManager.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDataBaseManager.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | +@class CNLiveAlbumAudioListModel; | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | +typedef NS_OPTIONS(NSUInteger, CNDBUpdateOption) { | ||
| 12 | + CNDBUpdateOptionState = 1 << 0, // 更新状态 | ||
| 13 | + CNDBUpdateOptionLastStateTime = 1 << 1, // 更新状态最后改变的时间 | ||
| 14 | + CNDBUpdateOptionResumeData = 1 << 2, // 更新下载的数据 | ||
| 15 | + CNDBUpdateOptionProgressData = 1 << 3, // 更新进度数据(包含tmpFileSize、totalFileSize、progress、intervalFileSize、lastSpeedTime) | ||
| 16 | + CNDBUpdateOptionAllParam = 1 << 4 // 更新全部数据 | ||
| 17 | +}; | ||
| 18 | +@interface CNLiveDataBaseManager : NSObject | ||
| 19 | + // 获取单例 | ||
| 20 | ++ (instancetype)shareManager; | ||
| 21 | + // 插入数据 | ||
| 22 | +- (void)insertModel:(CNLiveAlbumAudioListModel *)model; | ||
| 23 | + | ||
| 24 | + // 获取数据 | ||
| 25 | +- (CNLiveAlbumAudioListModel *)getModelWithUrl:(NSString *)url; // 根据url获取数据 | ||
| 26 | +- (CNLiveAlbumAudioListModel *)getWaitingModel; // 获取第一条等待的数据 | ||
| 27 | +- (CNLiveAlbumAudioListModel *)getLastDownloadingModel; // 获取最后一条正在下载的数据 | ||
| 28 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllCacheData; // 获取所有数据 | ||
| 29 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllDownloadingData; // 根据lastStateTime倒叙获取所有正在下载的数据 | ||
| 30 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllDownloadedData; // 获取所有下载完成的数据 | ||
| 31 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllUnDownloadedData; // 获取所有未下载完成的数据(包含正在下载、等待、暂停、错误) | ||
| 32 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllWaitingData; // 获取所有等待下载的数据 | ||
| 33 | +- (CNLiveAlbumAudioListModel *)getModelwithActivityId:(NSString *)activityId; //根据ativityId获取数据 | ||
| 34 | + // 更新数据 | ||
| 35 | +- (void)updateWithModel:(CNLiveAlbumAudioListModel *)model option:(CNDBUpdateOption)option; | ||
| 36 | + | ||
| 37 | + // 删除数据 | ||
| 38 | +- (void)deleteModelWithUrl:(NSString *)activityId; | ||
| 39 | +@end | ||
| 40 | + | ||
| 41 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/CNLiveDataBaseManager.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDataBaseManager.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveDataBaseManager.h" | ||
| 9 | +#import "CNLiveTimeTools.h" | ||
| 10 | +#import "CNLiveDownloadManager.h" | ||
| 11 | +#import "CNLiveAlbumAudioListModel.h" | ||
| 12 | +#import "CNLiveTimeTools.h" | ||
| 13 | +#import "CNLiveDownload.h" | ||
| 14 | +typedef NS_ENUM(NSInteger, CNDBGetDateOption) { | ||
| 15 | + CNDBGetDateOptionAllCacheData = 0, // 所有缓存数据 | ||
| 16 | + CNDBGetDateOptionAllDownloadingData, // 所有正在下载的数据 | ||
| 17 | + CNDBGetDateOptionAllDownloadedData, // 所有下载完成的数据 | ||
| 18 | + CNDBGetDateOptionAllUnDownloadedData, // 所有未下载完成的数据 | ||
| 19 | + CNDBGetDateOptionAllWaitingData, // 所有等待下载的数据 | ||
| 20 | + CNDBGetDateOptionModelWithUrl, // 通过url获取单条数据 | ||
| 21 | + CNDBGetDateOptionWaitingModel, // 第一条等待的数据 | ||
| 22 | + CNDBGetDateOptionLastDownloadingModel, // 最后一条正在下载的数据 | ||
| 23 | + CNDBGetDateOptionModelWithActivityId, //通过activityId获取model | ||
| 24 | +}; | ||
| 25 | +@interface CNLiveDataBaseManager () | ||
| 26 | +@property (nonatomic, strong) FMDatabaseQueue *dbQueue; | ||
| 27 | +@end | ||
| 28 | +@implementation CNLiveDataBaseManager | ||
| 29 | ++ (instancetype)shareManager | ||
| 30 | +{ | ||
| 31 | + static CNLiveDataBaseManager *manager = nil; | ||
| 32 | + | ||
| 33 | + static dispatch_once_t onceToken; | ||
| 34 | + dispatch_once(&onceToken, ^{ | ||
| 35 | + manager = [[self alloc] init]; | ||
| 36 | + }); | ||
| 37 | + | ||
| 38 | + return manager; | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +- (instancetype)init | ||
| 42 | +{ | ||
| 43 | + if (self = [super init]) { | ||
| 44 | + [self creatVideoCachesTable]; | ||
| 45 | + } | ||
| 46 | + | ||
| 47 | + return self; | ||
| 48 | +} | ||
| 49 | +#pragma mark - 创建一个数据库 | ||
| 50 | +- (void)creatVideoCachesTable | ||
| 51 | +{ | ||
| 52 | + // 数据库文件路径 | ||
| 53 | + NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:@"CNDownloadVideoCaches.sqlite"]; | ||
| 54 | + // 创建队列对象,内部会自动创建一个数据库, 并且自动打开 | ||
| 55 | + _dbQueue = [FMDatabaseQueue databaseQueueWithPath:path]; | ||
| 56 | + | ||
| 57 | + [_dbQueue inDatabase:^(FMDatabase *db) { | ||
| 58 | + // 创表 | ||
| 59 | + BOOL result = [db executeUpdate:@"CREATE TABLE IF NOT EXISTS t_videoCaches (id integer PRIMARY KEY AUTOINCREMENT, activityId text, contentId text,title text,albumName text,albumId text,img text,shareUrl text,counts text,viewCounts text,actor text,duration text,modelId text,schedule text,channelName text,time text,url text, resumeData blob, totalFileSize integer, tmpFileSize integer, state integer, progress float, lastSpeedTime double, intervalFileSize integer, lastStateTime integer, fileSize text)"]; | ||
| 60 | + if (![db columnExists:@"channelName" inTableWithName:@"t_videoCaches"] ) { //新添字段,先判断数据里有没有,没有,添加 | ||
| 61 | + NSString *channelName = [NSString stringWithFormat:@"ALTER TABLE %@ ADD %@ INTEGER",@"t_videoCaches",@"channelName"]; | ||
| 62 | + BOOL isSuccess = [db executeUpdate:channelName]; | ||
| 63 | + if (isSuccess) { | ||
| 64 | + NSLog(@"插入成功"); | ||
| 65 | + }else { | ||
| 66 | + NSLog(@"插入失败"); | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + if (result) { | ||
| 70 | + NSLog(@"音频缓存数据表创建成功"); | ||
| 71 | + }else { | ||
| 72 | + NSLog(@"音频缓存数据表创建失败"); | ||
| 73 | + } | ||
| 74 | + }]; | ||
| 75 | +} | ||
| 76 | + | ||
| 77 | +#pragma mark - 插入一条数据 | ||
| 78 | +- (void)insertModel:(CNLiveAlbumAudioListModel *)model | ||
| 79 | +{ | ||
| 80 | + [_dbQueue inDatabase:^(FMDatabase *db) { | ||
| 81 | + BOOL result = [db executeUpdate:@"INSERT INTO t_videoCaches (activityId,contentId,title,albumName,albumId,img,shareUrl,counts,viewCounts,actor,duration,modelId,schedule,channelName,time,url, resumeData, totalFileSize, tmpFileSize, state, progress, lastSpeedTime, intervalFileSize, lastStateTime, fileSize) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?,?)", model.activityId?model.activityId :[NSNull null],model.contentId?model.contentId:[NSNull null], model.title?model.title:[NSNull null],model.albumName ? model.albumName:[NSNull null],model.albumId?model.albumId:[NSNull null],model.img?model.img:[NSNull null],model.shareUrl?model.shareUrl:[NSNull null],model.counts?model.counts:[NSNull null],model.viewCounts?model.viewCounts:[NSNull null],model.actor ? model.actor:[NSNull null],model.duration ? model.duration:[NSNull null],model.modelId ?model.modelId :[NSNull null],model.schedule ?model.schedule:[NSNull null],model.channelName ? model.channelName:[NSNull null],model.time ? model.time:[NSNull null],model.url, model.resumeData, [NSNumber numberWithInteger:model.totalFileSize], [NSNumber numberWithInteger:model.tmpFileSize], [NSNumber numberWithInteger:model.state], [NSNumber numberWithFloat:model.progress], [NSNumber numberWithDouble:0], [NSNumber numberWithInteger:0], [NSNumber numberWithInteger:0],model.fileSize]; | ||
| 82 | + if (result) { | ||
| 83 | + NSLog(@"插入成功:%@", model.title); | ||
| 84 | + }else { | ||
| 85 | + NSLog(@"插入失败:%@", model.title); | ||
| 86 | + } | ||
| 87 | + }]; | ||
| 88 | +} | ||
| 89 | +#pragma mark - 根据url获取单条数据 | ||
| 90 | +- (CNLiveAlbumAudioListModel *)getModelWithUrl:(NSString *)url | ||
| 91 | + { | ||
| 92 | + return [self getModelWithOption:CNDBGetDateOptionModelWithUrl url:url activityId:nil]; | ||
| 93 | + } | ||
| 94 | +#pragma mark - 根据activityId获取Model | ||
| 95 | +- (CNLiveAlbumAudioListModel *)getModelwithActivityId:(NSString *)activityId { | ||
| 96 | + return [self getModelWithOption:CNDBGetDateOptionModelWithActivityId url:nil activityId:activityId]; | ||
| 97 | +} | ||
| 98 | +#pragma mark - 获取第一条等待的数据 | ||
| 99 | +- (CNLiveAlbumAudioListModel *)getWaitingModel | ||
| 100 | + { | ||
| 101 | + return [self getModelWithOption:CNDBGetDateOptionWaitingModel url:nil activityId:nil]; | ||
| 102 | + } | ||
| 103 | +#pragma mark - 获取正在下载的数据 | ||
| 104 | +- (CNLiveAlbumAudioListModel *)getLastDownloadingModel | ||
| 105 | + { | ||
| 106 | + return [self getModelWithOption:CNDBGetDateOptionLastDownloadingModel url:nil activityId:nil]; | ||
| 107 | + } | ||
| 108 | + | ||
| 109 | +#pragma mark - 获取所有数据 | ||
| 110 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllCacheData | ||
| 111 | + { | ||
| 112 | + return [self getDateWithOption:CNDBGetDateOptionAllCacheData]; | ||
| 113 | + } | ||
| 114 | +#pragma mark - 根据lastStateTime倒叙获取所有正在下载的数据 | ||
| 115 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllDownloadingData | ||
| 116 | + { | ||
| 117 | + return [self getDateWithOption:CNDBGetDateOptionAllDownloadingData]; | ||
| 118 | + } | ||
| 119 | +#pragma mark - 获取所有下载完成的数据 | ||
| 120 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllDownloadedData | ||
| 121 | + { | ||
| 122 | + return [self getDateWithOption:CNDBGetDateOptionAllDownloadedData]; | ||
| 123 | + } | ||
| 124 | +#pragma mark - 获取所有未下载完成的数据 | ||
| 125 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllUnDownloadedData | ||
| 126 | + { | ||
| 127 | + return [self getDateWithOption:CNDBGetDateOptionAllUnDownloadedData]; | ||
| 128 | + } | ||
| 129 | +#pragma mark - 获取所有等待下载的数据 | ||
| 130 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getAllWaitingData | ||
| 131 | + { | ||
| 132 | + return [self getDateWithOption:CNDBGetDateOptionAllWaitingData]; | ||
| 133 | + } | ||
| 134 | +#pragma mark - 获取单条数据 | ||
| 135 | +- (CNLiveAlbumAudioListModel *)getModelWithOption:(CNDBGetDateOption)option url:(NSString *)url activityId:(NSString *)activityId | ||
| 136 | + { | ||
| 137 | + __block CNLiveAlbumAudioListModel *model = nil; | ||
| 138 | + | ||
| 139 | + [_dbQueue inDatabase:^(FMDatabase *db) { | ||
| 140 | + FMResultSet *resultSet; | ||
| 141 | + switch (option) { | ||
| 142 | + case CNDBGetDateOptionModelWithUrl: | ||
| 143 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE url = ?", url]; | ||
| 144 | + break; | ||
| 145 | + | ||
| 146 | + case CNDBGetDateOptionWaitingModel: | ||
| 147 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state = ? order by lastStateTime asc limit 0,1", [NSNumber numberWithInteger:CNDownloadStateWaiting]]; | ||
| 148 | + break; | ||
| 149 | + | ||
| 150 | + case CNDBGetDateOptionLastDownloadingModel: | ||
| 151 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state = ? order by lastStateTime desc limit 0,1", [NSNumber numberWithInteger:CNDownloadStateDownloading]]; | ||
| 152 | + break; | ||
| 153 | + case CNDBGetDateOptionModelWithActivityId: | ||
| 154 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE activityId = ?", activityId]; | ||
| 155 | + break; | ||
| 156 | + default: | ||
| 157 | + break; | ||
| 158 | + } | ||
| 159 | + | ||
| 160 | + while ([resultSet next]) { | ||
| 161 | + model = [[CNLiveAlbumAudioListModel alloc] initWithFMResultSet:resultSet]; | ||
| 162 | + } | ||
| 163 | + }]; | ||
| 164 | + | ||
| 165 | + return model; | ||
| 166 | + } | ||
| 167 | +#pragma mark - 获取数据集合 | ||
| 168 | +- (NSArray<CNLiveAlbumAudioListModel *> *)getDateWithOption:(CNDBGetDateOption)option | ||
| 169 | + { | ||
| 170 | + __block NSArray<CNLiveAlbumAudioListModel *> *array = nil; | ||
| 171 | + | ||
| 172 | + [_dbQueue inDatabase:^(FMDatabase *db) { | ||
| 173 | + FMResultSet *resultSet; | ||
| 174 | + switch (option) { | ||
| 175 | + | ||
| 176 | + case CNDBGetDateOptionAllCacheData: | ||
| 177 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches"]; | ||
| 178 | + break; | ||
| 179 | + | ||
| 180 | + case CNDBGetDateOptionAllDownloadingData: | ||
| 181 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state = ? order by lastStateTime desc", [NSNumber numberWithInteger:CNDownloadStateDownloading]]; | ||
| 182 | + break; | ||
| 183 | + | ||
| 184 | + case CNDBGetDateOptionAllDownloadedData: | ||
| 185 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state = ?", [NSNumber numberWithInteger:CNDownloadStateFinish]]; | ||
| 186 | + break; | ||
| 187 | + | ||
| 188 | + case CNDBGetDateOptionAllUnDownloadedData: | ||
| 189 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state != ?", [NSNumber numberWithInteger:CNDownloadStateFinish]]; | ||
| 190 | + break; | ||
| 191 | + | ||
| 192 | + case CNDBGetDateOptionAllWaitingData: | ||
| 193 | + resultSet = [db executeQuery:@"SELECT * FROM t_videoCaches WHERE state = ?", [NSNumber numberWithInteger:CNDownloadStateWaiting]]; | ||
| 194 | + break; | ||
| 195 | + | ||
| 196 | + default: | ||
| 197 | + break; | ||
| 198 | + } | ||
| 199 | + | ||
| 200 | + NSMutableArray *tmpArr = [NSMutableArray array]; | ||
| 201 | + while ([resultSet next]) { | ||
| 202 | + [tmpArr addObject:[[CNLiveAlbumAudioListModel alloc] initWithFMResultSet:resultSet]]; | ||
| 203 | + } | ||
| 204 | + array = tmpArr; | ||
| 205 | + }]; | ||
| 206 | + | ||
| 207 | + return array; | ||
| 208 | + } | ||
| 209 | +#pragma mark - 更新数据 | ||
| 210 | +- (void)updateWithModel:(CNLiveAlbumAudioListModel *)model option:(CNDBUpdateOption)option | ||
| 211 | + { | ||
| 212 | + [_dbQueue inDatabase:^(FMDatabase *db) { | ||
| 213 | + if (option & CNDBUpdateOptionState) { | ||
| 214 | + //根据url 更新state数据 | ||
| 215 | + [self postStateChangeNotificationWithFMDatabase:db model:model]; | ||
| 216 | + [db executeUpdate:@"UPDATE t_videoCaches SET state = ?,url = ? WHERE activityId = ?", [NSNumber numberWithInteger:model.state], model.url,model.activityId]; | ||
| 217 | + } | ||
| 218 | + if (option & CNDBUpdateOptionLastStateTime) { | ||
| 219 | + [db executeUpdate:@"UPDATE t_videoCaches SET lastStateTime = ?,url = ? WHERE activityId = ?", [NSNumber numberWithInteger:[CNLiveTimeTools getTimeStampWithDate:[NSDate date]]], model.url,model.activityId]; | ||
| 220 | + } | ||
| 221 | + if (option & CNDBUpdateOptionResumeData) { | ||
| 222 | + [db executeUpdate:@"UPDATE t_videoCaches SET resumeData = ?,url = ? WHERE activityId = ?", model.resumeData, model.url,model.activityId]; | ||
| 223 | + } | ||
| 224 | + if (option & CNDBUpdateOptionProgressData) { | ||
| 225 | + [db executeUpdate:@"UPDATE t_videoCaches SET tmpFileSize = ?, totalFileSize = ?, progress = ?, lastSpeedTime = ?, intervalFileSize = ?,url = ? WHERE activityId = ?", [NSNumber numberWithInteger:model.tmpFileSize], [NSNumber numberWithFloat:model.totalFileSize], [NSNumber numberWithFloat:model.progress], [NSNumber numberWithDouble:model.lastSpeedTime], [NSNumber numberWithInteger:model.intervalFileSize], model.url,model.activityId]; | ||
| 226 | + } | ||
| 227 | + if (option & CNDBUpdateOptionAllParam) { | ||
| 228 | + [self postStateChangeNotificationWithFMDatabase:db model:model]; | ||
| 229 | + [db executeUpdate:@"UPDATE t_videoCaches SET resumeData = ?, totalFileSize = ?, tmpFileSize = ?, progress = ?, state = ?, lastSpeedTime = ?, intervalFileSize = ?, lastStateTime = ? ,url = ? WHERE activityId = ?", model.resumeData, [NSNumber numberWithInteger:model.totalFileSize], [NSNumber numberWithInteger:model.tmpFileSize], [NSNumber numberWithFloat:model.progress], [NSNumber numberWithInteger:model.state], [NSNumber numberWithDouble:model.lastSpeedTime], [NSNumber numberWithInteger:model.intervalFileSize], [NSNumber numberWithInteger:[CNLiveTimeTools getTimeStampWithDate:[NSDate date]]], model.url,model.activityId]; | ||
| 230 | + } | ||
| 231 | + }]; | ||
| 232 | + } | ||
| 233 | + | ||
| 234 | + | ||
| 235 | +#pragma mark - 状态改变通知 | ||
| 236 | +- (void)postStateChangeNotificationWithFMDatabase:(FMDatabase *)db model:(CNLiveAlbumAudioListModel *)model | ||
| 237 | + { | ||
| 238 | + // 原状态 | ||
| 239 | + //t_videoCaches创建的表名 where通过什么查询 通过url查询state | ||
| 240 | + NSInteger oldState = [db intForQuery:@"SELECT state FROM t_videoCaches WHERE activityId = ?", model.activityId]; | ||
| 241 | + | ||
| 242 | + if (oldState != model.state && oldState != CNDownloadStateFinish) { | ||
| 243 | + // 状态变更通知 | ||
| 244 | + [[NSNotificationCenter defaultCenter] postNotificationName:WjjAudioDownloadStateChangeNotification object:model]; | ||
| 245 | + } | ||
| 246 | + } | ||
| 247 | +#pragma mark - 删除数据库数据 | ||
| 248 | +- (void)deleteModelWithUrl:(NSString *)activityId | ||
| 249 | + { | ||
| 250 | + [_dbQueue inDatabase:^(FMDatabase *db) { // where 后面跟的是条件 | ||
| 251 | + BOOL result = [db executeUpdate:@"DELETE FROM t_videoCaches WHERE activityId = ?", activityId]; | ||
| 252 | + if (result) { | ||
| 253 | + // HWLog(@"删除成功:%@", url); | ||
| 254 | + }else { | ||
| 255 | + NSLog(@"删除失败:%@", activityId); | ||
| 256 | + } | ||
| 257 | + }]; | ||
| 258 | + } | ||
| 259 | + | ||
| 260 | + | ||
| 261 | +@end |
CNLiveDownloadManager/Classes/ViewModel/CNLiveDownload.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDownload.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#ifndef CNLiveDownload_h | ||
| 9 | +#define CNLiveDownload_h | ||
| 10 | + | ||
| 11 | +//分类-听见中国 -下载状态通知 | ||
| 12 | +#ifndef WjjAudioDownloadStateChangeNotification | ||
| 13 | +#define WjjAudioDownloadStateChangeNotification @"CNDownloadStateChangeNotification" | ||
| 14 | +#endif | ||
| 15 | +//分类-听见中国 -下载进度通知 | ||
| 16 | +#ifndef WjjAudioDownloadProgressNotification | ||
| 17 | +#define WjjAudioDownloadProgressNotification @"CNDownloadProgressNotification" | ||
| 18 | +#endif | ||
| 19 | +#endif /* CNLiveDownload_h */ |
CNLiveDownloadManager/Classes/ViewModel/CNLiveDownloadManager.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDownloadManager.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | +@class CNLiveAlbumAudioListModel; | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | +@interface CNLiveDownloadManager : NSObject | ||
| 12 | + // 开始下载 | ||
| 13 | +- (void)startDownloadTask:(CNLiveAlbumAudioListModel *)model; | ||
| 14 | + | ||
| 15 | + // 暂停下载 | ||
| 16 | +- (void)pauseDownloadTask:(CNLiveAlbumAudioListModel *)model; | ||
| 17 | + | ||
| 18 | + // 删除下载任务及本地缓存 | ||
| 19 | +- (void)deleteTaskAndCache:(CNLiveAlbumAudioListModel *)model; | ||
| 20 | + //全部暂停 | ||
| 21 | +- (void)pauseAllDownloadTask:(BOOL)isNoHaveNet; | ||
| 22 | + //全部开始 | ||
| 23 | +- (void)startAllDownloadTask:(BOOL)isHaveNoNet; | ||
| 24 | + @property (nonatomic, assign) BOOL allowsCellularAccess; // 是否允许蜂窝网络下载 | ||
| 25 | + @property (nonatomic, assign) BOOL isloading; //yes表示有请求download的url在进行 | ||
| 26 | +- (void)getDownloadUrl:(CNLiveAlbumAudioListModel *)model; | ||
| 27 | +@end | ||
| 28 | + | ||
| 29 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/CNLiveDownloadManager.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDownloadManager.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/1. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveDownloadManager.h" | ||
| 9 | +#import "NSString+CNLiveExtension.h" | ||
| 10 | +#import "CNLiveAlbumAudioListModel.h" | ||
| 11 | +#import "NSURLSession+CNLiveCorrectedResumeData.h" | ||
| 12 | +#import "CNLiveVodUrlUtil.h" | ||
| 13 | +#import "NSString+CNLiveExtension.h" | ||
| 14 | +#import "CNLiveNetworking.h" | ||
| 15 | +#import "CNUserInfoManager.h" | ||
| 16 | +#import "CNLiveDataBaseManager.h" | ||
| 17 | +#import "CNLiveDefinesHeader.h" | ||
| 18 | +#import "QMUIKit.h" | ||
| 19 | +#import "CNLiveTimeTools.h" | ||
| 20 | +#import "CNLiveDownload.h" | ||
| 21 | +#define CNLiveAppKeyWindow [UIApplication sharedApplication].delegate.window | ||
| 22 | +;@interface CNLiveDownloadManager ()<NSURLSessionDelegate,NSURLSessionDownloadDelegate,UIAlertViewDelegate> | ||
| 23 | +@property (nonatomic, strong) NSURLSession *session; // NSURLSession | ||
| 24 | +@property (nonatomic, strong) NSMutableDictionary *dataTaskDic; // 同时下载多个文件,需要创建多个NSURLSessionDownloadTask,用该字典来存储 | ||
| 25 | +@property (nonatomic, strong) NSMutableDictionary *downloadTaskDic; // 记录任务调用startDownloadTask:方法时间,禁止同一任务极短时间重复调用,防止状态显示错误 | ||
| 26 | +@property (nonatomic, assign) NSInteger currentCount; // 当前正在下载的个数 | ||
| 27 | +@property (nonatomic, assign) NSInteger maxConcurrentCount; // 最大同时下载数量 | ||
| 28 | +@property (nonatomic, assign) BOOL isNohaveNet; //没网 | ||
| 29 | +@end | ||
| 30 | + | ||
| 31 | +@implementation CNLiveDownloadManager | ||
| 32 | ++ (instancetype)shareManager { | ||
| 33 | + static CNLiveDownloadManager *manager = nil; | ||
| 34 | + static dispatch_once_t onceToken; | ||
| 35 | + dispatch_once(&onceToken, ^{ | ||
| 36 | + manager = [[self alloc] init]; | ||
| 37 | + }); | ||
| 38 | + | ||
| 39 | + return manager; | ||
| 40 | +} | ||
| 41 | +- (instancetype)init | ||
| 42 | +{ | ||
| 43 | + if (self = [super init]) { | ||
| 44 | + // 初始化 | ||
| 45 | + _currentCount = 0; | ||
| 46 | + _maxConcurrentCount = 1; | ||
| 47 | + _allowsCellularAccess = NO; | ||
| 48 | + _dataTaskDic = [NSMutableDictionary dictionary]; | ||
| 49 | + _downloadTaskDic = [NSMutableDictionary dictionary]; | ||
| 50 | + // 单线程代理队列 | ||
| 51 | + NSOperationQueue *queue = [[NSOperationQueue alloc] init]; | ||
| 52 | + queue.maxConcurrentOperationCount = 1; | ||
| 53 | + // 后台下载标识 | ||
| 54 | + NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:@"CNDownloadBackgroundSessionIdentifier"]; | ||
| 55 | + // 允许蜂窝网络下载,默认为YES,这里开启,我们添加了一个变量去控制用户切换选择 | ||
| 56 | + configuration.allowsCellularAccess = YES; | ||
| 57 | + // 创建NSURLSession,配置信息、代理、代理线程 | ||
| 58 | + _session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:queue]; | ||
| 59 | + [self monitorTheNetwork]; | ||
| 60 | + [self startDownloadWaitingTask]; | ||
| 61 | + } | ||
| 62 | + | ||
| 63 | + return self; | ||
| 64 | +} | ||
| 65 | +#pragma mark -请求下载Url | ||
| 66 | +- (void)getDownloadUrl:(CNLiveAlbumAudioListModel *)model { | ||
| 67 | + self.isloading = YES; | ||
| 68 | + [[CNLiveVodUrlUtil manager] getVodUrlWithVid:model.activityId channelName:model.channelName sid:CNUserShareModelUid playType:@"a" tag:@"" completeBlock:^(NSString * _Nonnull vodUrl) { | ||
| 69 | + if (vodUrl) { | ||
| 70 | + model.url = vodUrl; | ||
| 71 | + self.isloading = NO; | ||
| 72 | + [self startDownloadTask:model]; | ||
| 73 | + }else { | ||
| 74 | + CNLiveAlbumAudioListModel *downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 75 | + if (!downloadModel) { | ||
| 76 | + [QMUITips showWithText:@"添加下载失败" inView:CNLiveAppKeyWindow hideAfterDelay:1.5f]; | ||
| 77 | + }else { | ||
| 78 | + downloadModel.state = CNDownloadStateError; | ||
| 79 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState | CNDBUpdateOptionLastStateTime]; | ||
| 80 | + } | ||
| 81 | + //请求失败,继续下载下一个等待的数据 | ||
| 82 | + self.isloading = NO; | ||
| 83 | + [self startDownloadWaitingTask]; | ||
| 84 | + } | ||
| 85 | + }]; | ||
| 86 | +} | ||
| 87 | +#pragma mark -加入准备下载任务 | ||
| 88 | +- (void)startDownloadTask:(CNLiveAlbumAudioListModel *)model | ||
| 89 | +{ | ||
| 90 | + __weak typeof(self) weakSelf = self; | ||
| 91 | + // 同一任务,1.0s内禁止重复调用 | ||
| 92 | + if ([[NSDate date] timeIntervalSinceDate:[weakSelf.downloadTaskDic valueForKey:model.activityId]] < 1.0f) return; | ||
| 93 | + if (!CNLiveStringIsEmpty(model.activityId)) { | ||
| 94 | + [weakSelf.downloadTaskDic setValue:[NSDate date] forKey:model.activityId]; | ||
| 95 | + } | ||
| 96 | + // 取出数据库中模型数据,如果不存在,添加到数据库中(注意:需要保证url唯一,若多条目同一url,则要另做处理) | ||
| 97 | + CNLiveAlbumAudioListModel *downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 98 | + if (!downloadModel) { | ||
| 99 | + downloadModel = model; | ||
| 100 | + [[CNLiveDataBaseManager shareManager] insertModel:downloadModel]; | ||
| 101 | + } | ||
| 102 | + // 更新状态为等待下载 | ||
| 103 | + downloadModel.url = model.url; | ||
| 104 | + downloadModel.state = CNDownloadStateWaiting; | ||
| 105 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState | CNDBUpdateOptionLastStateTime]; | ||
| 106 | + | ||
| 107 | + // 下载(给定一个等待时间,保证currentCount更新) | ||
| 108 | + [NSThread sleepForTimeInterval:0.1f]; | ||
| 109 | + if ((weakSelf.currentCount < weakSelf.maxConcurrentCount) && [weakSelf networkingAllowsDownloadTask]) | ||
| 110 | + { | ||
| 111 | + [weakSelf downloadwithModel:downloadModel]; | ||
| 112 | + } | ||
| 113 | +} | ||
| 114 | +#pragma mark -开始真正下载 | ||
| 115 | +- (void)downloadwithModel:(CNLiveAlbumAudioListModel *)model | ||
| 116 | +{ | ||
| 117 | + _currentCount++; | ||
| 118 | + // cancelByProducingResumeData:回调有延时,给定一个等待时间,重新获取模型,保证获取到resumeData | ||
| 119 | + [NSThread sleepForTimeInterval:0.3f]; | ||
| 120 | + CNLiveAlbumAudioListModel *downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 121 | + | ||
| 122 | + // 更新状态为开始 | ||
| 123 | + downloadModel.state = CNDownloadStateDownloading; | ||
| 124 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState]; | ||
| 125 | + | ||
| 126 | + // 创建NSURLSessionDownloadTask | ||
| 127 | + NSURLSessionDownloadTask *downloadTask; | ||
| 128 | + | ||
| 129 | + if (downloadModel.resumeData) { | ||
| 130 | + CGFloat version = [[[UIDevice currentDevice] systemVersion] floatValue]; | ||
| 131 | + if (version >= 10.0 && version < 10.2) { | ||
| 132 | + downloadTask = [_session downloadTaskWithCorrectResumeData:downloadModel.resumeData]; | ||
| 133 | + }else { | ||
| 134 | + downloadTask = [_session downloadTaskWithResumeData:downloadModel.resumeData]; | ||
| 135 | + } | ||
| 136 | + | ||
| 137 | + }else { | ||
| 138 | + downloadTask = [_session downloadTaskWithRequest:[NSURLRequest requestWithURL:[NSURL URLWithString:downloadModel.url]]]; | ||
| 139 | + } | ||
| 140 | + // 添加描述标签 | ||
| 141 | + downloadTask.taskDescription = downloadModel.url; | ||
| 142 | + | ||
| 143 | + // 更新存储的NSURLSessionDownloadTask对象 | ||
| 144 | + if (!CNLiveStringIsEmpty(downloadModel.activityId)) { | ||
| 145 | + [_dataTaskDic setValue:downloadTask forKey:downloadModel.activityId]; | ||
| 146 | + } | ||
| 147 | + // 启动(继续下载) | ||
| 148 | + [downloadTask resume]; | ||
| 149 | +} | ||
| 150 | +#pragma mark -全部暂停和没网的时候暂停下载中和等待的数据 | ||
| 151 | +- (void)pauseAllDownloadTask:(BOOL)isNoHaveNet{ | ||
| 152 | + __weak typeof(self) weakSelf = self; | ||
| 153 | + NSArray<CNLiveAlbumAudioListModel*> *downloadTasks = [[CNLiveDataBaseManager shareManager] getAllUnDownloadedData]; | ||
| 154 | + NSInteger count = downloadTasks.count; | ||
| 155 | + for(NSInteger i=0; i<count; i++){ | ||
| 156 | + CNLiveAlbumAudioListModel *model = downloadTasks[i]; | ||
| 157 | + // 取最新数据 | ||
| 158 | + CNLiveAlbumAudioListModel*downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 159 | + if(downloadModel.state == CNDownloadStateDownloading){ | ||
| 160 | + // 获取NSURLSessionDownloadTask | ||
| 161 | + NSURLSessionDownloadTask *downloadTask = [_dataTaskDic valueForKey:model.activityId]; | ||
| 162 | + [downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) { | ||
| 163 | + // 更新下载数据 | ||
| 164 | + model.resumeData = resumeData; | ||
| 165 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionResumeData]; | ||
| 166 | + // 更新当前正在下载的个数 | ||
| 167 | + self.isloading = NO; | ||
| 168 | + if (weakSelf.currentCount > 0) weakSelf.currentCount--; | ||
| 169 | + }]; | ||
| 170 | + if (!isNoHaveNet) { | ||
| 171 | + downloadModel.state = CNDownloadStatePaused; | ||
| 172 | + }else { | ||
| 173 | + downloadModel.state = CNDownloadStatePausedNoNetwork; | ||
| 174 | + } | ||
| 175 | + }else if (downloadModel.state == CNDownloadStateWaiting){ | ||
| 176 | + if (!isNoHaveNet) { | ||
| 177 | + downloadModel.state = CNDownloadStatePaused; | ||
| 178 | + }else{ | ||
| 179 | + downloadModel.state = CNDownloadStatePausedNoNetwork; | ||
| 180 | + } | ||
| 181 | + } | ||
| 182 | + // 更新数据库状态为暂停 | ||
| 183 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState]; | ||
| 184 | + } | ||
| 185 | +} | ||
| 186 | + | ||
| 187 | +#pragma mark -全部开始和无网的开始因无网暂停的下载 | ||
| 188 | +- (void)startAllDownloadTask:(BOOL)isHaveNoNet{ | ||
| 189 | + NSArray<CNLiveAlbumAudioListModel *> *downloadTasks = [[CNLiveDataBaseManager shareManager] getAllUnDownloadedData]; | ||
| 190 | + NSInteger count = downloadTasks.count; | ||
| 191 | + for(NSInteger i=0; i<count; i++){ | ||
| 192 | + CNLiveAlbumAudioListModel *model = downloadTasks[i]; | ||
| 193 | + // 取最新数据 | ||
| 194 | + CNLiveAlbumAudioListModel *downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 195 | + //暂停,默认,错误 | ||
| 196 | + if (!isHaveNoNet) { | ||
| 197 | + if(downloadModel.state == CNDownloadStatePaused || downloadModel.state == CNDownloadStatePausedNoNetwork ||downloadModel.state == CNDownloadStateDefault || downloadModel.state == CNDownloadStateError){ | ||
| 198 | + downloadModel.state = CNDownloadStateWaiting; | ||
| 199 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState | CNDBUpdateOptionLastStateTime]; | ||
| 200 | + } | ||
| 201 | + }else { | ||
| 202 | + if(downloadModel.state == CNDownloadStatePausedNoNetwork || downloadModel.state == CNDownloadStateDefault || downloadModel.state == CNDownloadStateError ){ | ||
| 203 | + downloadModel.state = CNDownloadStateWaiting; | ||
| 204 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState | CNDBUpdateOptionLastStateTime]; | ||
| 205 | + } | ||
| 206 | + } | ||
| 207 | + } | ||
| 208 | + [self startDownloadWaitingTask]; | ||
| 209 | + //获取等待下载的数据,开始下载 | ||
| 210 | +} | ||
| 211 | +#pragma mark -单条暂停 | ||
| 212 | +- (void)pauseDownloadTask:(CNLiveAlbumAudioListModel *)model | ||
| 213 | +{ | ||
| 214 | + // 取最新数据 | ||
| 215 | + CNLiveAlbumAudioListModel *downloadModel = [[CNLiveDataBaseManager shareManager] getModelwithActivityId:model.activityId]; | ||
| 216 | + | ||
| 217 | + // 取消任务 | ||
| 218 | + [self cancelTaskWithModel:downloadModel delete:NO]; | ||
| 219 | + | ||
| 220 | + // 更新数据库状态为暂停 | ||
| 221 | + downloadModel.state = CNDownloadStatePaused; | ||
| 222 | + [[CNLiveDataBaseManager shareManager] updateWithModel:downloadModel option:CNDBUpdateOptionState]; | ||
| 223 | +} | ||
| 224 | +#pragma mark 删除下载任务及本地缓存 | ||
| 225 | +- (void)deleteTaskAndCache:(CNLiveAlbumAudioListModel *)model | ||
| 226 | +{ | ||
| 227 | + // 如果正在下载,取消任务 | ||
| 228 | + [self cancelTaskWithModel:model delete:YES]; | ||
| 229 | + | ||
| 230 | + // 删除本地缓存、数据库数据 | ||
| 231 | + dispatch_async(dispatch_get_global_queue(0, 0), ^{ | ||
| 232 | + if (!CNLiveStringIsEmpty(model.localPath)) { | ||
| 233 | + [[NSFileManager defaultManager] removeItemAtPath:model.localPath error:nil]; | ||
| 234 | + [[CNLiveDataBaseManager shareManager] deleteModelWithUrl:model.activityId]; | ||
| 235 | + }else { | ||
| 236 | + [[CNLiveDataBaseManager shareManager] deleteModelWithUrl:model.activityId]; | ||
| 237 | + } | ||
| 238 | + }); | ||
| 239 | +} | ||
| 240 | + | ||
| 241 | +#pragma mark -取消任务 | ||
| 242 | +- (void)cancelTaskWithModel:(CNLiveAlbumAudioListModel *)model delete:(BOOL)delete | ||
| 243 | +{ | ||
| 244 | + __weak typeof(self) weakSelf = self; | ||
| 245 | + if (model.state == CNDownloadStateDownloading) { | ||
| 246 | + // 获取NSURLSessionDownloadTask | ||
| 247 | + NSURLSessionDownloadTask *downloadTask = [_dataTaskDic valueForKey:model.activityId]; | ||
| 248 | + | ||
| 249 | + // 取消任务 | ||
| 250 | + [downloadTask cancelByProducingResumeData:^(NSData * _Nullable resumeData) { | ||
| 251 | + // 更新下载数据 | ||
| 252 | + model.resumeData = resumeData; | ||
| 253 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionResumeData]; | ||
| 254 | + // 更新当前正在下载的个数 | ||
| 255 | + if (weakSelf.currentCount > 0) weakSelf.currentCount--; | ||
| 256 | + | ||
| 257 | + // 开启等待下载任务 | ||
| 258 | + [weakSelf startDownloadWaitingTask]; | ||
| 259 | + }]; | ||
| 260 | + | ||
| 261 | + // 移除字典存储的对象 | ||
| 262 | + if (delete) { | ||
| 263 | + if (!CNLiveStringIsEmpty(model.activityId)) { | ||
| 264 | + [_dataTaskDic removeObjectForKey:model.activityId]; | ||
| 265 | + [_downloadTaskDic removeObjectForKey:model.activityId]; | ||
| 266 | + } | ||
| 267 | + } | ||
| 268 | + } | ||
| 269 | +} | ||
| 270 | + | ||
| 271 | +#pragma mark - 开始下载等待任务 | ||
| 272 | +- (void)startDownloadWaitingTask | ||
| 273 | +{ | ||
| 274 | + self.isloading = NO; | ||
| 275 | + if ((_currentCount < _maxConcurrentCount) && [self networkingAllowsDownloadTask]) { | ||
| 276 | + // 获取下一条等待的数据 | ||
| 277 | + NSArray *array = [[CNLiveDataBaseManager shareManager] getAllWaitingData]; | ||
| 278 | + if (array.count > 0 && !self.isloading) { | ||
| 279 | + [self getDownloadUrl:array[0]]; | ||
| 280 | + } | ||
| 281 | + } | ||
| 282 | +} | ||
| 283 | + | ||
| 284 | +#pragma mark - NSURLSessionDownloadDelegate | ||
| 285 | +#pragma mark - 接收到服务器返回数据,会被调用多次 | ||
| 286 | +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didWriteData:(int64_t)bytesWritten totalBytesWritten:(int64_t)totalBytesWritten totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite | ||
| 287 | +{ | ||
| 288 | + // 获取模型 | ||
| 289 | + CNLiveAlbumAudioListModel *model = [[CNLiveDataBaseManager shareManager] getModelWithUrl:downloadTask.taskDescription]; | ||
| 290 | + | ||
| 291 | + // 更新当前下载大小 | ||
| 292 | + model.tmpFileSize = (NSUInteger)totalBytesWritten; | ||
| 293 | + model.totalFileSize = (NSUInteger)totalBytesExpectedToWrite; | ||
| 294 | + | ||
| 295 | + // 计算速度时间内下载文件的大小 | ||
| 296 | + model.intervalFileSize += (NSUInteger)bytesWritten; | ||
| 297 | + | ||
| 298 | + // 获取上次计算时间与当前时间间隔 | ||
| 299 | + NSInteger intervals = [CNLiveTimeTools getIntervalsWithTimeStamp:model.lastSpeedTime]; | ||
| 300 | + if (intervals >= 1) { | ||
| 301 | + // 计算速度 | ||
| 302 | + model.speed = model.intervalFileSize / intervals; | ||
| 303 | + | ||
| 304 | + // 重置变量 | ||
| 305 | + model.intervalFileSize = 0; | ||
| 306 | + model.lastSpeedTime = [CNLiveTimeTools getTimeStampWithDate:[NSDate date]]; | ||
| 307 | + } | ||
| 308 | + | ||
| 309 | + // 计算进度 | ||
| 310 | + model.progress = 1.0 * model.tmpFileSize / model.totalFileSize; | ||
| 311 | + | ||
| 312 | + // 更新数据库中数据 | ||
| 313 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionProgressData]; | ||
| 314 | + | ||
| 315 | + // 进度通知 | ||
| 316 | + [[NSNotificationCenter defaultCenter] postNotificationName:WjjAudioDownloadProgressNotification object:model]; | ||
| 317 | +} | ||
| 318 | + | ||
| 319 | +#pragma mark - 下载完成 | ||
| 320 | +- (void)URLSession:(NSURLSession *)session downloadTask:(NSURLSessionDownloadTask *)downloadTask didFinishDownloadingToURL:(NSURL *)location | ||
| 321 | +{ | ||
| 322 | + // 获取模型 | ||
| 323 | + CNLiveAlbumAudioListModel *model = [[CNLiveDataBaseManager shareManager] getModelWithUrl:downloadTask.taskDescription]; | ||
| 324 | + | ||
| 325 | + // 移动文件,原路径文件由系统自动删除 | ||
| 326 | + NSError *error = nil; | ||
| 327 | + NSFileManager *fileManager = [NSFileManager defaultManager]; | ||
| 328 | + NSString *path = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:[NSString stringWithFormat:@"albumAudioList_%@",model.albumId]]; | ||
| 329 | + if (![fileManager fileExistsAtPath:path]) { | ||
| 330 | + [fileManager createDirectoryAtPath:path withIntermediateDirectories:YES attributes:nil error:nil]; | ||
| 331 | + } | ||
| 332 | + if (!CNLiveStringIsEmpty(model.localPath)) { | ||
| 333 | + [fileManager moveItemAtPath:[location path] toPath:model.localPath error:&error]; | ||
| 334 | + } | ||
| 335 | + if (error) NSLog(@"下载完成,移动文件发生错误:%@ ---- %@", error,model.localPath); | ||
| 336 | +} | ||
| 337 | + | ||
| 338 | +#pragma mark - NSURLSessionTaskDelegate | ||
| 339 | +#pragma mark -请求完成 | ||
| 340 | +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error | ||
| 341 | +{ | ||
| 342 | + // 调用cancel方法直接返回,在相应操作是直接进行处理 | ||
| 343 | + if (error && [error.localizedDescription isEqualToString:@"cancelled"]) return; | ||
| 344 | + | ||
| 345 | + // 获取模型 | ||
| 346 | + CNLiveAlbumAudioListModel *model = [[CNLiveDataBaseManager shareManager] getModelWithUrl:task.taskDescription]; | ||
| 347 | + | ||
| 348 | + // 下载时进程杀死,重新启动时回调错误 | ||
| 349 | + if (error && [error.userInfo objectForKey:NSURLErrorBackgroundTaskCancelledReasonKey]) { | ||
| 350 | + model.state = CNDownloadStateWaiting; | ||
| 351 | + model.resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]; | ||
| 352 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionState | CNDBUpdateOptionResumeData]; | ||
| 353 | + return; | ||
| 354 | + } | ||
| 355 | + // 更新下载数据、任务状态 | ||
| 356 | + if (error) { | ||
| 357 | + model.state = CNDownloadStateError; | ||
| 358 | + model.resumeData = [error.userInfo objectForKey:NSURLSessionDownloadTaskResumeData]; | ||
| 359 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionResumeData]; | ||
| 360 | + | ||
| 361 | + }else { | ||
| 362 | + model.state = CNDownloadStateFinish; | ||
| 363 | + } | ||
| 364 | + | ||
| 365 | + // 更新数据 | ||
| 366 | + if (_currentCount > 0) _currentCount--; | ||
| 367 | + if (!CNLiveStringIsEmpty(model.activityId)) { | ||
| 368 | + [_dataTaskDic removeObjectForKey:model.activityId]; | ||
| 369 | + [_downloadTaskDic removeObjectForKey:model.activityId]; | ||
| 370 | + } | ||
| 371 | + // 更新数据库状态 | ||
| 372 | + [[CNLiveDataBaseManager shareManager] updateWithModel:model option:CNDBUpdateOptionState]; | ||
| 373 | + | ||
| 374 | + // 开启等待下载任务 | ||
| 375 | + [self startDownloadWaitingTask]; | ||
| 376 | + NSLog(@"\n 文件:%@,didCompleteWithError\n 本地路径:%@ \n 错误:%@ \n", model.title, model.localPath, error); | ||
| 377 | +} | ||
| 378 | + | ||
| 379 | +#pragma mark - NSURLSessionDelegate | ||
| 380 | +// 应用处于后台,所有下载任务完成及NSURLSession协议调用之后调用 | ||
| 381 | +//这个放在主工程delegate里实现 | ||
| 382 | +//- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session | ||
| 383 | +//{ | ||
| 384 | +// | ||
| 385 | +// dispatch_async(dispatch_get_main_queue(), ^{ | ||
| 386 | +// AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate]; | ||
| 387 | +// if (appDelegate.backgroundSessionCompletionHandler) { | ||
| 388 | +// void (^completionHandler)(void) = appDelegate.backgroundSessionCompletionHandler; | ||
| 389 | +// appDelegate.backgroundSessionCompletionHandler = nil; | ||
| 390 | +// // 执行block,系统后台生成快照,释放阻止应用挂起的断言 | ||
| 391 | +// completionHandler(); | ||
| 392 | +// } | ||
| 393 | +// }); | ||
| 394 | +//} | ||
| 395 | + | ||
| 396 | +// 判断是否有网络和是否同意了4G | ||
| 397 | +- (BOOL)networkingAllowsDownloadTask | ||
| 398 | +{ | ||
| 399 | + // 当前网络状态 | ||
| 400 | + // 无网络 或 (当前为蜂窝网络,且不允许蜂窝网络下载) | ||
| 401 | + if (![CNLiveNetworking isNetworking]&& !_allowsCellularAccess) { | ||
| 402 | + return NO; | ||
| 403 | + } | ||
| 404 | + return YES; | ||
| 405 | + | ||
| 406 | +} | ||
| 407 | +#pragma mark -添加网络通知 | ||
| 408 | +- (void)monitorTheNetwork { | ||
| 409 | + __weak typeof(self) weakSelf = self; | ||
| 410 | + [CNLiveDownloadManager networkStatusWithBlock:^(CNLiveNetworkStatusType status) { | ||
| 411 | + switch (status) { | ||
| 412 | + case CNLiveNetworkStatusNotReachable:{ | ||
| 413 | + NSLog(@"无网"); | ||
| 414 | + if ([[CNLiveDataBaseManager shareManager] getLastDownloadingModel]) { | ||
| 415 | + [weakSelf pauseAllDownloadTask:YES]; | ||
| 416 | + weakSelf.isNohaveNet = YES; //还要考虑4G切换到wifi和wifi切换到4G | ||
| 417 | + } | ||
| 418 | + } | ||
| 419 | + break; | ||
| 420 | + case CNLiveNetworkStatusUnknown:{ | ||
| 421 | + NSLog(@"未知网络"); | ||
| 422 | + if ([[CNLiveDataBaseManager shareManager] getLastDownloadingModel]) { | ||
| 423 | + [weakSelf pauseAllDownloadTask:YES]; | ||
| 424 | + weakSelf.isNohaveNet = YES; | ||
| 425 | + } | ||
| 426 | + } | ||
| 427 | + break; | ||
| 428 | + case CNLiveNetworkStatusReachableViaWiFi:{ | ||
| 429 | + NSLog(@"wifi"); | ||
| 430 | + if(weakSelf.isNohaveNet) { | ||
| 431 | + [weakSelf startAllDownloadTask:YES]; | ||
| 432 | + } | ||
| 433 | + } | ||
| 434 | + break; | ||
| 435 | + case CNLiveNetworkStatusReachableViaWWAN:{ | ||
| 436 | + NSLog(@"4G"); | ||
| 437 | + if (weakSelf.isNohaveNet && weakSelf.allowsCellularAccess ) { | ||
| 438 | + [weakSelf startAllDownloadTask:YES]; | ||
| 439 | + }else { | ||
| 440 | + if ([[CNLiveDataBaseManager shareManager] getLastDownloadingModel]) { | ||
| 441 | + [weakSelf pauseAllDownloadTask:YES]; | ||
| 442 | + weakSelf.isNohaveNet = YES; //还要考虑4G切换到wifi和wifi切换到4G | ||
| 443 | + [weakSelf showAlertView]; | ||
| 444 | + } | ||
| 445 | + } | ||
| 446 | + } | ||
| 447 | + break; | ||
| 448 | + default: | ||
| 449 | + break; | ||
| 450 | + } | ||
| 451 | + }]; | ||
| 452 | +} | ||
| 453 | +#pragma mark -IM连接成功通知 | ||
| 454 | +//- (void)IMConnectSucc { | ||
| 455 | +// [self addDownloadReachabilityManager]; | ||
| 456 | +//} | ||
| 457 | +#pragma mark -网络弹框 | ||
| 458 | +- (void)showAlertView { | ||
| 459 | + | ||
| 460 | + UIAlertView *alertView=[[UIAlertView alloc]initWithTitle:@"当前无Wifi,是否允许用流量继续下载" message:nil delegate:self cancelButtonTitle:@"取消" otherButtonTitles:@"继续下载", nil]; | ||
| 461 | + [alertView show]; | ||
| 462 | +} | ||
| 463 | + | ||
| 464 | +//监听点击事件 代理方法 | ||
| 465 | +- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex | ||
| 466 | +{ | ||
| 467 | + if (buttonIndex==0) { | ||
| 468 | + NSLog(@"你点击了取消"); | ||
| 469 | + } | ||
| 470 | + else if (buttonIndex==1) { | ||
| 471 | + _allowsCellularAccess = YES; | ||
| 472 | + [self startAllDownloadTask:YES]; | ||
| 473 | + } | ||
| 474 | +} | ||
| 475 | + | ||
| 476 | +- (void)dealloc | ||
| 477 | +{ | ||
| 478 | + [CNLiveDownloadManager removeNetworkStatue]; | ||
| 479 | + [_session invalidateAndCancel]; | ||
| 480 | + [[NSNotificationCenter defaultCenter] removeObserver:self]; | ||
| 481 | +} | ||
| 482 | + | ||
| 483 | +@end |
CNLiveDownloadManager/Classes/ViewModel/CNLiveMediaEditorNetworkManager.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveMediaEditorNetworkManager.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | + | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface CNLiveMediaEditorNetworkManager : NSObject | ||
| 13 | +/** | ||
| 14 | + * 设置超时时间 | ||
| 15 | + */ | ||
| 16 | +@property (nonatomic, assign) NSTimeInterval timeoutInterval; | ||
| 17 | + | ||
| 18 | +/** | ||
| 19 | + * 缓存策略 | ||
| 20 | + */ | ||
| 21 | +@property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; | ||
| 22 | + | ||
| 23 | ++ (nonnull CNLiveMediaEditorNetworkManager *)manager; | ||
| 24 | + | ||
| 25 | +/** | ||
| 26 | + * GET 请求 | ||
| 27 | + * @param URL | ||
| 28 | + * @param parameters 上传参数 | ||
| 29 | + * @param success 请求成功回调 | ||
| 30 | + * @param failure 请求失败回调 | ||
| 31 | + */ | ||
| 32 | +- (void)requestGetURL:(nullable NSString *)URL | ||
| 33 | + parameters:(nullable NSDictionary *)parameters | ||
| 34 | + success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success | ||
| 35 | + failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | ||
| 36 | + | ||
| 37 | +/** | ||
| 38 | + * POST 请求 | ||
| 39 | + * @param URL | ||
| 40 | + * @param parameters 上传参数 | ||
| 41 | + * @param success 请求成功回调 | ||
| 42 | + * @param failure 请求失败回调 | ||
| 43 | + */ | ||
| 44 | +- (void)requestPostURL:(nullable NSString *)URL | ||
| 45 | + parameters:(nullable NSDictionary *)parameters | ||
| 46 | + success:(nullable void (^)(NSURLResponse *_Nullable response, id _Nullable responseObject))success | ||
| 47 | + failure:(nullable void (^)(NSURLResponse *_Nullable response, NSError *_Nullable error))failure; | ||
| 48 | + | ||
| 49 | + | ||
| 50 | +/** | ||
| 51 | + * 用于获取播放地址 | ||
| 52 | + */ | ||
| 53 | +- (void)requestGetVideoURL:(nullable NSString *)URL | ||
| 54 | + success:(nullable void (^)(NSString *_Nullable videoURL))success; | ||
| 55 | + | ||
| 56 | + | ||
| 57 | +- (void)destroyNetManager; | ||
| 58 | +@end | ||
| 59 | + | ||
| 60 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/CNLiveMediaEditorNetworkManager.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveMediaEditorNetworkManager.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveMediaEditorNetworkManager.h" | ||
| 9 | +#import "CNLiveMediaEditorRequestSerialization.h" | ||
| 10 | +/** | ||
| 11 | + * 网络超时时间 默认 60 | ||
| 12 | + */ | ||
| 13 | +static NSTimeInterval TimeoutInterval = 30.0 ; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + * 缓存策略 | ||
| 17 | + * NSURLRequestUseProtocolCachePolicy // 默认的缓存策略(取决于协议) | ||
| 18 | + * NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求 | ||
| 19 | + * NSURLRequestReloadIgnoringLocalAndRemoteCacheData // 未实现 | ||
| 20 | + * NSURLRequestReloadIgnoringCacheData = NSURLRequestReloadIgnoringLocalCacheData // 忽略缓存,重新请求 | ||
| 21 | + * NSURLRequestReturnCacheDataElseLoad// 有缓存就用缓存,忽略过期时间!没有缓存就重新请求 | ||
| 22 | + * NSURLRequestReturnCacheDataDontLoad// 有缓存就用缓存,没有缓存就不发请求,当做请求出错处理(用于离线模式) | ||
| 23 | + * NSURLRequestReloadRevalidatingCacheData // 未实现 | ||
| 24 | + */ | ||
| 25 | +static NSURLRequestCachePolicy CachePolicy = NSURLRequestUseProtocolCachePolicy; | ||
| 26 | + | ||
| 27 | +typedef void(^GetVideoURLSuccessBlock)(NSString *_Nullable videoURL); | ||
| 28 | + | ||
| 29 | +@interface CNLiveMediaEditorNetworkManager ()<NSURLSessionDelegate> | ||
| 30 | +{ | ||
| 31 | + BOOL _result; | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +@property (nonatomic, copy) GetVideoURLSuccessBlock successBlock; | ||
| 35 | + | ||
| 36 | +@end | ||
| 37 | + | ||
| 38 | +@implementation CNLiveMediaEditorNetworkManager | ||
| 39 | + | ||
| 40 | +- (void)dealloc | ||
| 41 | +{ | ||
| 42 | + // D_NSLog(@">>>>>>>>>>>>>> CNLiveKSYNetworkManager dealloc"); | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +- (void)destroyNetManager { | ||
| 46 | + self.successBlock = nil; | ||
| 47 | + // D_NSLog(@">>>>>>>>>>>>>> destroyNetManager"); | ||
| 48 | + | ||
| 49 | +} | ||
| 50 | + | ||
| 51 | ++ (CNLiveMediaEditorNetworkManager *)manager | ||
| 52 | +{ | ||
| 53 | + static CNLiveMediaEditorNetworkManager *manager = nil; | ||
| 54 | + | ||
| 55 | + static dispatch_once_t predicate; | ||
| 56 | + | ||
| 57 | + dispatch_once(&predicate, ^{ | ||
| 58 | + | ||
| 59 | + manager = [[CNLiveMediaEditorNetworkManager alloc] init]; | ||
| 60 | + | ||
| 61 | + }); | ||
| 62 | + | ||
| 63 | + manager.cachePolicy = CachePolicy; | ||
| 64 | + | ||
| 65 | + manager.timeoutInterval = TimeoutInterval; | ||
| 66 | + | ||
| 67 | + return manager; | ||
| 68 | +} | ||
| 69 | + | ||
| 70 | +- (instancetype)init | ||
| 71 | +{ | ||
| 72 | + self = [super init]; | ||
| 73 | + if (self) { | ||
| 74 | + self.cachePolicy = CachePolicy; | ||
| 75 | + self.timeoutInterval = TimeoutInterval; | ||
| 76 | + } | ||
| 77 | + return self; | ||
| 78 | +} | ||
| 79 | + | ||
| 80 | +-(void)requestGetURL:(NSString *)URL | ||
| 81 | + parameters:(NSDictionary *)parameters | ||
| 82 | + success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success | ||
| 83 | + failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure | ||
| 84 | +{ | ||
| 85 | + NSURLSessionDataTask *task = [self dataTaskWithRequestMethod:@"GET" URLString:URL parameters:parameters success:success failure:failure]; | ||
| 86 | + [task resume]; | ||
| 87 | +} | ||
| 88 | + | ||
| 89 | +- (void)requestPostURL:(NSString *)URL | ||
| 90 | + parameters:(NSDictionary *)parameters | ||
| 91 | + success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success | ||
| 92 | + failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure | ||
| 93 | +{ | ||
| 94 | + NSURLSessionDataTask *task = [self dataTaskWithRequestMethod:@"POST" URLString:URL parameters:parameters success:success failure:failure]; | ||
| 95 | + [task resume]; | ||
| 96 | +} | ||
| 97 | + | ||
| 98 | +- (void)requestGetVideoURL:(NSString *)URL success:(void (^)(NSString * _Nullable))success { | ||
| 99 | + | ||
| 100 | + self.successBlock = success; | ||
| 101 | + _result = NO; | ||
| 102 | + | ||
| 103 | + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; | ||
| 104 | + | ||
| 105 | + NSURLSession *session = [NSURLSession sessionWithConfiguration:sessionConfig | ||
| 106 | + delegate:self | ||
| 107 | + delegateQueue:[[NSOperationQueue alloc] init]]; | ||
| 108 | + | ||
| 109 | + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:URL] cachePolicy:self.cachePolicy timeoutInterval:self.timeoutInterval]; | ||
| 110 | + | ||
| 111 | + NSURLSessionDataTask *task = [session dataTaskWithRequest:request]; | ||
| 112 | + | ||
| 113 | + // 启动任务 | ||
| 114 | + [task resume]; | ||
| 115 | +} | ||
| 116 | + | ||
| 117 | +#pragma mark - | ||
| 118 | +#pragma mark - NSURLSessionDelegate | ||
| 119 | +// 1.接收到服务器的响应 | ||
| 120 | +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveResponse:(NSURLResponse *)response completionHandler:(void (^)(NSURLSessionResponseDisposition))completionHandler { | ||
| 121 | + // 允许处理服务器的响应,才会继续接收服务器返回的数据 | ||
| 122 | + completionHandler(NSURLSessionResponseCancel); | ||
| 123 | + _result = YES; | ||
| 124 | + self.successBlock([response.URL absoluteString]); | ||
| 125 | + | ||
| 126 | +} | ||
| 127 | + | ||
| 128 | +// 3.请求成功或者失败(如果失败,error有值) | ||
| 129 | +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { | ||
| 130 | + // 请求完成,成功或者失败的处理 | ||
| 131 | + | ||
| 132 | + if (_result) return; | ||
| 133 | + | ||
| 134 | + NSString *videoUrl302 = error.userInfo[@"NSErrorFailingURLStringKey"]; | ||
| 135 | + if (!videoUrl302 || ![videoUrl302 isKindOfClass:[NSString class]] || videoUrl302.length <= 0) { | ||
| 136 | + videoUrl302 = nil; | ||
| 137 | + } | ||
| 138 | + self.successBlock(videoUrl302); | ||
| 139 | + | ||
| 140 | +} | ||
| 141 | + | ||
| 142 | + | ||
| 143 | +- (NSURLSessionDataTask *)dataTaskWithRequestMethod:(NSString *)method | ||
| 144 | + URLString:(NSString *)URLString | ||
| 145 | + parameters:(NSDictionary *)parameters | ||
| 146 | + success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success | ||
| 147 | + failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure | ||
| 148 | +{ | ||
| 149 | + | ||
| 150 | + if (![URLString isKindOfClass:[NSString class]]) { | ||
| 151 | + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"please enter a valid url"}]; | ||
| 152 | + failure(nil, error); | ||
| 153 | + return nil; | ||
| 154 | + } | ||
| 155 | + | ||
| 156 | + NSString *newURLString; | ||
| 157 | + if ([method isEqualToString:@"GET"]) { | ||
| 158 | + if (parameters) { | ||
| 159 | + newURLString = [[URLString stringByAppendingString:@"?"] stringByAppendingString:[CNLiveMediaEditorRequestSerialization CNNetPlusQueryStringFromParameters:parameters]]; | ||
| 160 | + }else{ | ||
| 161 | + newURLString = URLString; | ||
| 162 | + } | ||
| 163 | + }else{ | ||
| 164 | + newURLString = URLString; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:newURLString] cachePolicy:self.cachePolicy timeoutInterval:self.timeoutInterval]; | ||
| 168 | + | ||
| 169 | + request.HTTPMethod = method; | ||
| 170 | + | ||
| 171 | + if([method isEqual:@"POST"]){ | ||
| 172 | + [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; | ||
| 173 | + request.HTTPBody =[[CNLiveMediaEditorRequestSerialization CNNetPlusQueryStringFromParameters:parameters] dataUsingEncoding:NSUTF8StringEncoding]; | ||
| 174 | + } | ||
| 175 | + | ||
| 176 | + NSURLSessionDataTask *task = [self dataTaskWithRequest:request success:success failure:failure]; | ||
| 177 | + | ||
| 178 | + return task; | ||
| 179 | +} | ||
| 180 | + | ||
| 181 | +- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request | ||
| 182 | + success:(void (^)(NSURLResponse * _Nullable, id _Nullable))success | ||
| 183 | + failure:(void (^)(NSURLResponse * _Nullable, NSError * _Nullable))failure | ||
| 184 | +{ | ||
| 185 | + NSURLSession *session = [NSURLSession sharedSession]; | ||
| 186 | + NSURLSessionDataTask *task = [session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) { | ||
| 187 | + | ||
| 188 | + dispatch_async(dispatch_get_main_queue(), ^{ | ||
| 189 | + if (error) { | ||
| 190 | + failure(response,error); | ||
| 191 | + }else{ | ||
| 192 | + if ([response isKindOfClass:[NSHTTPURLResponse class]]) { | ||
| 193 | + NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; | ||
| 194 | + if (httpResponse.statusCode < 400) { | ||
| 195 | + id jsonObj = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:nil]; | ||
| 196 | + success(httpResponse,jsonObj); | ||
| 197 | + } else { | ||
| 198 | + NSError *failureError = [NSError errorWithDomain:NSURLErrorDomain code:httpResponse.statusCode userInfo:httpResponse.allHeaderFields]; | ||
| 199 | + failure(httpResponse,failureError); | ||
| 200 | + } | ||
| 201 | + } else { | ||
| 202 | + failure(response,error); | ||
| 203 | + } | ||
| 204 | + } | ||
| 205 | + }); | ||
| 206 | + }]; | ||
| 207 | + | ||
| 208 | + return task; | ||
| 209 | +} | ||
| 210 | + | ||
| 211 | +- (NSURL *)formatURLString:(NSString *)url | ||
| 212 | +{ | ||
| 213 | + NSURL *urlString = [NSURL URLWithString:[url stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]]; | ||
| 214 | + return urlString; | ||
| 215 | +} | ||
| 216 | + | ||
| 217 | +@end | ||
| 218 | + |
CNLiveDownloadManager/Classes/ViewModel/CNLiveMediaEditorRequestSerialization.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveMediaEditorRequestSerialization.h | ||
| 3 | +// CNLiveBaseKit | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | + | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface CNLiveMediaEditorRequestSerialization : NSObject | ||
| 13 | ++ (nullable NSString *)CNNetPlusQueryStringFromParameters:(nullable NSDictionary *)parameters; | ||
| 14 | +@end | ||
| 15 | + | ||
| 16 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/CNLiveMediaEditorRequestSerialization.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveMediaEditorRequestSerialization.m | ||
| 3 | +// CNLiveBaseKit | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveMediaEditorRequestSerialization.h" | ||
| 9 | + | ||
| 10 | +@interface CNLiveMediaEditorRequestSerialization () | ||
| 11 | +@property (readwrite, nonatomic, strong) id value; | ||
| 12 | + | ||
| 13 | +@property (readwrite, nonatomic, strong) id field; | ||
| 14 | +@end | ||
| 15 | + | ||
| 16 | +@implementation CNLiveMediaEditorRequestSerialization | ||
| 17 | +- (id)initWithField:(id)field value:(id)value | ||
| 18 | +{ | ||
| 19 | + self = [super init]; | ||
| 20 | + | ||
| 21 | + if (self) { | ||
| 22 | + | ||
| 23 | + self.field = field; | ||
| 24 | + | ||
| 25 | + self.value = value; | ||
| 26 | + } | ||
| 27 | + | ||
| 28 | + return self; | ||
| 29 | + | ||
| 30 | +} | ||
| 31 | +#pragma mark - | ||
| 32 | + | ||
| 33 | +FOUNDATION_EXPORT NSArray * CNNetPlusQueryStringPairsFromDictionary(NSDictionary *dictionary); | ||
| 34 | +FOUNDATION_EXPORT NSArray * CNNetPlusQueryStringPairsFromKeyAndValue(NSString *key, id value); | ||
| 35 | + | ||
| 36 | ++ (NSString *)CNNetPlusQueryStringFromParameters:(NSDictionary *)parameters | ||
| 37 | +{ | ||
| 38 | + NSMutableArray *mutablePairs = [NSMutableArray array]; | ||
| 39 | + for (CNLiveMediaEditorRequestSerialization *pair in CNNetPlusQueryStringPairsFromDictionary(parameters)) { | ||
| 40 | + [mutablePairs addObject:[pair URLEncodedStringValue]]; | ||
| 41 | + } | ||
| 42 | + return [mutablePairs componentsJoinedByString:@"&"]; | ||
| 43 | +} | ||
| 44 | + | ||
| 45 | +NSArray * CNNetPlusQueryStringPairsFromDictionary(NSDictionary *dictionary) | ||
| 46 | +{ | ||
| 47 | + return CNNetPlusQueryStringPairsFromKeyAndValue(nil, dictionary); | ||
| 48 | +} | ||
| 49 | + | ||
| 50 | +/** | ||
| 51 | + * 处理上传参数 | ||
| 52 | + */ | ||
| 53 | +NSArray * CNNetPlusQueryStringPairsFromKeyAndValue(NSString *key, id value) | ||
| 54 | +{ | ||
| 55 | + NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; | ||
| 56 | + | ||
| 57 | + //排序方式 | ||
| 58 | + NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)]; | ||
| 59 | + | ||
| 60 | + if ([value isKindOfClass:[NSDictionary class]]) { //字典 | ||
| 61 | + NSDictionary *dictionary = value; | ||
| 62 | + for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[sortDescriptor]]) { | ||
| 63 | + id nestedValue = dictionary[nestedKey]; | ||
| 64 | + if (nestedKey) { | ||
| 65 | + [mutableQueryStringComponents addObjectsFromArray:CNNetPlusQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; | ||
| 66 | + } | ||
| 67 | + } | ||
| 68 | + } | ||
| 69 | + | ||
| 70 | + else if ([value isKindOfClass:[NSArray class]]){ //数组 | ||
| 71 | + NSArray *array = value; | ||
| 72 | + for (id nestedValue in array) { | ||
| 73 | + [mutableQueryStringComponents addObjectsFromArray:CNNetPlusQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; | ||
| 74 | + } | ||
| 75 | + }else if ([value isKindOfClass:[NSSet class]]){ //集合 | ||
| 76 | + NSSet *set = value; | ||
| 77 | + for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { | ||
| 78 | + [mutableQueryStringComponents addObjectsFromArray:CNNetPlusQueryStringPairsFromKeyAndValue(key, obj)]; | ||
| 79 | + } | ||
| 80 | + }else{ //其他类型 | ||
| 81 | + [mutableQueryStringComponents addObject:[[CNLiveMediaEditorRequestSerialization alloc] initWithField:key value:value]]; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + return mutableQueryStringComponents; | ||
| 85 | +} | ||
| 86 | + | ||
| 87 | +static NSString * CNNetPlusPercentEscapedStringFromString(NSString *string) { | ||
| 88 | + static NSString * const kCNNetPlusCharactersGeneralDelimitersToEncode = @":#[]@"; // does not include "?" or "/" due to RFC 3986 - Section 3.4 | ||
| 89 | + static NSString * const kCNNetPlusCharactersSubDelimitersToEncode = @"!$&'()*+,;="; | ||
| 90 | + | ||
| 91 | + NSMutableCharacterSet * allowedCharacterSet = [[NSCharacterSet URLQueryAllowedCharacterSet] mutableCopy]; | ||
| 92 | + [allowedCharacterSet removeCharactersInString:[kCNNetPlusCharactersGeneralDelimitersToEncode stringByAppendingString:kCNNetPlusCharactersSubDelimitersToEncode]]; | ||
| 93 | + | ||
| 94 | + | ||
| 95 | + static NSUInteger const batchSize = 50; | ||
| 96 | + | ||
| 97 | + NSUInteger index = 0; | ||
| 98 | + NSMutableString *escaped = @"".mutableCopy; | ||
| 99 | + | ||
| 100 | + while (index < string.length) { | ||
| 101 | +#pragma GCC diagnostic push | ||
| 102 | +#pragma GCC diagnostic ignored "-Wgnu" | ||
| 103 | + NSUInteger length = MIN(string.length - index, batchSize); | ||
| 104 | +#pragma GCC diagnostic pop | ||
| 105 | + NSRange range = NSMakeRange(index, length); | ||
| 106 | + | ||
| 107 | + range = [string rangeOfComposedCharacterSequencesForRange:range]; | ||
| 108 | + | ||
| 109 | + NSString *substring = [string substringWithRange:range]; | ||
| 110 | + NSString *encoded = [substring stringByAddingPercentEncodingWithAllowedCharacters:allowedCharacterSet]; | ||
| 111 | + [escaped appendString:encoded]; | ||
| 112 | + | ||
| 113 | + index += range.length; | ||
| 114 | + } | ||
| 115 | + | ||
| 116 | + return escaped; | ||
| 117 | +} | ||
| 118 | + | ||
| 119 | +- (NSString *)URLEncodedStringValue { | ||
| 120 | + if (!self.value || [self.value isEqual:[NSNull null]]) { | ||
| 121 | + return CNNetPlusPercentEscapedStringFromString([self.field description]); | ||
| 122 | + } else { | ||
| 123 | + return [NSString stringWithFormat:@"%@=%@", CNNetPlusPercentEscapedStringFromString([self.field description]), CNNetPlusPercentEscapedStringFromString([self.value description])]; | ||
| 124 | + } | ||
| 125 | +} | ||
| 126 | + | ||
| 127 | +@end |
CNLiveDownloadManager/Classes/ViewModel/CNLiveVodUrlUtil.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveVodUrlUtil.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import <Foundation/Foundation.h> | ||
| 9 | + | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface CNLiveVodUrlUtil : NSObject | ||
| 13 | ++ (instancetype)manager; | ||
| 14 | + | ||
| 15 | +/** | ||
| 16 | + 获取点播内容url | ||
| 17 | + | ||
| 18 | + @param vId 内容id | ||
| 19 | + @param channelName 频道名称 | ||
| 20 | + @param sid UserId | ||
| 21 | + @param playType 音频:"a" 视频:"v" | ||
| 22 | + @param tag 非必传 | ||
| 23 | + @param completeBlock 回调 | ||
| 24 | + */ | ||
| 25 | +- (void)getVodUrlWithVid:(NSString *)vId channelName:(NSString *)channelName sid:(NSString *)sid playType:(NSString *)playType tag:(NSString *)tag completeBlock:(void(^)(NSString *vodUrl))completeBlock; | ||
| 26 | +@end | ||
| 27 | + | ||
| 28 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/CNLiveVodUrlUtil.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveVodUrlUtil.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "CNLiveVodUrlUtil.h" | ||
| 9 | +#import "CNLiveMediaEditorNetworkManager.h" | ||
| 10 | +#import "CNEnvironmentHeader.h" | ||
| 11 | +#import "CNLiveBusinessTools.h" | ||
| 12 | +#import "NetworkAPIs.h" | ||
| 13 | +@implementation CNLiveVodUrlUtil | ||
| 14 | ++ (instancetype)manager { | ||
| 15 | + static CNLiveVodUrlUtil *instance = nil; | ||
| 16 | + static dispatch_once_t onceToken; | ||
| 17 | + | ||
| 18 | + dispatch_once(&onceToken, ^{ | ||
| 19 | + instance = [[self alloc] init]; | ||
| 20 | + }); | ||
| 21 | + return instance; | ||
| 22 | +} | ||
| 23 | + | ||
| 24 | +- (void)getVodUrlWithVid:(NSString *)vId channelName:(NSString *)channelName sid:(NSString *)sid playType:(NSString *)playType tag:(NSString *)tag completeBlock:(void(^)(NSString *vodUrl))completeBlock | ||
| 25 | +{ | ||
| 26 | + NSInteger time = [[NSDate date] timeIntervalSince1970]; | ||
| 27 | + NSString *timeString = [NSString stringWithFormat:@"%ld", (long)time]; | ||
| 28 | + | ||
| 29 | + NSString *timestamp = timeString; | ||
| 30 | + NSString *appId = AppId; | ||
| 31 | + | ||
| 32 | + NSString *uid = [CNLiveBusinessTools getUidForStat:timestamp]; | ||
| 33 | + ////playType @"a": @"v" | ||
| 34 | + //// | ||
| 35 | + NSDictionary *parameter1 = @{@"appId": appId, | ||
| 36 | + @"vId": vId?vId:@"", | ||
| 37 | + @"timestamp": timestamp, | ||
| 38 | + @"isHLS": @"1", | ||
| 39 | + @"plat": @"i", | ||
| 40 | + @"playType": playType ? playType: @"", | ||
| 41 | + @"platform_id": [NSBundle mainBundle].bundleIdentifier, | ||
| 42 | + @"channelName": channelName?channelName:@"", | ||
| 43 | + @"tag": tag?tag:@"", | ||
| 44 | + @"from": @"apple", @"sid":sid?sid:@"", | ||
| 45 | + @"uid": uid?uid:@""}; | ||
| 46 | + | ||
| 47 | + NSString *string1 = [NSString stringWithFormat:@"%@&key=%@", [CNLiveBusinessTools signvalue:parameter1], APPKey]; | ||
| 48 | + NSString *signString1 = [[CNLiveBusinessTools sha1:string1] uppercaseString]; | ||
| 49 | + | ||
| 50 | + NSString *videourl1 = [NSString stringWithFormat:@"%@?%@&sign=%@", CNGetVodUrl, [CNLiveBusinessTools signvalue:parameter1], signString1]; | ||
| 51 | + | ||
| 52 | + CNLiveMediaEditorNetworkManager *manager = [[CNLiveMediaEditorNetworkManager alloc] init]; | ||
| 53 | + | ||
| 54 | + [manager requestGetVideoURL:videourl1 success:^(NSString * _Nullable videoURL) { | ||
| 55 | + dispatch_async(dispatch_get_main_queue(), ^{ | ||
| 56 | + if (completeBlock) { | ||
| 57 | + completeBlock(videoURL); | ||
| 58 | + } | ||
| 59 | + }); | ||
| 60 | + }]; | ||
| 61 | +} | ||
| 62 | + | ||
| 63 | +@end |
CNLiveDownloadManager/Classes/ViewModel/NSURLSession+CNLiveCorrectedResumeData.h
0 → 100644
| 1 | +// | ||
| 2 | +// NSURLSession+CNLiveCorrectedResumeData.h | ||
| 3 | +// CNLiveBaseKit | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | + | ||
| 9 | + | ||
| 10 | +NS_ASSUME_NONNULL_BEGIN | ||
| 11 | + | ||
| 12 | +@interface NSURLSession (CNLiveCorrectedResumeData) | ||
| 13 | +- (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData; | ||
| 14 | +@end | ||
| 15 | + | ||
| 16 | +NS_ASSUME_NONNULL_END |
CNLiveDownloadManager/Classes/ViewModel/NSURLSession+CNLiveCorrectedResumeData.m
0 → 100644
| 1 | +// | ||
| 2 | +// NSURLSession+CNLiveCorrectedResumeData.m | ||
| 3 | +// CNLiveBaseKit | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 2019/6/3. | ||
| 6 | +// | ||
| 7 | + | ||
| 8 | +#import "NSURLSession+CNLiveCorrectedResumeData.h" | ||
| 9 | +static NSString *const resumeCurrentRequest = @"NSURLSessionResumeCurrentRequest"; | ||
| 10 | +static NSString *const resumeOriginalRequest = @"NSURLSessionResumeOriginalRequest"; | ||
| 11 | +@implementation NSURLSession (CNLiveCorrectedResumeData) | ||
| 12 | +- (NSURLSessionDownloadTask *)downloadTaskWithCorrectResumeData:(NSData *)resumeData | ||
| 13 | +{ | ||
| 14 | + NSData *data = [self getCorrectResumeDataWithData:resumeData]; | ||
| 15 | + data = data ? data : resumeData; | ||
| 16 | + NSURLSessionDownloadTask *task = [self downloadTaskWithResumeData:data]; | ||
| 17 | + NSMutableDictionary *resumeDic = [self getResumeDictionaryWithData:data]; | ||
| 18 | + | ||
| 19 | + if (resumeDic) { | ||
| 20 | + if (!task.originalRequest) { | ||
| 21 | + NSData *originalReqData = resumeDic[resumeOriginalRequest]; | ||
| 22 | + NSURLRequest *originalRequest = [NSKeyedUnarchiver unarchiveObjectWithData:originalReqData]; | ||
| 23 | + if (originalRequest) [task setValue:originalRequest forKey:@"originalRequest"]; | ||
| 24 | + } | ||
| 25 | + if (!task.currentRequest) { | ||
| 26 | + NSData *currentReqData = resumeDic[resumeCurrentRequest]; | ||
| 27 | + NSURLRequest *currentRequest = [NSKeyedUnarchiver unarchiveObjectWithData:currentReqData]; | ||
| 28 | + if (currentRequest) [task setValue:currentRequest forKey:@"currentRequest"]; | ||
| 29 | + } | ||
| 30 | + } | ||
| 31 | + | ||
| 32 | + return task; | ||
| 33 | +} | ||
| 34 | + | ||
| 35 | +- (NSData *)getCorrectResumeDataWithData:(NSData *)data | ||
| 36 | +{ | ||
| 37 | + if (!data) return nil; | ||
| 38 | + | ||
| 39 | + NSMutableDictionary *resumeDictionary = [self getResumeDictionaryWithData:data]; | ||
| 40 | + if (!resumeDictionary) return nil; | ||
| 41 | + | ||
| 42 | + resumeDictionary[resumeCurrentRequest] = [self getCorrectRequestDataWithData:resumeDictionary[resumeCurrentRequest]]; | ||
| 43 | + resumeDictionary[resumeOriginalRequest] = [self getCorrectRequestDataWithData:resumeDictionary[resumeOriginalRequest]]; | ||
| 44 | + | ||
| 45 | + return [NSPropertyListSerialization dataWithPropertyList:resumeDictionary format:NSPropertyListXMLFormat_v1_0 options:0 error:nil]; | ||
| 46 | +} | ||
| 47 | + | ||
| 48 | +- (NSMutableDictionary *)getResumeDictionaryWithData:(NSData *)data | ||
| 49 | +{ | ||
| 50 | + return [NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil]; | ||
| 51 | +} | ||
| 52 | + | ||
| 53 | +- (NSData *)getCorrectRequestDataWithData:(NSData *)data | ||
| 54 | +{ | ||
| 55 | + if (!data) return nil; | ||
| 56 | + | ||
| 57 | + if ([NSKeyedUnarchiver unarchiveObjectWithData:data]) return data; | ||
| 58 | + | ||
| 59 | + NSMutableDictionary *archive = [[NSPropertyListSerialization propertyListWithData:data options:NSPropertyListMutableContainersAndLeaves format:nil error:nil] mutableCopy]; | ||
| 60 | + if (!archive) return nil; | ||
| 61 | + | ||
| 62 | + NSInteger i = 0; | ||
| 63 | + id objectss = archive[@"$objects"]; | ||
| 64 | + while ([objectss[1] objectForKey:[NSString stringWithFormat:@"$%ld", i]]) { | ||
| 65 | + i++; | ||
| 66 | + } | ||
| 67 | + | ||
| 68 | + NSInteger j = 0; | ||
| 69 | + while ([archive[@"$objects"][1] objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]]) { | ||
| 70 | + NSMutableArray *array = archive[@"$objects"]; | ||
| 71 | + NSMutableDictionary *dic = array[1]; | ||
| 72 | + id obj = [dic objectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]]; | ||
| 73 | + if (obj) { | ||
| 74 | + [dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld", i + j]]; | ||
| 75 | + [dic removeObjectForKey:[NSString stringWithFormat:@"__nsurlrequest_proto_prop_obj_%ld", j]]; | ||
| 76 | + [array replaceObjectAtIndex:1 withObject:dic]; | ||
| 77 | + archive[@"$objects"] = array; | ||
| 78 | + } | ||
| 79 | + j++; | ||
| 80 | + } | ||
| 81 | + | ||
| 82 | + if ([archive[@"$objects"][1] objectForKey:@"__nsurlrequest_proto_props"]) { | ||
| 83 | + NSMutableArray *array = archive[@"$objects"]; | ||
| 84 | + NSMutableDictionary *dic = array[1]; | ||
| 85 | + id obj = [dic objectForKey:@"__nsurlrequest_proto_props"]; | ||
| 86 | + if (obj) { | ||
| 87 | + [dic setValue:obj forKey:[NSString stringWithFormat:@"$%ld", i + j]]; | ||
| 88 | + [dic removeObjectForKey:@"__nsurlrequest_proto_props"]; | ||
| 89 | + [array replaceObjectAtIndex:1 withObject:dic]; | ||
| 90 | + archive[@"$objects"] = array; | ||
| 91 | + } | ||
| 92 | + } | ||
| 93 | + | ||
| 94 | + if ([archive[@"$top"] objectForKey:@"NSKeyedArchiveRootObjectKey"]) { | ||
| 95 | + [archive[@"$top"] setObject:archive[@"$top"][@"NSKeyedArchiveRootObjectKey"] forKey: NSKeyedArchiveRootObjectKey]; | ||
| 96 | + [archive[@"$top"] removeObjectForKey:@"NSKeyedArchiveRootObjectKey"]; | ||
| 97 | + } | ||
| 98 | + | ||
| 99 | + return [NSPropertyListSerialization dataWithPropertyList:archive format:NSPropertyListBinaryFormat_v1_0 options:0 error:nil]; | ||
| 100 | +} | ||
| 101 | +@end |
Example/CNLiveDownloadManager.xcodeproj/project.pbxproj
0 → 100644
| 1 | +// !$*UTF8*$! | ||
| 2 | +{ | ||
| 3 | + archiveVersion = 1; | ||
| 4 | + classes = { | ||
| 5 | + }; | ||
| 6 | + objectVersion = 46; | ||
| 7 | + objects = { | ||
| 8 | + | ||
| 9 | +/* Begin PBXBuildFile section */ | ||
| 10 | + 3A484E3A8C834C0D7D28435D /* Pods_CNLiveDownloadManager_Example.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 94E0BBF4750718BCFD83CAE0 /* Pods_CNLiveDownloadManager_Example.framework */; }; | ||
| 11 | + 412D189855F76D0811C34BFE /* Pods_CNLiveDownloadManager_Tests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = E3D7A50D9FAB850D3C44A064 /* Pods_CNLiveDownloadManager_Tests.framework */; }; | ||
| 12 | + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; | ||
| 13 | + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58F195388D20070C39A /* CoreGraphics.framework */; }; | ||
| 14 | + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; | ||
| 15 | + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F596195388D20070C39A /* InfoPlist.strings */; }; | ||
| 16 | + 6003F59A195388D20070C39A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F599195388D20070C39A /* main.m */; }; | ||
| 17 | + 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */; }; | ||
| 18 | + 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5A6195388D20070C39A /* CNLiveViewController.m */; }; | ||
| 19 | + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5A8195388D20070C39A /* Images.xcassets */; }; | ||
| 20 | + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F5AF195388D20070C39A /* XCTest.framework */; }; | ||
| 21 | + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F58D195388D20070C39A /* Foundation.framework */; }; | ||
| 22 | + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6003F591195388D20070C39A /* UIKit.framework */; }; | ||
| 23 | + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 6003F5B8195388D20070C39A /* InfoPlist.strings */; }; | ||
| 24 | + 6003F5BC195388D20070C39A /* Tests.m in Sources */ = {isa = PBXBuildFile; fileRef = 6003F5BB195388D20070C39A /* Tests.m */; }; | ||
| 25 | + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */; }; | ||
| 26 | + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */; }; | ||
| 27 | +/* End PBXBuildFile section */ | ||
| 28 | + | ||
| 29 | +/* Begin PBXContainerItemProxy section */ | ||
| 30 | + 6003F5B3195388D20070C39A /* PBXContainerItemProxy */ = { | ||
| 31 | + isa = PBXContainerItemProxy; | ||
| 32 | + containerPortal = 6003F582195388D10070C39A /* Project object */; | ||
| 33 | + proxyType = 1; | ||
| 34 | + remoteGlobalIDString = 6003F589195388D20070C39A; | ||
| 35 | + remoteInfo = CNLiveDownloadManager; | ||
| 36 | + }; | ||
| 37 | +/* End PBXContainerItemProxy section */ | ||
| 38 | + | ||
| 39 | +/* Begin PBXFileReference section */ | ||
| 40 | + 25F58E15CCB760285426BA4B /* CNLiveDownloadManager.podspec */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = CNLiveDownloadManager.podspec; path = ../CNLiveDownloadManager.podspec; sourceTree = "<group>"; xcLanguageSpecificationIdentifier = xcode.lang.ruby; }; | ||
| 41 | + 4E591664CF796F923B830DF3 /* Pods-CNLiveDownloadManager_Example.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveDownloadManager_Example.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveDownloadManager_Example/Pods-CNLiveDownloadManager_Example.release.xcconfig"; sourceTree = "<group>"; }; | ||
| 42 | + 56C6C35211FE6387AC196F94 /* Pods-CNLiveDownloadManager_Example.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveDownloadManager_Example.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveDownloadManager_Example/Pods-CNLiveDownloadManager_Example.debug.xcconfig"; sourceTree = "<group>"; }; | ||
| 43 | + 6003F58A195388D20070C39A /* CNLiveDownloadManager_Example.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CNLiveDownloadManager_Example.app; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 44 | + 6003F58D195388D20070C39A /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; }; | ||
| 45 | + 6003F58F195388D20070C39A /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; }; | ||
| 46 | + 6003F591195388D20070C39A /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; | ||
| 47 | + 6003F595195388D20070C39A /* CNLiveDownloadManager-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "CNLiveDownloadManager-Info.plist"; sourceTree = "<group>"; }; | ||
| 48 | + 6003F597195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; | ||
| 49 | + 6003F599195388D20070C39A /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; }; | ||
| 50 | + 6003F59B195388D20070C39A /* CNLiveDownloadManager-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "CNLiveDownloadManager-Prefix.pch"; sourceTree = "<group>"; }; | ||
| 51 | + 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveAppDelegate.h; sourceTree = "<group>"; }; | ||
| 52 | + 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveAppDelegate.m; sourceTree = "<group>"; }; | ||
| 53 | + 6003F5A5195388D20070C39A /* CNLiveViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CNLiveViewController.h; sourceTree = "<group>"; }; | ||
| 54 | + 6003F5A6195388D20070C39A /* CNLiveViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = CNLiveViewController.m; sourceTree = "<group>"; }; | ||
| 55 | + 6003F5A8195388D20070C39A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = "<group>"; }; | ||
| 56 | + 6003F5AE195388D20070C39A /* CNLiveDownloadManager_Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CNLiveDownloadManager_Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 57 | + 6003F5AF195388D20070C39A /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; | ||
| 58 | + 6003F5B7195388D20070C39A /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; }; | ||
| 59 | + 6003F5B9195388D20070C39A /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; }; | ||
| 60 | + 6003F5BB195388D20070C39A /* Tests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = Tests.m; sourceTree = "<group>"; }; | ||
| 61 | + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; }; | ||
| 62 | + 71719F9E1E33DC2100824A3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; }; | ||
| 63 | + 72041DDD913A10D596ECFEEE /* Pods-CNLiveDownloadManager_Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveDownloadManager_Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveDownloadManager_Tests/Pods-CNLiveDownloadManager_Tests.debug.xcconfig"; sourceTree = "<group>"; }; | ||
| 64 | + 82FC0100889995D212B4E376 /* README.md */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = net.daringfireball.markdown; name = README.md; path = ../README.md; sourceTree = "<group>"; }; | ||
| 65 | + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = Main.storyboard; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; }; | ||
| 66 | + 94E0BBF4750718BCFD83CAE0 /* Pods_CNLiveDownloadManager_Example.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveDownloadManager_Example.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 67 | + BF5F74A07CE41BEC53E597F0 /* Pods-CNLiveDownloadManager_Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-CNLiveDownloadManager_Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-CNLiveDownloadManager_Tests/Pods-CNLiveDownloadManager_Tests.release.xcconfig"; sourceTree = "<group>"; }; | ||
| 68 | + CEE8B05CD80963DD46D613E0 /* LICENSE */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text; name = LICENSE; path = ../LICENSE; sourceTree = "<group>"; }; | ||
| 69 | + E3D7A50D9FAB850D3C44A064 /* Pods_CNLiveDownloadManager_Tests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_CNLiveDownloadManager_Tests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; | ||
| 70 | +/* End PBXFileReference section */ | ||
| 71 | + | ||
| 72 | +/* Begin PBXFrameworksBuildPhase section */ | ||
| 73 | + 6003F587195388D20070C39A /* Frameworks */ = { | ||
| 74 | + isa = PBXFrameworksBuildPhase; | ||
| 75 | + buildActionMask = 2147483647; | ||
| 76 | + files = ( | ||
| 77 | + 6003F590195388D20070C39A /* CoreGraphics.framework in Frameworks */, | ||
| 78 | + 6003F592195388D20070C39A /* UIKit.framework in Frameworks */, | ||
| 79 | + 6003F58E195388D20070C39A /* Foundation.framework in Frameworks */, | ||
| 80 | + 3A484E3A8C834C0D7D28435D /* Pods_CNLiveDownloadManager_Example.framework in Frameworks */, | ||
| 81 | + ); | ||
| 82 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 83 | + }; | ||
| 84 | + 6003F5AB195388D20070C39A /* Frameworks */ = { | ||
| 85 | + isa = PBXFrameworksBuildPhase; | ||
| 86 | + buildActionMask = 2147483647; | ||
| 87 | + files = ( | ||
| 88 | + 6003F5B0195388D20070C39A /* XCTest.framework in Frameworks */, | ||
| 89 | + 6003F5B2195388D20070C39A /* UIKit.framework in Frameworks */, | ||
| 90 | + 6003F5B1195388D20070C39A /* Foundation.framework in Frameworks */, | ||
| 91 | + 412D189855F76D0811C34BFE /* Pods_CNLiveDownloadManager_Tests.framework in Frameworks */, | ||
| 92 | + ); | ||
| 93 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 94 | + }; | ||
| 95 | +/* End PBXFrameworksBuildPhase section */ | ||
| 96 | + | ||
| 97 | +/* Begin PBXGroup section */ | ||
| 98 | + 19D326128EE4D599D6324204 /* Pods */ = { | ||
| 99 | + isa = PBXGroup; | ||
| 100 | + children = ( | ||
| 101 | + 56C6C35211FE6387AC196F94 /* Pods-CNLiveDownloadManager_Example.debug.xcconfig */, | ||
| 102 | + 4E591664CF796F923B830DF3 /* Pods-CNLiveDownloadManager_Example.release.xcconfig */, | ||
| 103 | + 72041DDD913A10D596ECFEEE /* Pods-CNLiveDownloadManager_Tests.debug.xcconfig */, | ||
| 104 | + BF5F74A07CE41BEC53E597F0 /* Pods-CNLiveDownloadManager_Tests.release.xcconfig */, | ||
| 105 | + ); | ||
| 106 | + name = Pods; | ||
| 107 | + sourceTree = "<group>"; | ||
| 108 | + }; | ||
| 109 | + 6003F581195388D10070C39A = { | ||
| 110 | + isa = PBXGroup; | ||
| 111 | + children = ( | ||
| 112 | + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */, | ||
| 113 | + 6003F593195388D20070C39A /* Example for CNLiveDownloadManager */, | ||
| 114 | + 6003F5B5195388D20070C39A /* Tests */, | ||
| 115 | + 6003F58C195388D20070C39A /* Frameworks */, | ||
| 116 | + 6003F58B195388D20070C39A /* Products */, | ||
| 117 | + 19D326128EE4D599D6324204 /* Pods */, | ||
| 118 | + ); | ||
| 119 | + sourceTree = "<group>"; | ||
| 120 | + }; | ||
| 121 | + 6003F58B195388D20070C39A /* Products */ = { | ||
| 122 | + isa = PBXGroup; | ||
| 123 | + children = ( | ||
| 124 | + 6003F58A195388D20070C39A /* CNLiveDownloadManager_Example.app */, | ||
| 125 | + 6003F5AE195388D20070C39A /* CNLiveDownloadManager_Tests.xctest */, | ||
| 126 | + ); | ||
| 127 | + name = Products; | ||
| 128 | + sourceTree = "<group>"; | ||
| 129 | + }; | ||
| 130 | + 6003F58C195388D20070C39A /* Frameworks */ = { | ||
| 131 | + isa = PBXGroup; | ||
| 132 | + children = ( | ||
| 133 | + 6003F58D195388D20070C39A /* Foundation.framework */, | ||
| 134 | + 6003F58F195388D20070C39A /* CoreGraphics.framework */, | ||
| 135 | + 6003F591195388D20070C39A /* UIKit.framework */, | ||
| 136 | + 6003F5AF195388D20070C39A /* XCTest.framework */, | ||
| 137 | + 94E0BBF4750718BCFD83CAE0 /* Pods_CNLiveDownloadManager_Example.framework */, | ||
| 138 | + E3D7A50D9FAB850D3C44A064 /* Pods_CNLiveDownloadManager_Tests.framework */, | ||
| 139 | + ); | ||
| 140 | + name = Frameworks; | ||
| 141 | + sourceTree = "<group>"; | ||
| 142 | + }; | ||
| 143 | + 6003F593195388D20070C39A /* Example for CNLiveDownloadManager */ = { | ||
| 144 | + isa = PBXGroup; | ||
| 145 | + children = ( | ||
| 146 | + 6003F59C195388D20070C39A /* CNLiveAppDelegate.h */, | ||
| 147 | + 6003F59D195388D20070C39A /* CNLiveAppDelegate.m */, | ||
| 148 | + 873B8AEA1B1F5CCA007FD442 /* Main.storyboard */, | ||
| 149 | + 6003F5A5195388D20070C39A /* CNLiveViewController.h */, | ||
| 150 | + 6003F5A6195388D20070C39A /* CNLiveViewController.m */, | ||
| 151 | + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */, | ||
| 152 | + 6003F5A8195388D20070C39A /* Images.xcassets */, | ||
| 153 | + 6003F594195388D20070C39A /* Supporting Files */, | ||
| 154 | + ); | ||
| 155 | + name = "Example for CNLiveDownloadManager"; | ||
| 156 | + path = CNLiveDownloadManager; | ||
| 157 | + sourceTree = "<group>"; | ||
| 158 | + }; | ||
| 159 | + 6003F594195388D20070C39A /* Supporting Files */ = { | ||
| 160 | + isa = PBXGroup; | ||
| 161 | + children = ( | ||
| 162 | + 6003F595195388D20070C39A /* CNLiveDownloadManager-Info.plist */, | ||
| 163 | + 6003F596195388D20070C39A /* InfoPlist.strings */, | ||
| 164 | + 6003F599195388D20070C39A /* main.m */, | ||
| 165 | + 6003F59B195388D20070C39A /* CNLiveDownloadManager-Prefix.pch */, | ||
| 166 | + ); | ||
| 167 | + name = "Supporting Files"; | ||
| 168 | + sourceTree = "<group>"; | ||
| 169 | + }; | ||
| 170 | + 6003F5B5195388D20070C39A /* Tests */ = { | ||
| 171 | + isa = PBXGroup; | ||
| 172 | + children = ( | ||
| 173 | + 6003F5BB195388D20070C39A /* Tests.m */, | ||
| 174 | + 6003F5B6195388D20070C39A /* Supporting Files */, | ||
| 175 | + ); | ||
| 176 | + path = Tests; | ||
| 177 | + sourceTree = "<group>"; | ||
| 178 | + }; | ||
| 179 | + 6003F5B6195388D20070C39A /* Supporting Files */ = { | ||
| 180 | + isa = PBXGroup; | ||
| 181 | + children = ( | ||
| 182 | + 6003F5B7195388D20070C39A /* Tests-Info.plist */, | ||
| 183 | + 6003F5B8195388D20070C39A /* InfoPlist.strings */, | ||
| 184 | + 606FC2411953D9B200FFA9A0 /* Tests-Prefix.pch */, | ||
| 185 | + ); | ||
| 186 | + name = "Supporting Files"; | ||
| 187 | + sourceTree = "<group>"; | ||
| 188 | + }; | ||
| 189 | + 60FF7A9C1954A5C5007DD14C /* Podspec Metadata */ = { | ||
| 190 | + isa = PBXGroup; | ||
| 191 | + children = ( | ||
| 192 | + 25F58E15CCB760285426BA4B /* CNLiveDownloadManager.podspec */, | ||
| 193 | + 82FC0100889995D212B4E376 /* README.md */, | ||
| 194 | + CEE8B05CD80963DD46D613E0 /* LICENSE */, | ||
| 195 | + ); | ||
| 196 | + name = "Podspec Metadata"; | ||
| 197 | + sourceTree = "<group>"; | ||
| 198 | + }; | ||
| 199 | +/* End PBXGroup section */ | ||
| 200 | + | ||
| 201 | +/* Begin PBXNativeTarget section */ | ||
| 202 | + 6003F589195388D20070C39A /* CNLiveDownloadManager_Example */ = { | ||
| 203 | + isa = PBXNativeTarget; | ||
| 204 | + buildConfigurationList = 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveDownloadManager_Example" */; | ||
| 205 | + buildPhases = ( | ||
| 206 | + 56D85D721C5939967106CB00 /* [CP] Check Pods Manifest.lock */, | ||
| 207 | + 6003F586195388D20070C39A /* Sources */, | ||
| 208 | + 6003F587195388D20070C39A /* Frameworks */, | ||
| 209 | + 6003F588195388D20070C39A /* Resources */, | ||
| 210 | + FD4AA0BF8DE86B4A432A5A0A /* [CP] Embed Pods Frameworks */, | ||
| 211 | + ); | ||
| 212 | + buildRules = ( | ||
| 213 | + ); | ||
| 214 | + dependencies = ( | ||
| 215 | + ); | ||
| 216 | + name = CNLiveDownloadManager_Example; | ||
| 217 | + productName = CNLiveDownloadManager; | ||
| 218 | + productReference = 6003F58A195388D20070C39A /* CNLiveDownloadManager_Example.app */; | ||
| 219 | + productType = "com.apple.product-type.application"; | ||
| 220 | + }; | ||
| 221 | + 6003F5AD195388D20070C39A /* CNLiveDownloadManager_Tests */ = { | ||
| 222 | + isa = PBXNativeTarget; | ||
| 223 | + buildConfigurationList = 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveDownloadManager_Tests" */; | ||
| 224 | + buildPhases = ( | ||
| 225 | + 8E7E18814F68BFFC19474C88 /* [CP] Check Pods Manifest.lock */, | ||
| 226 | + 6003F5AA195388D20070C39A /* Sources */, | ||
| 227 | + 6003F5AB195388D20070C39A /* Frameworks */, | ||
| 228 | + 6003F5AC195388D20070C39A /* Resources */, | ||
| 229 | + B90EAAB187AC920C2FDA35C2 /* [CP] Embed Pods Frameworks */, | ||
| 230 | + ); | ||
| 231 | + buildRules = ( | ||
| 232 | + ); | ||
| 233 | + dependencies = ( | ||
| 234 | + 6003F5B4195388D20070C39A /* PBXTargetDependency */, | ||
| 235 | + ); | ||
| 236 | + name = CNLiveDownloadManager_Tests; | ||
| 237 | + productName = CNLiveDownloadManagerTests; | ||
| 238 | + productReference = 6003F5AE195388D20070C39A /* CNLiveDownloadManager_Tests.xctest */; | ||
| 239 | + productType = "com.apple.product-type.bundle.unit-test"; | ||
| 240 | + }; | ||
| 241 | +/* End PBXNativeTarget section */ | ||
| 242 | + | ||
| 243 | +/* Begin PBXProject section */ | ||
| 244 | + 6003F582195388D10070C39A /* Project object */ = { | ||
| 245 | + isa = PBXProject; | ||
| 246 | + attributes = { | ||
| 247 | + CLASSPREFIX = CNLive; | ||
| 248 | + LastUpgradeCheck = 0720; | ||
| 249 | + ORGANIZATIONNAME = "殷巧娟"; | ||
| 250 | + TargetAttributes = { | ||
| 251 | + 6003F589195388D20070C39A = { | ||
| 252 | + DevelopmentTeam = 94X49GG3ZW; | ||
| 253 | + }; | ||
| 254 | + 6003F5AD195388D20070C39A = { | ||
| 255 | + TestTargetID = 6003F589195388D20070C39A; | ||
| 256 | + }; | ||
| 257 | + }; | ||
| 258 | + }; | ||
| 259 | + buildConfigurationList = 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveDownloadManager" */; | ||
| 260 | + compatibilityVersion = "Xcode 3.2"; | ||
| 261 | + developmentRegion = English; | ||
| 262 | + hasScannedForEncodings = 0; | ||
| 263 | + knownRegions = ( | ||
| 264 | + en, | ||
| 265 | + Base, | ||
| 266 | + ); | ||
| 267 | + mainGroup = 6003F581195388D10070C39A; | ||
| 268 | + productRefGroup = 6003F58B195388D20070C39A /* Products */; | ||
| 269 | + projectDirPath = ""; | ||
| 270 | + projectRoot = ""; | ||
| 271 | + targets = ( | ||
| 272 | + 6003F589195388D20070C39A /* CNLiveDownloadManager_Example */, | ||
| 273 | + 6003F5AD195388D20070C39A /* CNLiveDownloadManager_Tests */, | ||
| 274 | + ); | ||
| 275 | + }; | ||
| 276 | +/* End PBXProject section */ | ||
| 277 | + | ||
| 278 | +/* Begin PBXResourcesBuildPhase section */ | ||
| 279 | + 6003F588195388D20070C39A /* Resources */ = { | ||
| 280 | + isa = PBXResourcesBuildPhase; | ||
| 281 | + buildActionMask = 2147483647; | ||
| 282 | + files = ( | ||
| 283 | + 873B8AEB1B1F5CCA007FD442 /* Main.storyboard in Resources */, | ||
| 284 | + 71719F9F1E33DC2100824A3D /* LaunchScreen.storyboard in Resources */, | ||
| 285 | + 6003F5A9195388D20070C39A /* Images.xcassets in Resources */, | ||
| 286 | + 6003F598195388D20070C39A /* InfoPlist.strings in Resources */, | ||
| 287 | + ); | ||
| 288 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 289 | + }; | ||
| 290 | + 6003F5AC195388D20070C39A /* Resources */ = { | ||
| 291 | + isa = PBXResourcesBuildPhase; | ||
| 292 | + buildActionMask = 2147483647; | ||
| 293 | + files = ( | ||
| 294 | + 6003F5BA195388D20070C39A /* InfoPlist.strings in Resources */, | ||
| 295 | + ); | ||
| 296 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 297 | + }; | ||
| 298 | +/* End PBXResourcesBuildPhase section */ | ||
| 299 | + | ||
| 300 | +/* Begin PBXShellScriptBuildPhase section */ | ||
| 301 | + 56D85D721C5939967106CB00 /* [CP] Check Pods Manifest.lock */ = { | ||
| 302 | + isa = PBXShellScriptBuildPhase; | ||
| 303 | + buildActionMask = 2147483647; | ||
| 304 | + files = ( | ||
| 305 | + ); | ||
| 306 | + inputFileListPaths = ( | ||
| 307 | + ); | ||
| 308 | + inputPaths = ( | ||
| 309 | + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | ||
| 310 | + "${PODS_ROOT}/Manifest.lock", | ||
| 311 | + ); | ||
| 312 | + name = "[CP] Check Pods Manifest.lock"; | ||
| 313 | + outputFileListPaths = ( | ||
| 314 | + ); | ||
| 315 | + outputPaths = ( | ||
| 316 | + "$(DERIVED_FILE_DIR)/Pods-CNLiveDownloadManager_Example-checkManifestLockResult.txt", | ||
| 317 | + ); | ||
| 318 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 319 | + shellPath = /bin/sh; | ||
| 320 | + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | ||
| 321 | + showEnvVarsInLog = 0; | ||
| 322 | + }; | ||
| 323 | + 8E7E18814F68BFFC19474C88 /* [CP] Check Pods Manifest.lock */ = { | ||
| 324 | + isa = PBXShellScriptBuildPhase; | ||
| 325 | + buildActionMask = 2147483647; | ||
| 326 | + files = ( | ||
| 327 | + ); | ||
| 328 | + inputFileListPaths = ( | ||
| 329 | + ); | ||
| 330 | + inputPaths = ( | ||
| 331 | + "${PODS_PODFILE_DIR_PATH}/Podfile.lock", | ||
| 332 | + "${PODS_ROOT}/Manifest.lock", | ||
| 333 | + ); | ||
| 334 | + name = "[CP] Check Pods Manifest.lock"; | ||
| 335 | + outputFileListPaths = ( | ||
| 336 | + ); | ||
| 337 | + outputPaths = ( | ||
| 338 | + "$(DERIVED_FILE_DIR)/Pods-CNLiveDownloadManager_Tests-checkManifestLockResult.txt", | ||
| 339 | + ); | ||
| 340 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 341 | + shellPath = /bin/sh; | ||
| 342 | + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; | ||
| 343 | + showEnvVarsInLog = 0; | ||
| 344 | + }; | ||
| 345 | + B90EAAB187AC920C2FDA35C2 /* [CP] Embed Pods Frameworks */ = { | ||
| 346 | + isa = PBXShellScriptBuildPhase; | ||
| 347 | + buildActionMask = 2147483647; | ||
| 348 | + files = ( | ||
| 349 | + ); | ||
| 350 | + inputFileListPaths = ( | ||
| 351 | + ); | ||
| 352 | + inputPaths = ( | ||
| 353 | + "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveDownloadManager_Tests/Pods-CNLiveDownloadManager_Tests-frameworks.sh", | ||
| 354 | + "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", | ||
| 355 | + "${BUILT_PRODUCTS_DIR}/CNLiveBaseKit/CNLiveBaseKit.framework", | ||
| 356 | + "${BUILT_PRODUCTS_DIR}/CNLiveBaseTools/CNLiveBaseTools.framework", | ||
| 357 | + "${BUILT_PRODUCTS_DIR}/CNLiveBusinessTools/CNLiveBusinessTools.framework", | ||
| 358 | + "${BUILT_PRODUCTS_DIR}/CNLiveRequestBastKit/CNLiveRequestBastKit.framework", | ||
| 359 | + "${BUILT_PRODUCTS_DIR}/CNLiveTripartiteManagement/CNLiveTripartiteManagement.framework", | ||
| 360 | + "${BUILT_PRODUCTS_DIR}/CNLiveUserManagement/CNLiveUserManagement.framework", | ||
| 361 | + "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", | ||
| 362 | + "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework", | ||
| 363 | + "${BUILT_PRODUCTS_DIR}/QMUIKit/QMUIKit.framework", | ||
| 364 | + ); | ||
| 365 | + name = "[CP] Embed Pods Frameworks"; | ||
| 366 | + outputFileListPaths = ( | ||
| 367 | + ); | ||
| 368 | + outputPaths = ( | ||
| 369 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework", | ||
| 370 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBaseKit.framework", | ||
| 371 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBaseTools.framework", | ||
| 372 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBusinessTools.framework", | ||
| 373 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveRequestBastKit.framework", | ||
| 374 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveTripartiteManagement.framework", | ||
| 375 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveUserManagement.framework", | ||
| 376 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", | ||
| 377 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework", | ||
| 378 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QMUIKit.framework", | ||
| 379 | + ); | ||
| 380 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 381 | + shellPath = /bin/sh; | ||
| 382 | + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveDownloadManager_Tests/Pods-CNLiveDownloadManager_Tests-frameworks.sh\"\n"; | ||
| 383 | + showEnvVarsInLog = 0; | ||
| 384 | + }; | ||
| 385 | + FD4AA0BF8DE86B4A432A5A0A /* [CP] Embed Pods Frameworks */ = { | ||
| 386 | + isa = PBXShellScriptBuildPhase; | ||
| 387 | + buildActionMask = 2147483647; | ||
| 388 | + files = ( | ||
| 389 | + ); | ||
| 390 | + inputFileListPaths = ( | ||
| 391 | + ); | ||
| 392 | + inputPaths = ( | ||
| 393 | + "${SRCROOT}/Pods/Target Support Files/Pods-CNLiveDownloadManager_Example/Pods-CNLiveDownloadManager_Example-frameworks.sh", | ||
| 394 | + "${BUILT_PRODUCTS_DIR}/AFNetworking/AFNetworking.framework", | ||
| 395 | + "${BUILT_PRODUCTS_DIR}/CNLiveBaseKit/CNLiveBaseKit.framework", | ||
| 396 | + "${BUILT_PRODUCTS_DIR}/CNLiveBaseTools/CNLiveBaseTools.framework", | ||
| 397 | + "${BUILT_PRODUCTS_DIR}/CNLiveBusinessTools/CNLiveBusinessTools.framework", | ||
| 398 | + "${BUILT_PRODUCTS_DIR}/CNLiveDownloadManager/CNLiveDownloadManager.framework", | ||
| 399 | + "${BUILT_PRODUCTS_DIR}/CNLiveRequestBastKit/CNLiveRequestBastKit.framework", | ||
| 400 | + "${BUILT_PRODUCTS_DIR}/CNLiveTripartiteManagement/CNLiveTripartiteManagement.framework", | ||
| 401 | + "${BUILT_PRODUCTS_DIR}/CNLiveUserManagement/CNLiveUserManagement.framework", | ||
| 402 | + "${BUILT_PRODUCTS_DIR}/FMDB/FMDB.framework", | ||
| 403 | + "${BUILT_PRODUCTS_DIR}/MJExtension/MJExtension.framework", | ||
| 404 | + "${BUILT_PRODUCTS_DIR}/QMUIKit/QMUIKit.framework", | ||
| 405 | + ); | ||
| 406 | + name = "[CP] Embed Pods Frameworks"; | ||
| 407 | + outputFileListPaths = ( | ||
| 408 | + ); | ||
| 409 | + outputPaths = ( | ||
| 410 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/AFNetworking.framework", | ||
| 411 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBaseKit.framework", | ||
| 412 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBaseTools.framework", | ||
| 413 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveBusinessTools.framework", | ||
| 414 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveDownloadManager.framework", | ||
| 415 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveRequestBastKit.framework", | ||
| 416 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveTripartiteManagement.framework", | ||
| 417 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/CNLiveUserManagement.framework", | ||
| 418 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/FMDB.framework", | ||
| 419 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/MJExtension.framework", | ||
| 420 | + "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/QMUIKit.framework", | ||
| 421 | + ); | ||
| 422 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 423 | + shellPath = /bin/sh; | ||
| 424 | + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-CNLiveDownloadManager_Example/Pods-CNLiveDownloadManager_Example-frameworks.sh\"\n"; | ||
| 425 | + showEnvVarsInLog = 0; | ||
| 426 | + }; | ||
| 427 | +/* End PBXShellScriptBuildPhase section */ | ||
| 428 | + | ||
| 429 | +/* Begin PBXSourcesBuildPhase section */ | ||
| 430 | + 6003F586195388D20070C39A /* Sources */ = { | ||
| 431 | + isa = PBXSourcesBuildPhase; | ||
| 432 | + buildActionMask = 2147483647; | ||
| 433 | + files = ( | ||
| 434 | + 6003F59E195388D20070C39A /* CNLiveAppDelegate.m in Sources */, | ||
| 435 | + 6003F5A7195388D20070C39A /* CNLiveViewController.m in Sources */, | ||
| 436 | + 6003F59A195388D20070C39A /* main.m in Sources */, | ||
| 437 | + ); | ||
| 438 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 439 | + }; | ||
| 440 | + 6003F5AA195388D20070C39A /* Sources */ = { | ||
| 441 | + isa = PBXSourcesBuildPhase; | ||
| 442 | + buildActionMask = 2147483647; | ||
| 443 | + files = ( | ||
| 444 | + 6003F5BC195388D20070C39A /* Tests.m in Sources */, | ||
| 445 | + ); | ||
| 446 | + runOnlyForDeploymentPostprocessing = 0; | ||
| 447 | + }; | ||
| 448 | +/* End PBXSourcesBuildPhase section */ | ||
| 449 | + | ||
| 450 | +/* Begin PBXTargetDependency section */ | ||
| 451 | + 6003F5B4195388D20070C39A /* PBXTargetDependency */ = { | ||
| 452 | + isa = PBXTargetDependency; | ||
| 453 | + target = 6003F589195388D20070C39A /* CNLiveDownloadManager_Example */; | ||
| 454 | + targetProxy = 6003F5B3195388D20070C39A /* PBXContainerItemProxy */; | ||
| 455 | + }; | ||
| 456 | +/* End PBXTargetDependency section */ | ||
| 457 | + | ||
| 458 | +/* Begin PBXVariantGroup section */ | ||
| 459 | + 6003F596195388D20070C39A /* InfoPlist.strings */ = { | ||
| 460 | + isa = PBXVariantGroup; | ||
| 461 | + children = ( | ||
| 462 | + 6003F597195388D20070C39A /* en */, | ||
| 463 | + ); | ||
| 464 | + name = InfoPlist.strings; | ||
| 465 | + sourceTree = "<group>"; | ||
| 466 | + }; | ||
| 467 | + 6003F5B8195388D20070C39A /* InfoPlist.strings */ = { | ||
| 468 | + isa = PBXVariantGroup; | ||
| 469 | + children = ( | ||
| 470 | + 6003F5B9195388D20070C39A /* en */, | ||
| 471 | + ); | ||
| 472 | + name = InfoPlist.strings; | ||
| 473 | + sourceTree = "<group>"; | ||
| 474 | + }; | ||
| 475 | + 71719F9D1E33DC2100824A3D /* LaunchScreen.storyboard */ = { | ||
| 476 | + isa = PBXVariantGroup; | ||
| 477 | + children = ( | ||
| 478 | + 71719F9E1E33DC2100824A3D /* Base */, | ||
| 479 | + ); | ||
| 480 | + name = LaunchScreen.storyboard; | ||
| 481 | + sourceTree = "<group>"; | ||
| 482 | + }; | ||
| 483 | +/* End PBXVariantGroup section */ | ||
| 484 | + | ||
| 485 | +/* Begin XCBuildConfiguration section */ | ||
| 486 | + 6003F5BD195388D20070C39A /* Debug */ = { | ||
| 487 | + isa = XCBuildConfiguration; | ||
| 488 | + buildSettings = { | ||
| 489 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 490 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 491 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 492 | + CLANG_ENABLE_MODULES = YES; | ||
| 493 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 494 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 495 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 496 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 497 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 498 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 499 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 500 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 501 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 502 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 503 | + COPY_PHASE_STRIP = NO; | ||
| 504 | + ENABLE_TESTABILITY = YES; | ||
| 505 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 506 | + GCC_DYNAMIC_NO_PIC = NO; | ||
| 507 | + GCC_OPTIMIZATION_LEVEL = 0; | ||
| 508 | + GCC_PREPROCESSOR_DEFINITIONS = ( | ||
| 509 | + "DEBUG=1", | ||
| 510 | + "$(inherited)", | ||
| 511 | + ); | ||
| 512 | + GCC_SYMBOLS_PRIVATE_EXTERN = NO; | ||
| 513 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 514 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 515 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 516 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 517 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 518 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 519 | + IPHONEOS_DEPLOYMENT_TARGET = 9.3; | ||
| 520 | + ONLY_ACTIVE_ARCH = YES; | ||
| 521 | + SDKROOT = iphoneos; | ||
| 522 | + TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 523 | + }; | ||
| 524 | + name = Debug; | ||
| 525 | + }; | ||
| 526 | + 6003F5BE195388D20070C39A /* Release */ = { | ||
| 527 | + isa = XCBuildConfiguration; | ||
| 528 | + buildSettings = { | ||
| 529 | + ALWAYS_SEARCH_USER_PATHS = NO; | ||
| 530 | + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; | ||
| 531 | + CLANG_CXX_LIBRARY = "libc++"; | ||
| 532 | + CLANG_ENABLE_MODULES = YES; | ||
| 533 | + CLANG_ENABLE_OBJC_ARC = YES; | ||
| 534 | + CLANG_WARN_BOOL_CONVERSION = YES; | ||
| 535 | + CLANG_WARN_CONSTANT_CONVERSION = YES; | ||
| 536 | + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; | ||
| 537 | + CLANG_WARN_EMPTY_BODY = YES; | ||
| 538 | + CLANG_WARN_ENUM_CONVERSION = YES; | ||
| 539 | + CLANG_WARN_INT_CONVERSION = YES; | ||
| 540 | + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; | ||
| 541 | + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; | ||
| 542 | + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; | ||
| 543 | + COPY_PHASE_STRIP = YES; | ||
| 544 | + ENABLE_NS_ASSERTIONS = NO; | ||
| 545 | + GCC_C_LANGUAGE_STANDARD = gnu99; | ||
| 546 | + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; | ||
| 547 | + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; | ||
| 548 | + GCC_WARN_UNDECLARED_SELECTOR = YES; | ||
| 549 | + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; | ||
| 550 | + GCC_WARN_UNUSED_FUNCTION = YES; | ||
| 551 | + GCC_WARN_UNUSED_VARIABLE = YES; | ||
| 552 | + IPHONEOS_DEPLOYMENT_TARGET = 9.3; | ||
| 553 | + SDKROOT = iphoneos; | ||
| 554 | + TARGETED_DEVICE_FAMILY = "1,2"; | ||
| 555 | + VALIDATE_PRODUCT = YES; | ||
| 556 | + }; | ||
| 557 | + name = Release; | ||
| 558 | + }; | ||
| 559 | + 6003F5C0195388D20070C39A /* Debug */ = { | ||
| 560 | + isa = XCBuildConfiguration; | ||
| 561 | + baseConfigurationReference = 56C6C35211FE6387AC196F94 /* Pods-CNLiveDownloadManager_Example.debug.xcconfig */; | ||
| 562 | + buildSettings = { | ||
| 563 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 564 | + DEVELOPMENT_TEAM = 94X49GG3ZW; | ||
| 565 | + GCC_PRECOMPILE_PREFIX_HEADER = YES; | ||
| 566 | + GCC_PREFIX_HEADER = "CNLiveDownloadManager/CNLiveDownloadManager-Prefix.pch"; | ||
| 567 | + INFOPLIST_FILE = "CNLiveDownloadManager/CNLiveDownloadManager-Info.plist"; | ||
| 568 | + IPHONEOS_DEPLOYMENT_TARGET = 9.0; | ||
| 569 | + MODULE_NAME = ExampleApp; | ||
| 570 | + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; | ||
| 571 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 572 | + WRAPPER_EXTENSION = app; | ||
| 573 | + }; | ||
| 574 | + name = Debug; | ||
| 575 | + }; | ||
| 576 | + 6003F5C1195388D20070C39A /* Release */ = { | ||
| 577 | + isa = XCBuildConfiguration; | ||
| 578 | + baseConfigurationReference = 4E591664CF796F923B830DF3 /* Pods-CNLiveDownloadManager_Example.release.xcconfig */; | ||
| 579 | + buildSettings = { | ||
| 580 | + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; | ||
| 581 | + DEVELOPMENT_TEAM = 94X49GG3ZW; | ||
| 582 | + GCC_PRECOMPILE_PREFIX_HEADER = YES; | ||
| 583 | + GCC_PREFIX_HEADER = "CNLiveDownloadManager/CNLiveDownloadManager-Prefix.pch"; | ||
| 584 | + INFOPLIST_FILE = "CNLiveDownloadManager/CNLiveDownloadManager-Info.plist"; | ||
| 585 | + IPHONEOS_DEPLOYMENT_TARGET = 9.0; | ||
| 586 | + MODULE_NAME = ExampleApp; | ||
| 587 | + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; | ||
| 588 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 589 | + WRAPPER_EXTENSION = app; | ||
| 590 | + }; | ||
| 591 | + name = Release; | ||
| 592 | + }; | ||
| 593 | + 6003F5C3195388D20070C39A /* Debug */ = { | ||
| 594 | + isa = XCBuildConfiguration; | ||
| 595 | + baseConfigurationReference = 72041DDD913A10D596ECFEEE /* Pods-CNLiveDownloadManager_Tests.debug.xcconfig */; | ||
| 596 | + buildSettings = { | ||
| 597 | + BUNDLE_LOADER = "$(TEST_HOST)"; | ||
| 598 | + FRAMEWORK_SEARCH_PATHS = ( | ||
| 599 | + "$(SDKROOT)/Developer/Library/Frameworks", | ||
| 600 | + "$(inherited)", | ||
| 601 | + "$(DEVELOPER_FRAMEWORKS_DIR)", | ||
| 602 | + ); | ||
| 603 | + GCC_PRECOMPILE_PREFIX_HEADER = YES; | ||
| 604 | + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; | ||
| 605 | + GCC_PREPROCESSOR_DEFINITIONS = ( | ||
| 606 | + "DEBUG=1", | ||
| 607 | + "$(inherited)", | ||
| 608 | + ); | ||
| 609 | + INFOPLIST_FILE = "Tests/Tests-Info.plist"; | ||
| 610 | + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; | ||
| 611 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 612 | + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveDownloadManager_Example.app/CNLiveDownloadManager_Example"; | ||
| 613 | + WRAPPER_EXTENSION = xctest; | ||
| 614 | + }; | ||
| 615 | + name = Debug; | ||
| 616 | + }; | ||
| 617 | + 6003F5C4195388D20070C39A /* Release */ = { | ||
| 618 | + isa = XCBuildConfiguration; | ||
| 619 | + baseConfigurationReference = BF5F74A07CE41BEC53E597F0 /* Pods-CNLiveDownloadManager_Tests.release.xcconfig */; | ||
| 620 | + buildSettings = { | ||
| 621 | + BUNDLE_LOADER = "$(TEST_HOST)"; | ||
| 622 | + FRAMEWORK_SEARCH_PATHS = ( | ||
| 623 | + "$(SDKROOT)/Developer/Library/Frameworks", | ||
| 624 | + "$(inherited)", | ||
| 625 | + "$(DEVELOPER_FRAMEWORKS_DIR)", | ||
| 626 | + ); | ||
| 627 | + GCC_PRECOMPILE_PREFIX_HEADER = YES; | ||
| 628 | + GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch"; | ||
| 629 | + INFOPLIST_FILE = "Tests/Tests-Info.plist"; | ||
| 630 | + PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.demo.${PRODUCT_NAME:rfc1034identifier}"; | ||
| 631 | + PRODUCT_NAME = "$(TARGET_NAME)"; | ||
| 632 | + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/CNLiveDownloadManager_Example.app/CNLiveDownloadManager_Example"; | ||
| 633 | + WRAPPER_EXTENSION = xctest; | ||
| 634 | + }; | ||
| 635 | + name = Release; | ||
| 636 | + }; | ||
| 637 | +/* End XCBuildConfiguration section */ | ||
| 638 | + | ||
| 639 | +/* Begin XCConfigurationList section */ | ||
| 640 | + 6003F585195388D10070C39A /* Build configuration list for PBXProject "CNLiveDownloadManager" */ = { | ||
| 641 | + isa = XCConfigurationList; | ||
| 642 | + buildConfigurations = ( | ||
| 643 | + 6003F5BD195388D20070C39A /* Debug */, | ||
| 644 | + 6003F5BE195388D20070C39A /* Release */, | ||
| 645 | + ); | ||
| 646 | + defaultConfigurationIsVisible = 0; | ||
| 647 | + defaultConfigurationName = Release; | ||
| 648 | + }; | ||
| 649 | + 6003F5BF195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveDownloadManager_Example" */ = { | ||
| 650 | + isa = XCConfigurationList; | ||
| 651 | + buildConfigurations = ( | ||
| 652 | + 6003F5C0195388D20070C39A /* Debug */, | ||
| 653 | + 6003F5C1195388D20070C39A /* Release */, | ||
| 654 | + ); | ||
| 655 | + defaultConfigurationIsVisible = 0; | ||
| 656 | + defaultConfigurationName = Release; | ||
| 657 | + }; | ||
| 658 | + 6003F5C2195388D20070C39A /* Build configuration list for PBXNativeTarget "CNLiveDownloadManager_Tests" */ = { | ||
| 659 | + isa = XCConfigurationList; | ||
| 660 | + buildConfigurations = ( | ||
| 661 | + 6003F5C3195388D20070C39A /* Debug */, | ||
| 662 | + 6003F5C4195388D20070C39A /* Release */, | ||
| 663 | + ); | ||
| 664 | + defaultConfigurationIsVisible = 0; | ||
| 665 | + defaultConfigurationName = Release; | ||
| 666 | + }; | ||
| 667 | +/* End XCConfigurationList section */ | ||
| 668 | + }; | ||
| 669 | + rootObject = 6003F582195388D10070C39A /* Project object */; | ||
| 670 | +} |
Example/CNLiveDownloadManager.xcodeproj/xcshareddata/xcschemes/CNLiveDownloadManager-Example.xcscheme
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<Scheme | ||
| 3 | + LastUpgradeVersion = "0720" | ||
| 4 | + version = "1.3"> | ||
| 5 | + <BuildAction | ||
| 6 | + parallelizeBuildables = "YES" | ||
| 7 | + buildImplicitDependencies = "YES"> | ||
| 8 | + <BuildActionEntries> | ||
| 9 | + <BuildActionEntry | ||
| 10 | + buildForTesting = "YES" | ||
| 11 | + buildForRunning = "YES" | ||
| 12 | + buildForProfiling = "YES" | ||
| 13 | + buildForArchiving = "YES" | ||
| 14 | + buildForAnalyzing = "YES"> | ||
| 15 | + <BuildableReference | ||
| 16 | + BuildableIdentifier = "primary" | ||
| 17 | + BlueprintIdentifier = "6003F589195388D20070C39A" | ||
| 18 | + BuildableName = "CNLiveDownloadManager_Example.app" | ||
| 19 | + BlueprintName = "CNLiveDownloadManager_Example" | ||
| 20 | + ReferencedContainer = "container:CNLiveDownloadManager.xcodeproj"> | ||
| 21 | + </BuildableReference> | ||
| 22 | + </BuildActionEntry> | ||
| 23 | + </BuildActionEntries> | ||
| 24 | + </BuildAction> | ||
| 25 | + <TestAction | ||
| 26 | + buildConfiguration = "Debug" | ||
| 27 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 28 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 29 | + shouldUseLaunchSchemeArgsEnv = "YES"> | ||
| 30 | + <Testables> | ||
| 31 | + <TestableReference | ||
| 32 | + skipped = "NO"> | ||
| 33 | + <BuildableReference | ||
| 34 | + BuildableIdentifier = "primary" | ||
| 35 | + BlueprintIdentifier = "6003F5AD195388D20070C39A" | ||
| 36 | + BuildableName = "CNLiveDownloadManager_Tests.xctest" | ||
| 37 | + BlueprintName = "CNLiveDownloadManager_Tests" | ||
| 38 | + ReferencedContainer = "container:CNLiveDownloadManager.xcodeproj"> | ||
| 39 | + </BuildableReference> | ||
| 40 | + </TestableReference> | ||
| 41 | + </Testables> | ||
| 42 | + <MacroExpansion> | ||
| 43 | + <BuildableReference | ||
| 44 | + BuildableIdentifier = "primary" | ||
| 45 | + BlueprintIdentifier = "6003F589195388D20070C39A" | ||
| 46 | + BuildableName = "CNLiveDownloadManager_Example.app" | ||
| 47 | + BlueprintName = "CNLiveDownloadManager_Example" | ||
| 48 | + ReferencedContainer = "container:CNLiveDownloadManager.xcodeproj"> | ||
| 49 | + </BuildableReference> | ||
| 50 | + </MacroExpansion> | ||
| 51 | + <AdditionalOptions> | ||
| 52 | + </AdditionalOptions> | ||
| 53 | + </TestAction> | ||
| 54 | + <LaunchAction | ||
| 55 | + buildConfiguration = "Debug" | ||
| 56 | + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB" | ||
| 57 | + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB" | ||
| 58 | + launchStyle = "0" | ||
| 59 | + useCustomWorkingDirectory = "NO" | ||
| 60 | + ignoresPersistentStateOnLaunch = "NO" | ||
| 61 | + debugDocumentVersioning = "YES" | ||
| 62 | + debugServiceExtension = "internal" | ||
| 63 | + allowLocationSimulation = "YES"> | ||
| 64 | + <BuildableProductRunnable | ||
| 65 | + runnableDebuggingMode = "0"> | ||
| 66 | + <BuildableReference | ||
| 67 | + BuildableIdentifier = "primary" | ||
| 68 | + BlueprintIdentifier = "6003F589195388D20070C39A" | ||
| 69 | + BuildableName = "CNLiveDownloadManager_Example.app" | ||
| 70 | + BlueprintName = "CNLiveDownloadManager_Example" | ||
| 71 | + ReferencedContainer = "container:CNLiveDownloadManager.xcodeproj"> | ||
| 72 | + </BuildableReference> | ||
| 73 | + </BuildableProductRunnable> | ||
| 74 | + <AdditionalOptions> | ||
| 75 | + </AdditionalOptions> | ||
| 76 | + </LaunchAction> | ||
| 77 | + <ProfileAction | ||
| 78 | + buildConfiguration = "Release" | ||
| 79 | + shouldUseLaunchSchemeArgsEnv = "YES" | ||
| 80 | + savedToolIdentifier = "" | ||
| 81 | + useCustomWorkingDirectory = "NO" | ||
| 82 | + debugDocumentVersioning = "YES"> | ||
| 83 | + <BuildableProductRunnable | ||
| 84 | + runnableDebuggingMode = "0"> | ||
| 85 | + <BuildableReference | ||
| 86 | + BuildableIdentifier = "primary" | ||
| 87 | + BlueprintIdentifier = "6003F589195388D20070C39A" | ||
| 88 | + BuildableName = "CNLiveDownloadManager_Example.app" | ||
| 89 | + BlueprintName = "CNLiveDownloadManager_Example" | ||
| 90 | + ReferencedContainer = "container:CNLiveDownloadManager.xcodeproj"> | ||
| 91 | + </BuildableReference> | ||
| 92 | + </BuildableProductRunnable> | ||
| 93 | + </ProfileAction> | ||
| 94 | + <AnalyzeAction | ||
| 95 | + buildConfiguration = "Debug"> | ||
| 96 | + </AnalyzeAction> | ||
| 97 | + <ArchiveAction | ||
| 98 | + buildConfiguration = "Release" | ||
| 99 | + revealArchiveInOrganizer = "YES"> | ||
| 100 | + </ArchiveAction> | ||
| 101 | +</Scheme> |
Example/CNLiveDownloadManager/Base.lproj/LaunchScreen.storyboard
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM"> | ||
| 3 | + <device id="retina4_7" orientation="portrait"> | ||
| 4 | + <adaptation id="fullscreen"/> | ||
| 5 | + </device> | ||
| 6 | + <dependencies> | ||
| 7 | + <deployment identifier="iOS"/> | ||
| 8 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/> | ||
| 9 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| 10 | + </dependencies> | ||
| 11 | + <scenes> | ||
| 12 | + <!--View Controller--> | ||
| 13 | + <scene sceneID="EHf-IW-A2E"> | ||
| 14 | + <objects> | ||
| 15 | + <viewController id="01J-lp-oVM" sceneMemberID="viewController"> | ||
| 16 | + <layoutGuides> | ||
| 17 | + <viewControllerLayoutGuide type="top" id="Llm-lL-Icb"/> | ||
| 18 | + <viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/> | ||
| 19 | + </layoutGuides> | ||
| 20 | + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3"> | ||
| 21 | + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> | ||
| 22 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 23 | + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||
| 24 | + </view> | ||
| 25 | + </viewController> | ||
| 26 | + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
| 27 | + </objects> | ||
| 28 | + <point key="canvasLocation" x="53" y="375"/> | ||
| 29 | + </scene> | ||
| 30 | + </scenes> | ||
| 31 | +</document> |
Example/CNLiveDownloadManager/Base.lproj/Main.storyboard
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="13771" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="whP-gf-Uak"> | ||
| 3 | + <device id="retina4_7" orientation="portrait"> | ||
| 4 | + <adaptation id="fullscreen"/> | ||
| 5 | + </device> | ||
| 6 | + <dependencies> | ||
| 7 | + <deployment identifier="iOS"/> | ||
| 8 | + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="13772"/> | ||
| 9 | + <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> | ||
| 10 | + </dependencies> | ||
| 11 | + <scenes> | ||
| 12 | + <!--View Controller--> | ||
| 13 | + <scene sceneID="wQg-tq-qST"> | ||
| 14 | + <objects> | ||
| 15 | + <viewController id="whP-gf-Uak" customClass="CNLiveViewController" sceneMemberID="viewController"> | ||
| 16 | + <layoutGuides> | ||
| 17 | + <viewControllerLayoutGuide type="top" id="uEw-UM-LJ8"/> | ||
| 18 | + <viewControllerLayoutGuide type="bottom" id="Mvr-aV-6Um"/> | ||
| 19 | + </layoutGuides> | ||
| 20 | + <view key="view" contentMode="scaleToFill" id="TpU-gO-2f1"> | ||
| 21 | + <rect key="frame" x="0.0" y="0.0" width="375" height="667"/> | ||
| 22 | + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/> | ||
| 23 | + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/> | ||
| 24 | + </view> | ||
| 25 | + </viewController> | ||
| 26 | + <placeholder placeholderIdentifier="IBFirstResponder" id="tc2-Qw-aMS" userLabel="First Responder" sceneMemberID="firstResponder"/> | ||
| 27 | + </objects> | ||
| 28 | + <point key="canvasLocation" x="305" y="433"/> | ||
| 29 | + </scene> | ||
| 30 | + </scenes> | ||
| 31 | +</document> |
Example/CNLiveDownloadManager/CNLiveAppDelegate.h
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAppDelegate.h | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 05/31/2019. | ||
| 6 | +// Copyright (c) 2019 殷巧娟. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +@import UIKit; | ||
| 10 | + | ||
| 11 | +@interface CNLiveAppDelegate : UIResponder <UIApplicationDelegate> | ||
| 12 | + | ||
| 13 | +@property (strong, nonatomic) UIWindow *window; | ||
| 14 | + | ||
| 15 | +@end |
Example/CNLiveDownloadManager/CNLiveAppDelegate.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveAppDelegate.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 05/31/2019. | ||
| 6 | +// Copyright (c) 2019 殷巧娟. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "CNLiveAppDelegate.h" | ||
| 10 | + | ||
| 11 | +@implementation CNLiveAppDelegate | ||
| 12 | + | ||
| 13 | +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions | ||
| 14 | +{ | ||
| 15 | + // Override point for customization after application launch. | ||
| 16 | + return YES; | ||
| 17 | +} | ||
| 18 | + | ||
| 19 | +- (void)applicationWillResignActive:(UIApplication *)application | ||
| 20 | +{ | ||
| 21 | + // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. | ||
| 22 | + // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. | ||
| 23 | +} | ||
| 24 | + | ||
| 25 | +- (void)applicationDidEnterBackground:(UIApplication *)application | ||
| 26 | +{ | ||
| 27 | + // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. | ||
| 28 | + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. | ||
| 29 | +} | ||
| 30 | + | ||
| 31 | +- (void)applicationWillEnterForeground:(UIApplication *)application | ||
| 32 | +{ | ||
| 33 | + // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. | ||
| 34 | +} | ||
| 35 | + | ||
| 36 | +- (void)applicationDidBecomeActive:(UIApplication *)application | ||
| 37 | +{ | ||
| 38 | + // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. | ||
| 39 | +} | ||
| 40 | + | ||
| 41 | +- (void)applicationWillTerminate:(UIApplication *)application | ||
| 42 | +{ | ||
| 43 | + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. | ||
| 44 | +} | ||
| 45 | + | ||
| 46 | +@end |
Example/CNLiveDownloadManager/CNLiveDownloadManager-Info.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CFBundleDevelopmentRegion</key> | ||
| 6 | + <string>en</string> | ||
| 7 | + <key>CFBundleDisplayName</key> | ||
| 8 | + <string>${PRODUCT_NAME}</string> | ||
| 9 | + <key>CFBundleExecutable</key> | ||
| 10 | + <string>${EXECUTABLE_NAME}</string> | ||
| 11 | + <key>CFBundleIdentifier</key> | ||
| 12 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 13 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 14 | + <string>6.0</string> | ||
| 15 | + <key>CFBundleName</key> | ||
| 16 | + <string>${PRODUCT_NAME}</string> | ||
| 17 | + <key>CFBundlePackageType</key> | ||
| 18 | + <string>APPL</string> | ||
| 19 | + <key>CFBundleShortVersionString</key> | ||
| 20 | + <string>1.0</string> | ||
| 21 | + <key>CFBundleSignature</key> | ||
| 22 | + <string>????</string> | ||
| 23 | + <key>CFBundleVersion</key> | ||
| 24 | + <string>1.0</string> | ||
| 25 | + <key>LSRequiresIPhoneOS</key> | ||
| 26 | + <true/> | ||
| 27 | + <key>UILaunchStoryboardName</key> | ||
| 28 | + <string>LaunchScreen</string> | ||
| 29 | + <key>UIMainStoryboardFile</key> | ||
| 30 | + <string>Main</string> | ||
| 31 | + <key>UIRequiredDeviceCapabilities</key> | ||
| 32 | + <array> | ||
| 33 | + <string>armv7</string> | ||
| 34 | + </array> | ||
| 35 | + <key>UISupportedInterfaceOrientations</key> | ||
| 36 | + <array> | ||
| 37 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 38 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 39 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 40 | + </array> | ||
| 41 | + <key>UISupportedInterfaceOrientations~ipad</key> | ||
| 42 | + <array> | ||
| 43 | + <string>UIInterfaceOrientationPortrait</string> | ||
| 44 | + <string>UIInterfaceOrientationPortraitUpsideDown</string> | ||
| 45 | + <string>UIInterfaceOrientationLandscapeLeft</string> | ||
| 46 | + <string>UIInterfaceOrientationLandscapeRight</string> | ||
| 47 | + </array> | ||
| 48 | +</dict> | ||
| 49 | +</plist> |
Example/CNLiveDownloadManager/CNLiveDownloadManager-Prefix.pch
0 → 100644
| 1 | +// | ||
| 2 | +// Prefix header | ||
| 3 | +// | ||
| 4 | +// The contents of this file are implicitly included at the beginning of every source file. | ||
| 5 | +// | ||
| 6 | + | ||
| 7 | +#import <Availability.h> | ||
| 8 | + | ||
| 9 | +#ifndef __IPHONE_5_0 | ||
| 10 | +#warning "This project uses features only available in iOS SDK 5.0 and later." | ||
| 11 | +#endif | ||
| 12 | + | ||
| 13 | +#ifdef __OBJC__ | ||
| 14 | + @import UIKit; | ||
| 15 | + @import Foundation; | ||
| 16 | +#endif |
Example/CNLiveDownloadManager/CNLiveViewController.h
0 → 100644
Example/CNLiveDownloadManager/CNLiveViewController.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveViewController.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 05/31/2019. | ||
| 6 | +// Copyright (c) 2019 殷巧娟. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +#import "CNLiveViewController.h" | ||
| 10 | +@interface CNLiveViewController () | ||
| 11 | + | ||
| 12 | +@end | ||
| 13 | + | ||
| 14 | +@implementation CNLiveViewController | ||
| 15 | + | ||
| 16 | +- (void)viewDidLoad | ||
| 17 | +{ | ||
| 18 | + [super viewDidLoad]; | ||
| 19 | + // Do any additional setup after loading the view, typically from a nib. | ||
| 20 | +} | ||
| 21 | + | ||
| 22 | +- (void)didReceiveMemoryWarning | ||
| 23 | +{ | ||
| 24 | + [super didReceiveMemoryWarning]; | ||
| 25 | + // Dispose of any resources that can be recreated. | ||
| 26 | +} | ||
| 27 | + | ||
| 28 | +@end |
Example/CNLiveDownloadManager/Images.xcassets/AppIcon.appiconset/Contents.json
0 → 100644
| 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 | + "idiom" : "ios-marketing", | ||
| 90 | + "size" : "1024x1024", | ||
| 91 | + "scale" : "1x" | ||
| 92 | + } | ||
| 93 | + ], | ||
| 94 | + "info" : { | ||
| 95 | + "version" : 1, | ||
| 96 | + "author" : "xcode" | ||
| 97 | + } | ||
| 98 | +} |
Example/CNLiveDownloadManager/en.lproj/InfoPlist.strings
0 → 100644
Example/CNLiveDownloadManager/main.m
0 → 100644
| 1 | +// | ||
| 2 | +// main.m | ||
| 3 | +// CNLiveDownloadManager | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 05/31/2019. | ||
| 6 | +// Copyright (c) 2019 殷巧娟. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +@import UIKit; | ||
| 10 | +#import "CNLiveAppDelegate.h" | ||
| 11 | + | ||
| 12 | +int main(int argc, char * argv[]) | ||
| 13 | +{ | ||
| 14 | + @autoreleasepool { | ||
| 15 | + return UIApplicationMain(argc, argv, nil, NSStringFromClass([CNLiveAppDelegate class])); | ||
| 16 | + } | ||
| 17 | +} |
Example/Podfile
0 → 100644
| 1 | +use_frameworks! | ||
| 2 | + | ||
| 3 | +platform :ios, '9.0' | ||
| 4 | +source 'https://github.com/CocoaPods/Specs.git' | ||
| 5 | +source 'http://bj.gitlab.cnlive.com/ios-team/CNLiveRepos.git' | ||
| 6 | + | ||
| 7 | +target 'CNLiveDownloadManager_Example' do | ||
| 8 | + pod 'CNLiveDownloadManager', :path => '../' | ||
| 9 | + pod 'CNLiveTripartiteManagement/FMDB' | ||
| 10 | + pod 'CNLiveBaseKit' | ||
| 11 | + pod 'CNLiveTripartiteManagement/MJExtension' | ||
| 12 | + pod 'CNLiveBaseTools' | ||
| 13 | + pod 'CNLiveEnvironmentConfiguration' | ||
| 14 | + pod 'CNLiveBusinessTools' | ||
| 15 | + pod 'CNLiveBaseKit' | ||
| 16 | + pod 'CNLiveRequestBastKit' | ||
| 17 | + pod 'CNLiveTripartiteManagement/QMUIKit' | ||
| 18 | + target 'CNLiveDownloadManager_Tests' do | ||
| 19 | + inherit! :search_paths | ||
| 20 | + | ||
| 21 | + pod 'CNLiveTripartiteManagement/FMDB' | ||
| 22 | + pod 'CNLiveBaseKit' | ||
| 23 | + pod 'CNLiveTripartiteManagement/MJExtension' | ||
| 24 | + pod 'CNLiveEnvironmentConfiguration' | ||
| 25 | + pod 'CNLiveBusinessTools' | ||
| 26 | + pod 'CNLiveBaseKit' | ||
| 27 | + pod 'CNLiveRequestBastKit' | ||
| 28 | + pod 'CNLiveTripartiteManagement/QMUIKit' | ||
| 29 | + pod 'CNLiveBaseTools' | ||
| 30 | + end | ||
| 31 | +end |
Example/Tests/Tests-Info.plist
0 → 100644
| 1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
| 2 | +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> | ||
| 3 | +<plist version="1.0"> | ||
| 4 | +<dict> | ||
| 5 | + <key>CFBundleDevelopmentRegion</key> | ||
| 6 | + <string>en</string> | ||
| 7 | + <key>CFBundleExecutable</key> | ||
| 8 | + <string>${EXECUTABLE_NAME}</string> | ||
| 9 | + <key>CFBundleIdentifier</key> | ||
| 10 | + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string> | ||
| 11 | + <key>CFBundleInfoDictionaryVersion</key> | ||
| 12 | + <string>6.0</string> | ||
| 13 | + <key>CFBundlePackageType</key> | ||
| 14 | + <string>BNDL</string> | ||
| 15 | + <key>CFBundleShortVersionString</key> | ||
| 16 | + <string>1.0</string> | ||
| 17 | + <key>CFBundleSignature</key> | ||
| 18 | + <string>????</string> | ||
| 19 | + <key>CFBundleVersion</key> | ||
| 20 | + <string>1</string> | ||
| 21 | +</dict> | ||
| 22 | +</plist> |
Example/Tests/Tests-Prefix.pch
0 → 100644
Example/Tests/Tests.m
0 → 100644
| 1 | +// | ||
| 2 | +// CNLiveDownloadManagerTests.m | ||
| 3 | +// CNLiveDownloadManagerTests | ||
| 4 | +// | ||
| 5 | +// Created by 殷巧娟 on 05/31/2019. | ||
| 6 | +// Copyright (c) 2019 殷巧娟. All rights reserved. | ||
| 7 | +// | ||
| 8 | + | ||
| 9 | +@import XCTest; | ||
| 10 | + | ||
| 11 | +@interface Tests : XCTestCase | ||
| 12 | + | ||
| 13 | +@end | ||
| 14 | + | ||
| 15 | +@implementation Tests | ||
| 16 | + | ||
| 17 | +- (void)setUp | ||
| 18 | +{ | ||
| 19 | + [super setUp]; | ||
| 20 | + // Put setup code here. This method is called before the invocation of each test method in the class. | ||
| 21 | +} | ||
| 22 | + | ||
| 23 | +- (void)tearDown | ||
| 24 | +{ | ||
| 25 | + // Put teardown code here. This method is called after the invocation of each test method in the class. | ||
| 26 | + [super tearDown]; | ||
| 27 | +} | ||
| 28 | + | ||
| 29 | +- (void)testExample | ||
| 30 | +{ | ||
| 31 | + XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); | ||
| 32 | +} | ||
| 33 | + | ||
| 34 | +@end | ||
| 35 | + |
Example/Tests/en.lproj/InfoPlist.strings
0 → 100644
LICENSE
0 → 100644
| 1 | +Copyright (c) 2019 殷巧娟 <1427945373@qq.com> | ||
| 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. |
README.md
| 1 | +# CNLiveDownloadManager | ||
| 2 | + | ||
| 3 | +[](https://travis-ci.org/殷巧娟/CNLiveDownloadManager) | ||
| 4 | +[](https://cocoapods.org/pods/CNLiveDownloadManager) | ||
| 5 | +[](https://cocoapods.org/pods/CNLiveDownloadManager) | ||
| 6 | +[](https://cocoapods.org/pods/CNLiveDownloadManager) | ||
| 7 | + | ||
| 8 | +## Example | ||
| 9 | + | ||
| 10 | +To run the example project, clone the repo, and run `pod install` from the Example directory first. | ||
| 11 | + | ||
| 12 | +## Requirements | ||
| 13 | + | ||
| 14 | +## Installation | ||
| 15 | + | ||
| 16 | +CNLiveDownloadManager is available through [CocoaPods](https://cocoapods.org). To install | ||
| 17 | +it, simply add the following line to your Podfile: | ||
| 18 | + | ||
| 19 | +```ruby | ||
| 20 | +pod 'CNLiveDownloadManager' | ||
| 21 | +``` | ||
| 22 | + | ||
| 23 | +## Author | ||
| 24 | + | ||
| 25 | +殷巧娟, 1427945373@qq.com | ||
| 26 | + | ||
| 27 | +## License | ||
| 28 | + | ||
| 29 | +CNLiveDownloadManager is available under the MIT license. See the LICENSE file for more info. |
_Pods.xcodeproj
0 → 120000