diff --git a/README.md b/README.md index 5e7dc73..765bbe0 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,28 @@ -# iOSStudy -iOSStudy是一个开源的iOS应用内容是致力于帮助iOS开发者找到适合自己的学习资源 + +![Alt text] (https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudy/iOSStudy/%20Resource/images/appicon/icon_120.png) +_____________________________________________ +# 关于iOSStudy +
+iOSStudy 灵感来源于作者自学iOS开发的经验,收藏了一些博客视频网站等内容,希望可以帮助初学者找到更好的学习资源,作者也会不断的更新完善软件和内容,如果本软件对您的学习有所帮助欢迎到评分界面深深地点个赞,您的支持将是我前进的动力↖(^ω^)↗
+
+# 下一步计划 +
+1,加入开源软件推荐模块
+2,加入iCloud对收藏的支持
+
+ +# 官方博客 +
http://iosstudy.lofter.com/
+ +# 特别感谢 + +
+李辉 QQ:949843687 对该软件图标设计与制作
+龚凡凡 QQ:825244415 对该软件的技术支持
+
+ +# 联系我 +
+邮箱: chenguandong@163.com
+QQ: 787725000
+
diff --git a/iOSStudy/.gitignore b/iOSStudy/.gitignore new file mode 100644 index 0000000..a3cd143 --- /dev/null +++ b/iOSStudy/.gitignore @@ -0,0 +1,26 @@ +# Xcode +# +build/ +*.pbxuser +!default.pbxuser +*.mode1v3 +!default.mode1v3 +*.mode2v3 +!default.mode2v3 +*.perspectivev3 +!default.perspectivev3 +xcuserdata +*.xccheckout +*.moved-aside +DerivedData +*.hmap +*.ipa +*.xcuserstate + +# CocoaPods +# +# We recommend against adding the Pods directory to your .gitignore. However +# you should judge for yourself, the pros and cons are mentioned at: +# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control +# +# Pods/ diff --git a/iOSStudy/APService.h b/iOSStudy/APService.h new file mode 100644 index 0000000..bd529c3 --- /dev/null +++ b/iOSStudy/APService.h @@ -0,0 +1,175 @@ +// +// APService.h +// APService +// +// Created by JPush on 12-8-15. +// Copyright (c) 2012年 HXHG. All rights reserved. +// Version: 1.8.3 + +@class CLRegion; +@class UILocalNotification; + +extern NSString *const kJPFNetworkDidSetupNotification; // 建立连接 +extern NSString *const kJPFNetworkDidCloseNotification; // 关闭连接 +extern NSString *const kJPFNetworkDidRegisterNotification; // 注册成功 +extern NSString *const kJPFNetworkDidLoginNotification; // 登录成功 +extern NSString *const + kJPFNetworkDidReceiveMessageNotification; // 收到消息(非APNS) +extern NSString *const kJPFServiceErrorNotification; // 错误提示 + +@class CLLocation; +@interface APService : NSObject + +#pragma - mark 基本功能 +// 以下四个接口是必须调用的 ++ (void)setupWithOption:(NSDictionary *)launchingOption; // 初始化 ++ (void)registerForRemoteNotificationTypes:(NSUInteger)types + categories:(NSSet *)categories; // 注册APNS类型 ++ (void)registerDeviceToken:(NSData *)deviceToken; // 向服务器上报Device Token ++ (void)handleRemoteNotification:(NSDictionary *) + remoteInfo; // 处理收到的APNS消息,向服务器上报收到APNS消息 + +// 下面的接口是可选的 +// 设置标签和(或)别名(若参数为nil,则忽略;若是空对象,则清空;详情请参考文档:http://docs.jpush.cn/pages/viewpage.action?pageId=3309913) ++ (void)setTags:(NSSet *)tags + alias:(NSString *)alias + callbackSelector:(SEL)cbSelector + target:(id)theTarget; ++ (void)setTags:(NSSet *)tags + alias:(NSString *)alias + callbackSelector:(SEL)cbSelector + object:(id)theTarget; ++ (void)setTags:(NSSet *)tags + callbackSelector:(SEL)cbSelector + object:(id)theTarget; ++ (void)setAlias:(NSString *)alias + callbackSelector:(SEL)cbSelector + object:(id)theTarget; +// 用于过滤出正确可用的tags,如果总数量超出最大限制则返回最大数量的靠前的可用tags ++ (NSSet *)filterValidTags:(NSSet *)tags; + +#pragma - mark 上报日志 +/** + * 记录页面停留时间功能。 + * startLogPageView和stopLogPageView为自动计算停留时间 + * beginLogPageView为手动自己输入停留时间 + * + * @param pageName 页面名称 + * @param seconds 页面停留时间 + */ ++ (void)startLogPageView:(NSString *)pageName; ++ (void)stopLogPageView:(NSString *)pageName; ++ (void)beginLogPageView:(NSString *)pageName duration:(int)seconds; + +/** + * 开启Crash日志收集, 默认是关闭状态. +*/ ++ (void)crashLogON; + +/** + * 地理位置设置 + * 为了更精确的统计用户地理位置,可以调用此方法传入经纬度信息 + * 需要链接 CoreLocation.framework 并且 #import + * @param latitude 纬度. + * @param longitude 经度. + * @param location 直接传递CLLocation *型的地理信息 + */ ++ (void)setLatitude:(double)latitude longitude:(double)longitude; ++ (void)setLocation:(CLLocation *)location; + +#pragma - mark 本地通知 +/** +* 本地推送,最多支持64个 +* @param fireDate 本地推送触发的时间 +* @param alertBody 本地推送需要显示的内容 +* @param badge 角标的数字。如果不需要改变角标传-1 +* @param alertAction 弹框的按钮显示的内容(IOS 8默认为"打开",其他默认为"启动") +* @param notificationKey 本地推送标示符 +* @param userInfo 自定义参数,可以用来标识推送和增加附加信息 +* @param soundName 自定义通知声音,设置为nil为默认声音 + +* IOS8新参数 +* @param region 自定义参数 +* @param regionTriggersOnce 自定义参数 +* @param category 自定义参数 +*/ ++ (UILocalNotification *)setLocalNotification:(NSDate *)fireDate + alertBody:(NSString *)alertBody + badge:(int)badge + alertAction:(NSString *)alertAction + identifierKey:(NSString *)notificationKey + userInfo:(NSDictionary *)userInfo + soundName:(NSString *)soundName; + ++ (UILocalNotification *)setLocalNotification:(NSDate *)fireDate + alertBody:(NSString *)alertBody + badge:(int)badge + alertAction:(NSString *)alertAction + identifierKey:(NSString *)notificationKey + userInfo:(NSDictionary *)userInfo + soundName:(NSString *)soundName + region:(CLRegion *)region + regionTriggersOnce:(BOOL)regionTriggersOnce + category:(NSString *)category + NS_AVAILABLE_IOS(8_0); + +/** +* 本地推送在前台推送。默认App在前台运行时不会进行弹窗,在程序接收通知调用此接口可实现指定的推送弹窗。 +* @param notification 本地推送对象 +* @param notificationKey 需要前台显示的本地推送通知的标示符 +*/ ++ (void)showLocalNotificationAtFront:(UILocalNotification *)notification + identifierKey:(NSString *)notificationKey; +/** +* 删除本地推送 +* @param notificationKey 本地推送标示符 +* @param myUILocalNotification 本地推送对象 +*/ ++ (void)deleteLocalNotificationWithIdentifierKey:(NSString *)notificationKey; ++ (void)deleteLocalNotification:(UILocalNotification *)localNotification; + +/** +* 获取指定通知 +* @param notificationKey 本地推送标示符 +* @return 本地推送对象数组,[array count]为0时表示没找到 +*/ ++ (NSArray *)findLocalNotificationWithIdentifier:(NSString *)notificationKey; + +/** +* 清除所有本地推送对象 +*/ ++ (void)clearAllLocalNotifications; + +#pragma - mark 设置Badge +/** + * set setBadge + * @param value 设置JPush服务器的badge的值 + * 本地仍须调用UIApplication:setApplicationIconBadgeNumber函数,来设置脚标 + */ ++ (BOOL)setBadge:(NSInteger)value; +/** + * set setBadge + * @param value 清除JPush服务器对badge值的设定. + * 本地仍须调用UIApplication:setApplicationIconBadgeNumber函数,来设置脚标 + */ + ++ (void)resetBadge; + +/** + * get RegistrationID + */ ++ (NSString *)registrationID; + +#pragma - mark 打印日志信息配置 +/** + * setDebugMode获取更多的Log信息 + * 开发过程中建议开启DebugMode + * + * setLogOFF关闭除了错误信息外的所有Log + * 发布时建议开启LogOFF用于节省性能开销 + * + * 默认为不开启DebugLog,只显示基本的信息 + */ ++ (void)setDebugMode; ++ (void)setLogOFF; +@end diff --git a/iOSStudy/Base/BaseViewController.h b/iOSStudy/Base/BaseViewController.h index 7b5c39a..48ee353 100644 --- a/iOSStudy/Base/BaseViewController.h +++ b/iOSStudy/Base/BaseViewController.h @@ -7,7 +7,7 @@ // #import - +#import "NotificationCenterConstants.h" @interface BaseViewController : UIViewController @end diff --git a/iOSStudy/Base/BaseViewController.m b/iOSStudy/Base/BaseViewController.m index c6773d2..1ff56d8 100644 --- a/iOSStudy/Base/BaseViewController.m +++ b/iOSStudy/Base/BaseViewController.m @@ -7,6 +7,7 @@ // #import "BaseViewController.h" +#import "Constants .h" @interface BaseViewController () @@ -14,11 +15,16 @@ @interface BaseViewController () @implementation BaseViewController + - (void)viewDidLoad { [super viewDidLoad]; + // Do any additional setup after loading the view. + } + + -(void)viewWillAppear:(BOOL)animated{ [super viewWillAppear:YES]; diff --git a/iOSStudy/Bean/FavouriteBean.h b/iOSStudy/Bean/FavouriteBean.h index 1bc484a..5ebd56e 100644 --- a/iOSStudy/Bean/FavouriteBean.h +++ b/iOSStudy/Bean/FavouriteBean.h @@ -32,7 +32,7 @@ typedef NS_ENUM(NSInteger, FAVOURITE_TYPE) { */ @property(nonatomic,copy)NSString *url; /** - * 类型 1 博客 2 网站 3 视频 + * 类型 1 收藏博客 2 收藏网站 3 收藏视频 11,持久化博客 22,持久化网站 33,持久化视频 */ @property(nonatomic,copy)NSString* type; @end diff --git a/iOSStudy/Bean/blogBean/BlogBean.h b/iOSStudy/Bean/blogBean/BlogBean.h index a5d9180..5e4d6ae 100644 --- a/iOSStudy/Bean/blogBean/BlogBean.h +++ b/iOSStudy/Bean/blogBean/BlogBean.h @@ -38,4 +38,6 @@ * 博客地址 */ @property(nonatomic,copy)NSString*date; + +@property(nonatomic,copy)NSString*version; @end diff --git a/iOSStudy/Bean/blogBean/BlogBean.m b/iOSStudy/Bean/blogBean/BlogBean.m index 6e26d6f..c0152c9 100644 --- a/iOSStudy/Bean/blogBean/BlogBean.m +++ b/iOSStudy/Bean/blogBean/BlogBean.m @@ -13,6 +13,7 @@ + (NSDictionary *)JSONKeyPathsByPropertyKey{ return @{ + @"version":@"version", @"name": @"name", @"title": @"title", @"subTitle": @"subTitle", diff --git a/iOSStudy/Bean/blogBean/BlogJsonBean.h b/iOSStudy/Bean/blogBean/BlogJsonBean.h new file mode 100644 index 0000000..c8b122e --- /dev/null +++ b/iOSStudy/Bean/blogBean/BlogJsonBean.h @@ -0,0 +1,15 @@ +// +// BlogJsonBean.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface BlogJsonBean : MTLModel +@property(nonatomic,copy)NSString *version; +@property(nonatomic,strong)NSArray *bloglists; +@end diff --git a/iOSStudy/Bean/blogBean/BlogJsonBean.m b/iOSStudy/Bean/blogBean/BlogJsonBean.m new file mode 100644 index 0000000..11ecbd3 --- /dev/null +++ b/iOSStudy/Bean/blogBean/BlogJsonBean.m @@ -0,0 +1,22 @@ +// +// BlogJsonBean.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogJsonBean.h" + +@implementation BlogJsonBean + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"version": @"version", + @"bloglists": @"bloglists" + }; +} + +@end diff --git a/iOSStudy/Bean/versionBean/VersionBean.h b/iOSStudy/Bean/versionBean/VersionBean.h new file mode 100644 index 0000000..8866057 --- /dev/null +++ b/iOSStudy/Bean/versionBean/VersionBean.h @@ -0,0 +1,23 @@ +// +// VersionBean.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface VersionBean : MTLModel +/** + * 当前请求地址的URL + */ +@property(nonatomic,copy)NSString *url; + +/** + * 当前请求地址URL版本号 + */ +@property(nonatomic,copy)NSString *urlVersion; + +@end diff --git a/iOSStudy/Bean/versionBean/VersionBean.m b/iOSStudy/Bean/versionBean/VersionBean.m new file mode 100644 index 0000000..7c7641c --- /dev/null +++ b/iOSStudy/Bean/versionBean/VersionBean.m @@ -0,0 +1,24 @@ +// +// VersionBean.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "VersionBean.h" + +@implementation VersionBean + + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"url": @"url", + @"urlVersion": @"urlVersion" + }; +} + + +@end diff --git a/iOSStudy/Bean/videoBean/VideoBean.h b/iOSStudy/Bean/videoBean/VideoBean.h index c31da43..b85f495 100644 --- a/iOSStudy/Bean/videoBean/VideoBean.h +++ b/iOSStudy/Bean/videoBean/VideoBean.h @@ -8,9 +8,29 @@ #import "WebBean.h" -@interface VideoBean : WebBean +@interface VideoBean : MTLModel /** * zh 中文 us 英文 */ @property(nonatomic,copy)NSString *videoLanguageType; + + + +/** + * 网站标题 + */ +@property(nonatomic,copy)NSString*title; +/** + * 网站描述 + */ +@property(nonatomic,copy)NSString*subTitle; +/** + * 网站图片 + */ +@property(nonatomic,copy)NSString*webImage; +/** + * 网站地址 + */ +@property(nonatomic,copy)NSString*webUrl; + @end diff --git a/iOSStudy/Bean/videoBean/VideoBean.m b/iOSStudy/Bean/videoBean/VideoBean.m index 06d43ef..ab4a216 100644 --- a/iOSStudy/Bean/videoBean/VideoBean.m +++ b/iOSStudy/Bean/videoBean/VideoBean.m @@ -12,9 +12,13 @@ @implementation VideoBean + (NSDictionary *)JSONKeyPathsByPropertyKey{ - [super JSONKeyPathsByPropertyKey]; + return @{ - @"videoLanguageType": @"videoLanguageType", + @"title":@"title", + @"subTitle": @"subTitle", + @"webImage": @"webImage", + @"webUrl": @"webUrl", + @"videoLanguageType": @"videoLanguageType" }; } @end diff --git a/iOSStudy/Bean/webBean/WebBean.m b/iOSStudy/Bean/webBean/WebBean.m index 2adc3ea..fcbaba3 100644 --- a/iOSStudy/Bean/webBean/WebBean.m +++ b/iOSStudy/Bean/webBean/WebBean.m @@ -16,7 +16,7 @@ + (NSDictionary *)JSONKeyPathsByPropertyKey{ return @{ @"name": @"name", @"title": @"title", - @"subTitle": @"subTitile", + @"subTitle": @"subTitle", @"webImage": @"webImage", @"webUrl": @"webUrl" }; diff --git a/iOSStudy/Cell/STBaseTableViewCell.h b/iOSStudy/Cell/STBaseTableViewCell.h new file mode 100644 index 0000000..cf4a350 --- /dev/null +++ b/iOSStudy/Cell/STBaseTableViewCell.h @@ -0,0 +1,18 @@ +// +// BaseTableViewCell.h +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +@interface STBaseTableViewCell :SWTableViewCell +@property (weak, nonatomic) IBOutlet UIImageView *backgroundImageView; + +@property (weak, nonatomic) IBOutlet UIImageView *imageIcon; +@property (weak, nonatomic) IBOutlet UILabel *title; +@property (weak, nonatomic) IBOutlet UILabel *subtitle; + +@end diff --git a/iOSStudy/Cell/STBaseTableViewCell.m b/iOSStudy/Cell/STBaseTableViewCell.m new file mode 100644 index 0000000..68336c3 --- /dev/null +++ b/iOSStudy/Cell/STBaseTableViewCell.m @@ -0,0 +1,26 @@ +// +// BaseTableViewCell.m +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "STBaseTableViewCell.h" + +@implementation STBaseTableViewCell + +- (void)awakeFromNib { + // Initialization code + self.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + _imageIcon.layer.cornerRadius = 5; + _imageIcon.layer.masksToBounds = YES; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated { + [super setSelected:selected animated:animated]; + // Configure the view for the selected state +} + + +@end diff --git a/iOSStudy/Cell/STBaseTableViewCell.xib b/iOSStudy/Cell/STBaseTableViewCell.xib new file mode 100644 index 0000000..dbcc030 --- /dev/null +++ b/iOSStudy/Cell/STBaseTableViewCell.xib @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSStudy/Constants/EntityConstants.h b/iOSStudy/Constants/EntityConstants.h new file mode 100644 index 0000000..97defe3 --- /dev/null +++ b/iOSStudy/Constants/EntityConstants.h @@ -0,0 +1,15 @@ +// +// EntityConstants.h +// iOSStudy +// +// Created by chenguandong on 15/4/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +extern NSString *const FavouriteBean_title; +extern NSString *const FavouriteBean_subtitle; +extern NSString *const FavouriteBean_image_name; +extern NSString *const FavouriteBean_type; +extern NSString *const FavouriteBean_url; diff --git a/iOSStudy/Constants/EntityConstants.m b/iOSStudy/Constants/EntityConstants.m new file mode 100644 index 0000000..dfcdd0d --- /dev/null +++ b/iOSStudy/Constants/EntityConstants.m @@ -0,0 +1,15 @@ +// +// EntityConstants.m +// iOSStudy +// +// Created by chenguandong on 15/4/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "EntityConstants.h" + +NSString *const FavouriteBean_title = @"title"; +NSString *const FavouriteBean_subtitle = @"subtitle"; +NSString *const FavouriteBean_image_name = @"image_name"; +NSString *const FavouriteBean_type = @"type"; +NSString *const FavouriteBean_url = @"url"; diff --git a/iOSStudy/LICENSE b/iOSStudy/LICENSE new file mode 100644 index 0000000..fd0bea5 --- /dev/null +++ b/iOSStudy/LICENSE @@ -0,0 +1,22 @@ +The MIT License (MIT) + +Copyright (c) 2015 陈冠东 + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. + diff --git a/iOSStudy/Podfile b/iOSStudy/Podfile index c770198..a174ed8 100644 --- a/iOSStudy/Podfile +++ b/iOSStudy/Podfile @@ -1,9 +1,10 @@ platform :ios, '7.0' pod "AFNetworking", "~> 2.0" pod "SDWebImage" -pod 'FMDB' pod 'Mantle' pod 'SVProgressHUD' pod 'SVWebViewController' pod 'MJRefresh' pod 'SWTableViewCell', '~> 0.3.7' +pod 'Shimmer' + diff --git a/iOSStudy/Podfile.lock b/iOSStudy/Podfile.lock index ee61b81..3671611 100644 --- a/iOSStudy/Podfile.lock +++ b/iOSStudy/Podfile.lock @@ -1,59 +1,55 @@ PODS: - - AFNetworking (2.5.1): - - AFNetworking/NSURLConnection (= 2.5.1) - - AFNetworking/NSURLSession (= 2.5.1) - - AFNetworking/Reachability (= 2.5.1) - - AFNetworking/Security (= 2.5.1) - - AFNetworking/Serialization (= 2.5.1) - - AFNetworking/UIKit (= 2.5.1) - - AFNetworking/NSURLConnection (2.5.1): + - AFNetworking (2.5.3): + - AFNetworking/NSURLConnection (= 2.5.3) + - AFNetworking/NSURLSession (= 2.5.3) + - AFNetworking/Reachability (= 2.5.3) + - AFNetworking/Security (= 2.5.3) + - AFNetworking/Serialization (= 2.5.3) + - AFNetworking/UIKit (= 2.5.3) + - AFNetworking/NSURLConnection (2.5.3): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/NSURLSession (2.5.1): + - AFNetworking/NSURLSession (2.5.3): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/Reachability (2.5.1) - - AFNetworking/Security (2.5.1) - - AFNetworking/Serialization (2.5.1) - - AFNetworking/UIKit (2.5.1): + - AFNetworking/Reachability (2.5.3) + - AFNetworking/Security (2.5.3) + - AFNetworking/Serialization (2.5.3) + - AFNetworking/UIKit (2.5.3): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - FMDB (2.5): - - FMDB/standard (= 2.5) - - FMDB/common (2.5) - - FMDB/standard (2.5): - - FMDB/common - - Mantle (1.5.4): - - Mantle/extobjc (= 1.5.4) - - Mantle/extobjc (1.5.4) - - MJRefresh (0.0.1) - - SDWebImage (3.7.1): - - SDWebImage/Core (= 3.7.1) - - SDWebImage/Core (3.7.1) - - SVProgressHUD (1.1.2) + - Mantle (2.0): + - Mantle/extobjc (= 2.0) + - Mantle/extobjc (2.0) + - MJRefresh (1.4.6) + - SDWebImage (3.7.2): + - SDWebImage/Core (= 3.7.2) + - SDWebImage/Core (3.7.2) + - Shimmer (1.0.2) + - SVProgressHUD (1.1.3) - SVWebViewController (1.0) - SWTableViewCell (0.3.7) DEPENDENCIES: - AFNetworking (~> 2.0) - - FMDB - Mantle - MJRefresh - SDWebImage + - Shimmer - SVProgressHUD - SVWebViewController - SWTableViewCell (~> 0.3.7) SPEC CHECKSUMS: - AFNetworking: 8bee59492a6ff15d69130efa4d0dc67e0094a52a - FMDB: 0efa188cf0dd1ce82c27a478cd5f5fa245308677 - Mantle: d5fbaf30fbc58031223af13812c060e15934a1fe - MJRefresh: 02638d90855109026754562b7507e5c5eabfcc65 - SDWebImage: 116e88633b5b416ea0ca4b334a4ac59cf72dd38d - SVProgressHUD: da7a49e789af645d9279ffbca62318945a832438 - SVWebViewController: fbf917baa92744c54cfb89a52a4c056e409973a4 - SWTableViewCell: 25de71898e3fcd11cf75707ef90245acf990ec03 + AFNetworking: e1d86c2a96bb5d2e7408da36149806706ee122fe + Mantle: d7c75b6fb789b20f7ae30cd0d09435fe545896ff + MJRefresh: 2eaa3fd8f67fbb86497840fb0167446f7eb61dc7 + SDWebImage: 71b7cdc1d1721d6a82ed62889030225f2c249e29 + Shimmer: c5374be1c2b0c9e292fb05b339a513cf291cac86 + SVProgressHUD: 748080e4f36e603f6c02aec292664239df5279c1 + SVWebViewController: c36dda7326e81fcae0abf5d02bf7bbf7e41be901 + SWTableViewCell: 2a94aadc9d47b2b611fa064566bf57948b95b579 COCOAPODS: 0.35.0 diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m index e536f5d..1f93549 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m @@ -57,6 +57,7 @@ @interface AFHTTPRequestOperation () @end @implementation AFHTTPRequestOperation +@dynamic response; @dynamic lock; - (instancetype)initWithRequest:(NSURLRequest *)urlRequest { diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h index e1fb041..214937e 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h @@ -36,6 +36,14 @@ #import "AFSecurityPolicy.h" #import "AFNetworkReachabilityManager.h" +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + /** `AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management. @@ -151,12 +159,20 @@ /** The dispatch queue for the `completionBlock` of request operations. If `NULL` (default), the main queue is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_queue_t completionQueue; +#else +@property (nonatomic, assign) dispatch_queue_t completionQueue; +#endif /** The dispatch group for the `completionBlock` of request operations. If `NULL` (default), a private dispatch group is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_group_t completionGroup; +#else +@property (nonatomic, assign) dispatch_group_t completionGroup; +#endif ///--------------------------------------------- /// @name Creating and Initializing HTTP Clients diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h index bab8245..e77da03 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h @@ -32,6 +32,14 @@ #import "AFURLSessionManager.h" +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + /** `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths. diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m index 3a2323e..5a0fd6f 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m @@ -47,6 +47,7 @@ @interface AFHTTPSessionManager () @end @implementation AFHTTPSessionManager +@dynamic responseSerializer; + (instancetype)manager { return [[[self class] alloc] initWithBaseURL:nil]; diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h index 31ab79b..a458d10 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h @@ -23,6 +23,14 @@ #import #import +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { AFNetworkReachabilityStatusUnknown = -1, AFNetworkReachabilityStatusNotReachable = 0, diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m index 3415e98..fdcffea 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m @@ -86,7 +86,8 @@ static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused targ dispatch_async(dispatch_get_main_queue(), ^{ NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; - [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; + NSDictionary *userInfo = @{ AFNetworkingReachabilityNotificationStatusItem: @(status) }; + [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:userInfo]; }); } diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h index 4906f3b..ecf8999 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h @@ -57,7 +57,7 @@ typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { @property (nonatomic, assign) BOOL allowInvalidCertificates; /** - Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES` for `AFSSLPinningModePublicKey` or `AFSSLPinningModeCertificate`, otherwise `NO`. + Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. */ @property (nonatomic, assign) BOOL validatesDomainName; diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m index 41576bb..0ff8571 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m @@ -198,26 +198,11 @@ - (id)init { } self.validatesCertificateChain = YES; + self.validatesDomainName = YES; return self; } -#pragma mark - - -- (void)setSSLPinningMode:(AFSSLPinningMode)SSLPinningMode { - _SSLPinningMode = SSLPinningMode; - - switch (self.SSLPinningMode) { - case AFSSLPinningModePublicKey: - case AFSSLPinningModeCertificate: - self.validatesDomainName = YES; - break; - default: - self.validatesDomainName = NO; - break; - } -} - - (void)setPinnedCertificates:(NSArray *)pinnedCertificates { _pinnedCertificates = pinnedCertificates; @@ -254,14 +239,21 @@ - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); - if (self.SSLPinningMode != AFSSLPinningModeNone && !AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { + if (self.SSLPinningMode == AFSSLPinningModeNone) { + if (self.allowInvalidCertificates || AFServerTrustIsValid(serverTrust)){ + return YES; + } else { + return NO; + } + } else if (!AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { return NO; } - + NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); switch (self.SSLPinningMode) { case AFSSLPinningModeNone: - return YES; + default: + return NO; case AFSSLPinningModeCertificate: { NSMutableArray *pinnedCertificates = [NSMutableArray array]; for (NSData *certificateData in self.pinnedCertificates) { diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h index 7a5eccf..797c7ef 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h @@ -27,6 +27,14 @@ #import "AFURLResponseSerialization.h" #import "AFSecurityPolicy.h" +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + /** `AFURLConnectionOperation` is a subclass of `NSOperation` that implements `NSURLConnection` delegate methods. @@ -189,12 +197,20 @@ /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_queue_t completionQueue; +#else +@property (nonatomic, assign) dispatch_queue_t completionQueue; +#endif /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_group_t completionGroup; +#else +@property (nonatomic, assign) dispatch_group_t completionGroup; +#endif ///--------------------------------------------- /// @name Managing Request Operation Information diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m index 4c1b9f3..8f602bc 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m @@ -256,6 +256,47 @@ - (void)dealloc { #pragma mark - +// Workarounds for crashing behavior using Key-Value Observing with XCTest +// See https://github.com/AFNetworking/AFNetworking/issues/2523 + +- (void)setAllowsCellularAccess:(BOOL)allowsCellularAccess { + [self willChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; + _allowsCellularAccess = allowsCellularAccess; + [self didChangeValueForKey:NSStringFromSelector(@selector(allowsCellularAccess))]; +} + +- (void)setCachePolicy:(NSURLRequestCachePolicy)cachePolicy { + [self willChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; + _cachePolicy = cachePolicy; + [self didChangeValueForKey:NSStringFromSelector(@selector(cachePolicy))]; +} + +- (void)setHTTPShouldHandleCookies:(BOOL)HTTPShouldHandleCookies { + [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; + _HTTPShouldHandleCookies = HTTPShouldHandleCookies; + [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldHandleCookies))]; +} + +- (void)setHTTPShouldUsePipelining:(BOOL)HTTPShouldUsePipelining { + [self willChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; + _HTTPShouldUsePipelining = HTTPShouldUsePipelining; + [self didChangeValueForKey:NSStringFromSelector(@selector(HTTPShouldUsePipelining))]; +} + +- (void)setNetworkServiceType:(NSURLRequestNetworkServiceType)networkServiceType { + [self willChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; + _networkServiceType = networkServiceType; + [self didChangeValueForKey:NSStringFromSelector(@selector(networkServiceType))]; +} + +- (void)setTimeoutInterval:(NSTimeInterval)timeoutInterval { + [self willChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; + _timeoutInterval = timeoutInterval; + [self didChangeValueForKey:NSStringFromSelector(@selector(timeoutInterval))]; +} + +#pragma mark - + - (NSDictionary *)HTTPRequestHeaders { return [NSDictionary dictionaryWithDictionary:self.mutableHTTPRequestHeaders]; } diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m index c5a8563..b8e4d1c 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m @@ -532,7 +532,10 @@ - (id)copyWithZone:(NSZone *)zone { static UIImage * AFImageWithDataAtScale(NSData *data, CGFloat scale) { UIImage *image = [[UIImage alloc] initWithData:data]; - + if (image.images) { + return image; + } + return [[UIImage alloc] initWithCGImage:[image CGImage] scale:scale orientation:image.imageOrientation]; } @@ -549,10 +552,11 @@ - (id)copyWithZone:(NSZone *)zone { } else if ([response.MIMEType isEqualToString:@"image/jpeg"]) { imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); - // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so if so, fall back to AFImageWithDataAtScale if (imageRef) { CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef); CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace); + + // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so fall back to AFImageWithDataAtScale if (imageColorSpaceModel == kCGColorSpaceModelCMYK) { CGImageRelease(imageRef); imageRef = NULL; @@ -584,7 +588,8 @@ - (id)copyWithZone:(NSZone *)zone { return image; } - size_t bytesPerRow = 0; // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate + // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate + size_t bytesPerRow = 0; CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h index 966c3e8..584d964 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h @@ -27,6 +27,14 @@ #import "AFSecurityPolicy.h" #import "AFNetworkReachabilityManager.h" +#ifndef NS_DESIGNATED_INITIALIZER +#if __has_attribute(objc_designated_initializer) +#define NS_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer)) +#else +#define NS_DESIGNATED_INITIALIZER +#endif +#endif + /** `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. @@ -152,12 +160,20 @@ /** The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_queue_t completionQueue; +#else +@property (nonatomic, assign) dispatch_queue_t completionQueue; +#endif /** The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. */ +#if OS_OBJECT_HAVE_OBJC_SUPPORT @property (nonatomic, strong) dispatch_group_t completionGroup; +#else +@property (nonatomic, assign) dispatch_group_t completionGroup; +#endif ///--------------------------------- /// @name Working Around System Bugs diff --git a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m index a6ebbee..89bcda9 100644 --- a/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m +++ b/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m @@ -272,6 +272,10 @@ static inline void af_swizzleSelector(Class class, SEL originalSelector, SEL swi } } +static inline void af_addMethod(Class class, SEL selector, Method method) { + class_addMethod(class, selector, method_getImplementation(method), method_getTypeEncoding(method)); +} + static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume"; static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend"; @@ -280,12 +284,18 @@ @interface NSURLSessionTask (_AFStateObserving) @implementation NSURLSessionTask (_AFStateObserving) -+ (void)load { - static dispatch_once_t onceToken; - dispatch_once(&onceToken, ^{ - af_swizzleSelector([self class], @selector(resume), @selector(af_resume)); - af_swizzleSelector([self class], @selector(suspend), @selector(af_suspend)); - }); ++ (void)initialize { + if ([NSURLSessionTask class]) { + NSURLSessionDataTask *dataTask = [[NSURLSession sessionWithConfiguration:nil] dataTaskWithURL:nil]; + Class taskClass = [dataTask superclass]; + + af_addMethod(taskClass, @selector(af_resume), class_getInstanceMethod(self, @selector(af_resume))); + af_addMethod(taskClass, @selector(af_suspend), class_getInstanceMethod(self, @selector(af_suspend))); + af_swizzleSelector(taskClass, @selector(resume), @selector(af_resume)); + af_swizzleSelector(taskClass, @selector(suspend), @selector(af_suspend)); + + [dataTask cancel]; + } } #pragma mark - @@ -402,7 +412,7 @@ - (NSString *)taskDescriptionForSessionTasks { - (void)taskDidResume:(NSNotification *)notification { NSURLSessionTask *task = notification.object; - if ([task isKindOfClass:[NSURLSessionTask class]]) { + if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidResumeNotification object:task]; @@ -413,7 +423,7 @@ - (void)taskDidResume:(NSNotification *)notification { - (void)taskDidSuspend:(NSNotification *)notification { NSURLSessionTask *task = notification.object; - if ([task isKindOfClass:[NSURLSessionTask class]]) { + if ([task respondsToSelector:@selector(taskDescription)]) { if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidSuspendNotification object:task]; diff --git a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m index 5c6d4fa..03afaf0 100644 --- a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m +++ b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m @@ -114,7 +114,9 @@ - (BOOL)isNetworkActivityIndicatorVisible { } - (void)updateNetworkActivityIndicatorVisibility { +#if !defined(AF_APP_EXTENSIONS) [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]]; +#endif } - (void)setActivityCount:(NSInteger)activityCount { diff --git a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h index 3cc1694..a6f3fc0 100644 --- a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h +++ b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h @@ -24,7 +24,7 @@ #import -#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) #import diff --git a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m index bb4eabc..6890563 100644 --- a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m +++ b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m @@ -22,7 +22,7 @@ #import "UIAlertView+AFNetworking.h" -#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) #import "AFURLConnectionOperation.h" @@ -62,26 +62,32 @@ + (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION { - va_list otherTitleList; - va_start(otherTitleList, otherButtonTitles); - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; - for(NSString *otherTitle = otherButtonTitles; otherTitle != nil; otherTitle = va_arg(otherTitleList, NSString *)){ - [alertView addButtonWithTitle:otherTitle]; + NSMutableArray *mutableOtherTitles = [NSMutableArray array]; + va_list otherButtonTitleList; + va_start(otherButtonTitleList, otherButtonTitles); + { + for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) { + [mutableOtherTitles addObject:otherButtonTitle]; + } } - va_end(otherTitleList); - __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { + va_end(otherButtonTitleList); + __block __weak id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { NSError *error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey]; if (error) { NSString *title, *message; AFGetAlertViewTitleAndMessageFromError(error, &title, &message); + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; + for (NSString *otherButtonTitle in mutableOtherTitles) { + [alertView addButtonWithTitle:otherButtonTitle]; + } [alertView setTitle:title]; [alertView setMessage:message]; [alertView show]; } - [[NSNotificationCenter defaultCenter] removeObserver:observer name:AFNetworkingTaskDidCompleteNotification object:notification.object]; + [[NSNotificationCenter defaultCenter] removeObserver:observer]; }]; } #endif @@ -99,14 +105,17 @@ + (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOp cancelButtonTitle:(NSString *)cancelButtonTitle otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION { - va_list otherTitleList; - va_start(otherTitleList, otherButtonTitles); - UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; - for(NSString *otherTitle = otherButtonTitles; otherTitle != nil; otherTitle = va_arg(otherTitleList, NSString *)){ - [alertView addButtonWithTitle:otherTitle]; + NSMutableArray *mutableOtherTitles = [NSMutableArray array]; + va_list otherButtonTitleList; + va_start(otherButtonTitleList, otherButtonTitles); + { + for (NSString *otherButtonTitle = otherButtonTitles; otherButtonTitle != nil; otherButtonTitle = va_arg(otherButtonTitleList, NSString *)) { + [mutableOtherTitles addObject:otherButtonTitle]; + } } - va_end(otherTitleList); - __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidFinishNotification object:operation queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { + va_end(otherButtonTitleList); + + __block __weak id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidFinishNotification object:operation queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { if (notification.object && [notification.object isKindOfClass:[AFURLConnectionOperation class]]) { NSError *error = [(AFURLConnectionOperation *)notification.object error]; @@ -114,13 +123,17 @@ + (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOp NSString *title, *message; AFGetAlertViewTitleAndMessageFromError(error, &title, &message); + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; + for (NSString *otherButtonTitle in mutableOtherTitles) { + [alertView addButtonWithTitle:otherButtonTitle]; + } [alertView setTitle:title]; [alertView setMessage:message]; [alertView show]; } } - [[NSNotificationCenter defaultCenter] removeObserver:observer name:AFNetworkingOperationDidFinishNotification object:notification.object]; + [[NSNotificationCenter defaultCenter] removeObserver:observer]; }]; } diff --git a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h index 5838b56..1704ca1 100644 --- a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h +++ b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h @@ -40,7 +40,7 @@ ///---------------------------- /** - The image cache used to improve image loadiing performance on scroll views. By default, this is an `NSCache` subclass conforming to the `AFImageCache` protocol, which listens for notification warnings and evicts objects accordingly. + The image cache used to improve image loading performance on scroll views. By default, this is an `NSCache` subclass conforming to the `AFImageCache` protocol, which listens for notification warnings and evicts objects accordingly. */ + (id )sharedImageCache; diff --git a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m index 4ff13e4..7cc7f37 100644 --- a/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m +++ b/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m @@ -136,6 +136,11 @@ - (void)loadRequest:(NSURLRequest *)request #pragma clang diagnostic ignored "-Wgnu" __strong __typeof(weakSelf) strongSelf = weakSelf; [strongSelf loadData:data MIMEType:(MIMEType ?: [operation.response MIMEType]) textEncodingName:(textEncodingName ?: [operation.response textEncodingName]) baseURL:[operation.response URL]]; + + if ([strongSelf.delegate respondsToSelector:@selector(webViewDidFinishLoad:)]) { + [strongSelf.delegate webViewDidFinishLoad:strongSelf]; + } + #pragma clang diagnostic pop } failure:^(AFHTTPRequestOperation * __unused operation, NSError *error) { if (failure) { @@ -144,6 +149,10 @@ - (void)loadRequest:(NSURLRequest *)request }]; [self.af_HTTPRequestOperation start]; + + if ([self.delegate respondsToSelector:@selector(webViewDidStartLoad:)]) { + [self.delegate webViewDidStartLoad:self]; + } } @end diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshComponent.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshComponent.h new file mode 120000 index 0000000..ae7f688 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshComponent.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooter.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooter.h new file mode 120000 index 0000000..1ae69e3 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooter.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifFooter.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifFooter.h new file mode 120000 index 0000000..13717fa --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifFooter.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifHeader.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifHeader.h new file mode 120000 index 0000000..e4e9f63 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshGifHeader.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeader.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeader.h new file mode 120000 index 0000000..5c54c3f --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeader.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendFooter.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendFooter.h new file mode 120000 index 0000000..9c35a21 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendFooter.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendHeader.h b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendHeader.h new file mode 120000 index 0000000..70f2850 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshLegendHeader.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/MTLTransformerErrorHandling.h b/iOSStudy/Pods/Headers/Public/Mantle/MTLTransformerErrorHandling.h new file mode 120000 index 0000000..b885860 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Mantle/MTLTransformerErrorHandling.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLTransformerErrorHandling.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLJSONKeyPath.h b/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLJSONKeyPath.h new file mode 120000 index 0000000..b35a019 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLJSONKeyPath.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSDictionary+MTLJSONKeyPath.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLMappingAdditions.h b/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLMappingAdditions.h new file mode 120000 index 0000000..3cd348a --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLMappingAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSDictionary+MTLMappingAdditions.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmering.h b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmering.h new file mode 120000 index 0000000..6127444 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmering.h @@ -0,0 +1 @@ +../../../Shimmer/FBShimmering/FBShimmering.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringLayer.h b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringLayer.h new file mode 120000 index 0000000..039fed3 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringLayer.h @@ -0,0 +1 @@ +../../../Shimmer/FBShimmering/FBShimmeringLayer.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringView.h b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringView.h new file mode 120000 index 0000000..9885aa3 --- /dev/null +++ b/iOSStudy/Pods/Headers/Public/Shimmer/FBShimmeringView.h @@ -0,0 +1 @@ +../../../Shimmer/FBShimmering/FBShimmeringView.h \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/LICENSE b/iOSStudy/Pods/MJRefresh/LICENSE index 7f7ecfd..11bf234 100644 --- a/iOSStudy/Pods/MJRefresh/LICENSE +++ b/iOSStudy/Pods/MJRefresh/LICENSE @@ -1,4 +1,4 @@ -Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h old mode 100755 new mode 100644 index caebbd9..f3e97fd --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h @@ -1,32 +1,9 @@ -/** - * 代码地址: https://github.com/CoderMJLee/MJRefresh - * 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 - * 友情提示: 遇到一些小问题, 最好及时下载最新的代码试试 - */ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 #import "UIScrollView+MJRefresh.h" - -/** - MJ友情提示: - 1. 添加头部控件的方法 - [self.tableView addHeaderWithTarget:self action:@selector(headerRereshing)]; - 或者 - [self.tableView addHeaderWithCallback:^{ }]; - - 2. 添加尾部控件的方法 - [self.tableView addFooterWithTarget:self action:@selector(footerRereshing)]; - 或者 - [self.tableView addFooterWithCallback:^{ }]; - - 3. 可以在MJRefreshConst.h和MJRefreshConst.m文件中自定义显示的文字内容和文字颜色 - - 4. 本框架兼容iOS6\iOS7,iPhone\iPad横竖屏 - - 5.自动进入刷新状态 - 1> [self.tableView headerBeginRefreshing]; - 2> [self.tableView footerBeginRefreshing]; - - 6.结束刷新 - 1> [self.tableView headerEndRefreshing]; - 2> [self.tableView footerEndRefreshing]; -*/ \ No newline at end of file +#import "MJRefreshGifHeader.h" +#import "MJRefreshLegendHeader.h" +#import "MJRefreshGifFooter.h" +#import "MJRefreshLegendFooter.h" +#import "MJRefreshConst.h" \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.h new file mode 100644 index 0000000..c559da3 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.h @@ -0,0 +1,37 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshComponent.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// 刷新组件:基本的开始刷新和结束刷新行为 + +#import + +@interface MJRefreshComponent : UIView +{ + UIEdgeInsets _scrollViewOriginalInset; + __weak UIScrollView *_scrollView; +} + +#pragma mark - 文字处理 +/** 文字颜色 */ +@property (strong, nonatomic) UIColor *textColor; +/** 字体大小 */ +@property (strong, nonatomic) UIFont *font; + +#pragma mark - 刷新处理 +/** 正在刷新的回调 */ +@property (copy, nonatomic) void (^refreshingBlock)(); +/** 设置回调对象和回调方法 */ +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action; +@property (weak, nonatomic) id refreshingTarget; +@property (assign, nonatomic) SEL refreshingAction; +/** 进入刷新状态 */ +- (void)beginRefreshing; +/** 结束刷新状态 */ +- (void)endRefreshing; +/** 是否正在刷新 */ +- (BOOL)isRefreshing; +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.m new file mode 100644 index 0000000..b336aa2 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.m @@ -0,0 +1,81 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshComponent.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshComponent.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshComponent() +/** 记录scrollView刚开始的inset */ +@property (assign, nonatomic) UIEdgeInsets scrollViewOriginalInset; +/** 父控件 */ +@property (weak, nonatomic) UIScrollView *scrollView; +@end + +@implementation MJRefreshComponent +#pragma mark - 初始化 +- (instancetype)initWithFrame:(CGRect)frame +{ + if (self = [super initWithFrame:frame]) { + // 基本属性 + self.autoresizingMask = UIViewAutoresizingFlexibleWidth; + self.backgroundColor = [UIColor clearColor]; + + // 默认文字颜色和字体大小 + self.textColor = MJRefreshLabelTextColor; + self.font = MJRefreshLabelFont; + } + return self; +} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + // 旧的父控件 + [self.superview removeObserver:self forKeyPath:MJRefreshContentOffset context:nil]; + + if (newSuperview) { // 新的父控件 + [newSuperview addObserver:self forKeyPath:MJRefreshContentOffset options:NSKeyValueObservingOptionNew context:nil]; + + // 设置宽度 + self.mj_w = newSuperview.mj_w; + // 设置位置 + self.mj_x = 0; + + // 记录UIScrollView + self.scrollView = (UIScrollView *)newSuperview; + // 设置永远支持垂直弹簧效果 + self.scrollView.alwaysBounceVertical = YES; + // 记录UIScrollView最开始的contentInset + self.scrollViewOriginalInset = self.scrollView.contentInset; + } +} + +#pragma mark - 公共方法 +- (void)setRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + self.refreshingTarget = target; + self.refreshingAction = action; +} + +- (void)beginRefreshing +{ + +} + +- (void)endRefreshing +{ + +} + +- (BOOL)isRefreshing { + return NO; +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h old mode 100755 new mode 100644 index ae71f2a..987ee39 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h @@ -1,41 +1,48 @@ -// -// MJRefreshConst.h -// MJRefresh -// -// Created by mj on 14-1-3. -// Copyright (c) 2014年 itcast. All rights reserved. -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 #import +// 日志输出 #ifdef DEBUG #define MJLog(...) NSLog(__VA_ARGS__) #else #define MJLog(...) #endif -// objc_msgSend +// 过期提醒 +#define MJDeprecated(instead) NS_DEPRECATED(2_0, 2_0, 2_0, 2_0, instead) + +// 运行时objc_msgSend #define msgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) #define msgTarget(target) (__bridge void *)(target) +// RGB颜色 #define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] + // 文字颜色 -#define MJRefreshLabelTextColor MJColor(150, 150, 150) +#define MJRefreshLabelTextColor MJColor(100, 100, 100) + +// 字体大小 +#define MJRefreshLabelFont [UIFont boldSystemFontOfSize:13] // 图片路径 #define MJRefreshSrcName(file) [@"MJRefresh.bundle" stringByAppendingPathComponent:file] -UIKIT_EXTERN const CGFloat MJRefreshViewHeight; +// 常量 +UIKIT_EXTERN const CGFloat MJRefreshHeaderHeight; +UIKIT_EXTERN const CGFloat MJRefreshFooterHeight; UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; -UIKIT_EXTERN NSString *const MJRefreshFooterPullToRefresh; -UIKIT_EXTERN NSString *const MJRefreshFooterReleaseToRefresh; -UIKIT_EXTERN NSString *const MJRefreshFooterRefreshing; +UIKIT_EXTERN NSString *const MJRefreshHeaderUpdatedTimeKey; +UIKIT_EXTERN NSString *const MJRefreshContentOffset; +UIKIT_EXTERN NSString *const MJRefreshContentSize; +UIKIT_EXTERN NSString *const MJRefreshPanState; -UIKIT_EXTERN NSString *const MJRefreshHeaderPullToRefresh; -UIKIT_EXTERN NSString *const MJRefreshHeaderReleaseToRefresh; -UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshing; -UIKIT_EXTERN NSString *const MJRefreshHeaderTimeKey; +UIKIT_EXTERN NSString *const MJRefreshHeaderStateIdleText; +UIKIT_EXTERN NSString *const MJRefreshHeaderStatePullingText; +UIKIT_EXTERN NSString *const MJRefreshHeaderStateRefreshingText; -UIKIT_EXTERN NSString *const MJRefreshContentOffset; -extern NSString *const MJRefreshContentSize; \ No newline at end of file +UIKIT_EXTERN NSString *const MJRefreshFooterStateIdleText; +UIKIT_EXTERN NSString *const MJRefreshFooterStateRefreshingText; +UIKIT_EXTERN NSString *const MJRefreshFooterStateNoMoreDataText; \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m old mode 100755 new mode 100644 index 8280e44..5d44bdb --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m @@ -1,25 +1,21 @@ -// -// MJRefreshConst.m -// MJRefresh -// -// Created by mj on 14-1-3. -// Copyright (c) 2014年 itcast. All rights reserved. -// - +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 #import -const CGFloat MJRefreshViewHeight = 64.0; +const CGFloat MJRefreshHeaderHeight = 54.0; +const CGFloat MJRefreshFooterHeight = 44.0; const CGFloat MJRefreshFastAnimationDuration = 0.25; const CGFloat MJRefreshSlowAnimationDuration = 0.4; -NSString *const MJRefreshFooterPullToRefresh = @"上拉可以加载更多数据"; -NSString *const MJRefreshFooterReleaseToRefresh = @"松开立即加载更多数据"; -NSString *const MJRefreshFooterRefreshing = @"正在帮你加载数据..."; +NSString *const MJRefreshHeaderUpdatedTimeKey = @"MJRefreshHeaderUpdatedTimeKey"; +NSString *const MJRefreshContentOffset = @"contentOffset"; +NSString *const MJRefreshContentSize = @"contentSize"; +NSString *const MJRefreshPanState = @"pan.state"; -NSString *const MJRefreshHeaderPullToRefresh = @"下拉可以刷新"; -NSString *const MJRefreshHeaderReleaseToRefresh = @"松开立即刷新"; -NSString *const MJRefreshHeaderRefreshing = @"正在帮你刷新..."; -NSString *const MJRefreshHeaderTimeKey = @"MJRefreshHeaderView"; +NSString *const MJRefreshHeaderStateIdleText = @"下拉可以刷新"; +NSString *const MJRefreshHeaderStatePullingText = @"松开立即刷新"; +NSString *const MJRefreshHeaderStateRefreshingText = @"正在刷新数据中..."; -NSString *const MJRefreshContentOffset = @"contentOffset"; -NSString *const MJRefreshContentSize = @"contentSize"; \ No newline at end of file +NSString *const MJRefreshFooterStateIdleText = @"点击加载更多"; +NSString *const MJRefreshFooterStateRefreshingText = @"正在加载更多的数据..."; +NSString *const MJRefreshFooterStateNoMoreDataText = @"已经全部加载完毕"; \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.h new file mode 100644 index 0000000..228a9eb --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.h @@ -0,0 +1,40 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshComponent.h" + +typedef enum { + MJRefreshFooterStateIdle = 1, // 普通闲置状态 + MJRefreshFooterStateRefreshing, // 正在刷新中的状态 + MJRefreshFooterStateNoMoreData // 所有数据加载完毕,没有更多的数据了 +} MJRefreshFooterState; + +@interface MJRefreshFooter : MJRefreshComponent +/** 提示没有更多的数据 */ +- (void)noticeNoMoreData; +/** 重置没有更多的数据(消除没有更多数据的状态) */ +- (void)resetNoMoreData; + +/** 刷新控件的状态(交给子类重写) */ +@property (assign, nonatomic) MJRefreshFooterState state; + +/** 是否隐藏状态标签 */ +@property (assign, nonatomic, getter=isStateHidden) BOOL stateHidden; + +/** + * 设置state状态下的状态文字内容title + */ +- (void)setTitle:(NSString *)title forState:(MJRefreshFooterState)state; + +/** 是否自动刷新(默认为YES) */ +@property (assign, nonatomic, getter=isAutomaticallyRefresh) BOOL automaticallyRefresh; + +/** 当底部控件出现多少时就自动刷新(默认为1.0,也就是底部控件完全出现时,才会自动刷新) */ +@property (assign, nonatomic) CGFloat appearencePercentTriggerAutoRefresh; +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.m new file mode 100644 index 0000000..a272da8 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.m @@ -0,0 +1,325 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshFooter.h" +#import "MJRefreshConst.h" +#import "UIScrollView+MJExtension.h" +#import "MJRefreshHeader.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJRefresh.h" +#import + +@interface MJRefreshFooter() +/** 显示状态文字的标签 */ +@property (weak, nonatomic) UILabel *stateLabel; +/** 点击可以加载更多 */ +@property (weak, nonatomic) UIButton *loadMoreButton; +/** 没有更多的数据 */ +@property (weak, nonatomic) UILabel *noMoreLabel; +/** 即将要执行的代码 */ +@property (strong, nonatomic) NSMutableArray *willExecuteBlocks; +@end + +@implementation MJRefreshFooter +#pragma mark - 懒加载 +- (NSMutableArray *)willExecuteBlocks +{ + if (!_willExecuteBlocks) { + self.willExecuteBlocks = [NSMutableArray array]; + } + return _willExecuteBlocks; +} + +- (UIButton *)loadMoreButton +{ + if (!_loadMoreButton) { + UIButton *loadMoreButton = [[UIButton alloc] init]; + loadMoreButton.backgroundColor = [UIColor clearColor]; + [loadMoreButton addTarget:self action:@selector(buttonClick) forControlEvents:UIControlEventTouchUpInside]; + [self addSubview:_loadMoreButton = loadMoreButton]; + } + return _loadMoreButton; +} + +- (UILabel *)noMoreLabel +{ + if (!_noMoreLabel) { + UILabel *noMoreLabel = [[UILabel alloc] init]; + noMoreLabel.backgroundColor = [UIColor clearColor]; + noMoreLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_noMoreLabel = noMoreLabel]; + } + return _noMoreLabel; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + UILabel *stateLabel = [[UILabel alloc] init]; + stateLabel.backgroundColor = [UIColor clearColor]; + stateLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_stateLabel = stateLabel]; + } + return _stateLabel; +} + +#pragma mark - 初始化方法 +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + // 默认底部控件100%出现时才会自动刷新 + self.appearencePercentTriggerAutoRefresh = 1.0; + + // 设置为默认状态 + self.automaticallyRefresh = YES; + self.state = MJRefreshFooterStateIdle; + + // 初始化文字 + [self setTitle:MJRefreshFooterStateIdleText forState:MJRefreshFooterStateIdle]; + [self setTitle:MJRefreshFooterStateRefreshingText forState:MJRefreshFooterStateRefreshing]; + [self setTitle:MJRefreshFooterStateNoMoreDataText forState:MJRefreshFooterStateNoMoreData]; + } + return self; +} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + // 旧的父控件 + [self.superview removeObserver:self forKeyPath:MJRefreshContentSize context:nil]; + [self.superview removeObserver:self forKeyPath:MJRefreshPanState context:nil]; + + if (newSuperview) { // 新的父控件 + // 监听 + [newSuperview addObserver:self forKeyPath:MJRefreshContentSize options:NSKeyValueObservingOptionNew context:nil]; + [newSuperview addObserver:self forKeyPath:MJRefreshPanState options:NSKeyValueObservingOptionNew context:nil]; + + self.mj_h = MJRefreshFooterHeight; + _scrollView.mj_insetB += self.mj_h; + + // 重新调整frame + [self adjustFrameWithContentSize]; + } else { // 被移除了 + _scrollView.mj_insetB -= self.mj_h; + } +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.loadMoreButton.frame = self.bounds; + self.stateLabel.frame = self.bounds; + self.noMoreLabel.frame = self.bounds; +} + +#pragma mark - 私有方法 +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // 遇到这些情况就直接返回 + if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden) return; + + if (self.state == MJRefreshFooterStateIdle) { + // 当是Idle状态时,才需要检测是否要进入刷新状态 + if ([keyPath isEqualToString:MJRefreshPanState]) { + if (_scrollView.panGestureRecognizer.state == UIGestureRecognizerStateEnded) {// 手松开 + if (_scrollView.mj_insetT + _scrollView.mj_contentSizeH <= _scrollView.mj_h) { // 不够一个屏幕 + if (_scrollView.mj_offsetY > - _scrollView.mj_insetT) { // 向上拽 + [self beginRefreshing]; + } + } else { // 超出一个屏幕 + if (_scrollView.mj_offsetY > _scrollView.mj_contentSizeH + _scrollView.mj_insetB - _scrollView.mj_h) { + [self beginRefreshing]; + } + } + } + } else if ([keyPath isEqualToString:MJRefreshContentOffset]) { + if (self.state != MJRefreshFooterStateRefreshing && self.automaticallyRefresh) { + // 根据contentOffset调整state + [self adjustStateWithContentOffset]; + } + } + } + + // 不管是什么状态,都要调整位置 + if ([keyPath isEqualToString:MJRefreshContentSize]) { + [self adjustFrameWithContentSize]; + } +} + +#pragma mark 根据contentOffset调整state +- (void)adjustStateWithContentOffset +{ + if (self.mj_y == 0) return; + + if (_scrollView.mj_insetT + _scrollView.mj_contentSizeH > _scrollView.mj_h) { // 内容超过一个屏幕 + // 这里的_scrollView.mj_contentSizeH替换掉self.mj_y更为合理 + if (_scrollView.mj_offsetY > _scrollView.mj_contentSizeH - _scrollView.mj_h + self.mj_h * self.appearencePercentTriggerAutoRefresh + _scrollView.mj_insetB - self.mj_h) { + // 当底部刷新控件完全出现时,才刷新 + [self beginRefreshing]; + } + } +} + +- (void)adjustFrameWithContentSize +{ + // 设置位置 + self.mj_y = _scrollView.mj_contentSizeH; +} + +- (void)buttonClick +{ + [self beginRefreshing]; +} + +#pragma mark - 公共方法 +- (void)setHidden:(BOOL)hidden +{ + __weak typeof(self) weakSelf = self; + BOOL lastHidden = weakSelf.isHidden; + CGFloat h = weakSelf.mj_h; + [weakSelf.willExecuteBlocks addObject:^{ + if (!lastHidden && hidden) { + weakSelf.state = MJRefreshFooterStateIdle; + _scrollView.mj_insetB -= h; + } else if (lastHidden && !hidden) { + _scrollView.mj_insetB += h; + + [weakSelf adjustFrameWithContentSize]; + } + }]; + [weakSelf setNeedsDisplay]; // 放到drawRect是为了延迟执行,防止因为修改了inset,导致循环调用数据源方法 + + [super setHidden:hidden]; +} + +- (void)drawRect:(CGRect)rect +{ + [super drawRect:rect]; + + for (void (^block)() in self.willExecuteBlocks) { + block(); + } + [self.willExecuteBlocks removeAllObjects]; +} + +- (void)beginRefreshing +{ + self.state = MJRefreshFooterStateRefreshing; +} + +- (void)endRefreshing +{ + self.state = MJRefreshFooterStateIdle; +} + +- (BOOL)isRefreshing +{ + return self.state == MJRefreshFooterStateRefreshing; +} + +- (void)noticeNoMoreData +{ + self.state = MJRefreshFooterStateNoMoreData; +} + +- (void)resetNoMoreData +{ + self.state = MJRefreshFooterStateIdle; +} + +- (void)setTitle:(NSString *)title forState:(MJRefreshFooterState)state +{ + if (title == nil) return; + + // 刷新当前状态的文字 + switch (state) { + case MJRefreshFooterStateIdle: + [self.loadMoreButton setTitle:title forState:UIControlStateNormal]; + break; + + case MJRefreshFooterStateRefreshing: + self.stateLabel.text = title; + break; + + case MJRefreshFooterStateNoMoreData: + self.noMoreLabel.text = title; + break; + + default: + break; + } +} + +- (void)setState:(MJRefreshFooterState)state +{ + if (_state == state) return; + + _state = state; + + switch (state) { + case MJRefreshFooterStateIdle: + self.noMoreLabel.hidden = YES; + self.stateLabel.hidden = YES; + self.loadMoreButton.hidden = NO; + break; + + case MJRefreshFooterStateRefreshing: + { + self.loadMoreButton.hidden = YES; + self.noMoreLabel.hidden = YES; + if (!self.stateHidden) self.stateLabel.hidden = NO; + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + if (self.refreshingBlock) { + self.refreshingBlock(); + } + if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { + msgSend(msgTarget(self.refreshingTarget), self.refreshingAction, self); + } + }); + } + break; + + case MJRefreshFooterStateNoMoreData: + self.loadMoreButton.hidden = YES; + self.noMoreLabel.hidden = NO; + self.stateLabel.hidden = YES; + break; + + default: + break; + } +} + +- (void)setTextColor:(UIColor *)textColor +{ + [super setTextColor:textColor]; + + self.stateLabel.textColor = textColor; + [self.loadMoreButton setTitleColor:textColor forState:UIControlStateNormal]; + self.noMoreLabel.textColor = textColor; +} + +- (void)setFont:(UIFont *)font +{ + [super setFont:font]; + + self.loadMoreButton.titleLabel.font = font; + self.noMoreLabel.font = font; + self.stateLabel.font = font; +} + +- (void)setStateHidden:(BOOL)stateHidden +{ + _stateHidden = stateHidden; + + self.stateLabel.hidden = stateHidden; + [self setNeedsLayout]; +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.h new file mode 100644 index 0000000..56cdfce --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.h @@ -0,0 +1,15 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshGifFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshFooter.h" + +@interface MJRefreshGifFooter : MJRefreshFooter +/** 正在刷新时的动画图片 */ +@property (strong, nonatomic) NSArray *refreshingImages; +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m new file mode 100644 index 0000000..9176827 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m @@ -0,0 +1,90 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshGifFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshGifFooter.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshGifFooter() +/** 播放动画图片的控件 */ +@property (weak, nonatomic) UIImageView *gifView; +@end + +@implementation MJRefreshGifFooter +#pragma mark - 懒加载 +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +#pragma mark - 初始化方法 +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // 指示器 + self.gifView.frame = self.bounds; + if (self.stateHidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - 90; + } +} + +#pragma mark - 公共方法 +- (void)setState:(MJRefreshFooterState)state +{ + if (self.state == state) return; + + switch (state) { + case MJRefreshFooterStateIdle: + self.gifView.hidden = YES; + [self.gifView stopAnimating]; + break; + + case MJRefreshFooterStateRefreshing: + self.gifView.hidden = NO; + [self.gifView startAnimating]; + break; + + case MJRefreshFooterStateNoMoreData: + self.gifView.hidden = YES; + [self.gifView stopAnimating]; + break; + + default: + break; + } + + // super里面有回调,应该在最后面调用 + [super setState:state]; +} + +- (void)setRefreshingImages:(NSArray *)refreshingImages +{ + _refreshingImages = refreshingImages; + + self.gifView.animationImages = refreshingImages; + self.gifView.animationDuration = refreshingImages.count * 0.1; + + // 根据图片设置控件的高度 + UIImage *image = [refreshingImages firstObject]; + if (image.size.height > self.mj_h) { + _scrollView.mj_insetB -= self.mj_h; + self.mj_h = image.size.height; + _scrollView.mj_insetB += self.mj_h; + } +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.h new file mode 100644 index 0000000..8c1405b --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.h @@ -0,0 +1,15 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshGifHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// 带有gif图片功能的下拉刷新控件 + +#import "MJRefreshHeader.h" + +@interface MJRefreshGifHeader : MJRefreshHeader +/** 设置state状态下的动画图片images */ +- (void)setImages:(NSArray *)images forState:(MJRefreshHeaderState)state; +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m new file mode 100644 index 0000000..ecdf5cc --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m @@ -0,0 +1,130 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshGifHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshGifHeader.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshGifHeader() +/** 所有状态对应的动画图片 */ +@property (strong, nonatomic) NSMutableDictionary *stateImages; + +/** 播放动画图片的控件 */ +@property (weak, nonatomic) UIImageView *gifView; +@end + +@implementation MJRefreshGifHeader +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateImages +{ + if (!_stateImages) { + self.stateImages = [NSMutableDictionary dictionary]; + } + return _stateImages; +} + +- (UIImageView *)gifView +{ + if (!_gifView) { + UIImageView *gifView = [[UIImageView alloc] init]; + [self addSubview:_gifView = gifView]; + } + return _gifView; +} + +#pragma mark - 初始化 +- (void)layoutSubviews +{ + [super layoutSubviews]; + + self.gifView.frame = self.bounds; + if (self.stateHidden && self.updatedTimeHidden) { + self.gifView.contentMode = UIViewContentModeCenter; + } else { + self.gifView.contentMode = UIViewContentModeRight; + self.gifView.mj_w = self.mj_w * 0.5 - 90; + } +} + +#pragma mark - 公共方法 +#pragma mark 设置状态 +- (void)setState:(MJRefreshHeaderState)state +{ + if (self.state == state) return; + + // 旧状态 + MJRefreshHeaderState oldState = self.state; + + NSArray *images = self.stateImages[@(state)]; + if (images.count != 0) { + switch (state) { + case MJRefreshHeaderStateIdle: { + if (oldState == MJRefreshHeaderStateRefreshing) { + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(MJRefreshSlowAnimationDuration * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.pullingPercent = 0.0; + }); + } else { + self.pullingPercent = self.pullingPercent; + } + break; + } + + case MJRefreshHeaderStatePulling: + case MJRefreshHeaderStateRefreshing: { + [self.gifView stopAnimating]; + if (images.count == 1) { // 单张图片 + self.gifView.image = [images lastObject]; + } else { // 多张图片 + self.gifView.animationImages = images; + self.gifView.animationDuration = images.count * 0.1; + [self.gifView startAnimating]; + } + break; + } + + default: + break; + } + } + + // super里面有回调,应该在最后面调用 + [super setState:state]; +} + +- (void)setPullingPercent:(CGFloat)pullingPercent +{ + [super setPullingPercent:pullingPercent]; + + NSArray *images = self.stateImages[@(self.state)]; + switch (self.state) { + case MJRefreshHeaderStateIdle: { + [self.gifView stopAnimating]; + NSUInteger index = images.count * self.pullingPercent; + if (index >= images.count) index = images.count - 1; + self.gifView.image = images[index]; + break; + } + default: + break; + } +} + +- (void)setImages:(NSArray *)images forState:(MJRefreshHeaderState)state +{ + if (images == nil) return; + + self.stateImages[@(state)] = images; + + // 根据图片设置控件的高度 + UIImage *image = [images firstObject]; + if (image.size.height > self.mj_h) { + self.mj_h = image.size.height; + } +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.h new file mode 100644 index 0000000..9e83888 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.h @@ -0,0 +1,47 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// 下拉刷新控件:负责监控用户下拉的状态 + +#import "MJRefreshComponent.h" + +// 下拉刷新控件的状态 +typedef enum { + /** 普通闲置状态 */ + MJRefreshHeaderStateIdle = 1, + /** 松开就可以进行刷新的状态 */ + MJRefreshHeaderStatePulling, + /** 正在刷新中的状态 */ + MJRefreshHeaderStateRefreshing, + /** 即将刷新的状态 */ + MJRefreshHeaderStateWillRefresh +} MJRefreshHeaderState; + +@interface MJRefreshHeader : MJRefreshComponent +/** 利用这个key来保存上次的刷新时间(不同界面的刷新控件应该用不同的dateKey,以区分不同界面的刷新时间) */ +@property (copy, nonatomic) NSString *dateKey; + +/** 利用这个block来决定显示的更新时间 */ +@property (copy, nonatomic) NSString *(^updatedTimeTitle)(NSDate *updatedTime); + +/** + * 设置state状态下的状态文字内容title(别直接拿stateLabel修改文字) + */ +- (void)setTitle:(NSString *)title forState:(MJRefreshHeaderState)state; +/** 刷新控件的状态 */ +@property (assign, nonatomic) MJRefreshHeaderState state; + +#pragma mark - 文字控件的可见性处理 +/** 是否隐藏状态标签 */ +@property (assign, nonatomic, getter=isStateHidden) BOOL stateHidden; +/** 是否隐藏刷新时间标签 */ +@property (assign, nonatomic, getter=isUpdatedTimeHidden) BOOL updatedTimeHidden; + +#pragma mark - 交给子类重写 +/** 下拉的百分比(交给子类重写) */ +@property (assign, nonatomic) CGFloat pullingPercent; +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.m new file mode 100644 index 0000000..8c8a12b --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.m @@ -0,0 +1,346 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshHeader.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" +#import +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshHeader() +/** 显示上次刷新时间的标签 */ +@property (weak, nonatomic) UILabel *updatedTimeLabel; +/** 上次刷新时间 */ +@property (strong, nonatomic) NSDate *updatedTime; +/** 显示状态文字的标签 */ +@property (weak, nonatomic) UILabel *stateLabel; +/** 所有状态对应的文字 */ +@property (strong, nonatomic) NSMutableDictionary *stateTitles; +@end + +@implementation MJRefreshHeader +#pragma mark - 懒加载 +- (NSMutableDictionary *)stateTitles +{ + if (!_stateTitles) { + self.stateTitles = [NSMutableDictionary dictionary]; + } + return _stateTitles; +} + +- (UILabel *)stateLabel +{ + if (!_stateLabel) { + UILabel *stateLabel = [[UILabel alloc] init]; + stateLabel.backgroundColor = [UIColor clearColor]; + stateLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_stateLabel = stateLabel]; + } + return _stateLabel; +} + +- (UILabel *)updatedTimeLabel +{ + if (!_updatedTimeLabel) { + UILabel *updatedTimeLabel = [[UILabel alloc] init]; + updatedTimeLabel.backgroundColor = [UIColor clearColor]; + updatedTimeLabel.textAlignment = NSTextAlignmentCenter; + [self addSubview:_updatedTimeLabel = updatedTimeLabel]; + } + return _updatedTimeLabel; +} + +#pragma mark - 初始化方法 +- (instancetype)initWithFrame:(CGRect)frame { + if (self = [super initWithFrame:frame]) { + // 设置默认的dateKey + self.dateKey = MJRefreshHeaderUpdatedTimeKey; + + // 设置为默认状态 + self.state = MJRefreshHeaderStateIdle; + + // 初始化文字 + [self setTitle:MJRefreshHeaderStateIdleText forState:MJRefreshHeaderStateIdle]; + [self setTitle:MJRefreshHeaderStatePullingText forState:MJRefreshHeaderStatePulling]; + [self setTitle:MJRefreshHeaderStateRefreshingText forState:MJRefreshHeaderStateRefreshing]; + } + return self; +} + +- (void)willMoveToSuperview:(UIView *)newSuperview +{ + [super willMoveToSuperview:newSuperview]; + + if (newSuperview) { + self.mj_h = MJRefreshHeaderHeight; + } +} + +- (void)drawRect:(CGRect)rect +{ + if (self.state == MJRefreshHeaderStateWillRefresh) { + self.state = MJRefreshHeaderStateRefreshing; + } +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // 设置自己的位置 + self.mj_y = - self.mj_h; + + // 2个标签都隐藏 + if (self.stateHidden && self.updatedTimeHidden) return; + + if (self.updatedTimeHidden) { // 显示状态 + _stateLabel.frame = self.bounds; + } else if (self.stateHidden) { // 显示时间 + self.updatedTimeLabel.frame = self.bounds; + } else { // 都显示 + CGFloat stateH = self.mj_h * 0.55; + CGFloat stateW = self.mj_w; + // 1.状态标签 + _stateLabel.frame = CGRectMake(0, 0, stateW, stateH); + + // 2.时间标签 + CGFloat updatedTimeY = stateH; + CGFloat updatedTimeH = self.mj_h - stateH; + CGFloat updatedTimeW = stateW; + self.updatedTimeLabel.frame = CGRectMake(0, updatedTimeY, updatedTimeW, updatedTimeH); + } +} + +#pragma mark - 私有方法 +- (void)setDateKey:(NSString *)dateKey +{ + _dateKey = dateKey ? dateKey : MJRefreshHeaderUpdatedTimeKey; + + self.updatedTime = [[NSUserDefaults standardUserDefaults] objectForKey:_dateKey]; +} + +#pragma mark 设置最后的更新时间 +- (void)setUpdatedTime:(NSDate *)updatedTime +{ + _updatedTime = updatedTime; + + if (updatedTime) { + [[NSUserDefaults standardUserDefaults] setObject:updatedTime forKey:self.dateKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; + } + + if (self.updatedTimeTitle) { + self.updatedTimeLabel.text = self.updatedTimeTitle(updatedTime); + return; + } + + if (updatedTime) { + // 1.获得年月日 + NSCalendar *calendar = [NSCalendar currentCalendar]; + NSUInteger unitFlags = NSCalendarUnitYear| NSCalendarUnitMonth | NSCalendarUnitDay |NSCalendarUnitHour |NSCalendarUnitMinute; + NSDateComponents *cmp1 = [calendar components:unitFlags fromDate:updatedTime]; + NSDateComponents *cmp2 = [calendar components:unitFlags fromDate:[NSDate date]]; + + // 2.格式化日期 + NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; + if ([cmp1 day] == [cmp2 day]) { // 今天 + formatter.dateFormat = @"今天 HH:mm"; + } else if ([cmp1 year] == [cmp2 year]) { // 今年 + formatter.dateFormat = @"MM-dd HH:mm"; + } else { + formatter.dateFormat = @"yyyy-MM-dd HH:mm"; + } + NSString *time = [formatter stringFromDate:updatedTime]; + + // 3.显示日期 + self.updatedTimeLabel.text = [NSString stringWithFormat:@"最后更新:%@", time]; + } else { + self.updatedTimeLabel.text = @"最后更新:无记录"; + } +} + +#pragma mark KVO属性监听 +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + // 遇到这些情况就直接返回 + if (!self.userInteractionEnabled || self.alpha <= 0.01 || self.hidden || self.state == MJRefreshHeaderStateRefreshing) return; + + // 根据contentOffset调整state + if ([keyPath isEqualToString:MJRefreshContentOffset]) { + [self adjustStateWithContentOffset]; + } +} + +#pragma mark 根据contentOffset调整state +- (void)adjustStateWithContentOffset +{ + if (self.state != MJRefreshHeaderStateRefreshing) { + // 在刷新过程中,跳转到下一个控制器时,contentInset可能会变 + _scrollViewOriginalInset = _scrollView.contentInset; + } + + // 在刷新的 refreshing 状态,动态设置 content inset + if (self.state == MJRefreshHeaderStateRefreshing ) { + if(_scrollView.contentOffset.y >= -_scrollViewOriginalInset.top ) { + _scrollView.mj_insetT = _scrollViewOriginalInset.top; + } else { + _scrollView.mj_insetT = MIN(_scrollViewOriginalInset.top + self.mj_h, + _scrollViewOriginalInset.top - _scrollView.contentOffset.y); + } + return; + } + + // 当前的contentOffset + CGFloat offsetY = _scrollView.mj_offsetY; + // 头部控件刚好出现的offsetY + CGFloat happenOffsetY = - _scrollViewOriginalInset.top; + + // 如果是向上滚动到看不见头部控件,直接返回 + if (offsetY >= happenOffsetY) return; + + // 普通 和 即将刷新 的临界点 + CGFloat normal2pullingOffsetY = happenOffsetY - self.mj_h; + if (_scrollView.isDragging) { + self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h; + + if (self.state == MJRefreshHeaderStateIdle && offsetY < normal2pullingOffsetY) { + // 转为即将刷新状态 + self.state = MJRefreshHeaderStatePulling; + } else if (self.state == MJRefreshHeaderStatePulling && offsetY >= normal2pullingOffsetY) { + // 转为普通状态 + self.state = MJRefreshHeaderStateIdle; + } + } else if (self.state == MJRefreshHeaderStatePulling) {// 即将刷新 && 手松开 + self.pullingPercent = 1.0; + // 开始刷新 + self.state = MJRefreshHeaderStateRefreshing; + } else { + self.pullingPercent = (happenOffsetY - offsetY) / self.mj_h; + } +} + +#pragma mark - 公共方法 +- (void)setTitle:(NSString *)title forState:(MJRefreshHeaderState)state +{ + if (title == nil) return; + self.stateTitles[@(state)] = title; + + // 刷新当前状态的文字 + self.stateLabel.text = self.stateTitles[@(self.state)]; +} + +- (void)beginRefreshing +{ + if (self.window) { + self.state = MJRefreshHeaderStateRefreshing; + } else { + self.state = MJRefreshHeaderStateWillRefresh; + // 刷新(预防从另一个控制器回到这个控制器的情况,回来要重新刷新一下) + [self setNeedsDisplay]; + } +} + +- (void)endRefreshing +{ + dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.05 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ + self.state = MJRefreshHeaderStateIdle; + }); +} + +- (BOOL)isRefreshing +{ + return self.state == MJRefreshHeaderStateRefreshing; +} + +- (void)setState:(MJRefreshHeaderState)state +{ + if (_state == state) return; + + // 旧状态 + MJRefreshHeaderState oldState = _state; + + // 赋值 + _state = state; + + // 设置状态文字 + _stateLabel.text = _stateTitles[@(state)]; + + switch (state) { + case MJRefreshHeaderStateIdle: { + if (oldState == MJRefreshHeaderStateRefreshing) { + // 保存刷新时间 + self.updatedTime = [NSDate date]; + + // 恢复inset和offset + [UIView animateWithDuration:MJRefreshSlowAnimationDuration delay:0.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{ + // 修复top值不断累加 + _scrollView.mj_insetT -= self.mj_h; + } completion:nil]; + } + break; + } + + case MJRefreshHeaderStateRefreshing: { + [UIView animateWithDuration:MJRefreshFastAnimationDuration delay:0.0 options:UIViewAnimationOptionAllowUserInteraction|UIViewAnimationOptionBeginFromCurrentState animations:^{ + // 增加滚动区域 + CGFloat top = _scrollViewOriginalInset.top + self.mj_h; + _scrollView.mj_insetT = top; + + // 设置滚动位置 + _scrollView.mj_offsetY = - top; + } completion:^(BOOL finished) { + // 回调 + if (self.refreshingBlock) { + self.refreshingBlock(); + } + + if ([self.refreshingTarget respondsToSelector:self.refreshingAction]) { + msgSend(msgTarget(self.refreshingTarget), self.refreshingAction, self); + } + }]; + break; + } + + default: + break; + } +} + +- (void)setTextColor:(UIColor *)textColor +{ + [super setTextColor:textColor]; + + self.updatedTimeLabel.textColor = textColor; + self.stateLabel.textColor = textColor; +} + +- (void)setFont:(UIFont *)font +{ + [super setFont:font]; + + self.updatedTimeLabel.font = font; + self.stateLabel.font = font; +} + +- (void)setStateHidden:(BOOL)stateHidden +{ + _stateHidden = stateHidden; + + self.stateLabel.hidden = stateHidden; + [self setNeedsLayout]; +} + +- (void)setUpdatedTimeHidden:(BOOL)updatedTimeHidden +{ + _updatedTimeHidden = updatedTimeHidden; + + self.updatedTimeLabel.hidden = updatedTimeHidden; + [self setNeedsLayout]; +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.h new file mode 100644 index 0000000..b8d06f8 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshLegendFooter.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshFooter.h" + +@interface MJRefreshLegendFooter : MJRefreshFooter + +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m new file mode 100644 index 0000000..6c70655 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m @@ -0,0 +1,68 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshLegendFooter.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/5. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshLegendFooter.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" +#import "UIScrollView+MJExtension.h" + +@interface MJRefreshLegendFooter() +@property (nonatomic, weak) UIActivityIndicatorView *activityView; +@end + +@implementation MJRefreshLegendFooter +#pragma mark - 懒加载 +- (UIActivityIndicatorView *)activityView +{ + if (!_activityView) { + UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + [self addSubview:_activityView = activityView]; + } + return _activityView; +} + +#pragma mark - 初始化方法 +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // 指示器 + if (self.stateHidden) { + self.activityView.center = CGPointMake(self.mj_w * 0.5, self.mj_h * 0.5); + } else { + self.activityView.center = CGPointMake(self.mj_w * 0.5 - 100, self.mj_h * 0.5); + } +} + +#pragma mark - 公共方法 +- (void)setState:(MJRefreshFooterState)state +{ + if (self.state == state) return; + + switch (state) { + case MJRefreshFooterStateIdle: + [self.activityView stopAnimating]; + break; + + case MJRefreshFooterStateRefreshing: + [self.activityView startAnimating]; + break; + + case MJRefreshFooterStateNoMoreData: + [self.activityView stopAnimating]; + break; + + default: + break; + } + + // super里面有回调,应该在最后面调用 + [super setState:state]; +} +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.h new file mode 100644 index 0000000..a2f1969 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.h @@ -0,0 +1,14 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshLegendHeader.h +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// 传统的下拉刷新控件:箭头 + 圈圈 + +#import "MJRefreshHeader.h" + +@interface MJRefreshLegendHeader : MJRefreshHeader + +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m new file mode 100644 index 0000000..3349b13 --- /dev/null +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m @@ -0,0 +1,103 @@ +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 +// MJRefreshLegendHeader.m +// MJRefreshExample +// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// + +#import "MJRefreshLegendHeader.h" +#import "MJRefreshConst.h" +#import "UIView+MJExtension.h" + +@interface MJRefreshLegendHeader() +@property (nonatomic, weak) UIImageView *arrowImage; +@property (nonatomic, weak) UIActivityIndicatorView *activityView; +@end + +@implementation MJRefreshLegendHeader +#pragma mark - 懒加载 +- (UIImageView *)arrowImage +{ + if (!_arrowImage) { + UIImageView *arrowImage = [[UIImageView alloc] initWithImage:[UIImage imageNamed:MJRefreshSrcName(@"arrow.png")]]; + [self addSubview:_arrowImage = arrowImage]; + } + return _arrowImage; +} + +- (UIActivityIndicatorView *)activityView +{ + if (!_activityView) { + UIActivityIndicatorView *activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]; + activityView.bounds = self.arrowImage.bounds; + [self addSubview:_activityView = activityView]; + } + return _activityView; +} + +#pragma mark - 初始化 +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // 箭头 + CGFloat arrowX = (self.stateHidden && self.updatedTimeHidden) ? self.mj_w * 0.5 : (self.mj_w * 0.5 - 100); + self.arrowImage.center = CGPointMake(arrowX, self.mj_h * 0.5); + + // 指示器 + self.activityView.center = self.arrowImage.center; +} + +#pragma mark - 公共方法 +#pragma mark 设置状态 +- (void)setState:(MJRefreshHeaderState)state +{ + if (self.state == state) return; + + // 旧状态 + MJRefreshHeaderState oldState = self.state; + + switch (state) { + case MJRefreshHeaderStateIdle: { + if (oldState == MJRefreshHeaderStateRefreshing) { + self.arrowImage.transform = CGAffineTransformIdentity; + + [UIView animateWithDuration:MJRefreshSlowAnimationDuration animations:^{ + self.activityView.alpha = 0.0; + } completion:^(BOOL finished) { + self.arrowImage.alpha = 1.0; + self.activityView.alpha = 1.0; + [self.activityView stopAnimating]; + }]; + } else { + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowImage.transform = CGAffineTransformIdentity; + }]; + } + break; + } + + case MJRefreshHeaderStatePulling: { + [UIView animateWithDuration:MJRefreshFastAnimationDuration animations:^{ + self.arrowImage.transform = CGAffineTransformMakeRotation(0.000001 - M_PI); + }]; + break; + } + + case MJRefreshHeaderStateRefreshing: { + [self.activityView startAnimating]; + self.arrowImage.alpha = 0.0; + break; + } + + default: + break; + } + + // super里面有回调,应该在最后面调用 + [super setState:state]; +} + +@end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h index 96f5283..9735278 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h @@ -1,4 +1,5 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIScrollView+Extension.h // MJRefreshExample // @@ -9,14 +10,14 @@ #import @interface UIScrollView (MJExtension) -@property (assign, nonatomic) CGFloat mj_contentInsetTop; -@property (assign, nonatomic) CGFloat mj_contentInsetBottom; -@property (assign, nonatomic) CGFloat mj_contentInsetLeft; -@property (assign, nonatomic) CGFloat mj_contentInsetRight; +@property (assign, nonatomic) CGFloat mj_insetT; +@property (assign, nonatomic) CGFloat mj_insetB; +@property (assign, nonatomic) CGFloat mj_insetL; +@property (assign, nonatomic) CGFloat mj_insetR; -@property (assign, nonatomic) CGFloat mj_contentOffsetX; -@property (assign, nonatomic) CGFloat mj_contentOffsetY; +@property (assign, nonatomic) CGFloat mj_offsetX; +@property (assign, nonatomic) CGFloat mj_offsetY; -@property (assign, nonatomic) CGFloat mj_contentSizeWidth; -@property (assign, nonatomic) CGFloat mj_contentSizeHeight; +@property (assign, nonatomic) CGFloat mj_contentSizeW; +@property (assign, nonatomic) CGFloat mj_contentSizeH; @end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m index 0a5fe07..dace5a5 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m @@ -1,4 +1,5 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIScrollView+Extension.m // MJRefreshExample // @@ -9,98 +10,98 @@ #import "UIScrollView+MJExtension.h" @implementation UIScrollView (MJExtension) -- (void)setMj_contentInsetTop:(CGFloat)mj_contentInsetTop +- (void)setMj_insetT:(CGFloat)mj_insetT { UIEdgeInsets inset = self.contentInset; - inset.top = mj_contentInsetTop; + inset.top = mj_insetT; self.contentInset = inset; } -- (CGFloat)mj_contentInsetTop +- (CGFloat)mj_insetT { return self.contentInset.top; } -- (void)setMj_contentInsetBottom:(CGFloat)mj_contentInsetBottom +- (void)setMj_insetB:(CGFloat)mj_insetB { UIEdgeInsets inset = self.contentInset; - inset.bottom = mj_contentInsetBottom; + inset.bottom = mj_insetB; self.contentInset = inset; } -- (CGFloat)mj_contentInsetBottom +- (CGFloat)mj_insetB { return self.contentInset.bottom; } -- (void)setMj_contentInsetLeft:(CGFloat)mj_contentInsetLeft +- (void)setMj_insetL:(CGFloat)mj_insetL { UIEdgeInsets inset = self.contentInset; - inset.left = mj_contentInsetLeft; + inset.left = mj_insetL; self.contentInset = inset; } -- (CGFloat)mj_contentInsetLeft +- (CGFloat)mj_insetL { return self.contentInset.left; } -- (void)setMj_contentInsetRight:(CGFloat)mj_contentInsetRight +- (void)setMj_insetR:(CGFloat)mj_insetR { UIEdgeInsets inset = self.contentInset; - inset.right = mj_contentInsetRight; + inset.right = mj_insetR; self.contentInset = inset; } -- (CGFloat)mj_contentInsetRight +- (CGFloat)mj_insetR { return self.contentInset.right; } -- (void)setMj_contentOffsetX:(CGFloat)mj_contentOffsetX +- (void)setMj_offsetX:(CGFloat)mj_offsetX { CGPoint offset = self.contentOffset; - offset.x = mj_contentOffsetX; + offset.x = mj_offsetX; self.contentOffset = offset; } -- (CGFloat)mj_contentOffsetX +- (CGFloat)mj_offsetX { return self.contentOffset.x; } -- (void)setMj_contentOffsetY:(CGFloat)mj_contentOffsetY +- (void)setMj_offsetY:(CGFloat)mj_offsetY { CGPoint offset = self.contentOffset; - offset.y = mj_contentOffsetY; + offset.y = mj_offsetY; self.contentOffset = offset; } -- (CGFloat)mj_contentOffsetY +- (CGFloat)mj_offsetY { return self.contentOffset.y; } -- (void)setMj_contentSizeWidth:(CGFloat)mj_contentSizeWidth +- (void)setMj_contentSizeW:(CGFloat)mj_contentSizeW { CGSize size = self.contentSize; - size.width = mj_contentSizeWidth; + size.width = mj_contentSizeW; self.contentSize = size; } -- (CGFloat)mj_contentSizeWidth +- (CGFloat)mj_contentSizeW { return self.contentSize.width; } -- (void)setMj_contentSizeHeight:(CGFloat)mj_contentSizeHeight +- (void)setMj_contentSizeH:(CGFloat)mj_contentSizeH { CGSize size = self.contentSize; - size.height = mj_contentSizeHeight; + size.height = mj_contentSizeH; self.contentSize = size; } -- (CGFloat)mj_contentSizeHeight +- (CGFloat)mj_contentSizeH { return self.contentSize.height; } diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h index e5ae65b..740e4d4 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h @@ -1,21 +1,143 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIScrollView+MJRefresh.h // MJRefreshExample // -// Created by MJ Lee on 14-5-28. -// Copyright (c) 2014年 itcast. All rights reserved. -// +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. +// 给ScrollView增加下拉刷新、上拉刷新的功能 #import +#import "MJRefreshConst.h" + +@class MJRefreshGifHeader, MJRefreshLegendHeader, MJRefreshHeader; +@class MJRefreshGifFooter, MJRefreshLegendFooter, MJRefreshFooter; @interface UIScrollView (MJRefresh) +#pragma mark - 访问下拉刷新控件 +/** 下拉刷新控件 */ +@property (strong, nonatomic, readonly) MJRefreshHeader *header; +/** gif功能的下拉刷新控件 */ +@property (nonatomic, readonly) MJRefreshGifHeader *gifHeader; +/** 传统的下拉刷新控件 */ +@property (nonatomic, readonly) MJRefreshLegendHeader *legendHeader; + +#pragma mark - 添加下拉刷新控件 +/** + * 添加一个传统的下拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + */ +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block; +/** + * 添加一个传统的下拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + * @param dateKey 用来记录刷新时间的key + */ +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey; +/** + * 添加一个传统的下拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + */ +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action; +/** + * 添加一个传统的下拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + * @param dateKey 用来记录刷新时间的key + */ +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey; +/** + * 添加一个gif图片的下拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + */ +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block; +/** + * 添加一个gif图片的下拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + * @param dateKey 用来记录刷新时间的key + */ +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey; +/** + * 添加一个gif图片的下拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + */ +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action; +/** + * 添加一个gif图片的下拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + * @param dateKey 用来记录刷新时间的key + */ +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey; + +#pragma mark - 移除下拉刷新控件 +/** + * 移除下拉刷新控件 + */ +- (void)removeHeader; + +#pragma mark - 访问上拉刷新控件 +/** 上拉刷新控件 */ +@property (strong, nonatomic, readonly) MJRefreshFooter *footer; +/** gif功能的上拉刷新控件 */ +@property (nonatomic, readonly) MJRefreshGifFooter *gifFooter; +/** 传统的上拉刷新控件 */ +@property (nonatomic, readonly) MJRefreshLegendFooter *legendFooter; + +#pragma mark - 添加上拉刷新控件 +/** + * 添加一个传统的上拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + */ +- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingBlock:(void (^)())block; +/** + * 添加一个传统的上拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + */ +- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action; +/** + * 添加一个gif图片的上拉刷新控件 + * + * @param block 进入刷新状态就会自动调用这个block + */ +- (MJRefreshGifFooter *)addGifFooterWithRefreshingBlock:(void (^)())block; +/** + * 添加一个gif图片的上拉刷新控件 + * + * @param target 进入刷新状态就会自动调用target对象的action方法 + * @param action 进入刷新状态就会自动调用target对象的action方法 + */ +- (MJRefreshGifFooter *)addGifFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action; + +#pragma mark - 移除上拉刷新控件 +/** + * 移除上拉刷新控件 + */ +- (void)removeFooter; +@end + +#pragma mark - 1.0.0版本以前的接口 +@interface UIScrollView(MJRefreshDeprecated) #pragma mark - 下拉刷新 /** * 添加一个下拉刷新头部控件 * * @param callback 回调 */ -- (void)addHeaderWithCallback:(void (^)())callback; +- (void)addHeaderWithCallback:(void (^)())callback MJDeprecated("建议使用addLegendHeaderWithRefreshingBlock:"); /** * 添加一个下拉刷新头部控件 @@ -23,7 +145,7 @@ * @param callback 回调 * @param dateKey 刷新时间保存的key值 */ -- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey; +- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey MJDeprecated("建议使用addLegendHeaderWithRefreshingBlock:dateKey:"); /** * 添加一个下拉刷新头部控件 @@ -31,7 +153,7 @@ * @param target 目标 * @param action 回调方法 */ -- (void)addHeaderWithTarget:(id)target action:(SEL)action; +- (void)addHeaderWithTarget:(id)target action:(SEL)action MJDeprecated("建议使用addLegendHeaderWithRefreshingTarget:refreshingAction:"); /** * 添加一个下拉刷新头部控件 @@ -40,32 +162,27 @@ * @param action 回调方法 * @param dateKey 刷新时间保存的key值 */ -- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey; - -/** - * 移除下拉刷新头部控件 - */ -- (void)removeHeader; +- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey MJDeprecated("建议使用addLegendHeaderWithRefreshingTarget:refreshingAction:dateKey:"); /** * 主动让下拉刷新头部控件进入刷新状态 */ -- (void)headerBeginRefreshing; +- (void)headerBeginRefreshing MJDeprecated("建议使用[self.tableView.header beginRefreshing]"); /** * 让下拉刷新头部控件停止刷新状态 */ -- (void)headerEndRefreshing; +- (void)headerEndRefreshing MJDeprecated("建议使用[self.tableView.header endRefreshing]"); /** * 下拉刷新头部控件的可见性 */ -@property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden; +@property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden MJDeprecated("建议使用self.tableView.header.hidden"); /** * 是否正在下拉刷新 */ -@property (nonatomic, assign, readonly, getter = isHeaderRefreshing) BOOL headerRefreshing; +@property (nonatomic, assign, readonly, getter = isHeaderRefreshing) BOOL headerRefreshing MJDeprecated("建议使用self.tableView.header.isRefreshing"); #pragma mark - 上拉刷新 /** @@ -73,7 +190,7 @@ * * @param callback 回调 */ -- (void)addFooterWithCallback:(void (^)())callback; +- (void)addFooterWithCallback:(void (^)())callback MJDeprecated("建议使用addLegendFooterWithRefreshingBlock:"); /** * 添加一个上拉刷新尾部控件 @@ -81,44 +198,25 @@ * @param target 目标 * @param action 回调方法 */ -- (void)addFooterWithTarget:(id)target action:(SEL)action; - -/** - * 移除上拉刷新尾部控件 - */ -- (void)removeFooter; +- (void)addFooterWithTarget:(id)target action:(SEL)action MJDeprecated("建议使用addLegendFooterWithRefreshingTarget:refreshingAction:"); /** * 主动让上拉刷新尾部控件进入刷新状态 */ -- (void)footerBeginRefreshing; +- (void)footerBeginRefreshing MJDeprecated("建议使用[self.tableView.footer beginRefreshing]"); /** * 让上拉刷新尾部控件停止刷新状态 */ -- (void)footerEndRefreshing; +- (void)footerEndRefreshing MJDeprecated("建议使用[self.tableView.footer endRefreshing]"); /** * 上拉刷新头部控件的可见性 */ -@property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden; +@property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden MJDeprecated("建议使用self.tableView.footer.hidden"); /** * 是否正在上拉刷新 */ -@property (nonatomic, assign, readonly, getter = isFooterRefreshing) BOOL footerRefreshing; - -/** - * 设置尾部控件的文字 - */ -@property (copy, nonatomic) NSString *footerPullToRefreshText; // 默认:@"上拉可以加载更多数据" -@property (copy, nonatomic) NSString *footerReleaseToRefreshText; // 默认:@"松开立即加载更多数据" -@property (copy, nonatomic) NSString *footerRefreshingText; // 默认:@"MJ哥正在帮你加载数据..." - -/** - * 设置头部控件的文字 - */ -@property (copy, nonatomic) NSString *headerPullToRefreshText; // 默认:@"下拉可以刷新" -@property (copy, nonatomic) NSString *headerReleaseToRefreshText; // 默认:@"松开立即刷新" -@property (copy, nonatomic) NSString *headerRefreshingText; // 默认:@"MJ哥正在帮你刷新..." +@property (nonatomic, assign, readonly, getter = isFooterRefreshing) BOOL footerRefreshing MJDeprecated("建议使用self.tableView.footer.isRefreshing"); @end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m index 74a72b8..2b00a89 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m @@ -1,52 +1,250 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIScrollView+MJRefresh.m // MJRefreshExample // -// Created by MJ Lee on 14-5-28. -// Copyright (c) 2014年 itcast. All rights reserved. +// Created by MJ Lee on 15/3/4. +// Copyright (c) 2015年 itcast. All rights reserved. // #import "UIScrollView+MJRefresh.h" -#import "MJRefreshHeaderView.h" -#import "MJRefreshFooterView.h" +#import "MJRefreshGifHeader.h" +#import "MJRefreshLegendHeader.h" +#import "MJRefreshGifFooter.h" +#import "MJRefreshLegendFooter.h" #import -@interface UIScrollView() -@property (weak, nonatomic) MJRefreshHeaderView *header; -@property (weak, nonatomic) MJRefreshFooterView *footer; -@end +@implementation UIScrollView (MJRefresh) +#pragma mark - 下拉刷新 +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey +{ + MJRefreshLegendHeader *header = [self addLegendHeader]; + header.refreshingBlock = block; + header.dateKey = dateKey; + return header; +} +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey +{ + MJRefreshLegendHeader *header = [self addLegendHeader]; + header.refreshingTarget = target; + header.refreshingAction = action; + header.dateKey = dateKey; + return header; +} -@implementation UIScrollView (MJRefresh) +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + return [self addLegendHeaderWithRefreshingTarget:target refreshingAction:action dateKey:nil]; +} + +- (MJRefreshLegendHeader *)addLegendHeaderWithRefreshingBlock:(void (^)())block +{ + return [self addLegendHeaderWithRefreshingBlock:block dateKey:nil]; +} + +- (MJRefreshLegendHeader *)addLegendHeader +{ + MJRefreshLegendHeader *header = [[MJRefreshLegendHeader alloc] init]; + self.header = header; + + return header; +} + +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block dateKey:(NSString *)dateKey +{ + MJRefreshGifHeader *header = [self addGifHeader]; + header.refreshingBlock = block; + header.dateKey = dateKey; + return header; +} + +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action dateKey:(NSString *)dateKey +{ + MJRefreshGifHeader *header = [self addGifHeader]; + header.refreshingTarget = target; + header.refreshingAction = action; + header.dateKey = dateKey; + return header; +} + +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingBlock:(void (^)())block +{ + return [self addGifHeaderWithRefreshingBlock:block dateKey:nil]; +} + +- (MJRefreshGifHeader *)addGifHeaderWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + return [self addGifHeaderWithRefreshingTarget:target refreshingAction:action dateKey:nil]; +} + +- (MJRefreshGifHeader *)addGifHeader +{ + MJRefreshGifHeader *header = [[MJRefreshGifHeader alloc] init]; + self.header = header; + + return header; +} + +- (void)removeHeader +{ + self.header = nil; +} + +#pragma mark - Property Methods +#pragma mark gifHeader +- (MJRefreshGifHeader *)gifHeader +{ + if ([self.header isKindOfClass:[MJRefreshGifHeader class]]) { + return (MJRefreshGifHeader *)self.header; + } + + return nil; +} + +#pragma mark legendHeader +- (MJRefreshLegendHeader *)legendHeader +{ + if ([self.header isKindOfClass:[MJRefreshLegendHeader class]]) { + return (MJRefreshLegendHeader *)self.header; + } + + return nil; +} + +#pragma mark header +static char MJRefreshHeaderKey; +- (void)setHeader:(MJRefreshHeader *)header +{ + if (header != self.header) { + [self.header removeFromSuperview]; + + [self willChangeValueForKey:@"header"]; + objc_setAssociatedObject(self, &MJRefreshHeaderKey, + header, + OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"header"]; + + [self addSubview:header]; + } +} + +- (MJRefreshHeader *)header +{ + return objc_getAssociatedObject(self, &MJRefreshHeaderKey); +} + +#pragma mark - 上拉刷新 +- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingBlock:(void (^)())block +{ + MJRefreshLegendFooter *footer = [self addLegendFooter]; + footer.refreshingBlock = block; + return footer; +} + +- (MJRefreshLegendFooter *)addLegendFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshLegendFooter *footer = [self addLegendFooter]; + footer.refreshingTarget = target; + footer.refreshingAction = action; + return footer; +} + +- (MJRefreshLegendFooter *)addLegendFooter +{ + MJRefreshLegendFooter *footer = [[MJRefreshLegendFooter alloc] init]; + self.footer = footer; + + return footer; +} + +- (MJRefreshGifFooter *)addGifFooterWithRefreshingBlock:(void (^)())block +{ + MJRefreshGifFooter *footer = [self addGifFooter]; + footer.refreshingBlock = block; + return footer; +} -#pragma mark - 运行时相关 -static char MJRefreshHeaderViewKey; -static char MJRefreshFooterViewKey; +- (MJRefreshGifFooter *)addGifFooterWithRefreshingTarget:(id)target refreshingAction:(SEL)action +{ + MJRefreshGifFooter *footer = [self addGifFooter]; + footer.refreshingTarget = target; + footer.refreshingAction = action; + return footer; +} -- (void)setHeader:(MJRefreshHeaderView *)header { - [self willChangeValueForKey:@"MJRefreshHeaderViewKey"]; - objc_setAssociatedObject(self, &MJRefreshHeaderViewKey, - header, - OBJC_ASSOCIATION_ASSIGN); - [self didChangeValueForKey:@"MJRefreshHeaderViewKey"]; +- (MJRefreshGifFooter *)addGifFooter +{ + MJRefreshGifFooter *footer = [[MJRefreshGifFooter alloc] init]; + self.footer = footer; + + return footer; } -- (MJRefreshHeaderView *)header { - return objc_getAssociatedObject(self, &MJRefreshHeaderViewKey); +- (void)removeFooter +{ + self.footer = nil; } -- (void)setFooter:(MJRefreshFooterView *)footer { - [self willChangeValueForKey:@"MJRefreshFooterViewKey"]; - objc_setAssociatedObject(self, &MJRefreshFooterViewKey, - footer, - OBJC_ASSOCIATION_ASSIGN); - [self didChangeValueForKey:@"MJRefreshFooterViewKey"]; +static char MJRefreshFooterKey; +- (void)setFooter:(MJRefreshFooter *)footer +{ + if (footer != self.footer) { + [self.footer removeFromSuperview]; + + [self willChangeValueForKey:@"footer"]; + objc_setAssociatedObject(self, &MJRefreshFooterKey, + footer, + OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"footer"]; + + [self addSubview:footer]; + } } -- (MJRefreshFooterView *)footer { - return objc_getAssociatedObject(self, &MJRefreshFooterViewKey); +- (MJRefreshGifFooter *)gifFooter +{ + if ([self.footer isKindOfClass:[MJRefreshGifFooter class]]) { + return (MJRefreshGifFooter *)self.footer; + } + return nil; +} + +- (MJRefreshLegendFooter *)legendFooter +{ + if ([self.footer isKindOfClass:[MJRefreshLegendFooter class]]) { + return (MJRefreshLegendFooter *)self.footer; + } + return nil; } + +- (MJRefreshFooter *)footer +{ + return objc_getAssociatedObject(self, &MJRefreshFooterKey); +} + +#pragma mark - swizzle ++ (void)load +{ + Method method1 = class_getInstanceMethod([self class], NSSelectorFromString(@"dealloc")); + Method method2 = class_getInstanceMethod([self class], @selector(deallocSwizzle)); + method_exchangeImplementations(method1, method2); +} + +- (void)deallocSwizzle +{ + [self removeFooter]; + [self removeHeader]; + + [self deallocSwizzle]; +} + +@end + + +#pragma mark - 1.0.0版本以前的接口 +@implementation UIScrollView(MJRefreshDeprecated) #pragma mark - 下拉刷新 /** * 添加一个下拉刷新头部控件 @@ -58,20 +256,17 @@ - (void)addHeaderWithCallback:(void (^)())callback [self addHeaderWithCallback:callback dateKey:nil]; } +/** + * 添加一个下拉刷新头部控件 + * + * @param callback 回调 + * @param dateKey 刷新时间保存的key值 + */ - (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey { - // 1.创建新的header - if (!self.header) { - MJRefreshHeaderView *header = [MJRefreshHeaderView header]; - [self addSubview:header]; - self.header = header; - } - - // 2.设置block回调 - self.header.beginRefreshingCallback = callback; - - // 3.设置存储刷新时间的key + [self addLegendHeader]; self.header.dateKey = dateKey; + self.header.refreshingBlock = callback; } /** @@ -85,30 +280,18 @@ - (void)addHeaderWithTarget:(id)target action:(SEL)action [self addHeaderWithTarget:target action:action dateKey:nil]; } -- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey -{ - // 1.创建新的header - if (!self.header) { - MJRefreshHeaderView *header = [MJRefreshHeaderView header]; - [self addSubview:header]; - self.header = header; - } - - // 2.设置目标和回调方法 - self.header.beginRefreshingTaget = target; - self.header.beginRefreshingAction = action; - - // 3.设置存储刷新时间的key - self.header.dateKey = dateKey; -} - /** - * 移除下拉刷新头部控件 + * 添加一个下拉刷新头部控件 + * + * @param target 目标 + * @param action 回调方法 + * @param dateKey 刷新时间保存的key值 */ -- (void)removeHeader +- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey { - [self.header removeFromSuperview]; - self.header = nil; + [self addLegendHeader]; + self.header.dateKey = dateKey; + [self.header setRefreshingTarget:target refreshingAction:action]; } /** @@ -130,9 +313,9 @@ - (void)headerEndRefreshing /** * 下拉刷新头部控件的可见性 */ -- (void)setHeaderHidden:(BOOL)hidden +- (void)setHeaderHidden:(BOOL)headerHidden { - self.header.hidden = hidden; + self.header.hidden = headerHidden; } - (BOOL)isHeaderHidden @@ -140,6 +323,9 @@ - (BOOL)isHeaderHidden return self.header.isHidden; } +/** + * 是否正在下拉刷新 + */ - (BOOL)isHeaderRefreshing { return self.header.isRefreshing; @@ -153,15 +339,8 @@ - (BOOL)isHeaderRefreshing */ - (void)addFooterWithCallback:(void (^)())callback { - // 1.创建新的footer - if (!self.footer) { - MJRefreshFooterView *footer = [MJRefreshFooterView footer]; - [self addSubview:footer]; - self.footer = footer; - } - - // 2.设置block回调 - self.footer.beginRefreshingCallback = callback; + [self addLegendFooter]; + self.footer.refreshingBlock = callback; } /** @@ -172,25 +351,8 @@ - (void)addFooterWithCallback:(void (^)())callback */ - (void)addFooterWithTarget:(id)target action:(SEL)action { - // 1.创建新的footer - if (!self.footer) { - MJRefreshFooterView *footer = [MJRefreshFooterView footer]; - [self addSubview:footer]; - self.footer = footer; - } - - // 2.设置目标和回调方法 - self.footer.beginRefreshingTaget = target; - self.footer.beginRefreshingAction = action; -} - -/** - * 移除上拉刷新尾部控件 - */ -- (void)removeFooter -{ - [self.footer removeFromSuperview]; - self.footer = nil; + [self addLegendFooter]; + [self.footer setRefreshingTarget:target refreshingAction:action]; } /** @@ -210,11 +372,11 @@ - (void)footerEndRefreshing } /** - * 下拉刷新头部控件的可见性 + * 上拉刷新头部控件的可见性 */ -- (void)setFooterHidden:(BOOL)hidden +- (void)setFooterHidden:(BOOL)footerHidden { - self.footer.hidden = hidden; + self.footer.hidden = footerHidden; } - (BOOL)isFooterHidden @@ -222,71 +384,11 @@ - (BOOL)isFooterHidden return self.footer.isHidden; } -- (BOOL)isFooterRefreshing -{ - return self.footer.isRefreshing; -} - /** - * 文字 + * 是否正在上拉刷新 */ -- (void)setFooterPullToRefreshText:(NSString *)footerPullToRefreshText -{ - self.footer.pullToRefreshText = footerPullToRefreshText; -} - -- (NSString *)footerPullToRefreshText -{ - return self.footer.pullToRefreshText; -} - -- (void)setFooterReleaseToRefreshText:(NSString *)footerReleaseToRefreshText -{ - self.footer.releaseToRefreshText = footerReleaseToRefreshText; -} - -- (NSString *)footerReleaseToRefreshText -{ - return self.footer.releaseToRefreshText; -} - -- (void)setFooterRefreshingText:(NSString *)footerRefreshingText -{ - self.footer.refreshingText = footerRefreshingText; -} - -- (NSString *)footerRefreshingText -{ - return self.footer.refreshingText; -} - -- (void)setHeaderPullToRefreshText:(NSString *)headerPullToRefreshText -{ - self.header.pullToRefreshText = headerPullToRefreshText; -} - -- (NSString *)headerPullToRefreshText -{ - return self.header.pullToRefreshText; -} - -- (void)setHeaderReleaseToRefreshText:(NSString *)headerReleaseToRefreshText -{ - self.header.releaseToRefreshText = headerReleaseToRefreshText; -} - -- (NSString *)headerReleaseToRefreshText -{ - return self.header.releaseToRefreshText; -} - -- (void)setHeaderRefreshingText:(NSString *)headerRefreshingText -{ - self.header.refreshingText = headerRefreshingText; -} - -- (NSString *)headerRefreshingText +- (BOOL)isFooterRefreshing { - return self.header.refreshingText; + return self.footer.isRefreshing; } @end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h index 8033456..b4b1346 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h @@ -1,4 +1,5 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIView+Extension.h // MJRefreshExample // @@ -11,8 +12,8 @@ @interface UIView (MJExtension) @property (assign, nonatomic) CGFloat mj_x; @property (assign, nonatomic) CGFloat mj_y; -@property (assign, nonatomic) CGFloat mj_width; -@property (assign, nonatomic) CGFloat mj_height; +@property (assign, nonatomic) CGFloat mj_w; +@property (assign, nonatomic) CGFloat mj_h; @property (assign, nonatomic) CGSize mj_size; @property (assign, nonatomic) CGPoint mj_origin; @end diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m index a4f8194..1e3efed 100644 --- a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m +++ b/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m @@ -1,4 +1,5 @@ -// +// 代码地址: https://github.com/CoderMJLee/MJRefresh +// 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 // UIView+Extension.m // MJRefreshExample // @@ -33,26 +34,26 @@ - (CGFloat)mj_y return self.frame.origin.y; } -- (void)setMj_width:(CGFloat)mj_width +- (void)setMj_w:(CGFloat)mj_w { CGRect frame = self.frame; - frame.size.width = mj_width; + frame.size.width = mj_w; self.frame = frame; } -- (CGFloat)mj_width +- (CGFloat)mj_w { return self.frame.size.width; } -- (void)setMj_height:(CGFloat)mj_height +- (void)setMj_h:(CGFloat)mj_h { CGRect frame = self.frame; - frame.size.height = mj_height; + frame.size.height = mj_h; self.frame = frame; } -- (CGFloat)mj_height +- (CGFloat)mj_h { return self.frame.size.height; } diff --git a/iOSStudy/Pods/MJRefresh/README.md b/iOSStudy/Pods/MJRefresh/README.md index a2e50fa..39b9a5e 100644 --- a/iOSStudy/Pods/MJRefresh/README.md +++ b/iOSStudy/Pods/MJRefresh/README.md @@ -1,43 +1,213 @@ ## MJRefresh -The easiest way to use pull-to-refresh +* The easiest way to use pull-to-refresh +* 用法最简单的下拉刷新框架:一行代码搞定 -![(52326ce26803fabc46000000_18)](http://code4app.qiniudn.com/photo/52326ce26803fabc46000000_18.gif) +## 支持哪些控件的刷新 +* `UIScrollView`、`UITableView`、`UICollectionView`、`UIWebView` -### 添加头部控件 +## 如何使用MJRefresh +* cocoapods导入:`pod 'MJRefresh'` +* 手动导入: + * 将`MJRefreshExample/MJRefreshExample/MJRefresh`文件夹中的所有文件拽入项目中 + * 导入主头文件:`#import "MJRefresh.h"` ```objc -[self.tableView addHeaderWithTarget:self action:@selector(headerRereshing)]; +MJRefresh.bundle +MJRefresh.h +MJRefreshComponent.h MJRefreshComponent.m +MJRefreshConst.h MJRefreshConst.m +MJRefreshFooter.h MJRefreshFooter.m +MJRefreshGifFooter.h MJRefreshGifFooter.m +MJRefreshGifHeader.h MJRefreshGifHeader.m +MJRefreshHeader.h MJRefreshHeader.m +MJRefreshLegendFooter.h MJRefreshLegendFooter.m +MJRefreshLegendHeader.h MJRefreshLegendHeader.m +UIScrollView+MJExtension.h UIScrollView+MJExtension.m +UIScrollView+MJRefresh.h UIScrollView+MJRefresh.m +UIView+MJExtension.h UIView+MJExtension.m ``` -或者 + +## 有哪些App正在使用MJRefresh +![(App01)](http://images.cnitblog.com/blog2015/497279/201504/091535245558276.png) +![(App02)](http://images.cnitblog.com/blog2015/497279/201504/091535380555952.png) +![(App03)](http://images.cnitblog.com/blog2015/497279/201504/091535439466718.png) +* 其他可以关注:[M了个J-博客园](http://www.cnblogs.com/mjios/p/4409853.html) + +## 具体用法 +```objc +* 由于这个框架的功能较多,就不写具体文字描述其用法 +* 大家可以直接参考示例中的MJTableViewController和MJCollectionViewController,更为直观快速 +``` + +## 下拉刷新01-传统 +![(下拉刷新01-传统)](http://images.cnitblog.com/blog2015/497279/201503/061058415392353.gif) +```objc +// 添加传统的下拉刷新 +[self.tableView addLegendHeaderWithRefreshingBlock:^{ + // 进入刷新状态后会自动调用这个block +}]; +或 +// 添加传统的下拉刷新 +// 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) +[self.tableView addLegendHeaderWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; + +// 马上进入刷新状态 +[self.tableView.header beginRefreshing]; +``` + +## 下拉刷新02-动画图片 +![(下拉刷新02-动画图片)](http://images.cnitblog.com/blog2015/497279/201503/061058471802342.gif) +```objc +// 添加动画图片的下拉刷新 +// 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadNewData方法) +[self.tableView addGifHeaderWithRefreshingTarget:self refreshingAction:@selector(loadNewData)]; +// 设置普通状态的动画图片 +[self.tableView.gifHeader setImages:idleImages forState:MJRefreshHeaderStateIdle]; +// 设置即将刷新状态的动画图片(一松开就会刷新的状态) +[self.tableView.gifHeader setImages:pullingImages forState:MJRefreshHeaderStatePulling]; +// 设置正在刷新状态的动画图片 +[self.tableView.gifHeader setImages:refreshingImages forState:MJRefreshHeaderStateRefreshing]; +``` + +## 下拉刷新03-隐藏时间 +![(下拉刷新03-隐藏时间)](http://images.cnitblog.com/blog2015/497279/201503/061058524778760.gif) +```objc +// 隐藏时间 +self.tableView.header.updatedTimeHidden = YES; +``` + +## 下拉刷新04-隐藏状态和时间01 +![(下拉刷新04-隐藏状态和时间01)](http://images.cnitblog.com/blog2015/497279/201503/061058576024893.gif) ```objc -[self.tableView addHeaderWithCallback:^{ }]; +// 隐藏时间 +self.tableView.header.updatedTimeHidden = YES; +// 隐藏状态 +self.tableView.header.stateHidden = YES; ``` -### 添加尾部控件 +## 下拉刷新05-隐藏状态和时间02 +![(下拉刷新05-隐藏状态和时间02)](http://images.cnitblog.com/blog2015/497279/201503/061059030865069.gif) + +## 下拉刷新06-自定义文字 +![(下拉刷新06-自定义文字)](http://images.cnitblog.com/blog2015/497279/201503/081014254613179.gif) ```objc -[self.tableView addFooterWithTarget:self action:@selector(footerRereshing)]; +// 设置文字 +[self.tableView.header setTitle:@"Pull down to refresh" forState:MJRefreshHeaderStateIdle]; +[self.tableView.header setTitle:@"Release to refresh" forState:MJRefreshHeaderStatePulling]; +[self.tableView.header setTitle:@"Loading ..." forState:MJRefreshHeaderStateRefreshing]; + +// 设置字体 +self.tableView.header.font = [UIFont systemFontOfSize:15]; + +// 设置颜色 +self.tableView.header.textColor = [UIColor redColor]; ``` -或者 + +## 上拉刷新01-传统 +![(上拉刷新01-传统)](http://images.cnitblog.com/blog2015/497279/201503/061101472745361.gif) ```objc -[self.tableView addFooterWithCallback:^{ }]; +// 添加传统的上拉刷新 +[self.tableView addLegendFooterWithRefreshingBlock:^{ + // 进入刷新状态后会自动调用这个block +}]; +或 +// 添加传统的上拉刷新 +// 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) +[self.tableView addLegendFooterWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; ``` + +## 上拉刷新02-动画图片 +![(上拉刷新02-动画图片)](http://images.cnitblog.com/blog2015/497279/201503/061056372743988.gif) +```objc +// 添加动画图片的上拉刷新 +// 设置回调(一旦进入刷新状态,就调用target的action,也就是调用self的loadMoreData方法) +[self.tableView addGifFooterWithRefreshingTarget:self refreshingAction:@selector(loadMoreData)]; -### 自动进入刷新状态 +// 设置正在刷新状态的动画图片 +self.tableView.gifFooter.refreshingImages = refreshingImages; +``` + +## 上拉刷新03-隐藏状态01 +![(上拉刷新03-隐藏状态01)](http://images.cnitblog.com/blog2015/497279/201503/061102028365517.gif) ```objc -[self.tableView headerBeginRefreshing]; -[self.tableView footerBeginRefreshing]; +// 隐藏状态 +self.tableView.footer.stateHidden = YES; ``` -### 结束刷新 +## 上拉刷新04-隐藏状态02 +![(上拉刷新04-隐藏状态02)](http://images.cnitblog.com/blog2015/497279/201503/061058093525085.gif) + +## 上拉刷新05-全部加载完毕 +![(上拉刷新05-全部加载完毕)](http://images.cnitblog.com/blog2015/497279/201503/061058172117420.gif) +```objc +// 变为没有更多数据的状态 +[self.tableView.footer noticeNoMoreData]; +``` + +## 上拉刷新06-禁止自动加载 +![(上拉刷新06-禁止自动加载)](http://images.cnitblog.com/blog2015/497279/201503/061058237119539.gif) ```objc -[self.tableView headerEndRefreshing]; -[self.tableView footerEndRefreshing]; +// 禁止自动加载 +self.tableView.footer.automaticallyRefresh = NO; ``` + +## 上拉刷新07-自定义文字 +![(上拉刷新07-自定义文字)](http://images.cnitblog.com/blog2015/497279/201503/081014395552618.gif) +```objc +// 设置文字 +[self.tableView.footer setTitle:@"Click or drag up to refresh" forState:MJRefreshFooterStateIdle]; +[self.tableView.footer setTitle:@"Loading more ..." forState:MJRefreshFooterStateRefreshing]; +[self.tableView.footer setTitle:@"No more data" forState:MJRefreshFooterStateNoMoreData]; + +// 设置字体 +self.tableView.footer.font = [UIFont systemFontOfSize:17]; -### 可以在MJRefreshConst.h和MJRefreshConst.m文件中自定义显示的文字内容和文字颜色 +// 设置颜色 +self.tableView.footer.textColor = [UIColor blueColor]; +``` -### 本框架兼容的系统>=iOS6.0,iPhone\iPad横竖屏 +## 上拉刷新08-加载后隐藏 +![(上拉刷新08-加载后隐藏)](http://images.cnitblog.com/blog2015/497279/201503/061058360395406.gif) +```objc +// 隐藏当前的上拉刷新控件 +self.tableView.footer.hidden = YES; +``` + +## UICollectionView01-上下拉刷新 +![(UICollectionView01-上下拉刷新)](http://images.cnitblog.com/blog2015/497279/201503/061103282897223.gif) +```objc +// 添加传统的下拉刷新 +[self.collectionView addLegendHeaderWithRefreshingBlock:^{ + // 进入刷新状态后会自动调用这个block +}]; +// 添加传统的上拉刷新 +[self.collectionView addLegendFooterWithRefreshingBlock:^{ + // 进入刷新状态后会自动调用这个block +}]; +``` + +## UIWebView01-下拉刷新 +![(UIWebView01-下拉刷新)](http://ww1.sinaimg.cn/mw1024/800cdf9cjw1eq2zjzu78ng208w0fy4qp.gif) +```objc +// 添加下拉刷新控件 +[self.webView.scrollView addLegendHeaderWithRefreshingBlock:^{ + // 进入刷新状态后会自动调用这个block +}]; +``` + +## 提醒 +* 本框架纯ARC,兼容的系统>=iOS6.0、iPhone\iPad横竖屏 ## 期待 -* 如果在使用过程中遇到BUG,希望你能Issues我,谢谢 +* 如果在使用过程中遇到BUG,希望你能Issues我,谢谢(或者尝试下载最新的框架代码看看BUG修复没有) * 如果在使用过程中发现功能不够用,希望你能Issues我,我非常想为这个框架增加更多好用的功能,谢谢 -* 如果你想为MJRefresh输出代码,请拼命Pull Requests我 \ No newline at end of file +* 如果你想为MJRefresh输出代码,请拼命Pull Requests我 +* 一起携手打造天朝乃至世界最好用的刷新框架,做天朝程序员的骄傲 +* 如果你开发的应用中用到了MJRefresh,希望你能到[CocoaControls](https://www.cocoacontrols.com/controls/mjrefresh)添加你应用的iTunes路径,我将会安装使用你的应用,并且根据众多应用的使用情况,对MJRefresh进行一个更好的设计和完善,提供更多好用的功能,谢谢 + * 步骤01(微信是举个例子,百度“你的应用名称 itunes”) +![(step01)](http://ww4.sinaimg.cn/mw1024/800cdf9ctw1eq0viiv5rsj20sm0ea41t.jpg) + * 步骤02 +![(step02)](http://ww2.sinaimg.cn/mw1024/800cdf9ctw1eq0vilejxlj20tu0me7a0.jpg) + * 步骤03 +![(step03)](http://ww1.sinaimg.cn/mw1024/800cdf9ctw1eq0viocpo5j20wc0dc0un.jpg) + * 步骤04 +![(step04)](http://ww3.sinaimg.cn/mw1024/800cdf9ctw1eq0vir137xj20si0gewgu.jpg) diff --git a/iOSStudy/Pods/Manifest.lock b/iOSStudy/Pods/Manifest.lock index ee61b81..3671611 100644 --- a/iOSStudy/Pods/Manifest.lock +++ b/iOSStudy/Pods/Manifest.lock @@ -1,59 +1,55 @@ PODS: - - AFNetworking (2.5.1): - - AFNetworking/NSURLConnection (= 2.5.1) - - AFNetworking/NSURLSession (= 2.5.1) - - AFNetworking/Reachability (= 2.5.1) - - AFNetworking/Security (= 2.5.1) - - AFNetworking/Serialization (= 2.5.1) - - AFNetworking/UIKit (= 2.5.1) - - AFNetworking/NSURLConnection (2.5.1): + - AFNetworking (2.5.3): + - AFNetworking/NSURLConnection (= 2.5.3) + - AFNetworking/NSURLSession (= 2.5.3) + - AFNetworking/Reachability (= 2.5.3) + - AFNetworking/Security (= 2.5.3) + - AFNetworking/Serialization (= 2.5.3) + - AFNetworking/UIKit (= 2.5.3) + - AFNetworking/NSURLConnection (2.5.3): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/NSURLSession (2.5.1): + - AFNetworking/NSURLSession (2.5.3): - AFNetworking/Reachability - AFNetworking/Security - AFNetworking/Serialization - - AFNetworking/Reachability (2.5.1) - - AFNetworking/Security (2.5.1) - - AFNetworking/Serialization (2.5.1) - - AFNetworking/UIKit (2.5.1): + - AFNetworking/Reachability (2.5.3) + - AFNetworking/Security (2.5.3) + - AFNetworking/Serialization (2.5.3) + - AFNetworking/UIKit (2.5.3): - AFNetworking/NSURLConnection - AFNetworking/NSURLSession - - FMDB (2.5): - - FMDB/standard (= 2.5) - - FMDB/common (2.5) - - FMDB/standard (2.5): - - FMDB/common - - Mantle (1.5.4): - - Mantle/extobjc (= 1.5.4) - - Mantle/extobjc (1.5.4) - - MJRefresh (0.0.1) - - SDWebImage (3.7.1): - - SDWebImage/Core (= 3.7.1) - - SDWebImage/Core (3.7.1) - - SVProgressHUD (1.1.2) + - Mantle (2.0): + - Mantle/extobjc (= 2.0) + - Mantle/extobjc (2.0) + - MJRefresh (1.4.6) + - SDWebImage (3.7.2): + - SDWebImage/Core (= 3.7.2) + - SDWebImage/Core (3.7.2) + - Shimmer (1.0.2) + - SVProgressHUD (1.1.3) - SVWebViewController (1.0) - SWTableViewCell (0.3.7) DEPENDENCIES: - AFNetworking (~> 2.0) - - FMDB - Mantle - MJRefresh - SDWebImage + - Shimmer - SVProgressHUD - SVWebViewController - SWTableViewCell (~> 0.3.7) SPEC CHECKSUMS: - AFNetworking: 8bee59492a6ff15d69130efa4d0dc67e0094a52a - FMDB: 0efa188cf0dd1ce82c27a478cd5f5fa245308677 - Mantle: d5fbaf30fbc58031223af13812c060e15934a1fe - MJRefresh: 02638d90855109026754562b7507e5c5eabfcc65 - SDWebImage: 116e88633b5b416ea0ca4b334a4ac59cf72dd38d - SVProgressHUD: da7a49e789af645d9279ffbca62318945a832438 - SVWebViewController: fbf917baa92744c54cfb89a52a4c056e409973a4 - SWTableViewCell: 25de71898e3fcd11cf75707ef90245acf990ec03 + AFNetworking: e1d86c2a96bb5d2e7408da36149806706ee122fe + Mantle: d7c75b6fb789b20f7ae30cd0d09435fe545896ff + MJRefresh: 2eaa3fd8f67fbb86497840fb0167446f7eb61dc7 + SDWebImage: 71b7cdc1d1721d6a82ed62889030225f2c249e29 + Shimmer: c5374be1c2b0c9e292fb05b339a513cf291cac86 + SVProgressHUD: 748080e4f36e603f6c02aec292664239df5279c1 + SVWebViewController: c36dda7326e81fcae0abf5d02bf7bbf7e41be901 + SWTableViewCell: 2a94aadc9d47b2b611fa064566bf57948b95b579 COCOAPODS: 0.35.0 diff --git a/iOSStudy/Pods/Mantle/LICENSE.md b/iOSStudy/Pods/Mantle/LICENSE.md index 0c46720..4e9825a 100644 --- a/iOSStudy/Pods/Mantle/LICENSE.md +++ b/iOSStudy/Pods/Mantle/LICENSE.md @@ -1,4 +1,4 @@ -**Copyright (c) 2012 - 2014, GitHub, Inc.** +**Copyright (c) GitHub, Inc.** **All rights reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h b/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h index 368c5ab..93892d4 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h +++ b/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h @@ -8,165 +8,270 @@ #import -@class MTLModel; +@protocol MTLModel; +@protocol MTLTransformerErrorHandling; -// A MTLModel object that supports being parsed from and serialized to JSON. -@protocol MTLJSONSerializing +/// A MTLModel object that supports being parsed from and serialized to JSON. +@protocol MTLJSONSerializing @required -// Specifies how to map property keys to different key paths in JSON. -// -// Subclasses overriding this method should combine their values with those of -// `super`. -// -// Any property keys not present in the dictionary are assumed to match the JSON -// key that should be used. Any keys associated with NSNull will not participate -// in JSON serialization. -// -// Returns a dictionary mapping property keys to JSON key paths (as strings) or -// NSNull values. +/// Specifies how to map property keys to different key paths in JSON. +/// +/// Subclasses overriding this method should combine their values with those of +/// `super`. +/// +/// Values in the dictionary can either be key paths in the JSON representation +/// of the receiver or an array of such key paths. If an array is used, the +/// deserialized value will be a dictionary containing all of the keys in the +/// array. +/// +/// Any keys omitted will not participate in JSON serialization. +/// +/// Examples +/// +/// + (NSDictionary *)JSONKeyPathsByPropertyKey { +/// return @{ +/// @"name": @"POI.name", +/// @"point": @[ @"latitude", @"longitude" ], +/// @"starred": @"starred" +/// }; +/// } +/// +/// This will map the `starred` property to `JSONDictionary[@"starred"]`, `name` +/// to `JSONDictionary[@"POI"][@"name"]` and `point` to a dictionary equivalent +/// to: +/// +/// @{ +/// @"latitude": JSONDictionary[@"latitude"], +/// @"longitude": JSONDictionary[@"longitude"] +/// } +/// +/// Returns a dictionary mapping property keys to one or multiple JSON key paths +/// (as strings or arrays of strings). + (NSDictionary *)JSONKeyPathsByPropertyKey; @optional -// Specifies how to convert a JSON value to the given property key. If -// reversible, the transformer will also be used to convert the property value -// back to JSON. -// -// If the receiver implements a `+JSONTransformer` method, MTLJSONAdapter -// will use the result of that method instead. -// -// Returns a value transformer, or nil if no transformation should be performed. +/// Specifies how to convert a JSON value to the given property key. If +/// reversible, the transformer will also be used to convert the property value +/// back to JSON. +/// +/// If the receiver implements a `+JSONTransformer` method, MTLJSONAdapter +/// will use the result of that method instead. +/// +/// Returns a value transformer, or nil if no transformation should be performed. + (NSValueTransformer *)JSONTransformerForKey:(NSString *)key; -// Overridden to parse the receiver as a different class, based on information -// in the provided dictionary. -// -// This is mostly useful for class clusters, where the abstract base class would -// be passed into -[MTLJSONAdapter initWithJSONDictionary:modelClass:], but -// a subclass should be instantiated instead. -// -// JSONDictionary - The JSON dictionary that will be parsed. -// -// Returns the class that should be parsed (which may be the receiver), or nil -// to abort parsing (e.g., if the data is invalid). +/// Overridden to parse the receiver as a different class, based on information +/// in the provided dictionary. +/// +/// This is mostly useful for class clusters, where the abstract base class would +/// be passed into -[MTLJSONAdapter initWithJSONDictionary:modelClass:], but +/// a subclass should be instantiated instead. +/// +/// JSONDictionary - The JSON dictionary that will be parsed. +/// +/// Returns the class that should be parsed (which may be the receiver), or nil +/// to abort parsing (e.g., if the data is invalid). + (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary; @end -// The domain for errors originating from MTLJSONAdapter. +/// The domain for errors originating from MTLJSONAdapter. extern NSString * const MTLJSONAdapterErrorDomain; -// +classForParsingJSONDictionary: returned nil for the given dictionary. +/// +classForParsingJSONDictionary: returned nil for the given dictionary. extern const NSInteger MTLJSONAdapterErrorNoClassFound; -// The provided JSONDictionary is not valid. +/// The provided JSONDictionary is not valid. extern const NSInteger MTLJSONAdapterErrorInvalidJSONDictionary; -// The model's implementation of +JSONKeyPathsByPropertyKey included a key which -// does not actually exist in +propertyKeys. +/// The model's implementation of +JSONKeyPathsByPropertyKey included a key which +/// does not actually exist in +propertyKeys. extern const NSInteger MTLJSONAdapterErrorInvalidJSONMapping; -// Converts a MTLModel object to and from a JSON dictionary. +/// Converts a MTLModel object to and from a JSON dictionary. @interface MTLJSONAdapter : NSObject -// The model object that the receiver was initialized with, or that the receiver -// parsed from a JSON dictionary. -@property (nonatomic, strong, readonly) MTLModel *model; - -// Attempts to parse a JSON dictionary into a model object. -// -// modelClass - The MTLModel subclass to attempt to parse from the JSON. -// This class must conform to . This -// argument must not be nil. -// JSONDictionary - A dictionary representing JSON data. This should match the -// format returned by NSJSONSerialization. If this argument is -// nil, the method returns nil. -// error - If not NULL, this may be set to an error that occurs during -// parsing or initializing an instance of `modelClass`. -// -// Returns an instance of `modelClass` upon success, or nil if a parsing error -// occurred. +/// Attempts to parse a JSON dictionary into a model object. +/// +/// modelClass - The MTLModel subclass to attempt to parse from the JSON. +/// This class must conform to . This +/// argument must not be nil. +/// JSONDictionary - A dictionary representing JSON data. This should match the +/// format returned by NSJSONSerialization. If this argument is +/// nil, the method returns nil. +/// error - If not NULL, this may be set to an error that occurs during +/// parsing or initializing an instance of `modelClass`. +/// +/// Returns an instance of `modelClass` upon success, or nil if a parsing error +/// occurred. + (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error; -// Attempts to parse an array of JSON dictionary objects into a model objects -// of a specific class. -// -// modelClass - The MTLModel subclass to attempt to parse from the JSON. This -// class must conform to . This argument must -// not be nil. -// JSONArray - A array of dictionaries representing JSON data. This should -// match the format returned by NSJSONSerialization. If this -// argument is nil, the method returns nil. -// error - If not NULL, this may be set to an error that occurs during -// parsing or initializing an any of the instances of -// `modelClass`. -// -// Returns an array of `modelClass` instances upon success, or nil if a parsing -// error occurred. +/// Attempts to parse an array of JSON dictionary objects into a model objects +/// of a specific class. +/// +/// modelClass - The MTLModel subclass to attempt to parse from the JSON. This +/// class must conform to . This argument must +/// not be nil. +/// JSONArray - A array of dictionaries representing JSON data. This should +/// match the format returned by NSJSONSerialization. If this +/// argument is nil, the method returns nil. +/// error - If not NULL, this may be set to an error that occurs during +/// parsing or initializing an any of the instances of +/// `modelClass`. +/// +/// Returns an array of `modelClass` instances upon success, or nil if a parsing +/// error occurred. + (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error; -// Converts a model into a JSON representation. -// -// model - The model to use for JSON serialization. This argument must not be -// nil. -// -// Returns a JSON dictionary, or nil if a serialization error occurred. -+ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model; +/// Converts a model into a JSON representation. +/// +/// model - The model to use for JSON serialization. This argument must not be +/// nil. +/// error - If not NULL, this may be set to an error that occurs during +/// serializing. +/// +/// Returns a JSON dictionary, or nil if a serialization error occurred. ++ (NSDictionary *)JSONDictionaryFromModel:(id)model error:(NSError **)error; -// Converts a array of models into a JSON representation. -// -// models - The array of models to use for JSON serialization. This argument -// must not be nil. -// -// Returns a JSON array, or nil if a serialization error occurred for any -// model. -+ (NSArray *)JSONArrayFromModels:(NSArray *)models; +/// Converts a array of models into a JSON representation. +/// +/// models - The array of models to use for JSON serialization. This argument +/// must not be nil. +/// error - If not NULL, this may be set to an error that occurs during +/// serializing. +/// +/// Returns a JSON array, or nil if a serialization error occurred for any +/// model. ++ (NSArray *)JSONArrayFromModels:(NSArray *)models error:(NSError **)error; -// Initializes the receiver by attempting to parse a JSON dictionary into -// a model object. -// -// JSONDictionary - A dictionary representing JSON data. This should match the -// format returned by NSJSONSerialization. If this argument is -// nil, the method returns nil and an error with code -// MTLJSONAdapterErrorInvalidJSONDictionary. -// modelClass - The MTLModel subclass to attempt to parse from the JSON. -// This class must conform to . This -// argument must not be nil. -// error - If not NULL, this may be set to an error that occurs during -// parsing or initializing an instance of `modelClass`. -// -// Returns an initialized adapter upon success, or nil if a parsing error -// occurred. -- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error; +/// Initializes the receiver with a given model class. +/// +/// modelClass - The MTLModel subclass to attempt to parse from the JSON and +/// back. This class must conform to . This +/// argument must not be nil. +/// +/// Returns an initialized adapter. +- (id)initWithModelClass:(Class)modelClass; -// Initializes the receiver with an existing model. -// -// model - The model to use for JSON serialization. This argument must not be -// nil. -- (id)initWithModel:(MTLModel *)model; +/// Deserializes a model from a JSON dictionary. +/// +/// The adapter will call -validate: on the model and consider it an error if the +/// validation fails. +/// +/// JSONDictionary - A dictionary representing JSON data. This should match the +/// format returned by NSJSONSerialization. This argument must +/// not be nil. +/// error - If not NULL, this may be set to an error that occurs during +/// deserializing or validation. +/// +/// Returns a model object, or nil if a deserialization error occurred or the +/// model did not validate successfully. +- (id)modelFromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error; -// Serializes the receiver's `model` into JSON. -// -// Returns a JSON dictionary, or nil if a serialization error occurred. -- (NSDictionary *)JSONDictionary; +/// Serializes a model into JSON. +/// +/// model - The model to use for JSON serialization. This argument must not be +/// nil. +/// error - If not NULL, this may be set to an error that occurs during +/// serializing. +/// +/// Returns a model object, or nil if a serialization error occurred. +- (NSDictionary *)JSONDictionaryFromModel:(id)model error:(NSError **)error; -// Looks up the JSON key path in the model's +propertyKeys. -// -// Subclasses may override this method to customize the adapter's seralizing -// behavior. You should not call this method directly. -// -// key - The property key to retrieve the corresponding JSON key path for. This -// argument must not be nil. -// -// Returns a key path to use, or nil to omit the property from JSON. -- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key; +/// Filters the property keys used to serialize a given model. +/// +/// propertyKeys - The property keys for which `model` provides a mapping. +/// model - The model being serialized. +/// +/// Subclasses may override this method to determine which property keys should +/// be used when serializing `model`. For instance, this method can be used to +/// create more efficient updates of server-side resources. +/// +/// The default implementation simply returns `propertyKeys`. +/// +/// Returns a subset of propertyKeys that should be serialized for a given +/// model. +- (NSSet *)serializablePropertyKeys:(NSSet *)propertyKeys forModel:(id)model; + +/// An optional value transformer that should be used for properties of the given +/// class. +/// +/// A value transformer returned by the model's +JSONTransformerForKey: method +/// is given precedence over the one returned by this method. +/// +/// The default implementation invokes `+JSONTransformer` on the +/// receiver if it's implemented. It supports NSURL conversion through +/// +NSURLJSONTransformer. +/// +/// class - The class of the property to serialize. This property must not be +/// nil. +/// +/// Returns a value transformer or nil if no transformation should be used. ++ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)class; + +/// A value transformer that should be used for a properties of the given +/// primitive type. +/// +/// If `objCType` matches @encode(id), the value transformer returned by +/// +transformerForModelPropertiesOfClass: is used instead. +/// +/// The default implementation transforms properties that match @encode(BOOL) +/// using the MTLBooleanValueTransformerName transformer. +/// +/// objCType - The type encoding for the value of this property. This is the type +/// as it would be returned by the @encode() directive. +/// +/// Returns a value transformer or nil if no transformation should be used. ++ (NSValueTransformer *)transformerForModelPropertiesOfObjCType:(const char *)objCType; @end +@interface MTLJSONAdapter (ValueTransformers) + +/// Creates a reversible transformer to convert a JSON dictionary into a MTLModel +/// object, and vice-versa. +/// +/// modelClass - The MTLModel subclass to attempt to parse from the JSON. This +/// class must conform to . This argument must +/// not be nil. +/// +/// Returns a reversible transformer which uses the class of the receiver for +/// transforming values back and forth. ++ (NSValueTransformer *)dictionaryTransformerWithModelClass:(Class)modelClass; + +/// Creates a reversible transformer to convert an array of JSON dictionaries +/// into an array of MTLModel objects, and vice-versa. +/// +/// modelClass - The MTLModel subclass to attempt to parse from each JSON +/// dictionary. This class must conform to . +/// This argument must not be nil. +/// +/// Returns a reversible transformer which uses the class of the receiver for +/// transforming array elements back and forth. ++ (NSValueTransformer *)arrayTransformerWithModelClass:(Class)modelClass; + +/// This value transformer is used by MTLJSONAdapter to automatically convert +/// NSURL properties to JSON strings and vice versa. ++ (NSValueTransformer *)NSURLJSONTransformer; + +@end + +@class MTLModel; + @interface MTLJSONAdapter (Deprecated) -+ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary __attribute__((deprecated("Replaced by +modelOfClass:fromJSONDictionary:error:"))); -- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass __attribute__((deprecated("Replaced by -initWithJSONDictionary:modelClass:error:"))); +@property (nonatomic, strong, readonly) id model __attribute__((unavailable("Replaced by -modelFromJSONDictionary:error:"))); + ++ (NSArray *)JSONArrayFromModels:(NSArray *)models __attribute__((deprecated("Replaced by +JSONArrayFromModels:error:"))); + ++ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model __attribute__((deprecated("Replaced by +JSONDictionaryFromModel:error:"))); + +- (NSDictionary *)JSONDictionary __attribute__((unavailable("Replaced by -JSONDictionaryFromModel:error:"))); +- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key __attribute__((unavailable("Replaced by -serializablePropertyKeys:forModel:"))); +- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error __attribute__((unavailable("Replaced by -initWithModelClass:"))); +- (id)initWithModel:(id)model __attribute__((unavailable("Replaced by -initWithModelClass:"))); +- (NSDictionary *)serializeToJSONDictionary:(NSError **)error __attribute__((unavailable("Replaced by -JSONDictionaryFromModel:error:"))); @end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m b/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m index 9872921..71e7ef0 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m +++ b/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m @@ -6,9 +6,18 @@ // Copyright (c) 2013 GitHub. All rights reserved. // +#import + +#import "NSDictionary+MTLJSONKeyPath.h" + +#import "EXTRuntimeExtensions.h" +#import "EXTScope.h" #import "MTLJSONAdapter.h" #import "MTLModel.h" +#import "MTLTransformerErrorHandling.h" #import "MTLReflection.h" +#import "NSValueTransformer+MTLPredefinedTransformerAdditions.h" +#import "MTLValueTransformer.h" NSString * const MTLJSONAdapterErrorDomain = @"MTLJSONAdapterErrorDomain"; const NSInteger MTLJSONAdapterErrorNoClassFound = 2; @@ -30,12 +39,33 @@ @interface MTLJSONAdapter () // A cached copy of the return value of +JSONKeyPathsByPropertyKey. @property (nonatomic, copy, readonly) NSDictionary *JSONKeyPathsByPropertyKey; -// Looks up the NSValueTransformer that should be used for the given key. +// A cached copy of the return value of -valueTransformersForModelClass: +@property (nonatomic, copy, readonly) NSDictionary *valueTransformersByPropertyKey; + +// Used to cache the JSON adapters returned by -JSONAdapterForModelClass:error:. +@property (nonatomic, strong, readonly) NSMapTable *JSONAdaptersByModelClass; + +// If +classForParsingJSONDictionary: returns a model class different from the +// one this adapter was initialized with, use this method to obtain a cached +// instance of a suitable adapter instead. // -// key - The property key to transform from or to. This argument must not be nil. +// modelClass - The class from which to parse the JSON. This class must conform +// to . This argument must not be nil. +// error - If not NULL, this may be set to an error that occurs during +// initializing the adapter. // -// Returns a transformer to use, or nil to not transform the property. -- (NSValueTransformer *)JSONTransformerForKey:(NSString *)key; +// Returns a JSON adapter for modelClass, creating one of necessary. If no +// adapter could be created, nil is returned. +- (MTLJSONAdapter *)JSONAdapterForModelClass:(Class)modelClass error:(NSError **)error; + +// Collect all value transformers needed for a given class. +// +// modelClass - The class from which to parse the JSON. This class must conform +// to . This argument must not be nil. +// +// Returns a dictionary with the properties of modelClass that need +// transformation as keys and the value transformers as values. ++ (NSDictionary *)valueTransformersForModelClass:(Class)modelClass; @end @@ -44,8 +74,9 @@ @implementation MTLJSONAdapter #pragma mark Convenience methods + (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error { - MTLJSONAdapter *adapter = [[self alloc] initWithJSONDictionary:JSONDictionary modelClass:modelClass error:error]; - return adapter.model; + MTLJSONAdapter *adapter = [[self alloc] initWithModelClass:modelClass]; + + return [adapter modelFromJSONDictionary:JSONDictionary error:error]; } + (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error { @@ -65,25 +96,26 @@ + (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray MTLModel *model = [self modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:error]; if (model == nil) return nil; - + [models addObject:model]; } - + return models; } -+ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model { - MTLJSONAdapter *adapter = [[self alloc] initWithModel:model]; - return adapter.JSONDictionary; ++ (NSDictionary *)JSONDictionaryFromModel:(id)model error:(NSError **)error { + MTLJSONAdapter *adapter = [[self alloc] initWithModelClass:model.class]; + + return [adapter JSONDictionaryFromModel:model error:error]; } -+ (NSArray *)JSONArrayFromModels:(NSArray *)models { ++ (NSArray *)JSONArrayFromModels:(NSArray *)models error:(NSError **)error { NSParameterAssert(models != nil); NSParameterAssert([models isKindOfClass:NSArray.class]); NSMutableArray *JSONArray = [NSMutableArray arrayWithCapacity:models.count]; for (MTLModel *model in models) { - NSDictionary *JSONDictionary = [self JSONDictionaryFromModel:model]; + NSDictionary *JSONDictionary = [self JSONDictionaryFromModel:model error:error]; if (JSONDictionary == nil) return nil; [JSONArray addObject:JSONDictionary]; @@ -95,29 +127,139 @@ + (NSArray *)JSONArrayFromModels:(NSArray *)models { #pragma mark Lifecycle - (id)init { - NSAssert(NO, @"%@ must be initialized with a JSON dictionary or model object", self.class); + NSAssert(NO, @"%@ must be initialized with a model class", self.class); return nil; } -- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error { +- (id)initWithModelClass:(Class)modelClass { NSParameterAssert(modelClass != nil); - NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]); NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); - if (JSONDictionary == nil || ![JSONDictionary isKindOfClass:NSDictionary.class]) { - if (error != NULL) { - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Missing JSON dictionary", @""), - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%@ could not be created because an invalid JSON dictionary was provided: %@", @""), NSStringFromClass(modelClass), JSONDictionary.class], - }; - *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + self = [super init]; + if (self == nil) return nil; + + _modelClass = modelClass; + + _JSONKeyPathsByPropertyKey = [modelClass JSONKeyPathsByPropertyKey]; + + NSSet *propertyKeys = [self.modelClass propertyKeys]; + + for (NSString *mappedPropertyKey in _JSONKeyPathsByPropertyKey) { + if (![propertyKeys containsObject:mappedPropertyKey]) { + NSAssert(NO, @"%@ is not a property of %@.", mappedPropertyKey, modelClass); + return nil; + } + + id value = _JSONKeyPathsByPropertyKey[mappedPropertyKey]; + + if ([value isKindOfClass:NSArray.class]) { + for (NSString *keyPath in value) { + if ([keyPath isKindOfClass:NSString.class]) continue; + + NSAssert(NO, @"%@ must either map to a JSON key path or a JSON array of key paths, got: %@.", mappedPropertyKey, value); + return nil; + } + } else if (![value isKindOfClass:NSString.class]) { + NSAssert(NO, @"%@ must either map to a JSON key path or a JSON array of key paths, got: %@.",mappedPropertyKey, value); + return nil; } + } + + _valueTransformersByPropertyKey = [self.class valueTransformersForModelClass:modelClass]; + + _JSONAdaptersByModelClass = [NSMapTable strongToStrongObjectsMapTable]; + + return self; +} + +#pragma mark Serialization + +- (NSDictionary *)JSONDictionaryFromModel:(id)model error:(NSError **)error { + NSParameterAssert(model != nil); + NSParameterAssert([model isKindOfClass:self.modelClass]); + + if (self.modelClass != model.class) { + MTLJSONAdapter *otherAdapter = [self JSONAdapterForModelClass:model.class error:error]; + + return [otherAdapter JSONDictionaryFromModel:model error:error]; + } + + NSSet *propertyKeysToSerialize = [self serializablePropertyKeys:[NSSet setWithArray:self.JSONKeyPathsByPropertyKey.allKeys] forModel:model]; + + NSDictionary *dictionaryValue = [model.dictionaryValue dictionaryWithValuesForKeys:propertyKeysToSerialize.allObjects]; + NSMutableDictionary *JSONDictionary = [[NSMutableDictionary alloc] initWithCapacity:dictionaryValue.count]; + + __block BOOL success = YES; + __block NSError *tmpError = nil; + + [dictionaryValue enumerateKeysAndObjectsUsingBlock:^(NSString *propertyKey, id value, BOOL *stop) { + id JSONKeyPaths = self.JSONKeyPathsByPropertyKey[propertyKey]; + + if (JSONKeyPaths == nil) return; + + NSValueTransformer *transformer = self.valueTransformersByPropertyKey[propertyKey]; + if ([transformer.class allowsReverseTransformation]) { + // Map NSNull -> nil for the transformer, and then back for the + // dictionaryValue we're going to insert into. + if ([value isEqual:NSNull.null]) value = nil; + + if ([transformer respondsToSelector:@selector(reverseTransformedValue:success:error:)]) { + id errorHandlingTransformer = (id)transformer; + + value = [errorHandlingTransformer reverseTransformedValue:value success:&success error:&tmpError]; + + if (!success) { + *stop = YES; + return; + } + } else { + value = [transformer reverseTransformedValue:value] ?: NSNull.null; + } + } + + void (^createComponents)(id, NSString *) = ^(id obj, NSString *keyPath) { + NSArray *keyPathComponents = [keyPath componentsSeparatedByString:@"."]; + + // Set up dictionaries at each step of the key path. + for (NSString *component in keyPathComponents) { + if ([obj valueForKey:component] == nil) { + // Insert an empty mutable dictionary at this spot so that we + // can set the whole key path afterward. + [obj setValue:[NSMutableDictionary dictionary] forKey:component]; + } + + obj = [obj valueForKey:component]; + } + }; + + if ([JSONKeyPaths isKindOfClass:NSString.class]) { + createComponents(JSONDictionary, JSONKeyPaths); + + [JSONDictionary setValue:value forKeyPath:JSONKeyPaths]; + } + + if ([JSONKeyPaths isKindOfClass:NSArray.class]) { + for (NSString *JSONKeyPath in JSONKeyPaths) { + createComponents(JSONDictionary, JSONKeyPath); + + [JSONDictionary setValue:value[JSONKeyPath] forKeyPath:JSONKeyPath]; + } + } + }]; + + if (success) { + return JSONDictionary; + } else { + if (error != NULL) *error = tmpError; + return nil; } +} - if ([modelClass respondsToSelector:@selector(classForParsingJSONDictionary:)]) { - modelClass = [modelClass classForParsingJSONDictionary:JSONDictionary]; - if (modelClass == nil) { +- (id)modelFromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error { + if ([self.modelClass respondsToSelector:@selector(classForParsingJSONDictionary:)]) { + Class class = [self.modelClass classForParsingJSONDictionary:JSONDictionary]; + if (class == nil) { if (error != NULL) { NSDictionary *userInfo = @{ NSLocalizedDescriptionKey: NSLocalizedString(@"Could not parse JSON", @""), @@ -130,69 +272,70 @@ - (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)mo return nil; } - NSAssert([modelClass isSubclassOfClass:MTLModel.class], @"Class %@ returned from +classForParsingJSONDictionary: is not a subclass of MTLModel", modelClass); - NSAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)], @"Class %@ returned from +classForParsingJSONDictionary: does not conform to ", modelClass); - } + if (class != self.modelClass) { + NSAssert([class conformsToProtocol:@protocol(MTLJSONSerializing)], @"Class %@ returned from +classForParsingJSONDictionary: does not conform to ", class); - self = [super init]; - if (self == nil) return nil; + MTLJSONAdapter *otherAdapter = [self JSONAdapterForModelClass:class error:error]; - _modelClass = modelClass; - _JSONKeyPathsByPropertyKey = [[modelClass JSONKeyPathsByPropertyKey] copy]; + return [otherAdapter modelFromJSONDictionary:JSONDictionary error:error]; + } + } NSMutableDictionary *dictionaryValue = [[NSMutableDictionary alloc] initWithCapacity:JSONDictionary.count]; - NSSet *propertyKeys = [self.modelClass propertyKeys]; + for (NSString *propertyKey in [self.modelClass propertyKeys]) { + id JSONKeyPaths = self.JSONKeyPathsByPropertyKey[propertyKey]; - for (NSString *mappedPropertyKey in self.JSONKeyPathsByPropertyKey) { - if (![propertyKeys containsObject:mappedPropertyKey]) { - NSAssert(NO, @"%@ is not a property of %@.", mappedPropertyKey, modelClass); - return nil; - } + if (JSONKeyPaths == nil) continue; - id value = self.JSONKeyPathsByPropertyKey[mappedPropertyKey]; + id value; - if (![value isKindOfClass:NSString.class] && value != NSNull.null) { - NSAssert(NO, @"%@ must either map to a JSON key path or NSNull, got: %@.",mappedPropertyKey, value); - return nil; - } - } + if ([JSONKeyPaths isKindOfClass:NSArray.class]) { + NSMutableDictionary *dictionary = [NSMutableDictionary dictionary]; - for (NSString *propertyKey in propertyKeys) { - NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey]; - if (JSONKeyPath == nil) continue; + for (NSString *keyPath in JSONKeyPaths) { + BOOL success; + id value = [JSONDictionary mtl_valueForJSONKeyPath:keyPath success:&success error:error]; - id value; - @try { - value = [JSONDictionary valueForKeyPath:JSONKeyPath]; - } @catch (NSException *ex) { - if (error != NULL) { - NSDictionary *userInfo = @{ - NSLocalizedDescriptionKey: NSLocalizedString(@"Invalid JSON dictionary", nil), - NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%1$@ could not be parsed because an invalid JSON dictionary was provided for key path \"%2$@\"", nil), modelClass, JSONKeyPath], - MTLJSONAdapterThrownExceptionErrorKey: ex - }; + if (!success) return nil; - *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + if (value != nil) dictionary[keyPath] = value; } - return nil; + value = dictionary; + } else { + BOOL success; + value = [JSONDictionary mtl_valueForJSONKeyPath:JSONKeyPaths success:&success error:error]; + + if (!success) return nil; } if (value == nil) continue; @try { - NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey]; + NSValueTransformer *transformer = self.valueTransformersByPropertyKey[propertyKey]; if (transformer != nil) { // Map NSNull -> nil for the transformer, and then back for the // dictionary we're going to insert into. if ([value isEqual:NSNull.null]) value = nil; - value = [transformer transformedValue:value] ?: NSNull.null; + + if ([transformer respondsToSelector:@selector(transformedValue:success:error:)]) { + id errorHandlingTransformer = (id)transformer; + + BOOL success = YES; + value = [errorHandlingTransformer transformedValue:value success:&success error:error]; + + if (!success) return nil; + } else { + value = [transformer transformedValue:value]; + } + + if (value == nil) value = NSNull.null; } dictionaryValue[propertyKey] = value; } @catch (NSException *ex) { - NSLog(@"*** Caught exception %@ parsing JSON key path \"%@\" from: %@", ex, JSONKeyPath, JSONDictionary); + NSLog(@"*** Caught exception %@ parsing JSON key path \"%@\" from: %@", ex, JSONKeyPaths, JSONDictionary); // Fail fast in Debug builds. #if DEBUG @@ -213,96 +356,284 @@ - (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)mo } } - _model = [self.modelClass modelWithDictionary:dictionaryValue error:error]; - if (_model == nil) return nil; + id model = [self.modelClass modelWithDictionary:dictionaryValue error:error]; - return self; + return [model validate:error] ? model : nil; } -- (id)initWithModel:(MTLModel *)model { - NSParameterAssert(model != nil); ++ (NSDictionary *)valueTransformersForModelClass:(Class)modelClass { + NSParameterAssert(modelClass != nil); + NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); - self = [super init]; - if (self == nil) return nil; + NSMutableDictionary *result = [NSMutableDictionary dictionary]; - _model = model; - _modelClass = model.class; - _JSONKeyPathsByPropertyKey = [[model.class JSONKeyPathsByPropertyKey] copy]; + for (NSString *key in [modelClass propertyKeys]) { + SEL selector = MTLSelectorWithKeyPattern(key, "JSONTransformer"); + if ([modelClass respondsToSelector:selector]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[modelClass methodSignatureForSelector:selector]]; + invocation.target = modelClass; + invocation.selector = selector; + [invocation invoke]; - return self; -} + __unsafe_unretained id transformer = nil; + [invocation getReturnValue:&transformer]; -#pragma mark Serialization + if (transformer != nil) result[key] = transformer; -- (NSDictionary *)JSONDictionary { - NSDictionary *dictionaryValue = self.model.dictionaryValue; - NSMutableDictionary *JSONDictionary = [[NSMutableDictionary alloc] initWithCapacity:dictionaryValue.count]; + continue; + } - [dictionaryValue enumerateKeysAndObjectsUsingBlock:^(NSString *propertyKey, id value, BOOL *stop) { - NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey]; - if (JSONKeyPath == nil) return; + if ([modelClass respondsToSelector:@selector(JSONTransformerForKey:)]) { + NSValueTransformer *transformer = [modelClass JSONTransformerForKey:key]; - NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey]; - if ([transformer.class allowsReverseTransformation]) { - // Map NSNull -> nil for the transformer, and then back for the - // dictionaryValue we're going to insert into. - if ([value isEqual:NSNull.null]) value = nil; - value = [transformer reverseTransformedValue:value] ?: NSNull.null; + if (transformer != nil) result[key] = transformer; + + continue; } - NSArray *keyPathComponents = [JSONKeyPath componentsSeparatedByString:@"."]; + objc_property_t property = class_getProperty(modelClass, key.UTF8String); + + if (property == NULL) continue; + + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); + @onExit { + free(attributes); + }; + + NSValueTransformer *transformer = nil; + + if (*(attributes->type) == *(@encode(id))) { + Class propertyClass = attributes->objectClass; - // Set up dictionaries at each step of the key path. - id obj = JSONDictionary; - for (NSString *component in keyPathComponents) { - if ([obj valueForKey:component] == nil) { - // Insert an empty mutable dictionary at this spot so that we - // can set the whole key path afterward. - [obj setValue:[NSMutableDictionary dictionary] forKey:component]; + if (propertyClass != nil) { + transformer = [self transformerForModelPropertiesOfClass:propertyClass]; } - obj = [obj valueForKey:component]; + if (transformer == nil) transformer = [NSValueTransformer mtl_validatingTransformerForClass:NSObject.class]; + } else { + transformer = [self transformerForModelPropertiesOfObjCType:attributes->type] ?: [NSValueTransformer mtl_validatingTransformerForClass:NSValue.class]; } - [JSONDictionary setValue:value forKeyPath:JSONKeyPath]; - }]; + if (transformer != nil) result[key] = transformer; + } - return JSONDictionary; + return result; } -- (NSValueTransformer *)JSONTransformerForKey:(NSString *)key { - NSParameterAssert(key != nil); +- (MTLJSONAdapter *)JSONAdapterForModelClass:(Class)modelClass error:(NSError **)error { + NSParameterAssert(modelClass != nil); + NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); + + @synchronized(self) { + MTLJSONAdapter *result = [self.JSONAdaptersByModelClass objectForKey:modelClass]; + + if (result != nil) return result; - SEL selector = MTLSelectorWithKeyPattern(key, "JSONTransformer"); - if ([self.modelClass respondsToSelector:selector]) { - NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self.modelClass methodSignatureForSelector:selector]]; - invocation.target = self.modelClass; - invocation.selector = selector; - [invocation invoke]; + result = [[MTLJSONAdapter alloc] initWithModelClass:modelClass]; + + if (result != nil) { + [self.JSONAdaptersByModelClass setObject:result forKey:modelClass]; + } - __unsafe_unretained id result = nil; - [invocation getReturnValue:&result]; return result; } +} + +- (NSSet *)serializablePropertyKeys:(NSSet *)propertyKeys forModel:(id)model { + return propertyKeys; +} - if ([self.modelClass respondsToSelector:@selector(JSONTransformerForKey:)]) { - return [self.modelClass JSONTransformerForKey:key]; ++ (NSValueTransformer *)transformerForModelPropertiesOfClass:(Class)modelClass { + NSParameterAssert(modelClass != nil); + + SEL selector = MTLSelectorWithKeyPattern(NSStringFromClass(modelClass), "JSONTransformer"); + if (![self respondsToSelector:selector]) return nil; + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; + invocation.target = self; + invocation.selector = selector; + [invocation invoke]; + + __unsafe_unretained id result = nil; + [invocation getReturnValue:&result]; + return result; +} + ++ (NSValueTransformer *)transformerForModelPropertiesOfObjCType:(const char *)objCType { + NSParameterAssert(objCType != NULL); + + if (strcmp(objCType, @encode(BOOL)) == 0) { + return [NSValueTransformer valueTransformerForName:MTLBooleanValueTransformerName]; } return nil; } -- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key { - NSParameterAssert(key != nil); +@end - id JSONKeyPath = self.JSONKeyPathsByPropertyKey[key]; - if ([JSONKeyPath isEqual:NSNull.null]) return nil; +@implementation MTLJSONAdapter (ValueTransformers) - if (JSONKeyPath == nil) { - return key; - } else { - return JSONKeyPath; - } ++ (NSValueTransformer *)dictionaryTransformerWithModelClass:(Class)modelClass { + NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]); + NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); + + return [MTLValueTransformer + transformerUsingForwardBlock:^ id (id JSONDictionary, BOOL *success, NSError **error) { + if (JSONDictionary == nil) return nil; + + if (![JSONDictionary isKindOfClass:NSDictionary.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert JSON dictionary to model object", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSDictionary, got: %@", @""), JSONDictionary], + MTLTransformerErrorHandlingInputValueErrorKey : JSONDictionary + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + id model = [self modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:error]; + if (model == nil) { + *success = NO; + } + + return model; + } + reverseBlock:^ NSDictionary * (id model, BOOL *success, NSError **error) { + if (model == nil) return nil; + + if (![model isKindOfClass:MTLModel.class] || ![model conformsToProtocol:@protocol(MTLJSONSerializing)]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert model object to JSON dictionary", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected a MTLModel object conforming to , got: %@.", @""), model], + MTLTransformerErrorHandlingInputValueErrorKey : model + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSDictionary *result = [self JSONDictionaryFromModel:model error:error]; + if (result == nil) { + *success = NO; + } + + return result; + }]; +} + ++ (NSValueTransformer *)arrayTransformerWithModelClass:(Class)modelClass { + id dictionaryTransformer = [self dictionaryTransformerWithModelClass:modelClass]; + + return [MTLValueTransformer + transformerUsingForwardBlock:^ id (NSArray *dictionaries, BOOL *success, NSError **error) { + if (dictionaries == nil) return nil; + + if (![dictionaries isKindOfClass:NSArray.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert JSON array to model array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSArray, got: %@.", @""), dictionaries], + MTLTransformerErrorHandlingInputValueErrorKey : dictionaries + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictionaries.count]; + for (id JSONDictionary in dictionaries) { + if (JSONDictionary == NSNull.null) { + [models addObject:NSNull.null]; + continue; + } + + if (![JSONDictionary isKindOfClass:NSDictionary.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert JSON array to model array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSDictionary or an NSNull, got: %@.", @""), JSONDictionary], + MTLTransformerErrorHandlingInputValueErrorKey : JSONDictionary + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + id model = [dictionaryTransformer transformedValue:JSONDictionary success:success error:error]; + + if (*success == NO) return nil; + + if (model == nil) continue; + + [models addObject:model]; + } + + return models; + } + reverseBlock:^ id (NSArray *models, BOOL *success, NSError **error) { + if (models == nil) return nil; + + if (![models isKindOfClass:NSArray.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert model array to JSON array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSArray, got: %@.", @""), models], + MTLTransformerErrorHandlingInputValueErrorKey : models + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSMutableArray *dictionaries = [NSMutableArray arrayWithCapacity:models.count]; + for (id model in models) { + if (model == NSNull.null) { + [dictionaries addObject:NSNull.null]; + continue; + } + + if (![model isKindOfClass:MTLModel.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert JSON array to model array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected a MTLModel or an NSNull, got: %@.", @""), model], + MTLTransformerErrorHandlingInputValueErrorKey : model + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSDictionary *dict = [dictionaryTransformer reverseTransformedValue:model success:success error:error]; + + if (*success == NO) return nil; + + if (dict == nil) continue; + + [dictionaries addObject:dict]; + } + + return dictionaries; + }]; +} + ++ (NSValueTransformer *)NSURLJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; } @end @@ -312,12 +643,12 @@ @implementation MTLJSONAdapter (Deprecated) #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wdeprecated-implementations" -+ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary { - return [self modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:NULL]; ++ (NSArray *)JSONArrayFromModels:(NSArray *)models { + return [self JSONArrayFromModels:models error:NULL]; } -- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass { - return [self initWithJSONDictionary:JSONDictionary modelClass:modelClass error:NULL]; ++ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model { + return [self JSONDictionaryFromModel:model error:NULL]; } #pragma clang diagnostic pop diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h b/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h index 94b8f7b..86e140a 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h +++ b/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h @@ -8,121 +8,121 @@ #import "MTLModel.h" -// Defines how a MTLModel property key should be encoded into an archive. -// -// MTLModelEncodingBehaviorExcluded - The property should never be encoded. -// MTLModelEncodingBehaviorUnconditional - The property should always be -// encoded. -// MTLModelEncodingBehaviorConditional - The object should be encoded only -// if unconditionally encoded elsewhere. -// This should only be used for object -// properties. +/// Defines how a MTLModel property key should be encoded into an archive. +/// +/// MTLModelEncodingBehaviorExcluded - The property should never be encoded. +/// MTLModelEncodingBehaviorUnconditional - The property should always be +/// encoded. +/// MTLModelEncodingBehaviorConditional - The object should be encoded only +/// if unconditionally encoded elsewhere. +/// This should only be used for object +/// properties. typedef enum : NSUInteger { MTLModelEncodingBehaviorExcluded = 0, MTLModelEncodingBehaviorUnconditional, MTLModelEncodingBehaviorConditional, } MTLModelEncodingBehavior; -// Implements default archiving and unarchiving behaviors for MTLModel. +/// Implements default archiving and unarchiving behaviors for MTLModel. @interface MTLModel (NSCoding) -// Initializes the receiver from an archive. -// -// This will decode the original +modelVersion of the archived object, then -// invoke -decodeValueForKey:withCoder:modelVersion: for each of the receiver's -// +propertyKeys. -// -// Returns an initialized model object, or nil if a decoding error occurred. +/// Initializes the receiver from an archive. +/// +/// This will decode the original +modelVersion of the archived object, then +/// invoke -decodeValueForKey:withCoder:modelVersion: for each of the receiver's +/// +propertyKeys. +/// +/// Returns an initialized model object, or nil if a decoding error occurred. - (id)initWithCoder:(NSCoder *)coder; -// Archives the receiver using the given coder. -// -// This will encode the receiver's +modelVersion, then the receiver's properties -// according to the behaviors specified in +encodingBehaviorsByPropertyKey. +/// Archives the receiver using the given coder. +/// +/// This will encode the receiver's +modelVersion, then the receiver's properties +/// according to the behaviors specified in +encodingBehaviorsByPropertyKey. - (void)encodeWithCoder:(NSCoder *)coder; -// Determines how the +propertyKeys of the class are encoded into an archive. -// The values of this dictionary should be boxed MTLModelEncodingBehavior -// values. -// -// Any keys not present in the dictionary will be excluded from the archive. -// -// Subclasses overriding this method should combine their values with those of -// `super`. -// -// Returns a dictionary mapping the receiver's +propertyKeys to default encoding -// behaviors. If a property is an object with `weak` semantics, the default -// behavior is MTLModelEncodingBehaviorConditional; otherwise, the default is -// MTLModelEncodingBehaviorUnconditional. +/// Determines how the +propertyKeys of the class are encoded into an archive. +/// The values of this dictionary should be boxed MTLModelEncodingBehavior +/// values. +/// +/// Any keys not present in the dictionary will be excluded from the archive. +/// +/// Subclasses overriding this method should combine their values with those of +/// `super`. +/// +/// Returns a dictionary mapping the receiver's +propertyKeys to default encoding +/// behaviors. If a property is an object with `weak` semantics, the default +/// behavior is MTLModelEncodingBehaviorConditional; otherwise, the default is +/// MTLModelEncodingBehaviorUnconditional. + (NSDictionary *)encodingBehaviorsByPropertyKey; -// Determines the classes that are allowed to be decoded for each of the -// receiver's properties when using . The values of this -// dictionary should be NSArrays of Class objects. -// -// If any encodable keys (as determined by +encodingBehaviorsByPropertyKey) are -// not present in the dictionary, an exception will be thrown during secure -// encoding or decoding. -// -// Subclasses overriding this method should combine their values with those of -// `super`. -// -// Returns a dictionary mapping the receiver's encodable keys (as determined by -// +encodingBehaviorsByPropertyKey) to default allowed classes, based on the -// type that each property is declared as. If type of an encodable property -// cannot be determined (e.g., it is declared as `id`), it will be omitted from -// the dictionary, and subclasses must provide a valid value to prevent an -// exception being thrown during encoding/decoding. +/// Determines the classes that are allowed to be decoded for each of the +/// receiver's properties when using . The values of this +/// dictionary should be NSArrays of Class objects. +/// +/// If any encodable keys (as determined by +encodingBehaviorsByPropertyKey) are +/// not present in the dictionary, an exception will be thrown during secure +/// encoding or decoding. +/// +/// Subclasses overriding this method should combine their values with those of +/// `super`. +/// +/// Returns a dictionary mapping the receiver's encodable keys (as determined by +/// +encodingBehaviorsByPropertyKey) to default allowed classes, based on the +/// type that each property is declared as. If type of an encodable property +/// cannot be determined (e.g., it is declared as `id`), it will be omitted from +/// the dictionary, and subclasses must provide a valid value to prevent an +/// exception being thrown during encoding/decoding. + (NSDictionary *)allowedSecureCodingClassesByPropertyKey; -// Decodes the value of the given property key from an archive. -// -// By default, this method looks for a `-decodeWithCoder:modelVersion:` -// method on the receiver, and invokes it if found. -// -// If the custom method is not implemented and `coder` does not require secure -// coding, `-[NSCoder decodeObjectForKey:]` will be invoked with the given -// `key`. -// -// If the custom method is not implemented and `coder` requires secure coding, -// `-[NSCoder decodeObjectOfClasses:forKey:]` will be invoked with the -// information from +allowedSecureCodingClassesByPropertyKey and the given `key`. The -// receiver must conform to for this to work correctly. -// -// key - The property key to decode the value for. This argument cannot -// be nil. -// coder - The NSCoder representing the archive being decoded. This -// argument cannot be nil. -// modelVersion - The version of the original model object that was encoded. -// -// Returns the decoded and boxed value, or nil if the key was not present. +/// Decodes the value of the given property key from an archive. +/// +/// By default, this method looks for a `-decodeWithCoder:modelVersion:` +/// method on the receiver, and invokes it if found. +/// +/// If the custom method is not implemented and `coder` does not require secure +/// coding, `-[NSCoder decodeObjectForKey:]` will be invoked with the given +/// `key`. +/// +/// If the custom method is not implemented and `coder` requires secure coding, +/// `-[NSCoder decodeObjectOfClasses:forKey:]` will be invoked with the +/// information from +allowedSecureCodingClassesByPropertyKey and the given `key`. The +/// receiver must conform to for this to work correctly. +/// +/// key - The property key to decode the value for. This argument cannot +/// be nil. +/// coder - The NSCoder representing the archive being decoded. This +/// argument cannot be nil. +/// modelVersion - The version of the original model object that was encoded. +/// +/// Returns the decoded and boxed value, or nil if the key was not present. - (id)decodeValueForKey:(NSString *)key withCoder:(NSCoder *)coder modelVersion:(NSUInteger)modelVersion; -// The version of this MTLModel subclass. -// -// This version number is saved in archives so that later model changes can be -// made backwards-compatible with old versions. -// -// Subclasses should override this method to return a higher version number -// whenever a breaking change is made to the model. -// -// Returns 0. +/// The version of this MTLModel subclass. +/// +/// This version number is saved in archives so that later model changes can be +/// made backwards-compatible with old versions. +/// +/// Subclasses should override this method to return a higher version number +/// whenever a breaking change is made to the model. +/// +/// Returns 0. + (NSUInteger)modelVersion; @end -// This method must be overridden to support archives created by older versions -// of Mantle (before the `MTLModel+NSCoding` interface existed). +/// This method must be overridden to support archives created by older versions +/// of Mantle (before the `MTLModel+NSCoding` interface existed). @interface MTLModel (OldArchiveSupport) -// Converts an archived external representation to a dictionary suitable for -// passing to -initWithDictionary:. -// -// externalRepresentation - The decoded external representation of the receiver. -// fromVersion - The model version at the time the external -// representation was encoded. -// -// Returns nil by default, indicating that conversion failed. +/// Converts an archived external representation to a dictionary suitable for +/// passing to -initWithDictionary:. +/// +/// externalRepresentation - The decoded external representation of the receiver. +/// fromVersion - The model version at the time the external +/// representation was encoded. +/// +/// Returns nil by default, indicating that conversion failed. + (NSDictionary *)dictionaryValueFromArchivedExternalRepresentation:(NSDictionary *)externalRepresentation version:(NSUInteger)fromVersion; @end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m b/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m index 852f5ae..79a3b57 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m +++ b/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m @@ -10,7 +10,6 @@ #import "EXTRuntimeExtensions.h" #import "EXTScope.h" #import "MTLReflection.h" -#import // Used in archives to store the modelVersion of the archived instance. static NSString * const MTLModelVersionKey = @"MTLModelVersion"; diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLModel.h b/iOSStudy/Pods/Mantle/Mantle/MTLModel.h index 65da40d..96042b4 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLModel.h +++ b/iOSStudy/Pods/Mantle/Mantle/MTLModel.h @@ -8,118 +8,172 @@ #import -// An abstract base class for model objects, using reflection to provide -// sensible default behaviors. -// -// The default implementations of , -hash, and -isEqual: make use of -// the +propertyKeys method. -@interface MTLModel : NSObject - -// Returns a new instance of the receiver initialized using -// -initWithDictionary:error:. +/// Defines a property's storage behavior, which affects how it will be copied, +/// compared, and persisted. +/// +/// MTLPropertyStorageNone - This property is not included in -description, +/// -hash, or anything else. +/// MTLPropertyStorageTransitory - This property is included in one-off +/// operations like -copy and -dictionaryValue but +/// does not affect -isEqual: or -hash. +/// It may disappear at any time. +/// MTLPropertyStoragePermanent - The property is included in serialization +/// (like `NSCoding`) and equality, since it can +/// be expected to stick around. +typedef enum : NSUInteger { + MTLPropertyStorageNone, + MTLPropertyStorageTransitory, + MTLPropertyStoragePermanent, +} MTLPropertyStorage; + +/// This protocol defines the minimal interface that classes need to implement to +/// interact with Mantle adapters. +/// +/// It is intended for scenarios where inheriting from MTLModel is not feasible. +/// However, clients are encouraged to subclass the MTLModel class if they can. +/// +/// Clients that wish to implement their own adapters should target classes +/// conforming to this protocol rather than subclasses of MTLModel to ensure +/// maximum compatibility. +@protocol MTLModel + +/// Initializes a new instance of the receiver using key-value coding, setting +/// the keys and values in the given dictionary. +/// +/// dictionaryValue - Property keys and values to set on the instance. Any NSNull +/// values will be converted to nil before being used. KVC +/// validation methods will automatically be invoked for all of +/// the properties given. +/// error - If not NULL, this may be set to any error that occurs +/// (like a KVC validation error). +/// +/// Returns an initialized model object, or nil if validation failed. + (instancetype)modelWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error; -// Initializes the receiver with default values. -// -// This is the designated initializer for this class. -- (instancetype)init; +/// A dictionary representing the properties of the receiver. +/// +/// Combines the values corresponding to all +propertyKeys into a dictionary, +/// with any nil values represented by NSNull. +/// +/// This property must never be nil. +@property (nonatomic, copy, readonly) NSDictionary *dictionaryValue; -// Initializes the receiver using key-value coding, setting the keys and values -// in the given dictionary. -// -// Subclass implementations may override this method, calling the super -// implementation, in order to perform further processing and initialization -// after deserialization. -// -// dictionaryValue - Property keys and values to set on the receiver. Any NSNull -// values will be converted to nil before being used. KVC -// validation methods will automatically be invoked for all of -// the properties given. If nil, this method is equivalent to -// -init. -// error - If not NULL, this may be set to any error that occurs -// (like a KVC validation error). -// -// Returns an initialized model object, or nil if validation failed. +/// Initializes the receiver using key-value coding, setting the keys and values +/// in the given dictionary. +/// +/// Subclass implementations may override this method, calling the super +/// implementation, in order to perform further processing and initialization +/// after deserialization. +/// +/// dictionaryValue - Property keys and values to set on the receiver. Any NSNull +/// values will be converted to nil before being used. KVC +/// validation methods will automatically be invoked for all of +/// the properties given. If nil, this method is equivalent to +/// -init. +/// error - If not NULL, this may be set to any error that occurs +/// (like a KVC validation error). +/// +/// Returns an initialized model object, or nil if validation failed. - (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error; -// Returns the keys for all @property declarations, except for `readonly` -// properties without ivars, or properties on MTLModel itself. +/// Merges the value of the given key on the receiver with the value of the same +/// key from the given model object, giving precedence to the other model object. +- (void)mergeValueForKey:(NSString *)key fromModel:(id)model; + +/// Returns the keys for all @property declarations, except for `readonly` +/// properties without ivars, or properties on MTLModel itself. + (NSSet *)propertyKeys; -// A dictionary representing the properties of the receiver. -// -// The default implementation combines the values corresponding to all -// +propertyKeys into a dictionary, with any nil values represented by NSNull. -// -// This property must never be nil. -@property (nonatomic, copy, readonly) NSDictionary *dictionaryValue; +/// Validates the model. +/// +/// error - If not NULL, this may be set to any error that occurs during +/// validation +/// +/// Returns YES if the model is valid, or NO if the validation failed. +- (BOOL)validate:(NSError **)error; -// Merges the value of the given key on the receiver with the value of the same -// key from the given model object, giving precedence to the other model object. -// -// By default, this method looks for a `-mergeFromModel:` method on the -// receiver, and invokes it if found. If not found, and `model` is not nil, the -// value for the given key is taken from `model`. -- (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model; +@end -// Merges the values of the given model object into the receiver, using -// -mergeValueForKey:fromModel: for each key in +propertyKeys. -// -// `model` must be an instance of the receiver's class or a subclass thereof. -- (void)mergeValuesForKeysFromModel:(MTLModel *)model; +/// An abstract base class for model objects, using reflection to provide +/// sensible default behaviors. +/// +/// The default implementations of , -hash, and -isEqual: make use of +/// the +propertyKeys method. +@interface MTLModel : NSObject + +/// Initializes the receiver using key-value coding, setting the keys and values +/// in the given dictionary. +/// +/// dictionaryValue - Property keys and values to set on the receiver. Any NSNull +/// values will be converted to nil before being used. KVC +/// validation methods will automatically be invoked for all of +/// the properties given. If nil, this method is equivalent to +/// -init. +/// error - If not NULL, this may be set to any error that occurs +/// (like a KVC validation error). +/// +/// Returns an initialized model object, or nil if validation failed. +- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error; -// Compares the receiver with another object for equality. -// -// The default implementation is equivalent to comparing both models' -// -dictionaryValue. -// -// Note that this may lead to infinite loops if the receiver holds a circular -// reference to another MTLModel and both use the default behavior. -// It is recommended to override -isEqual: in this scenario. +/// Initializes the receiver with default values. +/// +/// This is the designated initializer for this class. +- (instancetype)init; + +/// By default, this method looks for a `-mergeFromModel:` method on the +/// receiver, and invokes it if found. If not found, and `model` is not nil, the +/// value for the given key is taken from `model`. +- (void)mergeValueForKey:(NSString *)key fromModel:(id)model; + +/// Merges the values of the given model object into the receiver, using +/// -mergeValueForKey:fromModel: for each key in +propertyKeys. +/// +/// `model` must be an instance of the receiver's class or a subclass thereof. +- (void)mergeValuesForKeysFromModel:(id)model; + +/// The storage behavior of a given key. +/// +/// The default implementation returns MTLPropertyStorageNone for properties that +/// are readonly and not backed by an instance variable and +/// MTLPropertyStoragePermanent otherwise. +/// +/// Subclasses can use this method to prevent MTLModel from resolving circular +/// references by returning MTLPropertyStorageTransitory. +/// +/// Returns the storage behavior for a given key on the receiver. ++ (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey; + +/// Compares the receiver with another object for equality. +/// +/// The default implementation is equivalent to comparing all properties of both +/// models for which +storageBehaviorForPropertyWithKey: returns +/// MTLPropertyStoragePermanent. +/// +/// Returns YES if the two models are considered equal, NO otherwise. - (BOOL)isEqual:(id)object; -// A string that describes the contents of the receiver. -// -// The default implementation is based on the receiver's class and its -// -dictionaryValue. -// -// Note that this may lead to infinite loops if the receiver holds a circular -// reference to another MTLModel and both use the default behavior. -// It is recommended to override -description in this scenario. +/// A string that describes the contents of the receiver. +/// +/// The default implementation is based on the receiver's class and all its +/// properties for which +storageBehaviorForPropertyWithKey: returns +/// MTLPropertyStoragePermanent. - (NSString *)description; @end -// Implements validation logic for MTLModel. +/// Implements validation logic for MTLModel. @interface MTLModel (Validation) -// Validates the model. -// -// The default implementation simply invokes -validateValue:forKey:error: with -// all +propertyKeys and their current value. If -validateValue:forKey:error: -// returns a new value, the property is set to that new value. -// -// error - If not NULL, this may be set to any error that occurs during -// validation -// -// Returns YES if the model is valid, or NO if the validation failed. +/// Validates the model. +/// +/// The default implementation simply invokes -validateValue:forKey:error: with +/// all +propertyKeys and their current value. If -validateValue:forKey:error: +/// returns a new value, the property is set to that new value. +/// +/// error - If not NULL, this may be set to any error that occurs during +/// validation +/// +/// Returns YES if the model is valid, or NO if the validation failed. - (BOOL)validate:(NSError **)error; @end - -@interface MTLModel (Unavailable) - -+ (instancetype)modelWithDictionary:(NSDictionary *)dictionaryValue __attribute__((deprecated("Replaced by +modelWithDictionary:error:"))); -- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue __attribute__((deprecated("Replaced by -initWithDictionary:error:"))); - -+ (instancetype)modelWithExternalRepresentation:(NSDictionary *)externalRepresentation __attribute__((deprecated("Replaced by -[MTLJSONAdapter initWithJSONDictionary:modelClass:]"))); -- (instancetype)initWithExternalRepresentation:(NSDictionary *)externalRepresentation __attribute__((deprecated("Replaced by -[MTLJSONAdapter initWithJSONDictionary:modelClass:]"))); - -@property (nonatomic, copy, readonly) NSDictionary *externalRepresentation __attribute__((deprecated("Replaced by MTLJSONAdapter.JSONDictionary"))); - -+ (NSDictionary *)externalRepresentationKeyPathsByPropertyKey __attribute__((deprecated("Replaced by +JSONKeyPathsByPropertyKey in "))); -+ (NSValueTransformer *)transformerForKey:(NSString *)key __attribute__((deprecated("Replaced by +JSONTransformerForKey: in "))); - -+ (NSDictionary *)migrateExternalRepresentation:(NSDictionary *)externalRepresentation fromVersion:(NSUInteger)fromVersion __attribute__((deprecated("Replaced by -decodeValueForKey:withCoder:modelVersion:"))); - -@end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLModel.m b/iOSStudy/Pods/Mantle/Mantle/MTLModel.m index 2ef60fe..5e3f5df 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLModel.m +++ b/iOSStudy/Pods/Mantle/Mantle/MTLModel.m @@ -13,14 +13,17 @@ #import "MTLReflection.h" #import -// This coupling is needed for backwards compatibility in MTLModel's deprecated -// methods. -#import "MTLJSONAdapter.h" -#import "MTLModel+NSCoding.h" - // Used to cache the reflection performed in +propertyKeys. static void *MTLModelCachedPropertyKeysKey = &MTLModelCachedPropertyKeysKey; +// Associated in +generateAndCachePropertyKeys with a set of all transitory +// property keys. +static void *MTLModelCachedTransitoryPropertyKeysKey = &MTLModelCachedTransitoryPropertyKeysKey; + +// Associated in +generateAndCachePropertyKeys with a set of all permanent +// property keys. +static void *MTLModelCachedPermanentPropertyKeysKey = &MTLModelCachedPermanentPropertyKeysKey; + // Validates a value for an object and sets it if necessary. // // obj - The object for which the value is being validated. This value @@ -67,6 +70,18 @@ static BOOL MTLValidateAndSetValue(id obj, NSString *key, id value, BOOL forceUp @interface MTLModel () +// Inspects all properties of returned by +propertyKeys using +// +storageBehaviorForPropertyWithKey and caches the results. ++ (void)generateAndCacheStorageBehaviors; + +// Returns a set of all property keys for which +// +storageBehaviorForPropertyWithKey returned MTLPropertyStorageTransitory. ++ (NSSet *)transitoryPropertyKeys; + +// Returns a set of all property keys for which +// +storageBehaviorForPropertyWithKey returned MTLPropertyStoragePermanent. ++ (NSSet *)permanentPropertyKeys; + // Enumerates all properties of the receiver's class hierarchy, starting at the // receiver, and continuing up until (but not including) MTLModel. // @@ -80,6 +95,31 @@ @implementation MTLModel #pragma mark Lifecycle ++ (void)generateAndCacheStorageBehaviors { + NSMutableSet *transitoryKeys = [NSMutableSet set]; + NSMutableSet *permanentKeys = [NSMutableSet set]; + + for (NSString *propertyKey in self.propertyKeys) { + switch ([self storageBehaviorForPropertyWithKey:propertyKey]) { + case MTLPropertyStorageNone: + break; + + case MTLPropertyStorageTransitory: + [transitoryKeys addObject:propertyKey]; + break; + + case MTLPropertyStoragePermanent: + [permanentKeys addObject:propertyKey]; + break; + } + } + + // It doesn't really matter if we replace another thread's work, since we do + // it atomically and the result should be the same. + objc_setAssociatedObject(self, MTLModelCachedTransitoryPropertyKeysKey, transitoryKeys, OBJC_ASSOCIATION_COPY); + objc_setAssociatedObject(self, MTLModelCachedPermanentPropertyKeysKey, permanentKeys, OBJC_ASSOCIATION_COPY); +} + + (instancetype)modelWithDictionary:(NSDictionary *)dictionary error:(NSError **)error { return [[self alloc] initWithDictionary:dictionary error:error]; } @@ -98,7 +138,7 @@ - (instancetype)initWithDictionary:(NSDictionary *)dictionary error:(NSError **) // a new object to be stored in this variable (and we don't want ARC to // double-free or leak the old or new values). __autoreleasing id value = [dictionary objectForKey:key]; - + if ([value isEqual:NSNull.null]) value = nil; BOOL success = MTLValidateAndSetValue(self, key, value, YES, error); @@ -139,15 +179,11 @@ + (NSSet *)propertyKeys { NSMutableSet *keys = [NSMutableSet set]; [self enumeratePropertiesUsingBlock:^(objc_property_t property, BOOL *stop) { - mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); - @onExit { - free(attributes); - }; - - if (attributes->readonly && attributes->ivar == NULL) return; - NSString *key = @(property_getName(property)); - [keys addObject:key]; + + if ([self storageBehaviorForPropertyWithKey:key] != MTLPropertyStorageNone) { + [keys addObject:key]; + } }]; // It doesn't really matter if we replace another thread's work, since we do @@ -157,13 +193,54 @@ + (NSSet *)propertyKeys { return keys; } ++ (NSSet *)transitoryPropertyKeys { + NSSet *transitoryPropertyKeys = objc_getAssociatedObject(self, MTLModelCachedTransitoryPropertyKeysKey); + + if (transitoryPropertyKeys == nil) { + [self generateAndCacheStorageBehaviors]; + transitoryPropertyKeys = objc_getAssociatedObject(self, MTLModelCachedTransitoryPropertyKeysKey); + } + + return transitoryPropertyKeys; +} + ++ (NSSet *)permanentPropertyKeys { + NSSet *permanentPropertyKeys = objc_getAssociatedObject(self, MTLModelCachedPermanentPropertyKeysKey); + + if (permanentPropertyKeys == nil) { + [self generateAndCacheStorageBehaviors]; + permanentPropertyKeys = objc_getAssociatedObject(self, MTLModelCachedPermanentPropertyKeysKey); + } + + return permanentPropertyKeys; +} + - (NSDictionary *)dictionaryValue { - return [self dictionaryWithValuesForKeys:self.class.propertyKeys.allObjects]; + NSSet *keys = [self.class.transitoryPropertyKeys setByAddingObjectsFromSet:self.class.permanentPropertyKeys]; + + return [self dictionaryWithValuesForKeys:keys.allObjects]; +} + ++ (MTLPropertyStorage)storageBehaviorForPropertyWithKey:(NSString *)propertyKey { + objc_property_t property = class_getProperty(self.class, propertyKey.UTF8String); + + if (property == NULL) return MTLPropertyStorageNone; + + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); + @onExit { + free(attributes); + }; + + if (attributes->readonly && attributes->ivar == NULL) { + return MTLPropertyStorageNone; + } else { + return MTLPropertyStoragePermanent; + } } #pragma mark Merging -- (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model { +- (void)mergeValueForKey:(NSString *)key fromModel:(NSObject *)model { NSParameterAssert(key != nil); SEL selector = MTLSelectorWithCapitalizedKeyPattern("merge", key, "FromModel:"); @@ -183,8 +260,9 @@ - (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model { [invocation invoke]; } -- (void)mergeValuesForKeysFromModel:(MTLModel *)model { +- (void)mergeValuesForKeysFromModel:(id)model { NSSet *propertyKeys = model.class.propertyKeys; + for (NSString *key in self.class.propertyKeys) { if (![propertyKeys containsObject:key]) continue; @@ -214,13 +292,15 @@ - (instancetype)copyWithZone:(NSZone *)zone { #pragma mark NSObject - (NSString *)description { - return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, self.dictionaryValue]; + NSDictionary *permanentProperties = [self dictionaryWithValuesForKeys:self.class.permanentPropertyKeys.allObjects]; + + return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, permanentProperties]; } - (NSUInteger)hash { NSUInteger value = 0; - for (NSString *key in self.class.propertyKeys) { + for (NSString *key in self.class.permanentPropertyKeys) { value ^= [[self valueForKey:key] hash]; } @@ -231,7 +311,7 @@ - (BOOL)isEqual:(MTLModel *)model { if (self == model) return YES; if (![model isMemberOfClass:self.class]) return NO; - for (NSString *key in self.class.propertyKeys) { + for (NSString *key in self.class.permanentPropertyKeys) { id selfValue = [self valueForKey:key]; id modelValue = [model valueForKey:key]; diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h b/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h index f4c100e..52c920b 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h +++ b/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h @@ -8,24 +8,24 @@ #import -// Creates a selector from a key and a constant string. -// -// key - The key to insert into the generated selector. This key should be in -// its natural case. -// suffix - A string to append to the key as part of the selector. -// -// Returns a selector, or NULL if the input strings cannot form a valid -// selector. +/// Creates a selector from a key and a constant string. +/// +/// key - The key to insert into the generated selector. This key should be in +/// its natural case. +/// suffix - A string to append to the key as part of the selector. +/// +/// Returns a selector, or NULL if the input strings cannot form a valid +/// selector. SEL MTLSelectorWithKeyPattern(NSString *key, const char *suffix) __attribute__((pure, nonnull(1, 2))); -// Creates a selector from a key and a constant prefix and suffix. -// -// prefix - A string to prepend to the key as part of the selector. -// key - The key to insert into the generated selector. This key should be in -// its natural case, and will have its first letter capitalized when -// inserted. -// suffix - A string to append to the key as part of the selector. -// -// Returns a selector, or NULL if the input strings cannot form a valid -// selector. +/// Creates a selector from a key and a constant prefix and suffix. +/// +/// prefix - A string to prepend to the key as part of the selector. +/// key - The key to insert into the generated selector. This key should be in +/// its natural case, and will have its first letter capitalized when +/// inserted. +/// suffix - A string to append to the key as part of the selector. +/// +/// Returns a selector, or NULL if the input strings cannot form a valid +/// selector. SEL MTLSelectorWithCapitalizedKeyPattern(const char *prefix, NSString *key, const char *suffix) __attribute__((pure, nonnull(1, 2, 3))); diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.h b/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.h new file mode 100644 index 0000000..2726d91 --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.h @@ -0,0 +1,66 @@ +// +// MTLTransformerErrorHandling.h +// Mantle +// +// Created by Robert Böhnke on 10/6/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +/// The domain for errors originating from the MTLTransformerErrorHandling +/// protocol. +/// +/// Transformers conforming to this protocol are expected to use this error +/// domain if the transformation fails. +extern NSString * const MTLTransformerErrorHandlingErrorDomain; + +/// Used to indicate that the input value was illegal. +/// +/// Transformers conforming to this protocol are expected to use this error code +/// if the transformation fails due to an invalid input value. +extern const NSInteger MTLTransformerErrorHandlingErrorInvalidInput; + +/// Associated with the invalid input value. +/// +/// Transformers conforming to this protocol are expected to associate this key +/// with the invalid input in the userInfo dictionary. +extern NSString * const MTLTransformerErrorHandlingInputValueErrorKey; + +/// This protocol can be implemented by NSValueTransformer subclasses to +/// communicate errors that occur during transformation. +@protocol MTLTransformerErrorHandling +@required + +/// Transforms a value, returning any error that occurred during transformation. +/// +/// value - The value to transform. +/// success - If not NULL, this will be set to a boolean indicating whether the +/// transformation was successful. +/// error - If not NULL, this may be set to an error that occurs during +/// transforming the value. +/// +/// Returns the result of the transformation which may be nil. Clients should +/// inspect the success parameter to decide how to proceed with the result. +- (id)transformedValue:(id)value success:(BOOL *)success error:(NSError **)error; + +@optional + +/// Reverse-transforms a value, returning any error that occurred during +/// transformation. +/// +/// Transformers conforming to this protocol are expected to implemented this +/// method if they support reverse transformation. +/// +/// value - The value to transform. +/// success - If not NULL, this will be set to a boolean indicating whether the +/// transformation was successful. +/// error - If not NULL, this may be set to an error that occurs during +/// transforming the value. +/// +/// Returns the result of the reverse transformation which may be nil. Clients +/// should inspect the success parameter to decide how to proceed with the +/// result. +- (id)reverseTransformedValue:(id)value success:(BOOL *)success error:(NSError **)error; + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.m b/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.m new file mode 100644 index 0000000..962e2c0 --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/MTLTransformerErrorHandling.m @@ -0,0 +1,15 @@ +// +// MTLTransformerErrorHandling.h +// Mantle +// +// Created by Robert Böhnke on 10/6/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLTransformerErrorHandling.h" + +NSString * const MTLTransformerErrorHandlingErrorDomain = @"MTLTransformerErrorHandlingErrorDomain"; + +const NSInteger MTLTransformerErrorHandlingErrorInvalidInput = 1; + +NSString * const MTLTransformerErrorHandlingInputValueErrorKey = @"MTLTransformerErrorHandlingInputValueErrorKey"; diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h b/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h index 231b59f..5deda94 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h +++ b/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h @@ -8,22 +8,45 @@ #import -typedef id (^MTLValueTransformerBlock)(id); +#import "MTLTransformerErrorHandling.h" -// -// A value transformer supporting block-based transformation. -// -@interface MTLValueTransformer : NSValueTransformer +/// A block that represents a transformation. +/// +/// value - The value to transform. +/// success - The block must set this parameter to indicate whether the +/// transformation was successful. +/// MTLValueTransformer will always call this block with *success +/// initialized to YES. +/// error - If not NULL, this may be set to an error that occurs during +/// transforming the value. +/// +/// Returns the result of the transformation, which may be nil. +typedef id (^MTLValueTransformerBlock)(id value, BOOL *success, NSError **error); + +/// +/// A value transformer supporting block-based transformation. +/// +@interface MTLValueTransformer : NSValueTransformer + +/// Returns a transformer which transforms values using the given block. Reverse +/// transformations will not be allowed. ++ (instancetype)transformerUsingForwardBlock:(MTLValueTransformerBlock)transformation; + +/// Returns a transformer which transforms values using the given block, for +/// forward or reverse transformations. ++ (instancetype)transformerUsingReversibleBlock:(MTLValueTransformerBlock)transformation; + +/// Returns a transformer which transforms values using the given blocks. ++ (instancetype)transformerUsingForwardBlock:(MTLValueTransformerBlock)forwardTransformation reverseBlock:(MTLValueTransformerBlock)reverseTransformation; + +@end + +@interface MTLValueTransformer (Deprecated) -// Returns a transformer which transforms values using the given block. Reverse -// transformations will not be allowed. -+ (instancetype)transformerWithBlock:(MTLValueTransformerBlock)transformationBlock; ++ (NSValueTransformer *)transformerWithBlock:(id (^)(id))transformationBlock __attribute__((deprecated("Replaced by +transformerUsingForwardBlock:"))); -// Returns a transformer which transforms values using the given block, for -// forward or reverse transformations. -+ (instancetype)reversibleTransformerWithBlock:(MTLValueTransformerBlock)transformationBlock; ++ (NSValueTransformer *)reversibleTransformerWithBlock:(id (^)(id))transformationBlock __attribute__((deprecated("Replaced by +transformerUsingReversibleBlock:"))); -// Returns a transformer which transforms values using the given blocks. -+ (instancetype)reversibleTransformerWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock; ++ (NSValueTransformer *)reversibleTransformerWithForwardBlock:(id (^)(id))forwardBlock reverseBlock:(id (^)(id))reverseBlock __attribute__((deprecated("Replaced by +transformerUsingForwardBlock:reverseBlock:"))); @end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m b/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m index 5400d45..701627b 100644 --- a/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m +++ b/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m @@ -26,15 +26,15 @@ @implementation MTLValueTransformer #pragma mark Lifecycle -+ (instancetype)transformerWithBlock:(MTLValueTransformerBlock)transformationBlock { - return [[self alloc] initWithForwardBlock:transformationBlock reverseBlock:nil]; ++ (instancetype)transformerUsingForwardBlock:(MTLValueTransformerBlock)forwardBlock { + return [[self alloc] initWithForwardBlock:forwardBlock reverseBlock:nil]; } -+ (instancetype)reversibleTransformerWithBlock:(MTLValueTransformerBlock)transformationBlock { - return [self reversibleTransformerWithForwardBlock:transformationBlock reverseBlock:transformationBlock]; ++ (instancetype)transformerUsingReversibleBlock:(MTLValueTransformerBlock)reversibleBlock { + return [self transformerUsingForwardBlock:reversibleBlock reverseBlock:reversibleBlock]; } -+ (instancetype)reversibleTransformerWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock { ++ (instancetype)transformerUsingForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock { return [[MTLReversibleValueTransformer alloc] initWithForwardBlock:forwardBlock reverseBlock:reverseBlock]; } @@ -57,11 +57,26 @@ + (BOOL)allowsReverseTransformation { } + (Class)transformedValueClass { - return [NSObject class]; + return NSObject.class; } - (id)transformedValue:(id)value { - return self.forwardBlock(value); + NSError *error = nil; + BOOL success = YES; + + return self.forwardBlock(value, &success, &error); +} + +- (id)transformedValue:(id)value success:(BOOL *)outerSuccess error:(NSError **)outerError { + NSError *error = nil; + BOOL success = YES; + + id transformedValue = self.forwardBlock(value, &success, &error); + + if (outerSuccess != NULL) *outerSuccess = success; + if (outerError != NULL) *outerError = error; + + return transformedValue; } @end @@ -82,7 +97,54 @@ + (BOOL)allowsReverseTransformation { } - (id)reverseTransformedValue:(id)value { - return self.reverseBlock(value); + NSError *error = nil; + BOOL success = YES; + + return self.reverseBlock(value, &success, &error); +} + +- (id)reverseTransformedValue:(id)value success:(BOOL *)outerSuccess error:(NSError **)outerError { + NSError *error = nil; + BOOL success = YES; + + id transformedValue = self.reverseBlock(value, &success, &error); + + if (outerSuccess != NULL) *outerSuccess = success; + if (outerError != NULL) *outerError = error; + + return transformedValue; } @end + + +@implementation MTLValueTransformer (Deprecated) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" + ++ (instancetype)transformerWithBlock:(id (^)(id))transformationBlock { + return [self transformerUsingForwardBlock:^(id value, BOOL *success, NSError **error) { + return transformationBlock(value); + }]; +} + ++ (instancetype)reversibleTransformerWithBlock:(id (^)(id))transformationBlock { + return [self transformerUsingReversibleBlock:^(id value, BOOL *success, NSError **error) { + return transformationBlock(value); + }]; +} + ++ (instancetype)reversibleTransformerWithForwardBlock:(id (^)(id))forwardBlock reverseBlock:(id (^)(id))reverseBlock { + return [self + transformerUsingForwardBlock:^(id value, BOOL *success, NSError **error) { + return forwardBlock(value); + } + reverseBlock:^(id value, BOOL *success, NSError **error) { + return reverseBlock(value); + }]; +} + +#pragma clang diagnostic pop + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/Mantle.h b/iOSStudy/Pods/Mantle/Mantle/Mantle.h index ebd74e7..102b7ad 100644 --- a/iOSStudy/Pods/Mantle/Mantle/Mantle.h +++ b/iOSStudy/Pods/Mantle/Mantle/Mantle.h @@ -15,12 +15,13 @@ FOUNDATION_EXPORT double MantleVersionNumber; FOUNDATION_EXPORT const unsigned char MantleVersionString[]; #import -#import #import #import #import +#import #import #import +#import #import #import #import diff --git a/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h index fd7347c..b8c2b56 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h @@ -10,19 +10,19 @@ @interface NSArray (MTLManipulationAdditions) -// The first object in the array or nil if the array is empty. -// Forwards to `firstObject` which has been first declared in iOS7, but works with iOS4/10.6. +/// The first object in the array or nil if the array is empty. +/// Forwards to `firstObject` which has been first declared in iOS7, but works with iOS4/10.6. @property (nonatomic, readonly, strong) id mtl_firstObject; -// Returns a new array without all instances of the given object. +/// Returns a new array without all instances of the given object. - (NSArray *)mtl_arrayByRemovingObject:(id)object; -// Returns a new array without the first object. If the array is empty, it -// returns the empty array. +/// Returns a new array without the first object. If the array is empty, it +/// returns the empty array. - (NSArray *)mtl_arrayByRemovingFirstObject; -// Returns a new array without the last object. If the array is empty, it -// returns the empty array. +/// Returns a new array without the last object. If the array is empty, it +/// returns the empty array. - (NSArray *)mtl_arrayByRemovingLastObject; @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.h b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.h new file mode 100644 index 0000000..eb70151 --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.h @@ -0,0 +1,27 @@ +// +// NSDictionary+MTLJSONKeyPath.h +// Mantle +// +// Created by Robert Böhnke on 19/03/14. +// Copyright (c) 2014 GitHub. All rights reserved. +// + +#import + +@interface NSDictionary (MTLJSONKeyPath) + +/// Looks up the value of a key path in the receiver. +/// +/// JSONKeyPath - The key path that should be resolved. Every element along this +/// key path needs to be an instance of NSDictionary for the +/// resolving to be successful. +/// success - If not NULL, this will be set to a boolean indicating whether +/// the key path was resolved successfully. +/// error - If not NULL, this may be set to an error that occurs during +/// resolving the value. +/// +/// Returns the value for the key path which may be nil. Clients should inspect +/// the success parameter to decide how to proceed with the result. +- (id)mtl_valueForJSONKeyPath:(NSString *)JSONKeyPath success:(BOOL *)success error:(NSError **)error; + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.m b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.m new file mode 100644 index 0000000..03ee2ad --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLJSONKeyPath.m @@ -0,0 +1,47 @@ +// +// NSDictionary+MTLJSONKeyPath.m +// Mantle +// +// Created by Robert Böhnke on 19/03/14. +// Copyright (c) 2014 GitHub. All rights reserved. +// + +#import "NSDictionary+MTLJSONKeyPath.h" + +#import "MTLJSONAdapter.h" + +@implementation NSDictionary (MTLJSONKeyPath) + +- (id)mtl_valueForJSONKeyPath:(NSString *)JSONKeyPath success:(BOOL *)success error:(NSError **)error { + NSArray *components = [JSONKeyPath componentsSeparatedByString:@"."]; + + id result = self; + for (NSString *component in components) { + // Check the result before resolving the key path component to not + // affect the last value of the path. + if (result == nil || result == NSNull.null) break; + + if (![result isKindOfClass:NSDictionary.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Invalid JSON dictionary", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"JSON key path %1$@ could not resolved because an incompatible JSON dictionary was supplied: \"%2$@\"", @""), JSONKeyPath, self] + }; + + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + } + + if (success != NULL) *success = NO; + + return nil; + } + + result = result[component]; + } + + if (success != NULL) *success = YES; + + return result; +} + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h index 83254d3..6126293 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h @@ -10,16 +10,22 @@ @interface NSDictionary (MTLManipulationAdditions) -// Merges the keys and values from the given dictionary into the receiver. If -// both the receiver and `dictionary` have a given key, the value from -// `dictionary` is used. -// -// Returns a new dictionary containing the entries of the receiver combined with -// those of `dictionary`. +/// Merges the keys and values from the given dictionary into the receiver. If +/// both the receiver and `dictionary` have a given key, the value from +/// `dictionary` is used. +/// +/// Returns a new dictionary containing the entries of the receiver combined with +/// those of `dictionary`. - (NSDictionary *)mtl_dictionaryByAddingEntriesFromDictionary:(NSDictionary *)dictionary; -// Creates a new dictionary with all the entries for the given keys removed from -// the receiver. -- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys; +/// Creates a new dictionary with all the entries for the given keys removed from +/// the receiver. +- (NSDictionary *)mtl_dictionaryByRemovingValuesForKeys:(NSArray *)keys; + +@end + +@interface NSDictionary (MTLManipulationAdditions_Deprecated) + +- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys __attribute__((deprecated("Replaced by -mtl_dictionaryByRemovingValuesForKeys:"))); @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m index 0ed5746..a7a1d7a 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m @@ -16,10 +16,23 @@ - (NSDictionary *)mtl_dictionaryByAddingEntriesFromDictionary:(NSDictionary *)di return result; } -- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys { +- (NSDictionary *)mtl_dictionaryByRemovingValuesForKeys:(NSArray *)keys { NSMutableDictionary *result = [self mutableCopy]; - [result removeObjectsForKeys:keys.allObjects]; + [result removeObjectsForKeys:keys]; return result; } @end + +@implementation NSDictionary (MTLManipulationAdditions_Deprecated) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" + +- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys { + return [self mtl_dictionaryByRemovingValuesForKeys:keys.allObjects]; +} + +#pragma clang diagnostic pop + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.h new file mode 100644 index 0000000..0071c89 --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.h @@ -0,0 +1,21 @@ +// +// NSDictionary+MTLMappingAdditions.h +// Mantle +// +// Created by Robert Böhnke on 10/31/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +@interface NSDictionary (MTLMappingAdditions) + +/// Creates an identity mapping for serialization. +/// +/// class - A subclass of MTLModel. +/// +/// Returns a dictionary that maps all properties of the given class to +/// themselves. ++ (NSDictionary *)mtl_identityPropertyMapWithModel:(Class)class; + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.m b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.m new file mode 100644 index 0000000..6ed8ffc --- /dev/null +++ b/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLMappingAdditions.m @@ -0,0 +1,23 @@ +// +// NSDictionary+MTLMappingAdditions.m +// Mantle +// +// Created by Robert Böhnke on 10/31/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLModel.h" + +#import "NSDictionary+MTLMappingAdditions.h" + +@implementation NSDictionary (MTLMappingAdditions) + ++ (NSDictionary *)mtl_identityPropertyMapWithModel:(Class)class { + NSCParameterAssert([class isSubclassOfClass:MTLModel.class]); + + NSArray *propertyKeys = [class propertyKeys].allObjects; + + return [NSDictionary dictionaryWithObjects:propertyKeys forKeys:propertyKeys]; +} + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h b/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h index f7c1e9e..3c82818 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h @@ -10,14 +10,14 @@ @interface NSError (MTLModelException) -// Creates a new error for an exception that occured during updating an -// MTLModel. -// -// exception - The exception that was thrown while updating the model. -// This argument must not be nil. -// -// Returns an error that takes its localized description and failure reason -// from the exception. +/// Creates a new error for an exception that occured during updating an +/// MTLModel. +/// +/// exception - The exception that was thrown while updating the model. +/// This argument must not be nil. +/// +/// Returns an error that takes its localized description and failure reason +/// from the exception. + (instancetype)mtl_modelErrorWithException:(NSException *)exception; @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h index 4f7c03e..0ca13e6 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h @@ -11,5 +11,5 @@ #import -// Returns whether both objects are identical or equal via -isEqual: +/// Returns whether both objects are identical or equal via -isEqual: BOOL MTLEqualObjects(id obj1, id obj2); diff --git a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h index eefceec..ca29b98 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h @@ -10,12 +10,12 @@ @interface NSValueTransformer (MTLInversionAdditions) -// Flips the direction of the receiver's transformation, such that -// -transformedValue: will become -reverseTransformedValue:, and vice-versa. -// -// The receiver must allow reverse transformation. -// -// Returns an inverted transformer. +/// Flips the direction of the receiver's transformation, such that +/// -transformedValue: will become -reverseTransformedValue:, and vice-versa. +/// +/// The receiver must allow reverse transformation. +/// +/// Returns an inverted transformer. - (NSValueTransformer *)mtl_invertedTransformer; @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m index 71fe4b0..2e536d6 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m +++ b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m @@ -7,6 +7,7 @@ // #import "NSValueTransformer+MTLInversionAdditions.h" +#import "MTLTransformerErrorHandling.h" #import "MTLValueTransformer.h" @implementation NSValueTransformer (MTLInversionAdditions) @@ -14,11 +15,23 @@ @implementation NSValueTransformer (MTLInversionAdditions) - (NSValueTransformer *)mtl_invertedTransformer { NSParameterAssert(self.class.allowsReverseTransformation); - return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(id value) { - return [self reverseTransformedValue:value]; - } reverseBlock:^(id value) { - return [self transformedValue:value]; - }]; + if ([self conformsToProtocol:@protocol(MTLTransformerErrorHandling)]) { + NSParameterAssert([self respondsToSelector:@selector(reverseTransformedValue:success:error:)]); + + id errorHandlingSelf = (id)self; + + return [MTLValueTransformer transformerUsingForwardBlock:^(id value, BOOL *success, NSError **error) { + return [errorHandlingSelf reverseTransformedValue:value success:success error:error]; + } reverseBlock:^(id value, BOOL *success, NSError **error) { + return [errorHandlingSelf transformedValue:value success:success error:error]; + }]; + } else { + return [MTLValueTransformer transformerUsingForwardBlock:^(id value, BOOL *success, NSError **error) { + return [self reverseTransformedValue:value]; + } reverseBlock:^(id value, BOOL *success, NSError **error) { + return [self transformedValue:value]; + }]; + } } @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h index 78a6b19..5369bf5 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h +++ b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h @@ -8,77 +8,72 @@ #import -// The name for a value transformer that converts strings into URLs and back. +#import "MTLTransformerErrorHandling.h" + +/// The name for a value transformer that converts strings into URLs and back. extern NSString * const MTLURLValueTransformerName; -// Ensure an NSNumber is backed by __NSCFBoolean/CFBooleanRef -// -// NSJSONSerialization, and likely other serialization libraries, ordinarily -// serialize NSNumbers as numbers, and thus booleans would be serialized as -// 0/1. The exception is when the NSNumber is backed by __NSCFBoolean, which, -// though very much an implementation detail, is detected and serialized as a -// proper boolean. +/// Ensure an NSNumber is backed by __NSCFBoolean/CFBooleanRef +/// +/// NSJSONSerialization, and likely other serialization libraries, ordinarily +/// serialize NSNumbers as numbers, and thus booleans would be serialized as +/// 0/1. The exception is when the NSNumber is backed by __NSCFBoolean, which, +/// though very much an implementation detail, is detected and serialized as a +/// proper boolean. extern NSString * const MTLBooleanValueTransformerName; @interface NSValueTransformer (MTLPredefinedTransformerAdditions) -// Creates a reversible transformer to convert a JSON dictionary into a MTLModel -// object, and vice-versa. -// -// modelClass - The MTLModel subclass to attempt to parse from the JSON. This -// class must conform to . This argument must -// not be nil. -// -// Returns a reversible transformer which uses MTLJSONAdapter for transforming -// values back and forth. -+ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass; - -// Creates a reversible transformer to convert an array of JSON dictionaries -// into an array of MTLModel objects, and vice-versa. -// -// modelClass - The MTLModel subclass to attempt to parse from each JSON -// dictionary. This class must conform to . -// This argument must not be nil. -// -// Returns a reversible transformer which uses MTLJSONAdapter for transforming -// array elements back and forth. -+ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass; +/// An optionally reversible transformer which applies the given transformer to +/// each element of an array. +/// +/// transformer - The transformer to apply to each element. If the transformer +/// is reversible, the transformer returned by this method will be +/// reversible. This argument must not be nil. +/// +/// Returns a transformer which applies a transformation to each element of an +/// array. ++ (NSValueTransformer *)mtl_arrayMappingTransformerWithTransformer:(NSValueTransformer *)transformer; -// A reversible value transformer to transform between the keys and objects of a -// dictionary. -// -// dictionary - The dictionary whose keys and values should be -// transformed between. This argument must not be nil. -// defaultValue - The result to fall back to, in case no key matching the -// input value was found during a forward transformation. -// reverseDefaultValue - The result to fall back to, in case no value matching -// the input value was found during a reverse -// transformation. -// -// Can for example be used for transforming between enum values and their string -// representation. -// -// NSValueTransformer *valueTransformer = [NSValueTransformer mtl_valueMappingTransformerWithDictionary:@{ -// @"foo": @(EnumDataTypeFoo), -// @"bar": @(EnumDataTypeBar), -// } defaultValue: @(EnumDataTypeUndefined) reverseDefaultValue: @"undefined"]; -// -// Returns a transformer that will map from keys to values in dictionary -// for forward transformation, and from values to keys for reverse -// transformations. If no matching key or value can be found, the respective -// default value is returned. -+ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue; +/// A reversible value transformer to transform between the keys and objects of a +/// dictionary. +/// +/// dictionary - The dictionary whose keys and values should be +/// transformed between. This argument must not be nil. +/// defaultValue - The result to fall back to, in case no key matching the +/// input value was found during a forward transformation. +/// reverseDefaultValue - The result to fall back to, in case no value matching +/// the input value was found during a reverse +/// transformation. +/// +/// Can for example be used for transforming between enum values and their string +/// representation. +/// +/// NSValueTransformer *valueTransformer = [NSValueTransformer mtl_valueMappingTransformerWithDictionary:@{ +/// @"foo": @(EnumDataTypeFoo), +/// @"bar": @(EnumDataTypeBar), +/// } defaultValue: @(EnumDataTypeUndefined) reverseDefaultValue: @"undefined"]; +/// +/// Returns a transformer which will map from keys to objects for forward +/// transformations, and from objects to keys for reverse transformations. ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue; -// Returns a value transformer created by calling -// `+mtl_valueMappingTransformerWithDictionary:defaultValue:reverseDefaultValue:` -// with a default value of `nil` and a reverse default value of `nil`. -+ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary; +/// Returns a value transformer created by calling +/// `+mtl_valueMappingTransformerWithDictionary:defaultValue:reverseDefaultValue:` +/// with a default value of `nil` and a reverse default value of `nil`. ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary; -@end +/// A value transformer that errors if the transformed value are not of the given +/// class. +/// +/// class - The expected class. This argument must not be nil. +/// +/// Returns a transformer which will return an error if the transformed in value +/// is not a member of class. Otherwise, the value is simply passed through. ++ (NSValueTransformer *)mtl_validatingTransformerForClass:(Class)class; -@interface NSValueTransformer (UnavailableMTLPredefinedTransformerAdditions) ++ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +[MTLJSONAdapter dictionaryTransformerWithModelClass:]"))); -+ (NSValueTransformer *)mtl_externalRepresentationTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +mtl_JSONDictionaryTransformerWithModelClass:"))); -+ (NSValueTransformer *)mtl_externalRepresentationArrayTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +mtl_JSONArrayTransformerWithModelClass:"))); ++ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +[MTLJSONAdapter arrayTransformerWithModelClass:]"))); @end diff --git a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m index 10622a0..407998d 100644 --- a/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m +++ b/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m @@ -21,20 +21,79 @@ @implementation NSValueTransformer (MTLPredefinedTransformerAdditions) + (void)load { @autoreleasepool { MTLValueTransformer *URLValueTransformer = [MTLValueTransformer - reversibleTransformerWithForwardBlock:^ id (NSString *str) { - if (![str isKindOfClass:NSString.class]) return nil; - return [NSURL URLWithString:str]; + transformerUsingForwardBlock:^ id (NSString *str, BOOL *success, NSError **error) { + if (str == nil) return nil; + + if (![str isKindOfClass:NSString.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to URL", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSString, got: %@.", @""), str], + MTLTransformerErrorHandlingInputValueErrorKey : str + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSURL *result = [NSURL URLWithString:str]; + + if (result == nil) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert string to URL", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Input URL string %@ was malformed", @""), str], + MTLTransformerErrorHandlingInputValueErrorKey : str + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + return result; } - reverseBlock:^ id (NSURL *URL) { - if (![URL isKindOfClass:NSURL.class]) return nil; + reverseBlock:^ id (NSURL *URL, BOOL *success, NSError **error) { + if (URL == nil) return nil; + + if (![URL isKindOfClass:NSURL.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert URL to string", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSURL, got: %@.", @""), URL], + MTLTransformerErrorHandlingInputValueErrorKey : URL + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } return URL.absoluteString; }]; - + [NSValueTransformer setValueTransformer:URLValueTransformer forName:MTLURLValueTransformerName]; MTLValueTransformer *booleanValueTransformer = [MTLValueTransformer - reversibleTransformerWithBlock:^ id (NSNumber *boolean) { - if (![boolean isKindOfClass:NSNumber.class]) return nil; + transformerUsingReversibleBlock:^ id (NSNumber *boolean, BOOL *success, NSError **error) { + if (boolean == nil) return nil; + + if (![boolean isKindOfClass:NSNumber.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not convert number to boolean-backed number or vice-versa", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSNumber, got: %@.", @""), boolean], + MTLTransformerErrorHandlingInputValueErrorKey : boolean + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } return (NSNumber *)(boolean.boolValue ? kCFBooleanTrue : kCFBooleanFalse); }]; @@ -44,98 +103,189 @@ + (void)load { #pragma mark Customizable Transformers -+ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass { - NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]); - NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); - - return [MTLValueTransformer - reversibleTransformerWithForwardBlock:^ id (id JSONDictionary) { - if (JSONDictionary == nil) return nil; - - NSAssert([JSONDictionary isKindOfClass:NSDictionary.class], @"Expected a dictionary, got: %@", JSONDictionary); - - return [MTLJSONAdapter modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:NULL]; ++ (NSValueTransformer *)mtl_arrayMappingTransformerWithTransformer:(NSValueTransformer *)transformer { + NSParameterAssert(transformer != nil); + + id (^forwardBlock)(NSArray *values, BOOL *success, NSError **error) = ^ id (NSArray *values, BOOL *success, NSError **error) { + if (values == nil) return nil; + + if (![values isKindOfClass:NSArray.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not transform non-array type", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSArray, got: %@.", @""), values], + MTLTransformerErrorHandlingInputValueErrorKey: values + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; } - reverseBlock:^ id (id model) { - if (model == nil) return nil; - - NSAssert([model isKindOfClass:MTLModel.class], @"Expected a MTLModel object, got %@", model); - NSAssert([model conformsToProtocol:@protocol(MTLJSONSerializing)], @"Expected a model object conforming to , got %@", model); - - return [MTLJSONAdapter JSONDictionaryFromModel:model]; - }]; -} - -+ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass { - NSValueTransformer *dictionaryTransformer = [self mtl_JSONDictionaryTransformerWithModelClass:modelClass]; - - return [MTLValueTransformer - reversibleTransformerWithForwardBlock:^ id (NSArray *dictionaries) { - if (dictionaries == nil) return nil; - - NSAssert([dictionaries isKindOfClass:NSArray.class], @"Expected an array of dictionaries, got: %@", dictionaries); + + NSMutableArray *transformedValues = [NSMutableArray arrayWithCapacity:values.count]; + NSInteger index = -1; + for (id value in values) { + index++; + if (value == NSNull.null) { + [transformedValues addObject:NSNull.null]; + continue; + } + + id transformedValue = nil; + if ([transformer conformsToProtocol:@protocol(MTLTransformerErrorHandling)]) { + NSError *underlyingError = nil; + transformedValue = [(id)transformer transformedValue:value success:success error:&underlyingError]; + + if (*success == NO) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not transform array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Could not transform value at index %d", @""), index], + NSUnderlyingErrorKey: underlyingError, + MTLTransformerErrorHandlingInputValueErrorKey: values + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + return nil; + } + } else { + transformedValue = [transformer transformedValue:value]; + } + + if (transformedValue == nil) continue; + + [transformedValues addObject:transformedValue]; + } + + return transformedValues; + }; + + id (^reverseBlock)(NSArray *values, BOOL *success, NSError **error) = nil; + if (transformer.class.allowsReverseTransformation) { + reverseBlock = ^ id (NSArray *values, BOOL *success, NSError **error) { + if (values == nil) return nil; + + if (![values isKindOfClass:NSArray.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not transform non-array type", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected an NSArray, got: %@.", @""), values], + MTLTransformerErrorHandlingInputValueErrorKey: values + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + *success = NO; + return nil; + } + + NSMutableArray *transformedValues = [NSMutableArray arrayWithCapacity:values.count]; + NSInteger index = -1; + for (id value in values) { + index++; + if (value == NSNull.null) { + [transformedValues addObject:NSNull.null]; - NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictionaries.count]; - for (id JSONDictionary in dictionaries) { - if (JSONDictionary == NSNull.null) { - [models addObject:NSNull.null]; continue; } + + id transformedValue = nil; + if ([transformer respondsToSelector:@selector(reverseTransformedValue:success:error:)]) { + NSError *underlyingError = nil; + transformedValue = [(id)transformer reverseTransformedValue:value success:success error:&underlyingError]; + + if (*success == NO) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not transform array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Could not transform value at index %d", @""), index], + NSUnderlyingErrorKey: underlyingError, + MTLTransformerErrorHandlingInputValueErrorKey: values + }; + + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; + } + return nil; + } + } else { + transformedValue = [transformer reverseTransformedValue:value]; + } + + if (transformedValue == nil) continue; + + [transformedValues addObject:transformedValue]; + } + + return transformedValues; + }; + } + if (reverseBlock != nil) { + return [MTLValueTransformer transformerUsingForwardBlock:forwardBlock reverseBlock:reverseBlock]; + } else { + return [MTLValueTransformer transformerUsingForwardBlock:forwardBlock]; + } +} - NSAssert([JSONDictionary isKindOfClass:NSDictionary.class], @"Expected a dictionary or an NSNull, got: %@", JSONDictionary); ++ (NSValueTransformer *)mtl_validatingTransformerForClass:(Class)class { + NSParameterAssert(class != nil); - id model = [dictionaryTransformer transformedValue:JSONDictionary]; - if (model == nil) continue; + return [MTLValueTransformer transformerUsingForwardBlock:^ id (id value, BOOL *success, NSError **error) { + if (value != nil && ![value isKindOfClass:class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Value did not match expected type", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"Expected %1$@ to be of class %2$@", @""), value, class], + MTLTransformerErrorHandlingInputValueErrorKey : value + }; - [models addObject:model]; + *error = [NSError errorWithDomain:MTLTransformerErrorHandlingErrorDomain code:MTLTransformerErrorHandlingErrorInvalidInput userInfo:userInfo]; } - - return models; + *success = NO; + return nil; } - reverseBlock:^ id (NSArray *models) { - if (models == nil) return nil; - - NSAssert([models isKindOfClass:NSArray.class], @"Expected an array of MTLModels, got: %@", models); - NSMutableArray *dictionaries = [NSMutableArray arrayWithCapacity:models.count]; - for (id model in models) { - if (model == NSNull.null) { - [dictionaries addObject:NSNull.null]; - continue; - } - - NSAssert([model isKindOfClass:MTLModel.class], @"Expected an MTLModel or an NSNull, got: %@", model); + return value; + }]; +} - NSDictionary *dict = [dictionaryTransformer reverseTransformedValue:model]; - if (dict == nil) continue; ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue { + NSParameterAssert(dictionary != nil); + NSParameterAssert(dictionary.count == [[NSSet setWithArray:dictionary.allValues] count]); - [dictionaries addObject:dict]; + return [MTLValueTransformer + transformerUsingForwardBlock:^ id (id key, BOOL *success, NSError **error) { + return dictionary[key ?: NSNull.null] ?: defaultValue; } - - return dictionaries; - }]; + reverseBlock:^ id (id value, BOOL *success, NSError **error) { + __block id result = nil; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id anObject, BOOL *stop) { + if ([value isEqual:anObject]) { + result = key; + *stop = YES; + } + }]; + + return result ?: reverseDefaultValue; + }]; } + (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary { return [self mtl_valueMappingTransformerWithDictionary:dictionary defaultValue:nil reverseDefaultValue:nil]; } -+ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue { - NSParameterAssert(dictionary != nil); - NSParameterAssert(dictionary.count == [[NSSet setWithArray:dictionary.allValues] count]); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" - return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(id key) { - return dictionary[key ?: NSNull.null] ?: defaultValue; - } reverseBlock:^(id object) { - __block id result = nil; - [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id anObject, BOOL *stop) { - if ([object isEqual:anObject]) { - result = key; - *stop = YES; - } - }]; - return result ?: reverseDefaultValue; - }]; ++ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass { + return [MTLJSONAdapter dictionaryTransformerWithModelClass:modelClass]; } ++ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass { + return [MTLJSONAdapter arrayTransformerWithModelClass:modelClass]; +} + +#pragma clang diagnostic pop + @end diff --git a/iOSStudy/Pods/Mantle/README.md b/iOSStudy/Pods/Mantle/README.md index b3bee10..3a1c6fb 100644 --- a/iOSStudy/Pods/Mantle/README.md +++ b/iOSStudy/Pods/Mantle/README.md @@ -1,4 +1,4 @@ -# Mantle +# Mantle [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch application. @@ -209,6 +209,8 @@ typedef enum : NSUInteger { return @{ @"URL": @"url", @"HTMLURL": @"html_url", + @"number": @"number", + @"state": @"state", @"reporterLogin": @"user.login", @"assignee": @"assignee", @"updatedAt": @"updated_at" @@ -298,8 +300,7 @@ NSDictionary *JSONDictionary = [MTLJSONAdapter JSONDictionaryFromModel:user]; ### `+JSONKeyPathsByPropertyKey` The dictionary returned by this method specifies how your model object's -properties map to the keys in the JSON representation. Properties that map to -`NSNull` will not be present in the JSON representation, for example: +properties map to the keys in the JSON representation, for example: ```objc @@ -317,8 +318,8 @@ properties map to the keys in the JSON representation. Properties that map to + (NSDictionary *)JSONKeyPathsByPropertyKey { return @{ - @"createdAt": @"created_at", - @"meUser": NSNull.null + @"name": @"name", + @"createdAt": @"created_at" }; } @@ -337,8 +338,7 @@ properties map to the keys in the JSON representation. Properties that map to In this example, the `XYUser` class declares four properties that Mantle handles in different ways: -- `name` is implicitly mapped to a key of the same name in the JSON - representation. +- `name` is mapped to a key of the same name in the JSON representation. - `createdAt` is converted to its snake case equivalent. - `meUser` is not serialized into JSON. - `helper` is initialized exactly once after JSON deserialization. @@ -346,6 +346,9 @@ handles in different ways: Use `-[NSDictionary mtl_dictionaryByAddingEntriesFromDictionary:]` if your model's superclass also implements `MTLJSONSerializing` to merge their mappings. +If you'd like to map all properties of a Model class to themselves, you can use +the `+[NSDictionary mtl_identityPropertyMapWithModel:]` helper method. + When deserializing JSON using `+[MTLJSONAdapter modelOfClass:fromJSONDictionary:error:]`, JSON keys that don't correspond to a property name or have an explicit mapping are ignored: diff --git a/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj b/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj index d94c134..d1054d9 100644 --- a/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj +++ b/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj @@ -10,70 +10,27 @@ 46 objects - 00184188B977DFF23A1F85C5 + 017B14BC9F461EE2E432473F - buildConfigurations - - F6CDC7E60CF17930F7262034 - 72575C4414A386B75A1236C3 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList - - 003A31C6AADD74836B88341F - - attributes - - LastUpgradeCheck - 0510 - - buildConfigurationList - EF1605A5BAD020789C0D6DCD - compatibilityVersion - Xcode 3.2 - developmentRegion - English - hasScannedForEncodings - 0 + includeInIndex + 1 isa - PBXProject - knownRegions - - en - - mainGroup - 29EBF6D132B45FA490AAE8C4 - productRefGroup - 7A9806F1FFB8C59E80CBFD08 - projectDirPath - - projectReferences - - projectRoot - - targets - - 41B60CD843C52B8457DCB0E0 - E0F50EA1905F2A7094812973 - F5AD41E8F4E3CBFFE9D0A6AD - D6558E03D7E8E7369D57D62A - EA053313AC9B201518E824AF - 7FFBF073B63F5E27B5D0072F - 6736EF81F571346B01E63AAB - 0D2F41CC755DC941A9D3282F - 0E44B521E203EC4F111815E4 - + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSDictionary+MTLMappingAdditions.h + path + Mantle/NSDictionary+MTLMappingAdditions.h + sourceTree + <group> - 00768924736E895D7D503478 + 021537B5204C0FECE2ACE390 buildConfigurations - A25EAE9D801AB760A4747E4B - 8A72EC2E5ADEFD1185ACE525 + C5774AA1A8FFF8FE8C6497E3 + D2FB14DD6996DA5416AAD4A7 defaultConfigurationIsVisible 0 @@ -82,198 +39,122 @@ isa XCConfigurationList - 015D98E4D31C2E29C4FB9DBA - - fileRef - B2DFB8ABE3C361564605FC09 - isa - PBXBuildFile - - 016D2ED5429A374F8D023442 - - fileRef - D405E1711A624A1719E082D2 - isa - PBXBuildFile - - 019033947122D26DFF88E20C + 0249F3F32ECE11C31DA2A281 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - SVWebViewControllerBack.png + SVWebViewControllerActivity.m path - SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png + SVWebViewController/UIActivities/SVWebViewControllerActivity.m sourceTree <group> - 02E92DC83C62401C25C8913C + 03161642A68CD1941BFCCA57 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSError+MTLModelException.m + SVIndefiniteAnimatedView.h path - Mantle/NSError+MTLModelException.m + SVProgressHUD/SVIndefiniteAnimatedView.h sourceTree <group> - 0371BF6A0BA2FCC5D93407F8 + 031749B0590F6DC7715C2614 - explicitFileType - archive.ar - includeInIndex - 0 + fileRef + 7EC2985EE432823B4911B78A isa - PBXFileReference - path - libPods-SDWebImage.a - sourceTree - BUILT_PRODUCTS_DIR + PBXBuildFile - 0398B69338481EC817F6F6EB + 0338848C9C451EFDEF77531F - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLModel.h path - libPods-FMDB.a + Mantle/MTLModel.h sourceTree - BUILT_PRODUCTS_DIR - - 03FA11483C1D0F3D8E20B008 - - fileRef - BDD54D59F9F168C7CDC3C286 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 04205120B87CE3914882E1E1 - - fileRef - F0D0B8FA1F237AF39207A58C - isa - PBXBuildFile + <group> - 051EC94587D0A832E9D6DEBA + 037956751483D4C23D81CEA0 + includeInIndex + 1 isa - PBXTargetDependency + PBXFileReference + lastKnownFileType + sourcecode.c.h name - Pods-SVWebViewController - target - 0D2F41CC755DC941A9D3282F - targetProxy - CCD36D89B4623217A9BB4F11 + SVWebViewControllerActivity.h + path + SVWebViewController/UIActivities/SVWebViewControllerActivity.h + sourceTree + <group> - 055CD4E1DAF33217D19B9141 + 038E0DFD617BDE9429BF052D fileRef - 52C22D274C762A81E9AEFD70 + 27FB9860B22C4D48341CBEA3 isa PBXBuildFile - 057A36C64C16BAE9CBB65645 + 03A5344E302537399735D750 includeInIndex 1 isa PBXFileReference name - SVWebViewControllerActivityChrome@2x.png + SVWebViewControllerBack.png path - SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png sourceTree <group> - 060110539E4022EC7547DC8A + 04AF025B73F1D4D57A6F2619 - children - - E1AD240F7028E1A092DCBEDC - 7B237DEB99E4A1EC780BD565 - + includeInIndex + 1 isa - PBXGroup + PBXFileReference name - Security + SVWebViewControllerActivityChrome-iPad@2x.png + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png sourceTree <group> - 06B18C667B34A3836288B3E6 - - buildActionMask - 2147483647 - files - - D003F4EA52D0953E6AF73AF6 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 06D77D3ADBE13269F32AE1CF - - buildActionMask - 2147483647 - files - - AB1DEC2C8FBB36DEECEF04E0 - 8CCB2EE71B1282861778906D - DD8F1007201AC5D9E168DE32 - ADC6D3BD671FB020D4E165E1 - 651297332C80103B10000DCA - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 071305CB59F3D8E013288619 + 04DBC1FBD91BF5F6C3311D26 - children - - C50CBBB3320CBFC5FA8EA34D - 8A081DC2D78B0C22A3B1CDDE - 6D6492CFDFC03E3EEED90937 - 225B176F2E2BC5974E8C8001 - BB46AB577CB11E2DEC496B53 - 304E5532CC66B25020968ED2 - 90692384AE86654AF740CBA0 - A110D8DB17AB6647C7795EBD - 674480447F049BFA1C4EA514 - 4D56B1E3005FDE505FCEF6C6 - 98D565C31B4E1BA8DEC0CD71 - 778D223C43915891DECBE645 - D139BE864E7331A490A31F83 - 7A75EF39F7B6094E98E9D58F - 11E705D1FBE2231D8B3FA30B - 76D0502FC1D6208D9E893050 - BB9E6E4F4B05385705EB97C0 - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - UIKit + SDImageCache.m + path + SDWebImage/SDImageCache.m sourceTree <group> - 0BC85B368F05F28D8AC1E014 + 0532441E1EECD858AA324EEE includeInIndex 1 @@ -282,67 +163,68 @@ lastKnownFileType sourcecode.c.h name - EXTScope.h + SDImageCache.h path - Mantle/extobjc/EXTScope.h + SDWebImage/SDImageCache.h sourceTree <group> - 0BD156919664C48A35EEDBFE + 05F1FBF4E58EB8857D059DAE fileRef - E7926F44F6DD7675C4CAB292 + 2458347131825864735CD1CC isa PBXBuildFile - 0BD65AA041B8332119344140 + 061F169028DE0BDB1A04F4C7 fileRef - 0E03512149CABB1F580F757D + 3E70C5C923F6BBDBA2F30CD4 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 0C14F1A11A291CA30BCB976F + 06BFC4042CE34CA8CF550A8A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - FMDB.h + NSData+ImageContentType.m path - src/fmdb/FMDB.h + SDWebImage/NSData+ImageContentType.m sourceTree <group> - 0D2F41CC755DC941A9D3282F + 06EFFA518FDEBA01C2EE99EE - buildConfigurationList - 00768924736E895D7D503478 - buildPhases + fileRef + CD33ACF6C201881D46574802 + isa + PBXBuildFile + + 0747044C261D3EADCE75FB02 + + children - FAFFA27183B7E1544DC2D54D - 9165E3916BCF3741753508DC - 06D77D3ADBE13269F32AE1CF + 46098DA747FC06C871433084 + 161E62A9465A051CE58E5A0D - buildRules - - dependencies - isa - PBXNativeTarget + PBXGroup name - Pods-SVWebViewController - productName - Pods-SVWebViewController - productReference - 8BF1A56862208AAE73DA9531 - productType - com.apple.product-type.library.static + Security + sourceTree + <group> - 0DDB7686E187F3FC19D520AC + 079C8DABD90354174F62579C explicitFileType archive.ar @@ -351,155 +233,759 @@ isa PBXFileReference path - libPods-Mantle.a + libPods-SDWebImage.a sourceTree BUILT_PRODUCTS_DIR - 0E03512149CABB1F580F757D + 08790C72DA11E17D2FBBCF0D - includeInIndex - 1 + fileRef + CD8349A3F4BF18C038579DC6 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIScrollView+MJExtension.h - path - MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h - sourceTree - <group> + PBXBuildFile + + 0A581658422105825B30893D + + fileRef + 0532441E1EECD858AA324EEE + isa + PBXBuildFile - 0E0B9761485C54F60690139C + 0ADA0BBE8F6E0CF27A17B204 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - AFHTTPRequestOperationManager.h + sourcecode.c.objc path - AFNetworking/AFHTTPRequestOperationManager.h + Pods-SVWebViewController-dummy.m sourceTree <group> - 0E0C3DD3CC95A1B05DA0ED85 - - fileRef - BB9E6E4F4B05385705EB97C0 - isa - PBXBuildFile - - 0E44B521E203EC4F111815E4 + 0B5DEF3990AA31FD46C539A6 - buildConfigurationList - 7571161F8493E257141282E2 - buildPhases - - 9AAAE1957C330405FAFB9600 - 8F935F9ED6A55A5476D707C4 - BDD171D88E04245FF41CFF78 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - Pods-SWTableViewCell - productName - Pods-SWTableViewCell - productReference - 463D037C8D05265B93AA341F - productType - com.apple.product-type.library.static - - 0E941574580314BABC46EF00 + baseConfigurationReference + 766E6FD13340EAC7CA2A74C0 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-Shimmer/Pods-Shimmer-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 0C00902A01286919FC46FC9B + + baseConfigurationReference + 37E7B477D7652800A3F341C3 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 0C2A438B42DC07E1A2B8E51B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFNetworkActivityIndicatorManager.h + path + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h + sourceTree + <group> + + 0C5F4AA88C010FED2B677BE0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImageView+HighlightedWebCache.m + path + SDWebImage/UIImageView+HighlightedWebCache.m + sourceTree + <group> + + 0CBA1F61EC68D9CDA478C899 + + buildConfigurationList + 70F13B6112440F37C2D167F8 + buildPhases + + 6BF3878F46EA166D96C264CA + 596FE4013EEEF9501024851D + 1691BA86D46755102259DA48 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-SDWebImage + productName + Pods-SDWebImage + productReference + 079C8DABD90354174F62579C + productType + com.apple.product-type.library.static + + 0CD662ED08D8060D2C191872 + + fileRef + 72330DDBCFF840EE908319EC + isa + PBXBuildFile + + 0DFC1AE4D0619E84823A76B7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-Mantle-prefix.pch + sourceTree + <group> + + 0F41C1FA82ED1CE863ACA0D2 + + baseConfigurationReference + 9067AD6B1D75736FA573D6DC + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 0FADB0BDACC612106361DF6A + + baseConfigurationReference + 4D975F3E0C5580B245740BA7 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 0FB12360D6BEA877E224ADA1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIButton+AFNetworking.h + path + UIKit+AFNetworking/UIButton+AFNetworking.h + sourceTree + <group> + + 11C73DBC7E4CD70B20E5C5F8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+MTLComparisonAdditions.h + path + Mantle/NSObject+MTLComparisonAdditions.h + sourceTree + <group> + + 11DFAC007737F49E7E5B5404 + + fileRef + 7A3E48B8E1F6B8E4E43315C9 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 1222A867D3B095E6CAD064E1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-AFNetworking-dummy.m + sourceTree + <group> + + 123002C87D23EABEC54428B6 + + buildConfigurations + + 0FADB0BDACC612106361DF6A + FA0452B54E39A5441282340D + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 12F59C763943F4966B45BFB4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIWebView+AFNetworking.h + path + UIKit+AFNetworking/UIWebView+AFNetworking.h + sourceTree + <group> + + 13E5B2F71EE5F50E7A1A8C32 + + fileRef + FD73A2A295E8C736206A0CFB + isa + PBXBuildFile + + 148737F71BBDF519ADD222EE + + buildConfigurations + + 424231F6B17A5FA7F4C0F3B4 + 87EF8679D2D2B77AB2C96FCE + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 148F4C03C79D34F342A4BA5C + + fileRef + AF5C6DD26F6C33671E226570 + isa + PBXBuildFile + + 15BB52D8A36F9448177D9DF6 + + fileRef + C9AF7C2EC59374EA95C53E40 + isa + PBXBuildFile + + 15C59580BF2B4473B05F415D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageDownloader.h + path + SDWebImage/SDWebImageDownloader.h + sourceTree + <group> + + 15FBF202A50ECA5AE8098F25 + + children + + 5BF9005E499D27C097642952 + C024D03913DF6EA5F878EFBE + 60A25E261550AFF0655E9701 + D9BC1825A20D16596316B079 + 037956751483D4C23D81CEA0 + 0249F3F32ECE11C31DA2A281 + 22E579B322935331734637C9 + 7EC2985EE432823B4911B78A + 62A22F50D3F5248A35D55225 + 25A0A19A077EC9E251FBD688 + 1E2F2E969C76A68F6E12F89C + 5C7D9293E6B269F06D2001DA + + isa + PBXGroup + name + SVWebViewController + path + SVWebViewController + sourceTree + <group> + + 161E62A9465A051CE58E5A0D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFSecurityPolicy.m + path + AFNetworking/AFSecurityPolicy.m + sourceTree + <group> + + 1651B2D612326489C798B0CC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIView+WebCacheOperation.h + path + SDWebImage/UIView+WebCacheOperation.h + sourceTree + <group> + + 1691BA86D46755102259DA48 buildActionMask 2147483647 files - CC2EB1431A8BBB896B00A972 + F462B3022831473DDF26EA18 + 0A581658422105825B30893D + 9381F7BB0A087C29FE037C45 + DDF77BFDA744563444169FA8 + F99B71AC8E9B4C2925D0F0BF + 87A539495A8DCAE923BEE754 + D9AC5E5A7FD9CD228B2E0E9E + FEAE6DA63CEC5559503A25DA + A32C110D789B8BD8916FDEC8 + 65CF839D7AAAAC698C0175E9 + E941B207D74922475F8D6E73 + 148F4C03C79D34F342A4BA5C + D644D20C4E3C77F3E6A6C450 + 13E5B2F71EE5F50E7A1A8C32 + 53A25457247088A54F54EA47 isa - PBXFrameworksBuildPhase + PBXHeadersBuildPhase runOnlyForDeploymentPostprocessing 0 - 0F22D9A04C4D256875AD1033 + 1740A3C059CD9E1542403D15 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLModel+NSCoding.h + path + Mantle/MTLModel+NSCoding.h + sourceTree + <group> + + 17491E9549DFECEE0C4A69AA + + children + + E39092337355ABB89F457406 + CD2CFD88AEC03BECA1A6CE00 + F21CB8120EF2D5EE038E22B2 + 203360E6A9E4664E6EEB92D1 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SWTableViewCell + sourceTree + <group> + + 175EC96C64ED690205508049 + + fileRef + CC488329354081651F356099 + isa + PBXBuildFile + + 1A142289B602EBE69D1249B4 + + baseConfigurationReference + 4D44B23CA21D5B5AF8203047 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 1B05BA6213F2E3EF2E531B9A + + fileRef + ED63151D6E956C666D9BD14F + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 1B9EB26BF91493E21387BF73 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImagePrefetcher.h + path + SDWebImage/SDWebImagePrefetcher.h + sourceTree + <group> + + 1C1CFA57D7F622E23C370378 + + fileRef + 037956751483D4C23D81CEA0 + isa + PBXBuildFile + + 1C41B699867939A9D201C820 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivitySafari@2x.png + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png + sourceTree + <group> + + 1C5C6F263232576A4496C2BE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIButton+WebCache.h + UIScrollView+MJRefresh.m path - SDWebImage/UIButton+WebCache.h + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m sourceTree <group> - 10BE1219154FDDC59F7E91E8 + 1C9277FFE7786BDB6BFD2700 - fileRef - AC1C5B4CE91F11AE998D64F6 + children + + 1D23F819420667DBDED3985E + 86EB9A08B9B6E1267BD57145 + E05AA74B831F33187A80AFB2 + F684B190D03659D4947FEA45 + E89A849D5C7F06D308A3B1A9 + F037D782B4ADF73E592EBDE5 + 860338F0E2A28100CD8283CB + isa - PBXBuildFile + PBXGroup + name + iOS + sourceTree + <group> - 10D51B68691D31108009BE93 + 1C92FEB632B8CFF036BFBDBE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - AFHTTPRequestOperation.m + SDWebImageManager.h path - AFNetworking/AFHTTPRequestOperation.m + SDWebImage/SDWebImageManager.h sourceTree <group> - 11292E3DE8EF40F9DCBCD526 + 1CC1562D9491C5AA136310C3 includeInIndex 1 isa PBXFileReference - lastKnownFileType - text.xcconfig + name + SVWebViewControllerBack@2x.png path - Pods-MJRefresh-Private.xcconfig + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png sourceTree <group> - 11E705D1FBE2231D8B3FA30B + 1CC1A3DF4C98E3580B5C08DB + + fileRef + 1D23F819420667DBDED3985E + isa + PBXBuildFile + + 1D23F819420667DBDED3985E - includeInIndex - 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + wrapper.framework name - UIRefreshControl+AFNetworking.m + CoreGraphics.framework path - UIKit+AFNetworking/UIRefreshControl+AFNetworking.m + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreGraphics.framework sourceTree - <group> + DEVELOPER_DIR - 12371F77B302ED20D4ABE615 + 1E2F2E969C76A68F6E12F89C children - EB111D63CDEEB43E08195847 + 414A8E14A710D9A3FC373D58 + ACB10044602E091306D20304 + 04AF025B73F1D4D57A6F2619 + A30E202D51051669B6D9A384 + CD8D1F166166902627915896 + CBF465FCFAE67B936CD7999F + 1C41B699867939A9D201C820 + 03A5344E302537399735D750 + 1CC1562D9491C5AA136310C3 + 919F53AD7511E994A55FF852 + 8B6ED94C6DDA6FF25C0DC284 isa PBXGroup @@ -508,68 +994,85 @@ sourceTree <group> - 12896047E29D3DF31213A494 + 1E803AD000DE2CF76ED8A078 - fileRef - EDA79BFF36ED8CC66472C4B4 + buildConfigurationList + 148737F71BBDF519ADD222EE + buildPhases + + 8A5EC5ADDF6D73BF84BB0439 + E2B6D58F73771CA96B3C2820 + 674019461553B37DDF831022 + + buildRules + + dependencies + isa - PBXBuildFile + PBXNativeTarget + name + Pods-SVWebViewController + productName + Pods-SVWebViewController + productReference + 7B223D387702971DA08CD4D7 + productType + com.apple.product-type.library.static - 13A1A364A5506D8A8B3CB81E + 1E8236F7F2D75641B9429C34 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SVModalWebViewController.m + UIScrollView+MJRefresh.h path - SVWebViewController/SVModalWebViewController.m + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h sourceTree <group> - 142C5427A774A7FFD4A9FD58 - - fileRef - 225B176F2E2BC5974E8C8001 - isa - PBXBuildFile - - 14C6C2B33E3B9C9DB8064CE3 + 1E9D734431398B2A8B2E6187 fileRef - 9F77207596AAC05C2F57FD7F + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 15C57B0A0D754AA9967330DF + 1EE396C30D8A13447C80F3A0 + buildActionMask + 2147483647 + files + + 9E016601CA43D1C5C8904B27 + 8E22501E03EA577E214D2510 + 175EC96C64ED690205508049 + 95E7FC2311C4858528731495 + 2AB74CF4139DA6C94534546B + 2C3DFA70707626353217C687 + 95881FA09CB265E1553DA033 + 748ADA32DF8501663602FE1E + C2DB8617DE738C880377729C + 4410ECC91FB8EA1E78851A6B + 36231F20F6D96FCF65E976E8 + 05F1FBF4E58EB8857D059DAE + isa - PBXFileReference - lastKnownFileType - wrapper.framework - name - SystemConfiguration.framework - path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/SystemConfiguration.framework - sourceTree - DEVELOPER_DIR + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 160D3E2EB45E710B513005B2 + 1EE3FDF8E269928BE3CA0FD8 fileRef - 18779A7BA8AAD008F51F3F9D + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - 16BE2A454A10A0FFBBFDD201 + 20251958D4B2711851B3E370 includeInIndex 1 @@ -577,12 +1080,14 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + SDWebImageDownloader.m path - Pods-AFNetworking-dummy.m + SDWebImage/SDWebImageDownloader.m sourceTree <group> - 1817BF46EC0C042C7D3CF340 + 202F6DB433134889BAACCDDB includeInIndex 1 @@ -591,24 +1096,13 @@ lastKnownFileType sourcecode.c.objc name - MTLJSONAdapter.m + UIButton+WebCache.m path - Mantle/MTLJSONAdapter.m + SDWebImage/UIButton+WebCache.m sourceTree <group> - 183B217DE3DE00FBD76C9DE5 - - isa - PBXTargetDependency - name - Pods-SDWebImage - target - 7FFBF073B63F5E27B5D0072F - targetProxy - 1A50A961A1670095B4C092C4 - - 18779A7BA8AAD008F51F3F9D + 203360E6A9E4664E6EEB92D1 includeInIndex 1 @@ -616,29 +1110,79 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - FMResultSet.h path - src/fmdb/FMResultSet.h + Pods-SWTableViewCell-prefix.pch sourceTree <group> - 187C3AFF7CA47A0B29C75D89 + 205ED29E148DADEBC19D323C - includeInIndex - 1 + baseConfigurationReference + 9C746065011B9B8E702645AE + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + XCBuildConfiguration + name + Debug + + 2160C45955F52B060F92C6E9 + + children + + CE3EDC27205A31036EFD90B8 + 4D975F3E0C5580B245740BA7 + 9643F891DE5CA3D4BB9E89D6 + CD9137A020694A9525101FB3 + + isa + PBXGroup name - MJRefreshBaseView.h + Support Files path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h + ../Target Support Files/Pods-MJRefresh sourceTree <group> - 1890A9018AFB550869401948 + 22737EECE55204DE3B79A47E includeInIndex 1 @@ -647,117 +1191,62 @@ lastKnownFileType sourcecode.c.objc name - SDWebImageDownloader.m + SDWebImageDownloaderOperation.m path - SDWebImage/SDWebImageDownloader.m + SDWebImage/SDWebImageDownloaderOperation.m sourceTree <group> - 1A404CF9215FA5CE825E6AE2 - - fileRef - 0C14F1A11A291CA30BCB976F - isa - PBXBuildFile - - 1A50A961A1670095B4C092C4 - - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 7FFBF073B63F5E27B5D0072F - remoteInfo - Pods-SDWebImage - - 1AF9F27A2984FABBCD8BB35F - - fileRef - 6A38B085018671A0ABB83BE1 - isa - PBXBuildFile - - 1B0ECD78A6C7584001AA72BE - - fileRef - 3FE2CB4E3BF724BF9DADD804 - isa - PBXBuildFile - - 1BF5129F506CB75B0F1BC5FB + 22E579B322935331734637C9 includeInIndex 1 isa PBXFileReference lastKnownFileType - wrapper.plug-in + sourcecode.c.h name - SVWebViewController.bundle + SVWebViewControllerActivityChrome.h path - SVWebViewController/SVWebViewController.bundle + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h sourceTree <group> - 1CD8DE0BC0E13E9F18B3F9A1 + 231F0312ABE7BE7661B60810 containerPortal - 003A31C6AADD74836B88341F + 81D979F3E87416F4B4516D5F isa PBXContainerItemProxy proxyType 1 remoteGlobalIDString - E0F50EA1905F2A7094812973 + 6CE6AFC3F8CD70241EF59AB9 remoteInfo - Pods-AFNetworking - - 1D5CA0F9B7FCF817B26A5DBE - - fileRef - 9449B700FD78B567CDCE349E - isa - PBXBuildFile + Pods-MJRefresh - 1D87621C8A8B06BD9D364D45 + 23763F10AD2F1762F40E6516 children - 752BB0BB115A89E3F4860E7E + 6D065165EADB62FE6ADC04D6 + 58E581BDA91FBF5066FFCCD5 + 6516689B190F38FDE8D21843 + CA80C3A4D5A7270178FB5B66 + 3DB788AB36F9B70305F82766 + 51CF2F2FD419BD460AFE8089 + A60FF7B612E384CD0FBBC028 isa PBXGroup name - Targets Support Files - sourceTree - <group> - - 1DBA1A3F18B0BCF7E976DA37 - - fileRef - D139BE864E7331A490A31F83 - isa - PBXBuildFile - - 1DFAEC12DD2639335AF49ACE - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - NSArray+MTLManipulationAdditions.m + Pods path - Mantle/NSArray+MTLManipulationAdditions.m + Target Support Files/Pods sourceTree <group> - 1F5410B3AD75104BB163C869 + 244FECFEBCA55B4B22B48100 includeInIndex 1 @@ -765,12 +1254,14 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + AFHTTPSessionManager.m path - Pods-dummy.m + AFNetworking/AFHTTPSessionManager.m sourceTree <group> - 2046088381816FB1A6115AE8 + 2458347131825864735CD1CC includeInIndex 1 @@ -779,20 +1270,13 @@ lastKnownFileType sourcecode.c.h name - AFURLRequestSerialization.h + UIView+MJExtension.h path - AFNetworking/AFURLRequestSerialization.h + MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h sourceTree <group> - 2170FBC10D2E8E490ECD303D - - fileRef - DC50FB9ACAC3D68AE360BF5F - isa - PBXBuildFile - - 217FA4FB15D4EDE83A84233D + 24A3F0A31F1D0773C9C49784 includeInIndex 1 @@ -800,34 +1284,27 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - MJRefreshConst.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h - sourceTree - <group> - - 21E3949570212F296A98F3C3 - - fileRef - 1F5410B3AD75104BB163C869 - isa - PBXBuildFile + Pods-SVProgressHUD-prefix.pch + sourceTree + <group> - 221E3FF2B9CDB1D4F3615F0D + 253314F7D8BF0DB55988AFAA includeInIndex 1 isa PBXFileReference lastKnownFileType - text.plist.xml + sourcecode.c.h + name + Mantle.h path - Pods-acknowledgements.plist + Mantle/Mantle.h sourceTree <group> - 222F9FE85B6C3B610407F404 + 2567A3A1F416E5F48EE273BB includeInIndex 1 @@ -836,13 +1313,13 @@ lastKnownFileType sourcecode.c.objc name - FMResultSet.m + NSDictionary+MTLManipulationAdditions.m path - src/fmdb/FMResultSet.m + Mantle/NSDictionary+MTLManipulationAdditions.m sourceTree <group> - 225B176F2E2BC5974E8C8001 + 25A0A19A077EC9E251FBD688 includeInIndex 1 @@ -851,28 +1328,52 @@ lastKnownFileType sourcecode.c.objc name - UIActivityIndicatorView+AFNetworking.m + SVWebViewControllerActivitySafari.m path - UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m sourceTree <group> - 2366FECF46A2354EC3AC77D5 + 2610D7C01A280C95688E34FA - includeInIndex - 1 + children + + 8C9C2943E986722994D47B81 + C7C42E7283B016DEFAC91CF2 + 747A95C1078F0A1823197D16 + CC488329354081651F356099 + 87D9BF752A70DA83F123E5E7 + CADA31036DC6EAB82967ECA4 + 7A0FE04DB8AACD8CD00D68CA + 6EC30786B89A1DAAEF831D65 + F2DF18E782B13E13F56BD784 + 37038513EB00C07B3A9C514E + 3DA0E29B98E2DCECB7129EED + AAC8341199D37437F70D1F22 + 95FF2B992C0CBC462AC1C0EF + BD21D8D91FCD26B8FAA257D1 + 492B1CA1D1972775DF51A6CF + B6D1E6F496CA960B50C331AD + 9E9D0D9F98C6F64688498FA0 + AD5F16EA93C42C324A1A2854 + 8BAFDC2A67AEA3220C90038A + 1E8236F7F2D75641B9429C34 + 1C5C6F263232576A4496C2BE + 2458347131825864735CD1CC + C50B6D365BE90FDCF50B69A7 + DA466A036868C7B919F43216 + 2160C45955F52B060F92C6E9 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - NSDictionary+MTLManipulationAdditions.h + MJRefresh path - Mantle/NSDictionary+MTLManipulationAdditions.h + MJRefresh sourceTree <group> - 2384225F66B601A470E03B2D + 267EA0919FE8615662F5C2BE includeInIndex 1 @@ -880,298 +1381,157 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - NSMutableArray+SWUtilityButtons.h path - SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h + Pods-SDWebImage-prefix.pch sourceTree <group> - 23A7B732974BAA16EF4D4F5A + 27FB9860B22C4D48341CBEA3 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - MTLModel+NSCoding.m + NSValueTransformer+MTLInversionAdditions.h path - Mantle/MTLModel+NSCoding.m + Mantle/NSValueTransformer+MTLInversionAdditions.h sourceTree <group> - 24200E9BAE5616D614E3BA14 - - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - CLANG_CXX_LANGUAGE_STANDARD - gnu++0x - CLANG_CXX_LIBRARY - libc++ - CLANG_ENABLE_MODULES - YES - CLANG_ENABLE_OBJC_ARC - YES - CLANG_WARN_BOOL_CONVERSION - YES - CLANG_WARN_CONSTANT_CONVERSION - YES - CLANG_WARN_DIRECT_OBJC_ISA_USAGE - YES - CLANG_WARN_EMPTY_BODY - YES - CLANG_WARN_ENUM_CONVERSION - YES - CLANG_WARN_INT_CONVERSION - YES - CLANG_WARN_OBJC_ROOT_CLASS - YES - COPY_PHASE_STRIP - YES - GCC_C_LANGUAGE_STANDARD - gnu99 - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - GCC_WARN_64_TO_32_BIT_CONVERSION - YES - GCC_WARN_ABOUT_RETURN_TYPE - YES - GCC_WARN_UNDECLARED_SELECTOR - YES - GCC_WARN_UNINITIALIZED_AUTOS - YES - GCC_WARN_UNUSED_FUNCTION - YES - GCC_WARN_UNUSED_VARIABLE - YES - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - ONLY_ACTIVE_ARCH - YES - STRIP_INSTALLED_PRODUCT - NO - - isa - XCBuildConfiguration - name - Debug - - 245A7D5B09274802299A5413 - - fileRef - DC6959F6B0389433A846F09B - isa - PBXBuildFile - - 2480FD39925604EC68E2B1B1 + 28008C3054989A0ECB72D888 children - F7446765000306425A8653CB - 33DC1FE29B55A083427A2983 - 3AACA1031CB453DF0B0F1B62 - 9E99E930712393BD264CF051 - B2FE89B302D990CFC2393FFB - 4346B230A89B46E6BE901D9E - A3516881B3D6F981B73AC538 - 6C91BBFD0AEB7230111657C4 + 1C9277FFE7786BDB6BFD2700 isa PBXGroup name - Pods + Frameworks sourceTree <group> - 24ECE29E2A83329E77BC464B - - fileRef - 716C03D21AAED4A8DD5ED96E - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 24EDA1E60FA28D25D59006F1 - - fileRef - 6D0FE93D2F53E6F9BE778A43 - isa - PBXBuildFile - - 256F4A417937912F5BA0262B - - fileRef - 8DC0686ECBB745003C3651C3 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 2579348338E55E4DD3339342 + 28674285769FA01B14B096A7 children - A9649B3D73F213DD8CAF3844 - E3C180F70C4829EC3E7C8741 - AD4009A3CA3371D1F8C780E5 - 7AF9843A5A131AAFDB93EA21 + 8689A3CC3FD222309ED05ACB + 06BFC4042CE34CA8CF550A8A + 0532441E1EECD858AA324EEE + 04DBC1FBD91BF5F6C3311D26 + 91AA46A6041EC1643446D46C + B545404BB9E4DE3AFE749CBB + 3D75C65180AD411A4D968C06 + B62A0CCA6FB761F67C50FD6C + 15C59580BF2B4473B05F415D + 20251958D4B2711851B3E370 + D15DE4AB72E69F69799EE587 + 22737EECE55204DE3B79A47E + 1C92FEB632B8CFF036BFBDBE + 9A7E479B26D9F0FDE6B70438 + E38AA2650B16052F84F74A50 + 1B9EB26BF91493E21387BF73 + 3843591682FC397B1C1ECC3F + FA622950AEB141300BCA6B1F + 202F6DB433134889BAACCDDB + BF004A408F3B27648FC59EC5 + 3E70C5C923F6BBDBA2F30CD4 + AF5C6DD26F6C33671E226570 + 71DC522FCAFF9D6B38C8C1C8 + C37FB122D4C23F324D71F0B7 + 0C5F4AA88C010FED2B677BE0 + FD73A2A295E8C736206A0CFB + 2BA319B679FD7E5367F430C6 + 1651B2D612326489C798B0CC + BC4BFA3BB3B2500FA7071308 isa PBXGroup name - Support Files - path - ../Target Support Files/Pods-FMDB + Core sourceTree <group> - 25BC2970B45A7D905D5F19BB + 288C837B4AE7323562462C3A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIScrollView+MJRefresh.m + NSDictionary+MTLJSONKeyPath.h path - MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m + Mantle/NSDictionary+MTLJSONKeyPath.h sourceTree <group> - 25CE073DBCD2584B257B39DA + 28CA5C2956701A65270F4AD9 fileRef - D0C3135DA2BA3C019BAF2DCF + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - 26D05A8A28DCD60C1CA8EC7E + 2AB74CF4139DA6C94534546B - buildActionMask - 2147483647 - files - - 749D67B382740B441A6C9985 - 04205120B87CE3914882E1E1 - F5336FA18F2792224B01F5AD - DDCF5122548DF51242583A68 - F44EDFC44AEF1BC95DB7FA7D - + fileRef + 6EC30786B89A1DAAEF831D65 isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile - 273E8CC1B7A1DF52553B76D7 + 2AC8126F41306857B4D7B228 - buildActionMask - 2147483647 - files - - A566AAD0BC4F7B6641A8C759 - FA2858642D021A2940D97851 - F3B157F0A7C5AE48DEF99006 - 9FA315080E627AB06418F4B4 - C2F2F561C27931B0CFA6A5AD - A0BC09B6CD44A3EC41327140 - 7C9788498CCBBD0718711B7D - 9F9C79DFE629562CA77CD2CA - 12896047E29D3DF31213A494 - 1D5CA0F9B7FCF817B26A5DBE - 6EE966C6726621AA9BA61694 - 142C5427A774A7FFD4A9FD58 - 47D9D21AF5FF6276C1230478 - BE940E795DD463ACED5B538C - 6DC5F2F2A80D898D1B9BA4E9 - 1DBA1A3F18B0BCF7E976DA37 - 79AE7927E2E34267BBB4EEFB - 0E0C3DD3CC95A1B05DA0ED85 - + fileRef + 20251958D4B2711851B3E370 isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 27A001025D8F6246D8E0D8D3 + 2B0136D8B5C9A7B320D8A50D includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - AFHTTPRequestOperation.h + text.xcconfig path - AFNetworking/AFHTTPRequestOperation.h + Pods-SVWebViewController-Private.xcconfig sourceTree <group> - 27CC88179E549D8028BB3973 + 2B0B2A2AC2732C870C917A82 - buildActionMask - 2147483647 - files - - 8C11E60C3F243002B20ABAF7 - A3E886CEC48C491886768370 - D6D6D28D37442BAAA468A18D - A3A92429628C08F12D3FC1CD - 24ECE29E2A83329E77BC464B - B5CE0321A8AEFC3F5FA0DF70 - 639C0E9A9E7ADF70C513571E - EDCDF1F1A409A8EF63058261 - 14C6C2B33E3B9C9DB8064CE3 - 895426A01E6E4514960D5307 - F38473E10FE10739CC22000B - 03FA11483C1D0F3D8E20B008 - 55A7772828B4EE4C2F35A0CD - 8D934380DB6CDDF6B1F43315 - 256F4A417937912F5BA0262B - + fileRef + D6CB1F2691B16FB9B1701C9C isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile - 282B0048A3E511971931B363 + 2B388C41DBF1EEF5D24C15BD includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFURLConnectionOperation.h + UIWebView+AFNetworking.m path - AFNetworking/AFURLConnectionOperation.h + UIKit+AFNetworking/UIWebView+AFNetworking.m sourceTree <group> - 283AD6CF440DCA9B38B0B53C + 2BA319B679FD7E5367F430C6 includeInIndex 1 @@ -1180,13 +1540,58 @@ lastKnownFileType sourcecode.c.objc name - MTLModel.m + UIImageView+WebCache.m path - Mantle/MTLModel.m + SDWebImage/UIImageView+WebCache.m sourceTree <group> - 290221507373808ABAA4054B + 2C3DFA70707626353217C687 + + fileRef + 37038513EB00C07B3A9C514E + isa + PBXBuildFile + + 2CC87DE56EE450C258CC1459 + + fileRef + 7A0FE04DB8AACD8CD00D68CA + isa + PBXBuildFile + + 2CE2F848E4E067A038B24583 + + fileRef + E3AB4479A70BBD8BEEB85735 + isa + PBXBuildFile + + 2CFDDB557FAFD4668FB15C36 + + fileRef + 3843591682FC397B1C1ECC3F + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 2DC4E99A25ACFE75B1E09DDB + + fileRef + 2DE7C234F276794E257B6C45 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 2DE7C234F276794E257B6C45 includeInIndex 1 @@ -1195,107 +1600,112 @@ lastKnownFileType sourcecode.c.objc name - AFHTTPSessionManager.m + MTLTransformerErrorHandling.m path - AFNetworking/AFHTTPSessionManager.m + Mantle/MTLTransformerErrorHandling.m sourceTree <group> - 292F5F1319A89AE506A962C2 + 2EA9025C8D014A7B2C9DCB08 + fileRef + 04DBC1FBD91BF5F6C3311D26 isa - PBXFileReference - lastKnownFileType - wrapper.framework - name - CoreGraphics.framework - path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreGraphics.framework - sourceTree - DEVELOPER_DIR + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 2F17FEC1B706F2EB39E2DA5D + + fileRef + F2DF18E782B13E13F56BD784 + isa + PBXBuildFile - 29A714F97FEC7249C075FD1B + 30595C98C9115B602BDC4BCB fileRef - 98D565C31B4E1BA8DEC0CD71 + 751596E07647168536D8770B + isa + PBXBuildFile + + 30AA1BB118127744A694AB67 + isa - PBXBuildFile + PBXTargetDependency + name + Pods-SVProgressHUD + target + D68D040FBA01D62A8E3F21CF + targetProxy + C8F8ADAD27B79FF7562751D5 - 29C91E9A9A1FACD36088397D + 31002E2D5A3FBDB190E2BA39 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + SWUtilityButtonTapGestureRecognizer.m path - Pods-SWTableViewCell-Private.xcconfig - sourceTree - <group> - - 29EBF6D132B45FA490AAE8C4 - - children - - EF04ADF8DBB1227D34EBBEEA - DD72EA41B8BD0DC998006611 - 2480FD39925604EC68E2B1B1 - 7A9806F1FFB8C59E80CBFD08 - 1D87621C8A8B06BD9D364D45 - - isa - PBXGroup + SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m sourceTree <group> - 2A7803167CE7616DAD6D45D8 + 31571A3142EC0360BA8CE5A1 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + wrapper.plug-in name - FMDatabase.h + SVProgressHUD.bundle path - src/fmdb/FMDatabase.h + SVProgressHUD/SVProgressHUD.bundle sourceTree <group> - 2C5859609EFA12DBF8041624 - - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - EA053313AC9B201518E824AF - remoteInfo - Pods-Mantle - - 2D3A6D4FA7D703DF6C8A7450 + 335361E3B7EBFEF025533997 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc + path + Pods-SDWebImage-dummy.m + sourceTree + <group> + + 354547649D0B305705F9A7B2 + + children + + 28674285769FA01B14B096A7 + 5E8DB0A06DAF83A7632381C1 + + isa + PBXGroup name - AFURLSessionManager.h + SDWebImage path - AFNetworking/AFURLSessionManager.h + SDWebImage sourceTree <group> - 2D77E6FB71644E503AB9ED42 + 356BDA711A406B42A2AA21CC fileRef - 23A7B732974BAA16EF4D4F5A + 3C5E49F687C4DB8F5FCDB770 isa PBXBuildFile settings @@ -1304,14 +1714,7 @@ -DOS_OBJECT_USE_OBJC=0 - 2E82A19ADA9D6FA582DFA1B8 - - fileRef - 5CDF5BD81D96D9F7921C8DC4 - isa - PBXBuildFile - - 2F252426DE161299AE05188D + 35A704D283AC845C1F7D3779 includeInIndex 1 @@ -1326,390 +1729,211 @@ sourceTree <group> - 2FC003B95AA7F89F6830FF92 + 36231F20F6D96FCF65E976E8 fileRef - 32C94CBBCF8C76526F8213DA + 1E8236F7F2D75641B9429C34 isa PBXBuildFile - 304E5532CC66B25020968ED2 + 37038513EB00C07B3A9C514E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIAlertView+AFNetworking.m + MJRefreshGifHeader.h path - UIKit+AFNetworking/UIAlertView+AFNetworking.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.h sourceTree <group> - 30531E76C05F3BC19F4D8D31 + 37335D22593D7576DD7BB8F3 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - SVWebViewControllerNext@2x.png + NSArray+MTLManipulationAdditions.h path - SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png + Mantle/NSArray+MTLManipulationAdditions.h sourceTree <group> - 30C3BD86CBED0DC2975AE9C1 - - fileRef - 282B0048A3E511971931B363 - isa - PBXBuildFile - - 31ED12F5CEA9A23F5663038A - - buildConfigurations - - 666B1AFF5E73BE290468F5EC - 8A8E2AEA05C87BF2E72C7FCA - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList - - 322D65FFB3319CBE9B35DD56 + 3775A139FB5A19BB0E215513 - children - - 575254127992AC3095637C85 - C8519CEEEF547AA9EE9D9271 - 928FEC03396D35D183A65963 - 8DCB4D41A489D80F71A9D029 - F19082954117D5EC4CBF111A - E32EAF52CDE8541AAA86F6A0 - B3C85AC9AFD3294AE7C56106 - 716C03D21AAED4A8DD5ED96E - 84E79296009B0C709F29B5C1 - 1890A9018AFB550869401948 - 60142F5566216743E153E6C3 - 9F59D37382C8481C4A3543E6 - 3C4B103B2DCE282C9C9EA571 - FD93687F5220E28F92C0D41E - E9A68AA93E6B24526C1517E5 - 69070D1F2DAD001B977D7FCD - 9F77207596AAC05C2F57FD7F - 0F22D9A04C4D256875AD1033 - 7A1CB4CAA83E0FC77E12607B - 43B8A0C73CAAAADDEBCE7C0C - 8E7746C93B5A382A8BFB31C8 - FD317A4CDFFEF6932C841E62 - BDD54D59F9F168C7CDC3C286 - 5CDF5BD81D96D9F7921C8DC4 - 9878234455241C9D71D7D974 - E96F46F8A984911D7538CA63 - BC949D87330F6EC5E34A3352 - 35DE48B4FA6E51BD7D1BA6FC - 8DC0686ECBB745003C3651C3 - isa - PBXGroup + PBXTargetDependency name - Core - sourceTree - <group> + Pods-SWTableViewCell + target + 93425A71C668EB5F6C7FA734 + targetProxy + 7AB6812792AFA62E07248261 - 32C94CBBCF8C76526F8213DA + 3798DEA0FAA541D316F5FE1C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - MJRefreshBaseView.m - path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m - sourceTree - <group> - - 3396072C759A0E898549D6E7 - - fileRef - 90E53DFD34C1281914AAC149 - isa - PBXBuildFile - - 33DC1FE29B55A083427A2983 - - children - - 2579348338E55E4DD3339342 - 3A04D5BA2926938475C2BC63 - - isa - PBXGroup + sourcecode.c.h name - FMDB + EXTScope.h path - FMDB + Mantle/extobjc/EXTScope.h sourceTree <group> - 34257C1DD98D838891B765BC + 379FAB72597E10BB2F1FEE69 children - 44E5FEBB52959F4FE292E75F - 29C91E9A9A1FACD36088397D - A2B106C048B78A5C6FBAA445 - 94AC0364478A39DA51322B7F + 52A314C9DA51CC9C91B55EE1 + 9067AD6B1D75736FA573D6DC + 751596E07647168536D8770B + 24A3F0A31F1D0773C9C49784 isa PBXGroup name Support Files path - ../Target Support Files/Pods-SWTableViewCell + ../Target Support Files/Pods-SVProgressHUD sourceTree <group> - 34A0A9B27EF8487D6B85D039 + 37C69F1225F365F71389C2B9 - includeInIndex - 1 + fileRef + 31002E2D5A3FBDB190E2BA39 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - AFNetworkReachabilityManager.m - path - AFNetworking/AFNetworkReachabilityManager.m - sourceTree - <group> + PBXBuildFile - 35DE48B4FA6E51BD7D1BA6FC + 37E7B477D7652800A3F341C3 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIView+WebCacheOperation.h + text.xcconfig path - SDWebImage/UIView+WebCacheOperation.h + Pods-SDWebImage-Private.xcconfig sourceTree <group> - 379C4A4E6343D5622A38206E + 383B6E4068731C879D329EBE fileRef - 0F22D9A04C4D256875AD1033 + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - 379D3CCD2FFBB2698E6A788E + 3843591682FC397B1C1ECC3F includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - metamacros.h + SDWebImagePrefetcher.m path - Mantle/extobjc/metamacros.h + SDWebImage/SDWebImagePrefetcher.m sourceTree <group> - 37B990D486EB877EA36E8C25 - - fileRef - 6352CB3951039CAB104F5D32 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 3886D77C2964260BA24AC311 + 38F13723B1DE2DB0C6785A56 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - CLANG_CXX_LANGUAGE_STANDARD - gnu++0x - CLANG_CXX_LIBRARY - libc++ - CLANG_ENABLE_MODULES - YES - CLANG_ENABLE_OBJC_ARC - YES - CLANG_WARN_BOOL_CONVERSION - YES - CLANG_WARN_CONSTANT_CONVERSION - YES - CLANG_WARN_DIRECT_OBJC_ISA_USAGE - YES - CLANG_WARN_EMPTY_BODY - YES - CLANG_WARN_ENUM_CONVERSION - YES - CLANG_WARN_INT_CONVERSION - YES - CLANG_WARN_OBJC_ROOT_CLASS - YES - COPY_PHASE_STRIP - NO - ENABLE_NS_ASSERTIONS - NO - GCC_C_LANGUAGE_STANDARD - gnu99 - GCC_PREPROCESSOR_DEFINITIONS - - RELEASE=1 - - GCC_WARN_64_TO_32_BIT_CONVERSION - YES - GCC_WARN_ABOUT_RETURN_TYPE - YES - GCC_WARN_UNDECLARED_SELECTOR - YES - GCC_WARN_UNINITIALIZED_AUTOS - YES - GCC_WARN_UNUSED_FUNCTION - YES - GCC_WARN_UNUSED_VARIABLE - YES - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - STRIP_INSTALLED_PRODUCT - NO - VALIDATE_PRODUCT - YES - + buildActionMask + 2147483647 + files + + 1E9D734431398B2A8B2E6187 + isa - XCBuildConfiguration - name - Release + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 3A04D5BA2926938475C2BC63 + 3992094AFFDF7D4ECD978CFD - children + buildActionMask + 2147483647 + files - 0C14F1A11A291CA30BCB976F - 2A7803167CE7616DAD6D45D8 - 595FC29ACF0D8E7894A124BF - 9E3CADF4D34242891C1E4725 - 96B82497505EF98401B50E1D - C684423B9F0BCABE69332621 - 6352CB3951039CAB104F5D32 - DC332F6A26805C987939E79B - FFF0E1F586F1C9698F168012 - 18779A7BA8AAD008F51F3F9D - 222F9FE85B6C3B610407F404 + 59AE4BAEA48D1EA20F038079 + 633FD29B2A326506D2C73CED + CF29DC3C94D7344966D490D7 + 99C6EE30C94DB596F2FCEBE2 + D3CE7AF1CEF858F829394CC8 + 37C69F1225F365F71389C2B9 + 4B6C8B40B745CC012679E0AA isa - PBXGroup - name - common - sourceTree - <group> + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 3A2FD88F529A99A655D5C439 + 3A88AB895E6CE17129F0F61A - includeInIndex - 1 + fileRef + A46D26FE67677E1BCCEC9648 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - SVIndefiniteAnimatedView.m - path - SVProgressHUD/SVIndefiniteAnimatedView.m - sourceTree - <group> + PBXBuildFile - 3AACA1031CB453DF0B0F1B62 + 3A8CF03BEBB4C969DAE1A58C - children - - 3D08731A2D8B7A9D2A860E1E - 187C3AFF7CA47A0B29C75D89 - 32C94CBBCF8C76526F8213DA - 217FA4FB15D4EDE83A84233D - A19B2B715041A76AD22B7BB7 - C5B29E7C81D4C77334248AA5 - 3ED88041ED6DCCA7AB130669 - DC6959F6B0389433A846F09B - D0C6BE4F0F08EEF1AD4759BF - 0E03512149CABB1F580F757D - DC50FB9ACAC3D68AE360BF5F - 8ED9213EE55680C24F1EB677 - 25BC2970B45A7D905D5F19BB - 635165301CE75B15CC16EE35 - D405E1711A624A1719E082D2 - 77D44783F9EE017394DF2D6A - 6A082816851C55476BD99C06 - + fileRef + 492B1CA1D1972775DF51A6CF isa - PBXGroup - name - MJRefresh - path - MJRefresh - sourceTree - <group> + PBXBuildFile + + 3AE2C49BD0132C3851A1A694 + + fileRef + 0ADA0BBE8F6E0CF27A17B204 + isa + PBXBuildFile - 3C4B103B2DCE282C9C9EA571 + 3B05348D9EADF7A7B1CBFCAF includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SDWebImageManager.h + SWUtilityButtonView.m path - SDWebImage/SDWebImageManager.h + SWTableViewCell/PodFiles/SWUtilityButtonView.m sourceTree <group> - 3C55B095805681785D374172 + 3B74DE952620ECCD576D889F - fileRef - D0C6BE4F0F08EEF1AD4759BF + buildActionMask + 2147483647 + files + + 86AEF979AA53AF316293C8AD + isa - PBXBuildFile - - 3CF9B45DDE34993A3FD50533 - - explicitFileType - archive.ar - includeInIndex + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing 0 - isa - PBXFileReference - path - libPods-MJRefresh.a - sourceTree - BUILT_PRODUCTS_DIR - 3D08731A2D8B7A9D2A860E1E + 3B7B0A7B452BFAC999ED51AF includeInIndex 1 @@ -1718,60 +1942,50 @@ lastKnownFileType sourcecode.c.h name - MJRefresh.h + SWLongPressGestureRecognizer.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h + SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h sourceTree <group> - 3E47599B0E330499635F07EE + 3C5E49F687C4DB8F5FCDB770 - explicitFileType - archive.ar includeInIndex - 0 + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLValueTransformer.m path - libPods.a + Mantle/MTLValueTransformer.m sourceTree - BUILT_PRODUCTS_DIR - - 3E7E94589902454FD328B4FD - - fileRef - 76D0502FC1D6208D9E893050 - isa - PBXBuildFile + <group> - 3ED88041ED6DCCA7AB130669 + 3D75C65180AD411A4D968C06 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - MJRefreshFooterView.m + SDWebImageDecoder.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m + SDWebImage/SDWebImageDecoder.h sourceTree <group> - 3F40BF383E1E1834C0191BD5 + 3D7A9C8AFBDC3B1B845A8354 fileRef - 771F20504BB303BB62A88285 + 747A95C1078F0A1823197D16 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 3FE2CB4E3BF724BF9DADD804 + 3DA0E29B98E2DCECB7129EED includeInIndex 1 @@ -1779,123 +1993,45 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + MJRefreshGifHeader.m path - Pods-SVProgressHUD-dummy.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifHeader.m sourceTree <group> - 404F813C33EA2B5B22382ED6 + 3DB788AB36F9B70305F82766 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig - path - Pods-AFNetworking.xcconfig - sourceTree - <group> - - 4128868F2EF04420A1F35E0D - - buildActionMask - 2147483647 - files - - 1B0ECD78A6C7584001AA72BE - 912AE7405EF879CF2313E84E - 055CD4E1DAF33217D19B9141 - - isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 41B60CD843C52B8457DCB0E0 - - buildConfigurationList - BEC66FA7BE915660404F69F2 - buildPhases - - E6D38302A5F37DB5658C41BB - F3B7C44428DC09B4933F043E - - buildRules - - dependencies - - 57232EF4CF27F922F799FEB8 - AD73A79FDD2F245D4F40C14B - 75C7388F53F668992B97A813 - DCFD647287A6F3DEE53059EB - 183B217DE3DE00FBD76C9DE5 - AADD81544137DB9F341D6ED3 - 051EC94587D0A832E9D6DEBA - 74B2111F4657AE8313673C8E - - isa - PBXNativeTarget - name - Pods - productName - Pods - productReference - 3E47599B0E330499635F07EE - productType - com.apple.product-type.library.static - - 4346B230A89B46E6BE901D9E - - children - - 9FB2FE90C5104F065B94608B - 3A2FD88F529A99A655D5C439 - 47ED5B3E2E498FA972A1AC3B - 52C22D274C762A81E9AEFD70 - 12371F77B302ED20D4ABE615 - F85DB5D3718ADE63303C06E7 - - isa - PBXGroup - name - SVProgressHUD + text.script.sh path - SVProgressHUD + Pods-resources.sh sourceTree <group> - 436DFB9BEE3EAF06EAB25B0A - - fileRef - 1DFAEC12DD2639335AF49ACE - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 43B8A0C73CAAAADDEBCE7C0C + 3E70C5C923F6BBDBA2F30CD4 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIImage+GIF.h + UIImage+GIF.m path - SDWebImage/UIImage+GIF.h + SDWebImage/UIImage+GIF.m sourceTree <group> - 4404E8E40C694424BA0B2EA2 + 407F2DBBB74D2FF06D5771AC fileRef - 514D95EC1DE6E7F84DFD7077 + E841AAF06ED6A0CAC0CC05ED isa PBXBuildFile settings @@ -1904,30 +2040,43 @@ -DOS_OBJECT_USE_OBJC=0 - 447B33241D6E8376ACAC2270 + 40FBFAB85410F664A548F0A9 - fileRef - 2046088381816FB1A6115AE8 + children + + 7388FE0012D1A4E22D1610D3 + DA2341FB44DCAD22E128F6E1 + 968359B7EB1738752C894204 + 3798DEA0FAA541D316F5FE1C + A46A12A72CF0AD1763E44FB6 + 73B5C770199A3692724BB0F2 + isa - PBXBuildFile + PBXGroup + name + extobjc + sourceTree + <group> - 44E5FEBB52959F4FE292E75F + 414A8E14A710D9A3FC373D58 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + wrapper.plug-in + name + SVWebViewController.bundle path - Pods-SWTableViewCell.xcconfig + SVWebViewController/SVWebViewController.bundle sourceTree <group> - 4510BD0D82B5FD8633E82F6C + 420247AC48DD4BCDF5E6B7D7 fileRef - 61E1D6F569824AE60EC953DC + 0C5F4AA88C010FED2B677BE0 isa PBXBuildFile settings @@ -1936,50 +2085,10 @@ -DOS_OBJECT_USE_OBJC=0 - 4639EC1DFC9BDEE03FCECD28 - - fileRef - FD317A4CDFFEF6932C841E62 - isa - PBXBuildFile - - 463D037C8D05265B93AA341F - - explicitFileType - archive.ar - includeInIndex - 0 - isa - PBXFileReference - path - libPods-SWTableViewCell.a - sourceTree - BUILT_PRODUCTS_DIR - - 46F1E537458316428EEE009F - - fileRef - C834791111C32E19511470D4 - isa - PBXBuildFile - - 475828FB9C2F29954582B1E4 - - includeInIndex - 1 - isa - PBXFileReference - name - SVWebViewControllerNext.png - path - SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png - sourceTree - <group> - - 47BC372C33FCDDB0603FF870 + 424231F6B17A5FA7F4C0F3B4 baseConfigurationReference - 11292E3DE8EF40F9DCBCD526 + 2B0136D8B5C9A7B320D8A50D buildSettings ALWAYS_SEARCH_USER_PATHS @@ -1995,7 +2104,7 @@ GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch + Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch GCC_PREPROCESSOR_DEFINITIONS DEBUG=1 @@ -2025,71 +2134,77 @@ name Debug - 47C11AD21FEAD8A5CAA86FC0 + 4410ECC91FB8EA1E78851A6B - explicitFileType - archive.ar - includeInIndex - 0 + fileRef + AD5F16EA93C42C324A1A2854 isa - PBXFileReference - path - libPods-AFNetworking.a - sourceTree - BUILT_PRODUCTS_DIR + PBXBuildFile - 47D9D21AF5FF6276C1230478 + 4418C6B2F2D85DBBEE36DBA8 fileRef - 304E5532CC66B25020968ED2 + 2567A3A1F416E5F48EE273BB isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 47ED5B3E2E498FA972A1AC3B + 4436096DFAA117FC404F08AE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SVProgressHUD.h + FBShimmeringLayer.m path - SVProgressHUD/SVProgressHUD.h + FBShimmering/FBShimmeringLayer.m sourceTree <group> - 48558FEAC015CC0EFC37FD0A + 445F7BBCE78291EE57C4F84D + + fileRef + F615D1D36012176EAC77C67D + isa + PBXBuildFile + + 46098DA747FC06C871433084 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SVWebViewControllerActivity.m + AFSecurityPolicy.h path - SVWebViewController/UIActivities/SVWebViewControllerActivity.m + AFNetworking/AFSecurityPolicy.h sourceTree <group> - 49C2583DD5BC008CD83F6071 + 46A720A0E12B13557BBA7BA3 fileRef - C50CBBB3320CBFC5FA8EA34D + 4436096DFAA117FC404F08AE isa PBXBuildFile - 4AC5FA018B13C92FA6D66B86 + 4714840E94F4B9196E39555D fileRef - 983F9AB5B982D654799AA2AC + C3DEEAC6027984E1CCDE0A79 isa PBXBuildFile - 4D56B1E3005FDE505FCEF6C6 + 4714BA30C5BDCD069A68421B includeInIndex 1 @@ -2098,41 +2213,77 @@ lastKnownFileType sourcecode.c.objc name - UIImageView+AFNetworking.m + SVIndefiniteAnimatedView.m path - UIKit+AFNetworking/UIImageView+AFNetworking.m + SVProgressHUD/SVIndefiniteAnimatedView.m sourceTree <group> - 514D95EC1DE6E7F84DFD7077 + 4850BE745D5CA828C6557D72 - includeInIndex - 1 + fileRef + 253314F7D8BF0DB55988AFAA + isa + PBXBuildFile + + 4877370E028EB1D55797780F + + baseConfigurationReference + CD2CFD88AEC03BECA1A6CE00 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + XCBuildConfiguration name - EXTRuntimeExtensions.m - path - Mantle/extobjc/EXTRuntimeExtensions.m - sourceTree - <group> + Release - 5161C757881F6F6873559967 + 48A921C553D24CB2062EEA3F - includeInIndex - 1 + fileRef + B113FB03415126F4B88F2139 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - path - Pods-SVProgressHUD-prefix.pch - sourceTree - <group> + PBXBuildFile - 52C22D274C762A81E9AEFD70 + 492B1CA1D1972775DF51A6CF includeInIndex 1 @@ -2141,139 +2292,147 @@ lastKnownFileType sourcecode.c.objc name - SVProgressHUD.m + MJRefreshLegendFooter.m path - SVProgressHUD/SVProgressHUD.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.m sourceTree <group> - 52D9636A49CE4EAB4B056599 + 4B3F73195C2488852EA8F7FA - includeInIndex - 1 + buildConfigurationList + CDE387D2836914F846D77F58 + buildPhases + + E68153ED11688501908927F4 + 866C612F677726DBC6F9B9D0 + + buildRules + + dependencies + + C847355BA3DEBAACBBE7DEAD + D57B5B10F635C06744DD1C8C + AB575AA86CF058702BDADE33 + 5D33BED88C7C8B56D97308AD + 30AA1BB118127744A694AB67 + EE34B75B8433DF4D70F5200D + 3775A139FB5A19BB0E215513 + EB2A2DDC51A4FD1EBBF8BA79 + isa - PBXFileReference + PBXNativeTarget name - SVWebViewControllerActivitySafari@2x.png - path - SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png - sourceTree - <group> + Pods + productName + Pods + productReference + CFDFBCB4455A036E8112FA54 + productType + com.apple.product-type.library.static - 531197FDF80BC84527CCAF02 + 4B6C8B40B745CC012679E0AA fileRef - F0D0B8FA1F237AF39207A58C + 3B05348D9EADF7A7B1CBFCAF isa PBXBuildFile - 532E5B4150ED4F50E11BF0C7 + 4B8BFDE18D1FCA43E9E5BB32 - includeInIndex - 1 + children + + 23763F10AD2F1762F40E6516 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - MTLModel+NSCoding.h - path - Mantle/MTLModel+NSCoding.h + Targets Support Files sourceTree <group> - 53C5A15AD63D3476D0CF1531 - - fileRef - F0D0B8FA1F237AF39207A58C - isa - PBXBuildFile - - 5453F743BF1ED5091106B499 + 4B945F8809DF8BB4D9F9E925 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - MTLManagedObjectAdapter.h + text.xcconfig path - Mantle/MTLManagedObjectAdapter.h + Pods-Mantle.xcconfig sourceTree <group> - 54AF66B17C0AEFF7AE1E5828 + 4C37BA56B960303B4E376BC6 children - 27A001025D8F6246D8E0D8D3 - 10D51B68691D31108009BE93 - 0E0B9761485C54F60690139C - 63B65631DCD63B55E53DCE03 - 282B0048A3E511971931B363 - BD7A57AABDA83E720552763E + 4B945F8809DF8BB4D9F9E925 + 4D44B23CA21D5B5AF8203047 + F615D1D36012176EAC77C67D + 0DFC1AE4D0619E84823A76B7 isa PBXGroup name - NSURLConnection + Support Files + path + ../Target Support Files/Pods-Mantle sourceTree <group> - 55A7772828B4EE4C2F35A0CD - - fileRef - 9878234455241C9D71D7D974 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 57232EF4CF27F922F799FEB8 + 4C74FDC86EA41CE2920EF95B + children + + 701F96ACC76C74D7DBFE587B + 9DE5B8BAF6520E75E0ECD2A3 + 649B019D2E9C917DF8824AFF + 998AB0CB323A17E35BDC295B + 0747044C261D3EADCE75FB02 + 6DA4BD4EE3CC4E837EA25655 + 516D4AB2E0380F4BDA49464A + DEA466424653E70B8209013D + isa - PBXTargetDependency + PBXGroup name - Pods-AFNetworking - target - E0F50EA1905F2A7094812973 - targetProxy - 1CD8DE0BC0E13E9F18B3F9A1 + AFNetworking + path + AFNetworking + sourceTree + <group> - 5737FC94B9492B6E6C616163 + 4C8B4F9E0751276ACBFFACEA includeInIndex 1 isa PBXFileReference lastKnownFileType - text + sourcecode.c.objc + name + NSDictionary+MTLMappingAdditions.m path - Pods-acknowledgements.markdown + Mantle/NSDictionary+MTLMappingAdditions.m sourceTree <group> - 573C8CC99C8641490B222C89 + 4D44B23CA21D5B5AF8203047 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - MTLValueTransformer.m + text.xcconfig path - Mantle/MTLValueTransformer.m + Pods-Mantle-Private.xcconfig sourceTree <group> - 575254127992AC3095637C85 + 4D6BEC56F9F00A366232143C includeInIndex 1 @@ -2282,26 +2441,33 @@ lastKnownFileType sourcecode.c.h name - NSData+ImageContentType.h + FBShimmering.h path - SDWebImage/NSData+ImageContentType.h + FBShimmering/FBShimmering.h sourceTree <group> - 57FA31C7342E4A8693201F60 + 4D6DEC0914D9319015537959 + + fileRef + 1C5C6F263232576A4496C2BE + isa + PBXBuildFile + + 4D975F3E0C5580B245740BA7 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + text.xcconfig path - Pods-MJRefresh-dummy.m + Pods-MJRefresh-Private.xcconfig sourceTree <group> - 585F33F75FFBDB5A2D635BC5 + 4DBE1DE7D270830D3052319C includeInIndex 1 @@ -2310,26 +2476,52 @@ lastKnownFileType text.xcconfig path - Pods-AFNetworking-Private.xcconfig + Pods-AFNetworking.xcconfig sourceTree <group> - 58D5E10B6F509A4D289AC17C + 4E764B30FFA33E665E98C3E6 + + fileRef + 5534E358144AA17472034E87 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 4F36D1CA09DF80E6C8E69420 + + fileRef + B27A22B747AB549ED4F93034 + isa + PBXBuildFile + + 509DA73C428A64C02BF0B75C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SWUtilityButtonView.h + AFNetworkActivityIndicatorManager.m path - SWTableViewCell/PodFiles/SWUtilityButtonView.h + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m sourceTree <group> - 595FC29ACF0D8E7894A124BF + 514C0D413A4720963B1FE848 + + fileRef + 70056B349FEB6A757345F167 + isa + PBXBuildFile + + 516C932F9D2EA6FCFA72DA5C includeInIndex 1 @@ -2338,444 +2530,313 @@ lastKnownFileType sourcecode.c.objc name - FMDatabase.m + AFURLConnectionOperation.m path - src/fmdb/FMDatabase.m + AFNetworking/AFURLConnectionOperation.m sourceTree <group> - 59C305ABE1A25B9CB62E5D80 - - buildActionMask - 2147483647 - files - - 7B339A4AB2229806F0376DB7 - BE9EDA04D687D70B682E1E0C - 69F567464F319FC63F2636E9 - 49C2583DD5BC008CD83F6071 - F02AEA09DBE0E12AF360F35D - 89DFAC3443DB77191DF2822E - C3A33DB3AF5947A220C22474 - 30C3BD86CBED0DC2975AE9C1 - 447B33241D6E8376ACAC2270 - D88A7258E9903DD9091947B3 - DB5A704B96D04FBF9549DA3B - FB392C3A7B8813F8724C2732 - EB394718051F19102CEA333B - 7CD1296E64395F26B193A132 - 8F938B6A800B85ACF6903654 - 29A714F97FEC7249C075FD1B - 615507F606D311E239F28363 - F78D23F252315D98B9BE3FA6 - 3E7E94589902454FD328B4FD - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 59DD36BD9A4D804D5A701ED2 + 516D4AB2E0380F4BDA49464A - buildActionMask - 2147483647 - files + children - 1A404CF9215FA5CE825E6AE2 - 7DA715BA2498F3CB799A4431 - C885E60E6C8BD0A926570AF5 - 892235EA9B366AF2D9486607 - E4F17FDA9A2004644DE362D1 - 160D3E2EB45E710B513005B2 + 4DBE1DE7D270830D3052319C + 9C746065011B9B8E702645AE + 1222A867D3B095E6CAD064E1 + 72EEDBD82F41D41F16FF3C11 isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-AFNetworking + sourceTree + <group> - 5A89A95B50754A00C6F8883D + 51AFD4B392A31A2289544A18 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + NSDictionary+MTLJSONKeyPath.m path - Pods-SVWebViewController.xcconfig + Mantle/NSDictionary+MTLJSONKeyPath.m sourceTree <group> - 5C59B57AC630CD73AB5E2D1E - - fileRef - 35DE48B4FA6E51BD7D1BA6FC - isa - PBXBuildFile - - 5CDF5BD81D96D9F7921C8DC4 + 51CF2F2FD419BD460AFE8089 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIImageView+HighlightedWebCache.h + text.xcconfig path - SDWebImage/UIImageView+HighlightedWebCache.h + Pods.debug.xcconfig sourceTree <group> - 5CEA9DDB4661A6FC3DC94DC6 - - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 6736EF81F571346B01E63AAB - remoteInfo - Pods-SVProgressHUD - - 5DF09EA3510F7C19B9A4DA3C + 51DD446E599BC1395844D43C fileRef - 187C3AFF7CA47A0B29C75D89 + FB68A1B10C381EEFC0E105CA isa PBXBuildFile - 60142F5566216743E153E6C3 + 52216402BFA370AED72D91F1 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - SDWebImageDownloaderOperation.h + text.xcconfig path - SDWebImage/SDWebImageDownloaderOperation.h + Pods-Shimmer.xcconfig sourceTree <group> - 613007691409B9A6751D3737 - - fileRef - AD4009A3CA3371D1F8C780E5 - isa - PBXBuildFile - - 615507F606D311E239F28363 + 525D311A9E6AFF1322548C37 fileRef - 778D223C43915891DECBE645 + 92549F33A3CC9D6F1C3DF977 isa PBXBuildFile - 61E1D6F569824AE60EC953DC + 52A314C9DA51CC9C91B55EE1 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - MTLManagedObjectAdapter.m + text.xcconfig path - Mantle/MTLManagedObjectAdapter.m + Pods-SVProgressHUD.xcconfig sourceTree <group> - 62417097E44F7D3F8139F32F + 536892A184C34EDCDF63E390 - baseConfigurationReference - A1B208310F6C031CA9568682 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - NO - DSTROOT - /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - + fileRef + 2B388C41DBF1EEF5D24C15BD isa - XCBuildConfiguration - name - Debug + PBXBuildFile - 62A6847E2C4950BA9C5A8A73 + 53A25457247088A54F54EA47 fileRef - 02E92DC83C62401C25C8913C + 1651B2D612326489C798B0CC + isa + PBXBuildFile + + 53A7BA974083ADCCB4248257 + + fileRef + 5BF9005E499D27C097642952 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 633433250CA4F0951A356573 + 53CF4E2FFFD543ABD0F1621C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - EXTKeyPathCoding.h + AFHTTPRequestOperationManager.m path - Mantle/extobjc/EXTKeyPathCoding.h + AFNetworking/AFHTTPRequestOperationManager.m sourceTree <group> - 635165301CE75B15CC16EE35 + 5521BE44945832991316CDC3 + + fileRef + 46098DA747FC06C871433084 + isa + PBXBuildFile + + 5534E358144AA17472034E87 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIView+MJExtension.h + NSArray+MTLManipulationAdditions.m path - MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h + Mantle/NSArray+MTLManipulationAdditions.m sourceTree <group> - 6352CB3951039CAB104F5D32 + 56F5234FA9A1B6FF50B9D373 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - FMDatabasePool.m + SWCellScrollView.h path - src/fmdb/FMDatabasePool.m + SWTableViewCell/PodFiles/SWCellScrollView.h sourceTree <group> - 639C0E9A9E7ADF70C513571E + 577435415A323B682400D54D + + buildConfigurationList + D7989D1C30764BC7F9C80624 + buildPhases + + 9793FB0E42D61D8B1B043E9E + 38F13723B1DE2DB0C6785A56 + FB8D9C35B856FEED38800CB1 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-Mantle + productName + Pods-Mantle + productReference + 9CEFCB11A62BDBC8D6BA730C + productType + com.apple.product-type.library.static + + 57B4B477E70A079BAB1DAD37 fileRef - 9F59D37382C8481C4A3543E6 + C024D03913DF6EA5F878EFBE isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 63B65631DCD63B55E53DCE03 + 58024541C4A799EB0EBD4A64 + + children + + 03161642A68CD1941BFCCA57 + 4714BA30C5BDCD069A68421B + 8887F965AE8E56F4A4FE710A + D1404AB4AA7E3E03EECDBA21 + 7E75A1D26B56E04FE835CF83 + 379FAB72597E10BB2F1FEE69 + + isa + PBXGroup + name + SVProgressHUD + path + SVProgressHUD + sourceTree + <group> + + 5824DF828B372575804DB4F5 + + buildConfigurations + + 0B5DEF3990AA31FD46C539A6 + A5DC01003F4419E2230FF9A9 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 58E581BDA91FBF5066FFCCD5 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - AFHTTPRequestOperationManager.m + text.plist.xml path - AFNetworking/AFHTTPRequestOperationManager.m + Pods-acknowledgements.plist sourceTree <group> - 640D32B00E7CA013FAA9F891 + 596FE4013EEEF9501024851D - fileRef - 2384225F66B601A470E03B2D + buildActionMask + 2147483647 + files + + FAA80B71B5EAE806B91F3C3A + 63CD09D5E84ABDF378BDE9CA + isa - PBXBuildFile + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 651297332C80103B10000DCA + 59AE4BAEA48D1EA20F038079 fileRef - BD9CA4ED0FDE48B5335FA601 + D21098B980D4B99BBE4EBCB0 isa PBXBuildFile - 65D19C9FCE68CD267930EF33 + 59C0FED9BB0FB19B319543E7 fileRef - E9A68AA93E6B24526C1517E5 + 7CFB13291239474A4401636E isa PBXBuildFile - 662A98C63D4A25AEDD5B5EC8 + 59CCB50AEA5DFB9086E74FAE fileRef - 69070D1F2DAD001B977D7FCD + 37335D22593D7576DD7BB8F3 isa PBXBuildFile - 662F6BC68D35264D3A2E14DF + 59D7C7EEA8FE7A18F7242FAB - baseConfigurationReference - E0E9DDEE088E41C8CF4C003D - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - + includeInIndex + 1 isa - XCBuildConfiguration + PBXFileReference + lastKnownFileType + sourcecode.c.h name - Release + AFURLResponseSerialization.h + path + AFNetworking/AFURLResponseSerialization.h + sourceTree + <group> - 666B1AFF5E73BE290468F5EC + 5B2761C05AC940A3B44CABDD - baseConfigurationReference - B9F5BA86ACFC81B344D15D30 - buildSettings + fileRef + 22737EECE55204DE3B79A47E + isa + PBXBuildFile + settings - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - NO - DSTROOT - /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 - isa - XCBuildConfiguration - name - Debug - - 6736EF81F571346B01E63AAB - - buildConfigurationList - 00184188B977DFF23A1F85C5 - buildPhases - - 4128868F2EF04420A1F35E0D - 7371E4E66A36022278C4AA90 - 73926FAB26BEDB4523776F71 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - Pods-SVProgressHUD - productName - Pods-SVProgressHUD - productReference - C8409304ABBDB3DE6635DB18 - productType - com.apple.product-type.library.static - 674480447F049BFA1C4EA514 + 5B5B0973E9590ACF8941A307 includeInIndex 1 @@ -2783,21 +2844,12 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - UIImageView+AFNetworking.h path - UIKit+AFNetworking/UIImageView+AFNetworking.h + Pods-SVWebViewController-prefix.pch sourceTree <group> - 67528D3EFE5A643ED1F3CCAA - - fileRef - 0BC85B368F05F28D8AC1E014 - isa - PBXBuildFile - - 69070D1F2DAD001B977D7FCD + 5BF9005E499D27C097642952 includeInIndex 1 @@ -2806,67 +2858,93 @@ lastKnownFileType sourcecode.c.h name - SDWebImagePrefetcher.h + SVModalWebViewController.h path - SDWebImage/SDWebImagePrefetcher.h + SVWebViewController/SVModalWebViewController.h + sourceTree + <group> + + 5C7D9293E6B269F06D2001DA + + children + + EAF234E3AA32CB7DAE26A06F + 2B0136D8B5C9A7B320D8A50D + 0ADA0BBE8F6E0CF27A17B204 + 5B5B0973E9590ACF8941A307 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SVWebViewController sourceTree <group> - 6947C9D1C5EE33C1D2440E0C + 5D33BED88C7C8B56D97308AD + + isa + PBXTargetDependency + name + Pods-SDWebImage + target + 0CBA1F61EC68D9CDA478C899 + targetProxy + 9A3726BF835126AC3A215F0A + + 5DFCBC9D949176E5760EC64E fileRef - F0DD19AA7C01867C1769DBE1 + 0338848C9C451EFDEF77531F isa PBXBuildFile - 69F567464F319FC63F2636E9 + 5E76D0C8307E26EBB442C355 - fileRef - D9CF805123DCF31BD815B4BB + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-Shimmer-dummy.m + sourceTree + <group> - 6A082816851C55476BD99C06 + 5E8DB0A06DAF83A7632381C1 children - B3654B8D5A85FC44A7A6B1FE - 11292E3DE8EF40F9DCBCD526 - 57FA31C7342E4A8693201F60 - A7755A9FB17EA678C37DCD95 + AD0CEA85A2185B48B09C220B + 37E7B477D7652800A3F341C3 + 335361E3B7EBFEF025533997 + 267EA0919FE8615662F5C2BE isa PBXGroup name Support Files path - ../Target Support Files/Pods-MJRefresh + ../Target Support Files/Pods-SDWebImage sourceTree <group> - 6A38B085018671A0ABB83BE1 + 5EEA0F052F38C601F48496AB + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.h - name - MTLReflection.h path - Mantle/MTLReflection.h + libPods-Shimmer.a sourceTree - <group> - - 6AE46452959456D9CAA2648A - - fileRef - 3ED88041ED6DCCA7AB130669 - isa - PBXBuildFile + BUILT_PRODUCTS_DIR - 6B6B026C7F8F1376C998B055 + 60217EF2C452852C1A0BAB32 includeInIndex 1 @@ -2875,52 +2953,36 @@ lastKnownFileType sourcecode.c.h path - Pods-Mantle-prefix.pch + Pods-Shimmer-prefix.pch sourceTree <group> - 6C469821D18CEA22E80ACA5E - - fileRef - CE4B7722CAC9ED8DD0114663 - isa - PBXBuildFile - - 6C883654D7A0A3023FD1840D + 606339BB1F98D18E401A0055 - fileRef - E96F46F8A984911D7538CA63 - isa - PBXBuildFile - - 6C91BBFD0AEB7230111657C4 - - children + buildConfigurationList + 5824DF828B372575804DB4F5 + buildPhases - 2384225F66B601A470E03B2D - BF9582E6D1D11AAE4C82790C - CE4B7722CAC9ED8DD0114663 - D2AE7F8D94E0B80BFA8F603A - A32AD2139187CB1F5F2B6247 - FC45931EABC40836F3C02FDB - B2DFB8ABE3C361564605FC09 - D8F1FDF888DD2382AECC30C3 - C56F74D0AAB1C57653DA7F7A - 983F9AB5B982D654799AA2AC - 58D5E10B6F509A4D289AC17C - F3E77A78BED9A830D2670005 - 34257C1DD98D838891B765BC + AF9098952D1C698BC780EB65 + D7FD3BD46B1CABD2F2AE50EE + B3A659BBB79CFA97EFB8C1B4 + buildRules + + dependencies + isa - PBXGroup + PBXNativeTarget name - SWTableViewCell - path - SWTableViewCell - sourceTree - <group> + Pods-Shimmer + productName + Pods-Shimmer + productReference + 5EEA0F052F38C601F48496AB + productType + com.apple.product-type.library.static - 6D0FE93D2F53E6F9BE778A43 + 60A25E261550AFF0655E9701 includeInIndex 1 @@ -2929,20 +2991,13 @@ lastKnownFileType sourcecode.c.h name - EXTRuntimeExtensions.h + SVWebViewController.h path - Mantle/extobjc/EXTRuntimeExtensions.h + SVWebViewController/SVWebViewController.h sourceTree <group> - 6D3B22115589829E7FEAC2D2 - - fileRef - 7EABDBD965900014161BECCC - isa - PBXBuildFile - - 6D6492CFDFC03E3EEED90937 + 62A22F50D3F5248A35D55225 includeInIndex 1 @@ -2951,49 +3006,50 @@ lastKnownFileType sourcecode.c.h name - UIActivityIndicatorView+AFNetworking.h + SVWebViewControllerActivitySafari.h path - UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h sourceTree <group> - 6DC5F2F2A80D898D1B9BA4E9 + 62A986D71B8732D3ED882DA2 fileRef - 4D56B1E3005FDE505FCEF6C6 + 860338F0E2A28100CD8283CB isa PBXBuildFile - 6EE966C6726621AA9BA61694 + 633FD29B2A326506D2C73CED fileRef - 16BE2A454A10A0FFBBFDD201 + F21CB8120EF2D5EE038E22B2 isa PBXBuildFile - 70F7A8DB0E39B67802CA7A76 + 63CD09D5E84ABDF378BDE9CA - includeInIndex - 1 + fileRef + E05AA74B831F33187A80AFB2 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - SVWebViewController.h - path - SVWebViewController/SVWebViewController.h - sourceTree - <group> + PBXBuildFile - 7119A73FBB159384BD4FC17E + 649B019D2E9C917DF8824AFF - fileRef - D8F1FDF888DD2382AECC30C3 + children + + B27A22B747AB549ED4F93034 + 244FECFEBCA55B4B22B48100 + CA17115300376D75D26440F2 + 8808B35EE72A9298BBA51786 + isa - PBXBuildFile + PBXGroup + name + NSURLSession + sourceTree + <group> - 716C03D21AAED4A8DD5ED96E + 6516689B190F38FDE8D21843 includeInIndex 1 @@ -3001,24 +3057,15 @@ PBXFileReference lastKnownFileType sourcecode.c.objc - name - SDWebImageDecoder.m path - SDWebImage/SDWebImageDecoder.m + Pods-dummy.m sourceTree <group> - 720BC6CAA4ECD29F66CE897D - - fileRef - A32AD2139187CB1F5F2B6247 - isa - PBXBuildFile - - 72575C4414A386B75A1236C3 + 6588A0868BCC4183CA3B6A86 baseConfigurationReference - F20B4E0EAAA530D24685A4E2 + 4D44B23CA21D5B5AF8203047 buildSettings ALWAYS_SEARCH_USER_PATHS @@ -3030,7 +3077,7 @@ GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch + Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch INSTALL_PATH $(BUILT_PRODUCTS_DIR) IPHONEOS_DEPLOYMENT_TARGET @@ -3065,302 +3112,242 @@ name Release - 726EFC473FE50E3788EFFEEF - - fileRef - F0D0B8FA1F237AF39207A58C - isa - PBXBuildFile - - 72C660C537791274ABD52CB9 - - fileRef - AD4719C2919B562DF3C80502 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - 72D8C02503DA06347455FDD9 - - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - D6558E03D7E8E7369D57D62A - remoteInfo - Pods-MJRefresh - - 730266F29F62BC3EB931952F + 65CF839D7AAAAC698C0175E9 fileRef - C32A44B3BB593CF09E391F55 + FA622950AEB141300BCA6B1F isa PBXBuildFile - 7371E4E66A36022278C4AA90 - - buildActionMask - 2147483647 - files - - B81737201F183B1D172A4B4D - BFA9BA48E845CDA5D016018D - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 73866FD56D89AA5A3F622874 - - buildActionMask - 2147483647 - files - - 4404E8E40C694424BA0B2EA2 - 91ACDD3A1590BBCBEDEBA6E4 - 8AFBA1F303183188ABA0AD0D - 4510BD0D82B5FD8633E82F6C - 2D77E6FB71644E503AB9ED42 - 9B92478EA76FF9303AFAE57A - EAABEB6BACA94FCEFBA11DFD - FB6C8948A46CF245ECD20949 - 436DFB9BEE3EAF06EAB25B0A - 3F40BF383E1E1834C0191BD5 - 62A6847E2C4950BA9C5A8A73 - C3756A16C38B7B1455914F49 - FDAFE1F6255ECC888D7503AB - 72C660C537791274ABD52CB9 - DFFAC01197AE918D4C9DFD66 - - isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 73926FAB26BEDB4523776F71 + 674019461553B37DDF831022 buildActionMask 2147483647 files - CB6E38F58D69B7640B71B0D2 - 7EEF3E303A89EACE920C35DD + 53A7BA974083ADCCB4248257 + 9E1F1FBB05AEABE72CE1EB2A + 1C1CFA57D7F622E23C370378 + FB840FFD2E5B875EC18E84DE + 76EAC2827D40982C6B2AEE5C isa PBXHeadersBuildPhase runOnlyForDeploymentPostprocessing 0 - 7398CA0C7FAD6B1A8E5B3A95 + 6813759A3D4B289309C65CC8 - children - - 1BF5129F506CB75B0F1BC5FB - 80D1CC4C00005AC726EEF730 - E29DFA8F7F2E89354CECB6C3 - 057A36C64C16BAE9CBB65645 - 795E09B9C10CEEFC412F3BF1 - D2504912E25654781C939724 - 52D9636A49CE4EAB4B056599 - 019033947122D26DFF88E20C - 86C0AE129EAF30BD5988B84A - 475828FB9C2F29954582B1E4 - 30531E76C05F3BC19F4D8D31 - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - Resources + SWTableViewCell.m + path + SWTableViewCell/PodFiles/SWTableViewCell.m sourceTree <group> - 749D67B382740B441A6C9985 + 6853E7DEAC952ED017DD382B fileRef - 292F5F1319A89AE506A962C2 + 0C2A438B42DC07E1A2B8E51B isa PBXBuildFile - 74B2111F4657AE8313673C8E - - isa - PBXTargetDependency - name - Pods-SWTableViewCell - target - 0E44B521E203EC4F111815E4 - targetProxy - A212E3E719279B15D99358D7 - - 74ED67273EBDF1D93351D598 + 6922FCE247854E0C6FD2B49C includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + MTLReflection.h path - Pods-SVProgressHUD.xcconfig + Mantle/MTLReflection.h sourceTree <group> - 752BB0BB115A89E3F4860E7E + 6A9D880FB2B5B01B5C3566A4 children - 5737FC94B9492B6E6C616163 - 221E3FF2B9CDB1D4F3615F0D - 1F5410B3AD75104BB163C869 - C0ECB4C8D31A24B2C3CF9E1F - FC5FC75F692847F3591B34B3 - ECDFCA3A35CD6A95747B8E90 - E0E9DDEE088E41C8CF4C003D + 9D641BF01B9DCB3759BB7650 + ED63151D6E956C666D9BD14F + 0338848C9C451EFDEF77531F + E841AAF06ED6A0CAC0CC05ED + 1740A3C059CD9E1542403D15 + 815759C5B0D9D8181BED265B + 6922FCE247854E0C6FD2B49C + CFC410BCCACA205D410F13B3 + 72330DDBCFF840EE908319EC + 2DE7C234F276794E257B6C45 + 988E655792186A580DD56ECC + 3C5E49F687C4DB8F5FCDB770 + 253314F7D8BF0DB55988AFAA + 37335D22593D7576DD7BB8F3 + 5534E358144AA17472034E87 + 288C837B4AE7323562462C3A + 51AFD4B392A31A2289544A18 + B1F4FF21E45DFB02CAA6DBFF + 2567A3A1F416E5F48EE273BB + 017B14BC9F461EE2E432473F + 4C8B4F9E0751276ACBFFACEA + CD8349A3F4BF18C038579DC6 + A01D6EC0BFF8D2AB4B0FEFB8 + 11C73DBC7E4CD70B20E5C5F8 + E775B6493ABD67E0B9F1A83E + 27FB9860B22C4D48341CBEA3 + B5A085F43F7BA05E99922AEF + CD33ACF6C201881D46574802 + 7A3E48B8E1F6B8E4E43315C9 + 4C37BA56B960303B4E376BC6 + 40FBFAB85410F664A548F0A9 isa PBXGroup name - Pods + Mantle path - Target Support Files/Pods + Mantle sourceTree <group> - 7571161F8493E257141282E2 + 6B0A44465BD93D4F1D552675 - buildConfigurations - - 823C291B70653700AE069288 - 7DB2B870719E2167330488F5 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + fileRef + E775B6493ABD67E0B9F1A83E isa - XCConfigurationList + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 75C7388F53F668992B97A813 + 6B37248339C21DF24CD921DE + fileRef + 3B7B0A7B452BFAC999ED51AF isa - PBXTargetDependency - name - Pods-MJRefresh - target - D6558E03D7E8E7369D57D62A - targetProxy - 72D8C02503DA06347455FDD9 + PBXBuildFile - 76D0502FC1D6208D9E893050 + 6BF3878F46EA166D96C264CA - includeInIndex - 1 + buildActionMask + 2147483647 + files + + 94A0B58F2FAF9C1CBD3A7105 + F095602FA7AC56B1A442458D + 2EA9025C8D014A7B2C9DCB08 + C28A118CD27C32728F03EB4F + B8B5CBC18C4215410E396EBB + 2AC8126F41306857B4D7B228 + 5B2761C05AC940A3B44CABDD + 78794F2C9DDADE41F7FD5AB3 + 2CFDDB557FAFD4668FB15C36 + ABB9619998DACD77052F7D09 + 061F169028DE0BDB1A04F4C7 + 8DA2B81909CC09D1C204671D + 420247AC48DD4BCDF5E6B7D7 + FA1529D54F26EFCAE13119BE + 83CFA37EDC0935EFFD9704D7 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIWebView+AFNetworking.h - path - UIKit+AFNetworking/UIWebView+AFNetworking.h - sourceTree - <group> + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 76F2FB474F9C57ED0AB606BB + 6C9BB6BBF80FB04842296734 - children - - 2046088381816FB1A6115AE8 - D09A62E8A6854C6E80B36152 - 7E1CD1AAAE86E52A5E55A54C - EDA79BFF36ED8CC66472C4B4 - + fileRef + 6922FCE247854E0C6FD2B49C isa - PBXGroup - name - Serialization - sourceTree - <group> + PBXBuildFile - 771F20504BB303BB62A88285 + 6CE6AFC3F8CD70241EF59AB9 - includeInIndex - 1 + buildConfigurationList + 123002C87D23EABEC54428B6 + buildPhases + + 8DD65D28966370811AABAD20 + DC8F3FCA873B6D58BD536AEC + 1EE396C30D8A13447C80F3A0 + + buildRules + + dependencies + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXNativeTarget name - NSDictionary+MTLManipulationAdditions.m - path - Mantle/NSDictionary+MTLManipulationAdditions.m - sourceTree - <group> + Pods-MJRefresh + productName + Pods-MJRefresh + productReference + 942FFA243C26063337A25F3C + productType + com.apple.product-type.library.static - 778D223C43915891DECBE645 + 6D065165EADB62FE6ADC04D6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - UIProgressView+AFNetworking.h + text path - UIKit+AFNetworking/UIProgressView+AFNetworking.h + Pods-acknowledgements.markdown sourceTree <group> - 77B2205754BF87FD2229D9F2 - - fileRef - D2AE7F8D94E0B80BFA8F603A - isa - PBXBuildFile - - 77D44783F9EE017394DF2D6A + 6DA4BD4EE3CC4E837EA25655 children - 2F252426DE161299AE05188D + BEA878B43A1467881A0B05D9 + 7B77F3265638135D167796E4 + 59D7C7EEA8FE7A18F7242FAB + 8C9E7A7C0B30CF70BA821647 isa PBXGroup name - Resources + Serialization sourceTree <group> - 795E09B9C10CEEFC412F3BF1 + 6E70AEEBE69E729815D15C10 + + fileRef + 8C9E7A7C0B30CF70BA821647 + isa + PBXBuildFile + + 6EC30786B89A1DAAEF831D65 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h name - SVWebViewControllerActivitySafari-iPad.png + MJRefreshGifFooter.h path - SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.h sourceTree <group> - 79AE7927E2E34267BBB4EEFB - - fileRef - 11E705D1FBE2231D8B3FA30B - isa - PBXBuildFile - - 7A1CB4CAA83E0FC77E12607B + 70056B349FEB6A757345F167 includeInIndex 1 @@ -3369,13 +3356,13 @@ lastKnownFileType sourcecode.c.objc name - UIButton+WebCache.m + UIProgressView+AFNetworking.m path - SDWebImage/UIButton+WebCache.m + UIKit+AFNetworking/UIProgressView+AFNetworking.m sourceTree <group> - 7A75EF39F7B6094E98E9D58F + 701F96ACC76C74D7DBFE587B includeInIndex 1 @@ -3384,47 +3371,52 @@ lastKnownFileType sourcecode.c.h name - UIRefreshControl+AFNetworking.h + AFNetworking.h path - UIKit+AFNetworking/UIRefreshControl+AFNetworking.h + AFNetworking/AFNetworking.h sourceTree <group> - 7A9806F1FFB8C59E80CBFD08 + 70CDF1B0FB6B3C3599FC5BDD - children + buildConfigurationList + 98484AC1E6D81524BCE077DD + buildPhases - 3E47599B0E330499635F07EE - 47C11AD21FEAD8A5CAA86FC0 - 0398B69338481EC817F6F6EB - 3CF9B45DDE34993A3FD50533 - 0DDB7686E187F3FC19D520AC - 0371BF6A0BA2FCC5D93407F8 - C8409304ABBDB3DE6635DB18 - 8BF1A56862208AAE73DA9531 - 463D037C8D05265B93AA341F + 7912FDF0D8853EF27A50D85E + 9A7DB548A2EAB74C183F19D1 + 8705DB8A847BA110AA5ABA47 + buildRules + + dependencies + isa - PBXGroup + PBXNativeTarget name - Products - sourceTree - <group> + Pods-AFNetworking + productName + Pods-AFNetworking + productReference + 8FE9BF5050F6FC295DDC2348 + productType + com.apple.product-type.library.static - 7AF9843A5A131AAFDB93EA21 + 70F13B6112440F37C2D167F8 - includeInIndex - 1 + buildConfigurations + + 75590BD8E7AE2E526793E2B2 + 0C00902A01286919FC46FC9B + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - path - Pods-FMDB-prefix.pch - sourceTree - <group> + XCConfigurationList - 7B237DEB99E4A1EC780BD565 + 71DC522FCAFF9D6B38C8C1C8 includeInIndex 1 @@ -3433,98 +3425,42 @@ lastKnownFileType sourcecode.c.objc name - AFSecurityPolicy.m + UIImage+MultiFormat.m path - AFNetworking/AFSecurityPolicy.m + SDWebImage/UIImage+MultiFormat.m sourceTree <group> - 7B339A4AB2229806F0376DB7 - - fileRef - 27A001025D8F6246D8E0D8D3 - isa - PBXBuildFile - - 7C9788498CCBBD0718711B7D - - fileRef - BD7A57AABDA83E720552763E - isa - PBXBuildFile - - 7CD1296E64395F26B193A132 - - fileRef - 90692384AE86654AF740CBA0 - isa - PBXBuildFile - - 7D4286C5720F98FA2A3F8A35 + 7216C951E31F705D623F936A - fileRef - 8ED9213EE55680C24F1EB677 - isa - PBXBuildFile - - 7DA715BA2498F3CB799A4431 - - fileRef - 2A7803167CE7616DAD6D45D8 + buildActionMask + 2147483647 + files + + E0064455F987AA18ECC111F4 + 8F962D84A0DA970EE6722D99 + isa - PBXBuildFile + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 7DB2B870719E2167330488F5 + 72330DDBCFF840EE908319EC - baseConfigurationReference - 29C91E9A9A1FACD36088397D - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - + includeInIndex + 1 isa - XCBuildConfiguration + PBXFileReference + lastKnownFileType + sourcecode.c.h name - Release + MTLTransformerErrorHandling.h + path + Mantle/MTLTransformerErrorHandling.h + sourceTree + <group> - 7E1CD1AAAE86E52A5E55A54C + 72EEDBD82F41D41F16FF3C11 includeInIndex 1 @@ -3532,17 +3468,15 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - AFURLResponseSerialization.h path - AFNetworking/AFURLResponseSerialization.h + Pods-AFNetworking-prefix.pch sourceTree <group> - 7E41E08A91865687803B6C82 + 73538EEEADB1058CDECEF95C baseConfigurationReference - A1B208310F6C031CA9568682 + A60FF7B612E384CD0FBBC028 buildSettings ALWAYS_SEARCH_USER_PATHS @@ -3553,8 +3487,6 @@ /tmp/xcodeproj.dst GCC_PRECOMPILE_PREFIX_HEADER YES - GCC_PREFIX_HEADER - Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch INSTALL_PATH $(BUILT_PRODUCTS_DIR) IPHONEOS_DEPLOYMENT_TARGET @@ -3589,141 +3521,90 @@ name Release - 7E4322D8FA302168CB5CFFB2 - - buildActionMask - 2147483647 - files - - 87A2F8DB244BEC5D78F28B8B - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 7E4DEC9F5579FF9E6012310D - - buildActionMask - 2147483647 - files - - 2FC003B95AA7F89F6830FF92 - ECFFA56C6B3F8AC988E09B43 - 6AE46452959456D9CAA2648A - 3C55B095805681785D374172 - D568513A73D383D812B92361 - 2170FBC10D2E8E490ECD303D - CCD59E2FDDA491F626635409 - 016D2ED5429A374F8D023442 - - isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 7EABDBD965900014161BECCC + 7388FE0012D1A4E22D1610D3 + includeInIndex + 1 isa PBXFileReference lastKnownFileType - wrapper.framework + sourcecode.c.h name - ImageIO.framework + EXTKeyPathCoding.h path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/ImageIO.framework + Mantle/extobjc/EXTKeyPathCoding.h sourceTree - DEVELOPER_DIR - - 7EEF3E303A89EACE920C35DD - - fileRef - 47ED5B3E2E498FA972A1AC3B - isa - PBXBuildFile - - 7F117C1078DB1AD4F3B4FE11 - - fileRef - 928FEC03396D35D183A65963 - isa - PBXBuildFile + <group> - 7F71FB5470A79B51285AB34E + 73B5C770199A3692724BB0F2 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSObject+MTLComparisonAdditions.m + metamacros.h path - Mantle/NSObject+MTLComparisonAdditions.m + Mantle/extobjc/metamacros.h sourceTree <group> - 7FFBF073B63F5E27B5D0072F + 73F06571B260553C31103BC9 - buildConfigurationList - 8EB04CFA656709317963A2B2 - buildPhases - - 27CC88179E549D8028BB3973 - B75F517882BF000A53EC59B3 - EBB725B945B1732ECF3A9006 - - buildRules - - dependencies - + includeInIndex + 1 isa - PBXNativeTarget + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - Pods-SDWebImage - productName - Pods-SDWebImage - productReference - 0371BF6A0BA2FCC5D93407F8 - productType - com.apple.product-type.library.static + UIActivityIndicatorView+AFNetworking.m + path + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m + sourceTree + <group> - 80D1CC4C00005AC726EEF730 + 747A95C1078F0A1823197D16 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - SVWebViewControllerActivityChrome-iPad.png + MJRefreshComponent.m path - SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.m sourceTree <group> - 816C64CDAD58A599C6C8138B + 748ADA32DF8501663602FE1E - children - - CAC00BB41401121BDC44E7E5 - B9F5BA86ACFC81B344D15D30 - A95D82B9D1D2BEFE3D2DAB00 - 6B6B026C7F8F1376C998B055 - + fileRef + BD21D8D91FCD26B8FAA257D1 isa - PBXGroup - name - Support Files + PBXBuildFile + + 751596E07647168536D8770B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc path - ../Target Support Files/Pods-Mantle + Pods-SVProgressHUD-dummy.m sourceTree <group> - 823C291B70653700AE069288 + 75590BD8E7AE2E526793E2B2 baseConfigurationReference - 29C91E9A9A1FACD36088397D + 37E7B477D7652800A3F341C3 buildSettings ALWAYS_SEARCH_USER_PATHS @@ -3739,7 +3620,7 @@ GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch + Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch GCC_PREPROCESSOR_DEFINITIONS DEBUG=1 @@ -3769,28 +3650,98 @@ name Debug - 82D7942CFFB4B5F9A8039B0E + 75EB3E8632BA17AD3DB6A98D - buildConfigurations + fileRef + 76B7796A1EB6299CE260128F + isa + PBXBuildFile + + 766E6FD13340EAC7CA2A74C0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-Shimmer-Private.xcconfig + sourceTree + <group> + + 76B7796A1EB6299CE260128F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FBShimmeringLayer.h + path + FBShimmering/FBShimmeringLayer.h + sourceTree + <group> + + 76EAC2827D40982C6B2AEE5C + + fileRef + 62A22F50D3F5248A35D55225 + isa + PBXBuildFile + + 78794F2C9DDADE41F7FD5AB3 + + fileRef + 9A7E479B26D9F0FDE6B70438 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 7912FDF0D8853EF27A50D85E + + buildActionMask + 2147483647 + files - FC51B49E4686DFD82E09DE0B - AF263AC92D39C068F246DF63 + FEEA599D4AD5EEB6BFEE8A7D + F722582AF97F8BC79D022EB9 + BC5EAF24594607E38A7636C1 + BBB4F0C42599E9EC3619BD9D + FC41A5A6C2DA7175CC3736A2 + C43EF4B93C5AC394AA76BC4F + FC6DA76B60E9169D68FB7BCB + B61350AA0E1ECAE94B5C03A3 + 6E70AEEBE69E729815D15C10 + 81487A46AB821C62AFB9CA08 + 9804F4F62BBB5D18B11673E6 + 7F8E08C8B095E02971789904 + BAFE0E98CDCE41DE001C1B4A + 3A88AB895E6CE17129F0F61A + 51DD446E599BC1395844D43C + 514C0D413A4720963B1FE848 + 8FC00C6E9189DC2E8F15E968 + 536892A184C34EDCDF63E390 - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release isa - XCConfigurationList + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 83C50DBF98466D8F993D6269 + 79848890F54B80767F70DD47 fileRef - 3D08731A2D8B7A9D2A860E1E + D9BC1825A20D16596316B079 isa PBXBuildFile - 846C466F2240C4C93CD6C24C + 7A0FE04DB8AACD8CD00D68CA includeInIndex 1 @@ -3799,13 +3750,82 @@ lastKnownFileType sourcecode.c.objc name - SVWebViewController.m + MJRefreshFooter.m path - SVWebViewController/SVWebViewController.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.m + sourceTree + <group> + + 7A3E48B8E1F6B8E4E43315C9 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSValueTransformer+MTLPredefinedTransformerAdditions.m + path + Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m + sourceTree + <group> + + 7AB6812792AFA62E07248261 + + containerPortal + 81D979F3E87416F4B4516D5F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 93425A71C668EB5F6C7FA734 + remoteInfo + Pods-SWTableViewCell + + 7B223D387702971DA08CD4D7 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SVWebViewController.a + sourceTree + BUILT_PRODUCTS_DIR + + 7B77F3265638135D167796E4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFURLRequestSerialization.m + path + AFNetworking/AFURLRequestSerialization.m sourceTree <group> - 84E79296009B0C709F29B5C1 + 7BF20CB8E89FE06EA149B817 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SVProgressHUD.a + sourceTree + BUILT_PRODUCTS_DIR + + 7CFB13291239474A4401636E includeInIndex 1 @@ -3814,13 +3834,28 @@ lastKnownFileType sourcecode.c.h name - SDWebImageDownloader.h + UIProgressView+AFNetworking.h path - SDWebImage/SDWebImageDownloader.h + UIKit+AFNetworking/UIProgressView+AFNetworking.h + sourceTree + <group> + + 7D3DFDFFF6AA0103584F02A3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWCellScrollView.m + path + SWTableViewCell/PodFiles/SWCellScrollView.m sourceTree <group> - 856BC697A0DE727D2365B4B7 + 7DDB2A7EFEFD7D66D7D642B4 includeInIndex 1 @@ -3829,90 +3864,154 @@ lastKnownFileType sourcecode.c.h name - NSError+MTLModelException.h + SWUtilityButtonView.h path - Mantle/NSError+MTLModelException.h + SWTableViewCell/PodFiles/SWUtilityButtonView.h sourceTree <group> - 86C0AE129EAF30BD5988B84A + 7E60A67D22F82309B3B23922 includeInIndex 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.objc name - SVWebViewControllerBack@2x.png + AFNetworkReachabilityManager.m path - SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png + AFNetworking/AFNetworkReachabilityManager.m sourceTree <group> - 86F73289E11C480C16D33BCB + 7E75A1D26B56E04FE835CF83 - baseConfigurationReference - ECDFCA3A35CD6A95747B8E90 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - NO - DSTROOT - /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - + children + + 31571A3142EC0360BA8CE5A1 + isa - XCBuildConfiguration + PBXGroup name - Debug + Resources + sourceTree + <group> + + 7EC2985EE432823B4911B78A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVWebViewControllerActivityChrome.m + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m + sourceTree + <group> + + 7F8E08C8B095E02971789904 + + fileRef + 73F06571B260553C31103BC9 + isa + PBXBuildFile - 87A2F8DB244BEC5D78F28B8B + 80982DEADF8B2A5F2B26ADE1 fileRef - F0D0B8FA1F237AF39207A58C + 8BAFDC2A67AEA3220C90038A isa PBXBuildFile - 892235EA9B366AF2D9486607 + 81487A46AB821C62AFB9CA08 + + fileRef + 8808B35EE72A9298BBA51786 + isa + PBXBuildFile + + 815759C5B0D9D8181BED265B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLModel+NSCoding.m + path + Mantle/MTLModel+NSCoding.m + sourceTree + <group> + + 81D979F3E87416F4B4516D5F + + attributes + + LastUpgradeCheck + 0510 + + buildConfigurationList + 021537B5204C0FECE2ACE390 + compatibilityVersion + Xcode 3.2 + developmentRegion + English + hasScannedForEncodings + 0 + isa + PBXProject + knownRegions + + en + + mainGroup + DEF1C98505E86E50864C1FC3 + productRefGroup + DACCC598E67DEDF2B964152C + projectDirPath + + projectReferences + + projectRoot + + targets + + 4B3F73195C2488852EA8F7FA + 70CDF1B0FB6B3C3599FC5BDD + 6CE6AFC3F8CD70241EF59AB9 + 577435415A323B682400D54D + 0CBA1F61EC68D9CDA478C899 + D68D040FBA01D62A8E3F21CF + 1E803AD000DE2CF76ED8A078 + 93425A71C668EB5F6C7FA734 + 606339BB1F98D18E401A0055 + + + 836D5E6C17DB983DF1634A69 - fileRef - C684423B9F0BCABE69332621 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFURLConnectionOperation.h + path + AFNetworking/AFURLConnectionOperation.h + sourceTree + <group> - 895426A01E6E4514960D5307 + 83CFA37EDC0935EFFD9704D7 fileRef - 7A1CB4CAA83E0FC77E12607B + BC4BFA3BB3B2500FA7071308 isa PBXBuildFile settings @@ -3921,14 +4020,21 @@ -DOS_OBJECT_USE_OBJC=0 - 89DFAC3443DB77191DF2822E + 842CCB76DC43252D77BC0631 + + fileRef + 988E655792186A580DD56ECC + isa + PBXBuildFile + + 84A9291CE1BE9DD63DB2034A fileRef - 9AC054684C72878BFD1354BD + 7388FE0012D1A4E22D1610D3 isa PBXBuildFile - 8A081DC2D78B0C22A3B1CDDE + 84FE7E230D2FC3B77F845364 includeInIndex 1 @@ -3937,92 +4043,43 @@ lastKnownFileType sourcecode.c.objc name - AFNetworkActivityIndicatorManager.m + UIRefreshControl+AFNetworking.m path - UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m + UIKit+AFNetworking/UIRefreshControl+AFNetworking.m sourceTree <group> - 8A72EC2E5ADEFD1185ACE525 + 853955DAA548D7FF44BCEE0F baseConfigurationReference - E8D5D18DAA535CA6B08AA393 + CD2CFD88AEC03BECA1A6CE00 buildSettings ALWAYS_SEARCH_USER_PATHS NO COPY_PHASE_STRIP - YES + NO DSTROOT /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS + Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS - -DNS_BLOCK_ASSERTIONS=1 + DEBUG=1 $(inherited) - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - - isa - XCBuildConfiguration - name - Release - - 8A8E2AEA05C87BF2E72C7FCA - - baseConfigurationReference - B9F5BA86ACFC81B344D15D30 - buildSettings - - ALWAYS_SEARCH_USER_PATHS + GCC_SYMBOLS_PRIVATE_EXTERN NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch INSTALL_PATH $(BUILT_PRODUCTS_DIR) IPHONEOS_DEPLOYMENT_TARGET 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - OTHER_LDFLAGS OTHER_LIBTOOLFLAGS @@ -4035,254 +4092,294 @@ iphoneos SKIP_INSTALL YES - VALIDATE_PRODUCT - YES isa XCBuildConfiguration name - Release + Debug - 8AFBA1F303183188ABA0AD0D + 860338F0E2A28100CD8283CB - fileRef - 1817BF46EC0C042C7D3CF340 isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + PBXFileReference + lastKnownFileType + wrapper.framework + name + SystemConfiguration.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/SystemConfiguration.framework + sourceTree + DEVELOPER_DIR - 8BF1A56862208AAE73DA9531 + 866C612F677726DBC6F9B9D0 - explicitFileType - archive.ar - includeInIndex + buildActionMask + 2147483647 + files + + 383B6E4068731C879D329EBE + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing 0 + + 8689A3CC3FD222309ED05ACB + + includeInIndex + 1 isa PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSData+ImageContentType.h path - libPods-SVWebViewController.a + SDWebImage/NSData+ImageContentType.h sourceTree - BUILT_PRODUCTS_DIR - - 8C11E60C3F243002B20ABAF7 - - fileRef - C8519CEEEF547AA9EE9D9271 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + <group> - 8CCB2EE71B1282861778906D + 86AEF979AA53AF316293C8AD fileRef - 70F7A8DB0E39B67802CA7A76 + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - 8D934380DB6CDDF6B1F43315 + 86E430012FC510D92AFD64FF fileRef - BC949D87330F6EC5E34A3352 + 73B5C770199A3692724BB0F2 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 8DC0686ECBB745003C3651C3 + 86EB9A08B9B6E1267BD57145 - includeInIndex - 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + wrapper.framework name - UIView+WebCacheOperation.m + Foundation.framework path - SDWebImage/UIView+WebCacheOperation.m + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework sourceTree - <group> + DEVELOPER_DIR - 8DCB4D41A489D80F71A9D029 + 8705DB8A847BA110AA5ABA47 - includeInIndex - 1 + buildActionMask + 2147483647 + files + + 525D311A9E6AFF1322548C37 + D4C3346C10EF1BC04F58673E + 4F36D1CA09DF80E6C8E69420 + 6853E7DEAC952ED017DD382B + BDDAD42C906683E324BA0911 + EA8986163F9F6442BA8F993E + 5521BE44945832991316CDC3 + C958D94D49E6ECE38DDFD29E + A13AB7B838A1874D45D4B857 + 94D7806ED1B894F9AC3B12F3 + E9A7BB0F66E56933CE58368F + 2B0B2A2AC2732C870C917A82 + D4DB003F66931D9E0941ED7A + D2D8B6939934DB2DEE11DAA4 + 2CE2F848E4E067A038B24583 + 48A921C553D24CB2062EEA3F + 59C0FED9BB0FB19B319543E7 + 4714840E94F4B9196E39555D + D7880C07AA847B66E17F9F0A + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - SDImageCache.m - path - SDWebImage/SDImageCache.m - sourceTree - <group> + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 - 8E7746C93B5A382A8BFB31C8 + 878766D5C2D02668B15FED39 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIImage+GIF.m + UIAlertView+AFNetworking.h path - SDWebImage/UIImage+GIF.m + UIKit+AFNetworking/UIAlertView+AFNetworking.h sourceTree <group> - 8EB04CFA656709317963A2B2 + 87A539495A8DCAE923BEE754 - buildConfigurations - - 62417097E44F7D3F8139F32F - 7E41E08A91865687803B6C82 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + fileRef + D15DE4AB72E69F69799EE587 isa - XCConfigurationList + PBXBuildFile - 8ED9213EE55680C24F1EB677 + 87D9BF752A70DA83F123E5E7 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIScrollView+MJRefresh.h + MJRefreshConst.m path - MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m sourceTree <group> - 8F935F9ED6A55A5476D707C4 - - buildActionMask - 2147483647 - files - - 726EFC473FE50E3788EFFEEF - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - 8F938B6A800B85ACF6903654 + 87EF8679D2D2B77AB2C96FCE - fileRef - 674480447F049BFA1C4EA514 + baseConfigurationReference + 2B0136D8B5C9A7B320D8A50D + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + isa - PBXBuildFile + XCBuildConfiguration + name + Release - 90692384AE86654AF740CBA0 + 8808B35EE72A9298BBA51786 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIButton+AFNetworking.h + AFURLSessionManager.m path - UIKit+AFNetworking/UIButton+AFNetworking.h + AFNetworking/AFURLSessionManager.m + sourceTree + <group> + + 8874020BE170050E5657645F + + children + + AF470BA25B4AEDD098801E35 + D21098B980D4B99BBE4EBCB0 + 56F5234FA9A1B6FF50B9D373 + 7D3DFDFFF6AA0103584F02A3 + 3B7B0A7B452BFAC999ED51AF + F9BA8200CBE82E1229395A4D + C87C1D1B8FEAEBDCBE6C0C34 + 6813759A3D4B289309C65CC8 + A119B53B64AF254F3DAF7205 + 31002E2D5A3FBDB190E2BA39 + 7DDB2A7EFEFD7D66D7D642B4 + 3B05348D9EADF7A7B1CBFCAF + 17491E9549DFECEE0C4A69AA + + isa + PBXGroup + name + SWTableViewCell + path + SWTableViewCell sourceTree <group> - 90E53DFD34C1281914AAC149 + 8887F965AE8E56F4A4FE710A includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h + name + SVProgressHUD.h path - Pods-SVWebViewController-dummy.m + SVProgressHUD/SVProgressHUD.h sourceTree <group> - 912AE7405EF879CF2313E84E - - fileRef - 3A2FD88F529A99A655D5C439 - isa - PBXBuildFile - - 9165E3916BCF3741753508DC + 8A5EC5ADDF6D73BF84BB0439 buildActionMask 2147483647 files - 53C5A15AD63D3476D0CF1531 + 3AE2C49BD0132C3851A1A694 + 57B4B477E70A079BAB1DAD37 + 79848890F54B80767F70DD47 + DD032B17044D0D8A8AC9BE55 + 031749B0590F6DC7715C2614 + A6FA98CBF0C13750E7030466 isa - PBXFrameworksBuildPhase + PBXSourcesBuildPhase runOnlyForDeploymentPostprocessing 0 - 91ACDD3A1590BBCBEDEBA6E4 + 8ABA1813E160CE5AB0761F51 fileRef - E62260C013619653C0C58B3D + DA2341FB44DCAD22E128F6E1 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - 928FEC03396D35D183A65963 + 8B6ED94C6DDA6FF25C0DC284 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - SDImageCache.h + SVWebViewControllerNext@2x.png path - SDWebImage/SDImageCache.h + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png sourceTree <group> - 92947A2B649AE65D923B7C2E - - fileRef - A2B106C048B78A5C6FBAA445 - isa - PBXBuildFile - - 92D1A0BBD0D2B1EA721B084C - - fileRef - 3C4B103B2DCE282C9C9EA571 - isa - PBXBuildFile - - 9449B700FD78B567CDCE349E + 8BAFDC2A67AEA3220C90038A includeInIndex 1 @@ -4291,13 +4388,13 @@ lastKnownFileType sourcecode.c.objc name - AFURLSessionManager.m + UIScrollView+MJExtension.m path - AFNetworking/AFURLSessionManager.m + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m sourceTree <group> - 94AC0364478A39DA51322B7F + 8C9C2943E986722994D47B81 includeInIndex 1 @@ -4305,40 +4402,72 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + MJRefresh.h path - Pods-SWTableViewCell-prefix.pch + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h sourceTree <group> - 94D197FD4192DB667B6E9A51 + 8C9E7A7C0B30CF70BA821647 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - AFNetworkReachabilityManager.h + AFURLResponseSerialization.m path - AFNetworking/AFNetworkReachabilityManager.h + AFNetworking/AFURLResponseSerialization.m sourceTree <group> - 968006EA8109A263FDFD3965 + 8CD2CBEC6F0C20AD99BBD7CF - includeInIndex - 1 + fileRef + 5E76D0C8307E26EBB442C355 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - path - Pods-SDWebImage-dummy.m - sourceTree - <group> + PBXBuildFile + + 8DA2B81909CC09D1C204671D + + fileRef + 71DC522FCAFF9D6B38C8C1C8 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - 96B82497505EF98401B50E1D + 8DD65D28966370811AABAD20 + + buildActionMask + 2147483647 + files + + 3D7A9C8AFBDC3B1B845A8354 + EF5E0E26F44584766F139292 + 2CC87DE56EE450C258CC1459 + 2F17FEC1B706F2EB39E2DA5D + B8D26D6ED9F85684B440CE85 + F6093A0B5FB224E073CD4A9C + 3A8CF03BEBB4C969DAE1A58C + F12F8D2E100E02797A7DC981 + CC1C67ABB4980F1129CC1ABF + 80982DEADF8B2A5F2B26ADE1 + 4D6DEC0914D9319015537959 + C7F772BBF7D7D5FEA9CE8ABA + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 8E04C8067D58420429F849D3 includeInIndex 1 @@ -4347,70 +4476,88 @@ lastKnownFileType sourcecode.c.objc name - FMDatabaseAdditions.m + UIAlertView+AFNetworking.m path - src/fmdb/FMDatabaseAdditions.m + UIKit+AFNetworking/UIAlertView+AFNetworking.m sourceTree <group> - 96E033AF44F3F21FB871FC01 + 8E22501E03EA577E214D2510 fileRef - 48558FEAC015CC0EFC37FD0A + C7C42E7283B016DEFAC91CF2 isa PBXBuildFile - 971BBE7FBC532FD0C3684E99 + 8F962D84A0DA970EE6722D99 + fileRef + 8887F965AE8E56F4A4FE710A isa - PBXFileReference - lastKnownFileType - wrapper.framework - name - MobileCoreServices.framework - path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/MobileCoreServices.framework - sourceTree - DEVELOPER_DIR + PBXBuildFile - 97959B6C405A6219826BAFBE + 8FC00C6E9189DC2E8F15E968 fileRef - 13A1A364A5506D8A8B3CB81E + 84FE7E230D2FC3B77F845364 isa PBXBuildFile - 983F9AB5B982D654799AA2AC + 8FE9BF5050F6FC295DDC2348 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-AFNetworking.a + sourceTree + BUILT_PRODUCTS_DIR + + 9067AD6B1D75736FA573D6DC includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + text.xcconfig + path + Pods-SVProgressHUD-Private.xcconfig + sourceTree + <group> + + 919F53AD7511E994A55FF852 + + includeInIndex + 1 + isa + PBXFileReference name - SWUtilityButtonTapGestureRecognizer.m + SVWebViewControllerNext.png path - SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png sourceTree <group> - 9878234455241C9D71D7D974 + 91AA46A6041EC1643446D46C includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIImageView+HighlightedWebCache.m + SDWebImageCompat.h path - SDWebImage/UIImageView+HighlightedWebCache.m + SDWebImage/SDWebImageCompat.h sourceTree <group> - 98D565C31B4E1BA8DEC0CD71 + 92549F33A3CC9D6F1C3DF977 includeInIndex 1 @@ -4419,50 +4566,61 @@ lastKnownFileType sourcecode.c.h name - UIKit+AFNetworking.h + AFHTTPRequestOperation.h path - UIKit+AFNetworking/UIKit+AFNetworking.h + AFNetworking/AFHTTPRequestOperation.h sourceTree <group> - 9AAAE1957C330405FAFB9600 + 93425A71C668EB5F6C7FA734 - buildActionMask - 2147483647 - files + buildConfigurationList + A87A36A32F40E52DF1C88755 + buildPhases - C1DE7C20F35B97860D706B66 - 92947A2B649AE65D923B7C2E - 77B2205754BF87FD2229D9F2 - F49B17CD5DB7BF511AD95FE0 - 7119A73FBB159384BD4FC17E - 4AC5FA018B13C92FA6D66B86 - B58F93C474B2E8430B05D256 + 3992094AFFDF7D4ECD978CFD + 3B74DE952620ECCD576D889F + F9D859481550E0BAAFC49F8D + buildRules + + dependencies + isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXNativeTarget + name + Pods-SWTableViewCell + productName + Pods-SWTableViewCell + productReference + A6AD37D8B00F8892C4806CF5 + productType + com.apple.product-type.library.static + + 9381F7BB0A087C29FE037C45 + + fileRef + 91AA46A6041EC1643446D46C + isa + PBXBuildFile - 9AC054684C72878BFD1354BD + 942FFA243C26063337A25F3C + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.h - name - AFNetworking.h path - AFNetworking/AFNetworking.h + libPods-MJRefresh.a sourceTree - <group> + BUILT_PRODUCTS_DIR - 9B92478EA76FF9303AFAE57A + 94A0B58F2FAF9C1CBD3A7105 fileRef - 283AD6CF440DCA9B38B0B53C + 06BFC4042CE34CA8CF550A8A isa PBXBuildFile settings @@ -4471,189 +4629,136 @@ -DOS_OBJECT_USE_OBJC=0 - 9C079AF4CCEEC69481F2BF10 + 94D7806ED1B894F9AC3B12F3 + + fileRef + 59D7C7EEA8FE7A18F7242FAB + isa + PBXBuildFile + + 95881FA09CB265E1553DA033 fileRef - CA15D003C21CFCA2294BE5DB + AAC8341199D37437F70D1F22 isa PBXBuildFile - 9E3CADF4D34242891C1E4725 + 95E7FC2311C4858528731495 + + fileRef + CADA31036DC6EAB82967ECA4 + isa + PBXBuildFile + + 95FF2B992C0CBC462AC1C0EF includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - FMDatabaseAdditions.h + MJRefreshHeader.m path - src/fmdb/FMDatabaseAdditions.h + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.m sourceTree <group> - 9E99E930712393BD264CF051 + 9643F891DE5CA3D4BB9E89D6 - children - - A6D689B150BE62B7DB1AC767 - 1817BF46EC0C042C7D3CF340 - 5453F743BF1ED5091106B499 - 61E1D6F569824AE60EC953DC - C834791111C32E19511470D4 - 283AD6CF440DCA9B38B0B53C - 532E5B4150ED4F50E11BF0C7 - 23A7B732974BAA16EF4D4F5A - 6A38B085018671A0ABB83BE1 - A8C971E5B6D1D6B34B5C9A1B - E7926F44F6DD7675C4CAB292 - 573C8CC99C8641490B222C89 - AF131B236DD5AB2E742ADEF2 - F0DD19AA7C01867C1769DBE1 - 1DFAEC12DD2639335AF49ACE - 2366FECF46A2354EC3AC77D5 - 771F20504BB303BB62A88285 - 856BC697A0DE727D2365B4B7 - 02E92DC83C62401C25C8913C - BFCFD346B7D3A14BA3BA069B - 7F71FB5470A79B51285AB34E - AC1C5B4CE91F11AE998D64F6 - AADE27D38FBFB33465D0DA5F - D0C3135DA2BA3C019BAF2DCF - AD4719C2919B562DF3C80502 - 816C64CDAD58A599C6C8138B - C932222C6328C3C84A162E3B - + includeInIndex + 1 isa - PBXGroup - name - Mantle + PBXFileReference + lastKnownFileType + sourcecode.c.objc path - Mantle + Pods-MJRefresh-dummy.m sourceTree <group> - 9E9A3CEB47FB55E4697B447A - - fileRef - 532E5B4150ED4F50E11BF0C7 - isa - PBXBuildFile - - 9EC42BD6CC05E3F9835DEB3C + 968359B7EB1738752C894204 - children - - EA98CE819CDC3A1C462DA862 - A1B208310F6C031CA9568682 - 968006EA8109A263FDFD3965 - AA553D7A3D3565A545F3AD41 - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - Support Files + EXTRuntimeExtensions.m path - ../Target Support Files/Pods-SDWebImage + Mantle/extobjc/EXTRuntimeExtensions.m sourceTree <group> - 9EDC843AF94153F5B29AD001 - - fileRef - 58D5E10B6F509A4D289AC17C - isa - PBXBuildFile - - 9EFF5CE823942564335B0542 - - fileRef - 60142F5566216743E153E6C3 - isa - PBXBuildFile - - 9F4821AF45F02268E44D0C1D - - fileRef - 84E79296009B0C709F29B5C1 - isa - PBXBuildFile - - 9F59D37382C8481C4A3543E6 + 96D4C1202D853D89B6302975 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SDWebImageDownloaderOperation.m + AFNetworkReachabilityManager.h path - SDWebImage/SDWebImageDownloaderOperation.m + AFNetworking/AFNetworkReachabilityManager.h sourceTree <group> - 9F745963084D8E9E216392E2 + 9793FB0E42D61D8B1B043E9E buildActionMask 2147483647 files - A361D7EB87257BFB39CD297F - 24EDA1E60FA28D25D59006F1 - 67528D3EFE5A643ED1F3CCAA - FC77BBB341E0605E8ED130FB - B668271A16D47AF44F9BBCDA - 9E9A3CEB47FB55E4697B447A - 46F1E537458316428EEE009F - 1AF9F27A2984FABBCD8BB35F - 0BD156919664C48A35EEDBFE - FED8EC57D00423F3832AA2A9 - 6947C9D1C5EE33C1D2440E0C - 9FF9F40002ADF22BEF8BE069 - ABDDECC9891EA588DA2A5FF8 - E45958CE3CBD11F1707F441C - 10BE1219154FDDC59F7E91E8 - 25CE073DBCD2584B257B39DA - D79E955756AA01C364E52FE8 + A83C6E63C79B9ED792ABFF3E + AB54FC747D875B8A17635816 + 1B05BA6213F2E3EF2E531B9A + FDDB69BCEA27A3D2EAF6260B + 407F2DBBB74D2FF06D5771AC + C6DB08D280F61DACBF4D3AAD + 2DC4E99A25ACFE75B1E09DDB + 356BDA711A406B42A2AA21CC + 4E764B30FFA33E665E98C3E6 + FBC45023CA1F858225841F8C + 4418C6B2F2D85DBBEE36DBA8 + F4CF5630FC9C35B1117974BD + 98EBA7623C2CF142FEB7D884 + 6B0A44465BD93D4F1D552675 + C582AF7193A0AFF4C3D19FF8 + 11DFAC007737F49E7E5B5404 + 445F7BBCE78291EE57C4F84D isa - PBXHeadersBuildPhase + PBXSourcesBuildPhase runOnlyForDeploymentPostprocessing 0 - 9F77207596AAC05C2F57FD7F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - SDWebImagePrefetcher.m - path - SDWebImage/SDWebImagePrefetcher.m - sourceTree - <group> - - 9F9C79DFE629562CA77CD2CA + 9804F4F62BBB5D18B11673E6 fileRef - D09A62E8A6854C6E80B36152 + 1222A867D3B095E6CAD064E1 isa PBXBuildFile - 9FA315080E627AB06418F4B4 + 98484AC1E6D81524BCE077DD - fileRef - 8A081DC2D78B0C22A3B1CDDE + buildConfigurations + + 205ED29E148DADEBC19D323C + B75CF58239E7FE5D406B27FC + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release isa - PBXBuildFile + XCConfigurationList - 9FB2FE90C5104F065B94608B + 988E655792186A580DD56ECC includeInIndex 1 @@ -4662,54 +4767,76 @@ lastKnownFileType sourcecode.c.h name - SVIndefiniteAnimatedView.h + MTLValueTransformer.h path - SVProgressHUD/SVIndefiniteAnimatedView.h + Mantle/MTLValueTransformer.h sourceTree <group> - 9FF9F40002ADF22BEF8BE069 + 98EBA7623C2CF142FEB7D884 fileRef - 2366FECF46A2354EC3AC77D5 + A01D6EC0BFF8D2AB4B0FEFB8 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - A0BC09B6CD44A3EC41327140 + 998AB0CB323A17E35BDC295B - fileRef - 7B237DEB99E4A1EC780BD565 + children + + 96D4C1202D853D89B6302975 + 7E60A67D22F82309B3B23922 + isa - PBXBuildFile + PBXGroup + name + Reachability + sourceTree + <group> - A0EB66A861D7F9BE99167595 + 99C6EE30C94DB596F2FCEBE2 fileRef - 595FC29ACF0D8E7894A124BF + F9BA8200CBE82E1229395A4D isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - A110D8DB17AB6647C7795EBD + 9A3726BF835126AC3A215F0A - includeInIndex + containerPortal + 81D979F3E87416F4B4516D5F + isa + PBXContainerItemProxy + proxyType 1 + remoteGlobalIDString + 0CBA1F61EC68D9CDA478C899 + remoteInfo + Pods-SDWebImage + + 9A7DB548A2EAB74C183F19D1 + + buildActionMask + 2147483647 + files + + 1CC1A3DF4C98E3580B5C08DB + 28CA5C2956701A65270F4AD9 + 9B72ABF3B1BEF1542A0BF493 + F4A2225775DD229E3C63BECD + 62A986D71B8732D3ED882DA2 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIButton+AFNetworking.m - path - UIKit+AFNetworking/UIButton+AFNetworking.m - sourceTree - <group> + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - A19B2B715041A76AD22B7BB7 + 9A7E479B26D9F0FDE6B70438 includeInIndex 1 @@ -4718,63 +4845,20 @@ lastKnownFileType sourcecode.c.objc name - MJRefreshConst.m + SDWebImageManager.m path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m + SDWebImage/SDWebImageManager.m sourceTree <group> - A19CDB887CB102ECC06C0723 + 9B72ABF3B1BEF1542A0BF493 - baseConfigurationReference - 11292E3DE8EF40F9DCBCD526 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - + fileRef + F684B190D03659D4947FEA45 isa - XCBuildConfiguration - name - Release + PBXBuildFile - A1B208310F6C031CA9568682 + 9C746065011B9B8E702645AE includeInIndex 1 @@ -4783,93 +4867,24 @@ lastKnownFileType text.xcconfig path - Pods-SDWebImage-Private.xcconfig + Pods-AFNetworking-Private.xcconfig sourceTree <group> - A212E3E719279B15D99358D7 - - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - 0E44B521E203EC4F111815E4 - remoteInfo - Pods-SWTableViewCell - - A25EAE9D801AB760A4747E4B - - baseConfigurationReference - E8D5D18DAA535CA6B08AA393 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - NO - DSTROOT - /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - - isa - XCBuildConfiguration - name - Debug - - A2B106C048B78A5C6FBAA445 + 9CEFCB11A62BDBC8D6BA730C + explicitFileType + archive.ar includeInIndex - 1 + 0 isa PBXFileReference - lastKnownFileType - sourcecode.c.objc path - Pods-SWTableViewCell-dummy.m + libPods-Mantle.a sourceTree - <group> - - A2EBB8311F6F713C23AA9103 - - fileRef - F19082954117D5EC4CBF111A - isa - PBXBuildFile + BUILT_PRODUCTS_DIR - A32AD2139187CB1F5F2B6247 + 9D641BF01B9DCB3759BB7650 includeInIndex 1 @@ -4878,100 +4893,82 @@ lastKnownFileType sourcecode.c.h name - SWLongPressGestureRecognizer.h + MTLJSONAdapter.h path - SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h + Mantle/MTLJSONAdapter.h sourceTree <group> - A3516881B3D6F981B73AC538 + 9DE5B8BAF6520E75E0ECD2A3 children - FA9D9250626EDCE049F74048 - 13A1A364A5506D8A8B3CB81E - 70F7A8DB0E39B67802CA7A76 - 846C466F2240C4C93CD6C24C - AC6F1AA84590ACFF61BAAD60 - 48558FEAC015CC0EFC37FD0A - D9813C4AEDC5894EE1B3451F - C32A44B3BB593CF09E391F55 - BD9CA4ED0FDE48B5335FA601 - CA15D003C21CFCA2294BE5DB - 7398CA0C7FAD6B1A8E5B3A95 - AE42B8105AFFE0B288D61B38 + 92549F33A3CC9D6F1C3DF977 + BCE701251DF69F3F6F83B283 + AD8E2E838E28925DC440CEB5 + 53CF4E2FFFD543ABD0F1621C + 836D5E6C17DB983DF1634A69 + 516C932F9D2EA6FCFA72DA5C isa PBXGroup name - SVWebViewController - path - SVWebViewController + NSURLConnection sourceTree <group> - A361D7EB87257BFB39CD297F - - fileRef - 633433250CA4F0951A356573 - isa - PBXBuildFile - - A3A92429628C08F12D3FC1CD + 9E016601CA43D1C5C8904B27 fileRef - E32EAF52CDE8541AAA86F6A0 + 8C9C2943E986722994D47B81 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - A3E886CEC48C491886768370 + 9E1F1FBB05AEABE72CE1EB2A fileRef - 968006EA8109A263FDFD3965 + 60A25E261550AFF0655E9701 isa PBXBuildFile - A566AAD0BC4F7B6641A8C759 + 9E9D0D9F98C6F64688498FA0 - fileRef - 10D51B68691D31108009BE93 + includeInIndex + 1 isa - PBXBuildFile + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MJRefreshLegendHeader.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.m + sourceTree + <group> - A6D689B150BE62B7DB1AC767 + A01D6EC0BFF8D2AB4B0FEFB8 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - MTLJSONAdapter.h + NSError+MTLModelException.m path - Mantle/MTLJSONAdapter.h + Mantle/NSError+MTLModelException.m sourceTree <group> - A6EA95925C726D0A8F6D6DA1 + A087CA9E108E9E21024C9172 - containerPortal - 003A31C6AADD74836B88341F + fileRef + 86EB9A08B9B6E1267BD57145 isa - PBXContainerItemProxy - proxyType - 1 - remoteGlobalIDString - F5AD41E8F4E3CBFFE9D0A6AD - remoteInfo - Pods-FMDB + PBXBuildFile - A735B515C1DCF4D2370CAF9A + A119B53B64AF254F3DAF7205 includeInIndex 1 @@ -4979,25 +4976,41 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + SWUtilityButtonTapGestureRecognizer.h path - Pods-SVWebViewController-prefix.pch + SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h sourceTree <group> - A7755A9FB17EA678C37DCD95 + A13AB7B838A1874D45D4B857 + + fileRef + BEA878B43A1467881A0B05D9 + isa + PBXBuildFile + + A30E202D51051669B6D9A384 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h + name + SVWebViewControllerActivityChrome@2x.png path - Pods-MJRefresh-prefix.pch + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png sourceTree <group> - A8C971E5B6D1D6B34B5C9A1B + A32C110D789B8BD8916FDEC8 + + fileRef + 1B9EB26BF91493E21387BF73 + isa + PBXBuildFile + + A46A12A72CF0AD1763E44FB6 includeInIndex 1 @@ -5006,13 +5019,13 @@ lastKnownFileType sourcecode.c.objc name - MTLReflection.m + EXTScope.m path - Mantle/MTLReflection.m + Mantle/extobjc/EXTScope.m sourceTree <group> - A95D82B9D1D2BEFE3D2DAB00 + A46D26FE67677E1BCCEC9648 includeInIndex 1 @@ -5020,12 +5033,71 @@ PBXFileReference lastKnownFileType sourcecode.c.objc + name + UIButton+AFNetworking.m path - Pods-Mantle-dummy.m + UIKit+AFNetworking/UIButton+AFNetworking.m sourceTree <group> - A9649B3D73F213DD8CAF3844 + A5C8556A075FD35AD30BACD1 + + fileRef + 4D6BEC56F9F00A366232143C + isa + PBXBuildFile + + A5DC01003F4419E2230FF9A9 + + baseConfigurationReference + 766E6FD13340EAC7CA2A74C0 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-Shimmer/Pods-Shimmer-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + A60FF7B612E384CD0FBBC028 includeInIndex 1 @@ -5034,30 +5106,64 @@ lastKnownFileType text.xcconfig path - Pods-FMDB.xcconfig + Pods.release.xcconfig sourceTree <group> - A98547DB16A7BA47C179FA8D + A6AD37D8B00F8892C4806CF5 - children + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SWTableViewCell.a + sourceTree + BUILT_PRODUCTS_DIR + + A6FA98CBF0C13750E7030466 + + fileRef + 25A0A19A077EC9E251FBD688 + isa + PBXBuildFile + + A74B2B655F7C0D0312999B5C + + fileRef + 4714BA30C5BDCD069A68421B + isa + PBXBuildFile + + A83C6E63C79B9ED792ABFF3E + + fileRef + 968359B7EB1738752C894204 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + A87A36A32F40E52DF1C88755 + + buildConfigurations - 292F5F1319A89AE506A962C2 - F0D0B8FA1F237AF39207A58C - 7EABDBD965900014161BECCC - 971BBE7FBC532FD0C3684E99 - F5FB40E1554F5686F97998FA - D2F8B867A02B15A8D833E6E7 - 15C57B0A0D754AA9967330DF + 853955DAA548D7FF44BCEE0F + 4877370E028EB1D55797780F + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release isa - PBXGroup - name - iOS - sourceTree - <group> + XCConfigurationList - AA553D7A3D3565A545F3AD41 + A90F74085A3775EED69FD854 includeInIndex 1 @@ -5065,146 +5171,162 @@ PBXFileReference lastKnownFileType sourcecode.c.h + name + FBShimmeringView.h path - Pods-SDWebImage-prefix.pch + FBShimmering/FBShimmeringView.h sourceTree <group> - AADD81544137DB9F341D6ED3 + A93E13864D80CA2BBDF0CE3B + fileRef + 11C73DBC7E4CD70B20E5C5F8 isa - PBXTargetDependency - name - Pods-SVProgressHUD - target - 6736EF81F571346B01E63AAB - targetProxy - 5CEA9DDB4661A6FC3DC94DC6 + PBXBuildFile - AADE27D38FBFB33465D0DA5F + AAC8341199D37437F70D1F22 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSValueTransformer+MTLInversionAdditions.m + MJRefreshHeader.h path - Mantle/NSValueTransformer+MTLInversionAdditions.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeader.h sourceTree <group> - AB1DEC2C8FBB36DEECEF04E0 + AB54FC747D875B8A17635816 fileRef - FA9D9250626EDCE049F74048 + A46A12A72CF0AD1763E44FB6 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + AB575AA86CF058702BDADE33 + + isa + PBXTargetDependency + name + Pods-Mantle + target + 577435415A323B682400D54D + targetProxy + CD4A5D420DBD6E66570EB0DF - ABDDECC9891EA588DA2A5FF8 + ABB9619998DACD77052F7D09 fileRef - 856BC697A0DE727D2365B4B7 + 202F6DB433134889BAACCDDB isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - AC1C5B4CE91F11AE998D64F6 + ACB10044602E091306D20304 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - NSValueTransformer+MTLInversionAdditions.h + SVWebViewControllerActivityChrome-iPad.png path - Mantle/NSValueTransformer+MTLInversionAdditions.h + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png sourceTree <group> - AC6F1AA84590ACFF61BAAD60 + AD0CEA85A2185B48B09C220B includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h - name - SVWebViewControllerActivity.h + text.xcconfig path - SVWebViewController/UIActivities/SVWebViewControllerActivity.h + Pods-SDWebImage.xcconfig sourceTree <group> - AD4009A3CA3371D1F8C780E5 + AD5F16EA93C42C324A1A2854 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h + name + UIScrollView+MJExtension.h path - Pods-FMDB-dummy.m + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h sourceTree <group> - AD4719C2919B562DF3C80502 + AD8E2E838E28925DC440CEB5 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSValueTransformer+MTLPredefinedTransformerAdditions.m + AFHTTPRequestOperationManager.h path - Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m + AFNetworking/AFHTTPRequestOperationManager.h sourceTree <group> - AD73A79FDD2F245D4F40C14B - - isa - PBXTargetDependency - name - Pods-FMDB - target - F5AD41E8F4E3CBFFE9D0A6AD - targetProxy - A6EA95925C726D0A8F6D6DA1 - - ADC6D3BD671FB020D4E165E1 - - fileRef - D9813C4AEDC5894EE1B3451F - isa - PBXBuildFile - - AE42B8105AFFE0B288D61B38 + AE9AE9605C535FD64A7E4136 children - 5A89A95B50754A00C6F8883D - E8D5D18DAA535CA6B08AA393 - 90E53DFD34C1281914AAC149 - A735B515C1DCF4D2370CAF9A + 4C74FDC86EA41CE2920EF95B + 2610D7C01A280C95688E34FA + 6A9D880FB2B5B01B5C3566A4 + 354547649D0B305705F9A7B2 + 58024541C4A799EB0EBD4A64 + 15FBF202A50ECA5AE8098F25 + 8874020BE170050E5657645F + E19E6C14D588684CC18224AE isa PBXGroup name - Support Files - path - ../Target Support Files/Pods-SVWebViewController + Pods sourceTree <group> - AF131B236DD5AB2E742ADEF2 + AEE0860D1763213A0AFE6929 + + buildActionMask + 2147483647 + files + + 30595C98C9115B602BDC4BCB + A74B2B655F7C0D0312999B5C + CD8984A1672C44CD6FA8B455 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + AF470BA25B4AEDD098801E35 includeInIndex 1 @@ -5212,71 +5334,14 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - Mantle.h - path - Mantle/Mantle.h - sourceTree - <group> - - AF263AC92D39C068F246DF63 - - baseConfigurationReference - E3C180F70C4829EC3E7C8741 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - - isa - XCBuildConfiguration - name - Release - - B0F31E9D675CDD8EF475F4A7 - - fileRef - 43B8A0C73CAAAADDEBCE7C0C - isa - PBXBuildFile + name + NSMutableArray+SWUtilityButtons.h + path + SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h + sourceTree + <group> - B2DFB8ABE3C361564605FC09 + AF5C6DD26F6C33671E226570 includeInIndex 1 @@ -5285,92 +5350,43 @@ lastKnownFileType sourcecode.c.h name - SWTableViewCell.h + UIImage+MultiFormat.h path - SWTableViewCell/PodFiles/SWTableViewCell.h + SDWebImage/UIImage+MultiFormat.h sourceTree <group> - B2FE89B302D990CFC2393FFB + AF9098952D1C698BC780EB65 - children + buildActionMask + 2147483647 + files - 322D65FFB3319CBE9B35DD56 - 9EC42BD6CC05E3F9835DEB3C + 46A720A0E12B13557BBA7BA3 + 15BB52D8A36F9448177D9DF6 + 8CD2CBEC6F0C20AD99BBD7CF isa - PBXGroup - name - SDWebImage - path - SDWebImage - sourceTree - <group> + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - B3654B8D5A85FC44A7A6B1FE + B113FB03415126F4B88F2139 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + UIKit+AFNetworking.h path - Pods-MJRefresh.xcconfig + UIKit+AFNetworking/UIKit+AFNetworking.h sourceTree <group> - B37092B574E47123FA62F48A - - baseConfigurationReference - 585F33F75FFBDB5A2D635BC5 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - YES - DSTROOT - /tmp/xcodeproj.dst - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_CFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_CPLUSPLUSFLAGS - - -DNS_BLOCK_ASSERTIONS=1 - $(inherited) - - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - VALIDATE_PRODUCT - YES - - isa - XCBuildConfiguration - name - Release - - B3C85AC9AFD3294AE7C56106 + B1F4FF21E45DFB02CAA6DBFF includeInIndex 1 @@ -5379,126 +5395,72 @@ lastKnownFileType sourcecode.c.h name - SDWebImageDecoder.h + NSDictionary+MTLManipulationAdditions.h path - SDWebImage/SDWebImageDecoder.h + Mantle/NSDictionary+MTLManipulationAdditions.h sourceTree <group> - B49FB948DC12B27713617596 + B27A22B747AB549ED4F93034 - children - - D9CF805123DCF31BD815B4BB - 290221507373808ABAA4054B - 2D3A6D4FA7D703DF6C8A7450 - 9449B700FD78B567CDCE349E - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + sourcecode.c.h name - NSURLSession + AFHTTPSessionManager.h + path + AFNetworking/AFHTTPSessionManager.h sourceTree <group> - B58F93C474B2E8430B05D256 - - fileRef - F3E77A78BED9A830D2670005 - isa - PBXBuildFile - - B5CE0321A8AEFC3F5FA0DF70 - - fileRef - 1890A9018AFB550869401948 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - B668271A16D47AF44F9BBCDA - - fileRef - 5453F743BF1ED5091106B499 - isa - PBXBuildFile - - B75F517882BF000A53EC59B3 - - buildActionMask - 2147483647 - files - - DDA12FA0A07A90423DAC2DAF - 6D3B22115589829E7FEAC2D2 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - B7B2983751AA2DB871BE4F87 + B3A659BBB79CFA97EFB8C1B4 buildActionMask 2147483647 files - 83C50DBF98466D8F993D6269 - 5DF09EA3510F7C19B9A4DA3C - FE4113033936F46AED1AC492 - E047647F1042A54423864302 - 245A7D5B09274802299A5413 - 0BD65AA041B8332119344140 - 7D4286C5720F98FA2A3F8A35 - D059787EBF44D5A0BC02F87F + A5C8556A075FD35AD30BACD1 + 75EB3E8632BA17AD3DB6A98D + D4597DB6B6075E95AAE77F0F isa PBXHeadersBuildPhase runOnlyForDeploymentPostprocessing 0 - B81737201F183B1D172A4B4D - - fileRef - F0D0B8FA1F237AF39207A58C - isa - PBXBuildFile - - B9011D79C925C7A071C4D24A + B4D86A148E61EDCE85A2F9CF baseConfigurationReference - 585F33F75FFBDB5A2D635BC5 + 9067AD6B1D75736FA573D6DC buildSettings ALWAYS_SEARCH_USER_PATHS NO COPY_PHASE_STRIP - NO + YES DSTROOT /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO + Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch INSTALL_PATH $(BUILT_PRODUCTS_DIR) IPHONEOS_DEPLOYMENT_TARGET 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + OTHER_LDFLAGS OTHER_LIBTOOLFLAGS @@ -5511,41 +5473,30 @@ iphoneos SKIP_INSTALL YES + VALIDATE_PRODUCT + YES isa XCBuildConfiguration name - Debug - - B9F5BA86ACFC81B344D15D30 - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - Pods-Mantle-Private.xcconfig - sourceTree - <group> + Release - BB46AB577CB11E2DEC496B53 + B545404BB9E4DE3AFE749CBB includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIAlertView+AFNetworking.h + SDWebImageCompat.m path - UIKit+AFNetworking/UIAlertView+AFNetworking.h + SDWebImage/SDWebImageCompat.m sourceTree <group> - BB9E6E4F4B05385705EB97C0 + B5A085F43F7BA05E99922AEF includeInIndex 1 @@ -5554,28 +5505,20 @@ lastKnownFileType sourcecode.c.objc name - UIWebView+AFNetworking.m + NSValueTransformer+MTLInversionAdditions.m path - UIKit+AFNetworking/UIWebView+AFNetworking.m + Mantle/NSValueTransformer+MTLInversionAdditions.m sourceTree <group> - BC949D87330F6EC5E34A3352 + B61350AA0E1ECAE94B5C03A3 - includeInIndex - 1 + fileRef + 7B77F3265638135D167796E4 isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - UIImageView+WebCache.m - path - SDWebImage/UIImageView+WebCache.m - sourceTree - <group> + PBXBuildFile - BD7A57AABDA83E720552763E + B62A0CCA6FB761F67C50FD6C includeInIndex 1 @@ -5584,13 +5527,13 @@ lastKnownFileType sourcecode.c.objc name - AFURLConnectionOperation.m + SDWebImageDecoder.m path - AFNetworking/AFURLConnectionOperation.m + SDWebImage/SDWebImageDecoder.m sourceTree <group> - BD9CA4ED0FDE48B5335FA601 + B6D1E6F496CA960B50C331AD includeInIndex 1 @@ -5599,138 +5542,125 @@ lastKnownFileType sourcecode.c.h name - SVWebViewControllerActivitySafari.h + MJRefreshLegendHeader.h path - SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendHeader.h sourceTree <group> - BDD171D88E04245FF41CFF78 - - buildActionMask - 2147483647 - files - - 640D32B00E7CA013FAA9F891 - 6C469821D18CEA22E80ACA5E - 720BC6CAA4ECD29F66CE897D - 015D98E4D31C2E29C4FB9DBA - D0A9652EBFFEC41C2F239263 - 9EDC843AF94153F5B29AD001 - - isa - PBXHeadersBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - BDD54D59F9F168C7CDC3C286 + B75CF58239E7FE5D406B27FC - includeInIndex - 1 + baseConfigurationReference + 9C746065011B9B8E702645AE + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + XCBuildConfiguration name - UIImage+MultiFormat.m - path - SDWebImage/UIImage+MultiFormat.m - sourceTree - <group> + Release - BE940E795DD463ACED5B538C + B8B5CBC18C4215410E396EBB fileRef - A110D8DB17AB6647C7795EBD + B62A0CCA6FB761F67C50FD6C isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - BE9EDA04D687D70B682E1E0C + B8D26D6ED9F85684B440CE85 fileRef - 0E0B9761485C54F60690139C + 3DA0E29B98E2DCECB7129EED isa PBXBuildFile - BEC66FA7BE915660404F69F2 + BAFE0E98CDCE41DE001C1B4A - buildConfigurations - - 86F73289E11C480C16D33BCB - 662F6BC68D35264D3A2E14DF - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release + fileRef + 8E04C8067D58420429F849D3 isa - XCConfigurationList + PBXBuildFile - BF9582E6D1D11AAE4C82790C + BBB4F0C42599E9EC3619BD9D - includeInIndex - 1 + fileRef + 509DA73C428A64C02BF0B75C isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc - name - NSMutableArray+SWUtilityButtons.m - path - SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m - sourceTree - <group> + PBXBuildFile - BFA9BA48E845CDA5D016018D + BC3B5779BE0E0FCD39A14E06 fileRef - F5FB40E1554F5686F97998FA + 56F5234FA9A1B6FF50B9D373 isa PBXBuildFile - BFCFD346B7D3A14BA3BA069B + BC4BFA3BB3B2500FA7071308 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - NSObject+MTLComparisonAdditions.h - path - Mantle/NSObject+MTLComparisonAdditions.h - sourceTree - <group> - - C0ECB4C8D31A24B2C3CF9E1F - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + UIView+WebCacheOperation.m path - Pods-environment.h + SDWebImage/UIView+WebCacheOperation.m sourceTree <group> - C1DE7C20F35B97860D706B66 + BC5EAF24594607E38A7636C1 fileRef - BF9582E6D1D11AAE4C82790C + 244FECFEBCA55B4B22B48100 isa PBXBuildFile - C2F2F561C27931B0CFA6A5AD - - fileRef - 34A0A9B27EF8487D6B85D039 - isa - PBXBuildFile - - C32A44B3BB593CF09E391F55 + BCE701251DF69F3F6F83B283 includeInIndex 1 @@ -5739,32 +5669,13 @@ lastKnownFileType sourcecode.c.objc name - SVWebViewControllerActivityChrome.m + AFHTTPRequestOperation.m path - SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m + AFNetworking/AFHTTPRequestOperation.m sourceTree <group> - C3756A16C38B7B1455914F49 - - fileRef - 7F71FB5470A79B51285AB34E - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - C3A33DB3AF5947A220C22474 - - fileRef - E1AD240F7028E1A092DCBEDC - isa - PBXBuildFile - - C50CBBB3320CBFC5FA8EA34D + BD21D8D91FCD26B8FAA257D1 includeInIndex 1 @@ -5773,20 +5684,20 @@ lastKnownFileType sourcecode.c.h name - AFNetworkActivityIndicatorManager.h + MJRefreshLegendFooter.h path - UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshLegendFooter.h sourceTree <group> - C55BDF5794C4C27E7A69A131 + BDDAD42C906683E324BA0911 fileRef - 575254127992AC3095637C85 + 96D4C1202D853D89B6302975 isa PBXBuildFile - C56F74D0AAB1C57653DA7F7A + BEA878B43A1467881A0B05D9 includeInIndex 1 @@ -5795,13 +5706,13 @@ lastKnownFileType sourcecode.c.h name - SWUtilityButtonTapGestureRecognizer.h + AFURLRequestSerialization.h path - SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h + AFNetworking/AFURLRequestSerialization.h sourceTree <group> - C5B29E7C81D4C77334248AA5 + BF004A408F3B27648FC59EC5 includeInIndex 1 @@ -5810,41 +5721,68 @@ lastKnownFileType sourcecode.c.h name - MJRefreshFooterView.h + UIImage+GIF.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h + SDWebImage/UIImage+GIF.h sourceTree <group> - C684423B9F0BCABE69332621 + C024D03913DF6EA5F878EFBE includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - FMDatabasePool.h + SVModalWebViewController.m path - src/fmdb/FMDatabasePool.h + SVWebViewController/SVModalWebViewController.m sourceTree <group> - C7236453AB69F2D92E70EC3B + C05C776692313812C3B4C2B4 - includeInIndex - 1 + fileRef + A119B53B64AF254F3DAF7205 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - path - Pods-AFNetworking-prefix.pch - sourceTree - <group> + PBXBuildFile + + C180BFF717BA5B8A67FFFE53 + + fileRef + C87C1D1B8FEAEBDCBE6C0C34 + isa + PBXBuildFile + + C28A118CD27C32728F03EB4F + + fileRef + B545404BB9E4DE3AFE749CBB + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + C2DB8617DE738C880377729C + + fileRef + B6D1E6F496CA960B50C331AD + isa + PBXBuildFile + + C2F2047F3A09455A94637A0D + + fileRef + B1F4FF21E45DFB02CAA6DBFF + isa + PBXBuildFile - C834791111C32E19511470D4 + C37FB122D4C23F324D71F0B7 includeInIndex 1 @@ -5853,66 +5791,42 @@ lastKnownFileType sourcecode.c.h name - MTLModel.h + UIImageView+HighlightedWebCache.h path - Mantle/MTLModel.h + SDWebImage/UIImageView+HighlightedWebCache.h sourceTree <group> - C8409304ABBDB3DE6635DB18 - - explicitFileType - archive.ar - includeInIndex - 0 - isa - PBXFileReference - path - libPods-SVProgressHUD.a - sourceTree - BUILT_PRODUCTS_DIR - - C8519CEEEF547AA9EE9D9271 + C3DEEAC6027984E1CCDE0A79 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - NSData+ImageContentType.m + UIRefreshControl+AFNetworking.h path - SDWebImage/NSData+ImageContentType.m + UIKit+AFNetworking/UIRefreshControl+AFNetworking.h sourceTree <group> - C885E60E6C8BD0A926570AF5 + C43EF4B93C5AC394AA76BC4F fileRef - 9E3CADF4D34242891C1E4725 + 161E62A9465A051CE58E5A0D isa PBXBuildFile - C932222C6328C3C84A162E3B + C4B0E3A997266DC86B2EF69E - children - - 633433250CA4F0951A356573 - 6D0FE93D2F53E6F9BE778A43 - 514D95EC1DE6E7F84DFD7077 - 0BC85B368F05F28D8AC1E014 - E62260C013619653C0C58B3D - 379D3CCD2FFBB2698E6A788E - + fileRef + 7DDB2A7EFEFD7D66D7D642B4 isa - PBXGroup - name - extobjc - sourceTree - <group> + PBXBuildFile - CA15D003C21CFCA2294BE5DB + C50B6D365BE90FDCF50B69A7 includeInIndex 1 @@ -5921,60 +5835,137 @@ lastKnownFileType sourcecode.c.objc name - SVWebViewControllerActivitySafari.m + UIView+MJExtension.m path - SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m + MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m sourceTree <group> - CAC00BB41401121BDC44E7E5 + C5774AA1A8FFF8FE8C6497E3 - includeInIndex - 1 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + YES + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + ONLY_ACTIVE_ARCH + YES + STRIP_INSTALLED_PRODUCT + NO + isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - Pods-Mantle.xcconfig - sourceTree - <group> + XCBuildConfiguration + name + Debug - CB6E38F58D69B7640B71B0D2 + C582AF7193A0AFF4C3D19FF8 fileRef - 9FB2FE90C5104F065B94608B + B5A085F43F7BA05E99922AEF isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - CC2EB1431A8BBB896B00A972 + C6DB08D280F61DACBF4D3AAD fileRef - F0D0B8FA1F237AF39207A58C + CFC410BCCACA205D410F13B3 isa PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + - CCD36D89B4623217A9BB4F11 + C7C42E7283B016DEFAC91CF2 - containerPortal - 003A31C6AADD74836B88341F - isa - PBXContainerItemProxy - proxyType + includeInIndex 1 - remoteGlobalIDString - 0D2F41CC755DC941A9D3282F - remoteInfo - Pods-SVWebViewController + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefreshComponent.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshComponent.h + sourceTree + <group> - CCD59E2FDDA491F626635409 + C7F772BBF7D7D5FEA9CE8ABA fileRef - 25BC2970B45A7D905D5F19BB + C50B6D365BE90FDCF50B69A7 isa PBXBuildFile - CE4B7722CAC9ED8DD0114663 + C847355BA3DEBAACBBE7DEAD + + isa + PBXTargetDependency + name + Pods-AFNetworking + target + 70CDF1B0FB6B3C3599FC5BDD + targetProxy + E6C8436A64906E61F0ACBEB8 + + C87C1D1B8FEAEBDCBE6C0C34 includeInIndex 1 @@ -5983,27 +5974,33 @@ lastKnownFileType sourcecode.c.h name - SWCellScrollView.h + SWTableViewCell.h path - SWTableViewCell/PodFiles/SWCellScrollView.h + SWTableViewCell/PodFiles/SWTableViewCell.h sourceTree <group> - D003F4EA52D0953E6AF73AF6 + C8F8ADAD27B79FF7562751D5 - fileRef - F0D0B8FA1F237AF39207A58C + containerPortal + 81D979F3E87416F4B4516D5F isa - PBXBuildFile + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + D68D040FBA01D62A8E3F21CF + remoteInfo + Pods-SVProgressHUD - D059787EBF44D5A0BC02F87F + C958D94D49E6ECE38DDFD29E fileRef - 635165301CE75B15CC16EE35 + 836D5E6C17DB983DF1634A69 isa PBXBuildFile - D09A62E8A6854C6E80B36152 + C9AF7C2EC59374EA95C53E40 includeInIndex 1 @@ -6012,20 +6009,13 @@ lastKnownFileType sourcecode.c.objc name - AFURLRequestSerialization.m + FBShimmeringView.m path - AFNetworking/AFURLRequestSerialization.m + FBShimmering/FBShimmeringView.m sourceTree <group> - D0A9652EBFFEC41C2F239263 - - fileRef - C56F74D0AAB1C57653DA7F7A - isa - PBXBuildFile - - D0C3135DA2BA3C019BAF2DCF + CA17115300376D75D26440F2 includeInIndex 1 @@ -6034,43 +6024,41 @@ lastKnownFileType sourcecode.c.h name - NSValueTransformer+MTLPredefinedTransformerAdditions.h + AFURLSessionManager.h path - Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h + AFNetworking/AFURLSessionManager.h sourceTree <group> - D0C6BE4F0F08EEF1AD4759BF + CA80C3A4D5A7270178FB5B66 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - MJRefreshHeaderView.m + sourcecode.c.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m + Pods-environment.h sourceTree <group> - D139BE864E7331A490A31F83 + CADA31036DC6EAB82967ECA4 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIProgressView+AFNetworking.m + MJRefreshFooter.h path - UIKit+AFNetworking/UIProgressView+AFNetworking.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooter.h sourceTree <group> - D2504912E25654781C939724 + CBF465FCFAE67B936CD7999F includeInIndex 1 @@ -6083,150 +6071,105 @@ sourceTree <group> - D2AE7F8D94E0B80BFA8F603A + CC1C67ABB4980F1129CC1ABF + + fileRef + 9643F891DE5CA3D4BB9E89D6 + isa + PBXBuildFile + + CC488329354081651F356099 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SWCellScrollView.m + MJRefreshConst.h path - SWTableViewCell/PodFiles/SWCellScrollView.m + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h sourceTree <group> - D2F8B867A02B15A8D833E6E7 + CD2CFD88AEC03BECA1A6CE00 + includeInIndex + 1 isa PBXFileReference lastKnownFileType - wrapper.framework - name - Security.framework + text.xcconfig path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Security.framework + Pods-SWTableViewCell-Private.xcconfig sourceTree - DEVELOPER_DIR + <group> - D405E1711A624A1719E082D2 + CD33ACF6C201881D46574802 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - UIView+MJExtension.m + NSValueTransformer+MTLPredefinedTransformerAdditions.h path - MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m + Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h sourceTree <group> - D568513A73D383D812B92361 - - fileRef - 57FA31C7342E4A8693201F60 - isa - PBXBuildFile - - D6558E03D7E8E7369D57D62A - - buildConfigurationList - FB388FD7B6E8D0EC4EFA5D58 - buildPhases - - 7E4DEC9F5579FF9E6012310D - 7E4322D8FA302168CB5CFFB2 - B7B2983751AA2DB871BE4F87 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - Pods-MJRefresh - productName - Pods-MJRefresh - productReference - 3CF9B45DDE34993A3FD50533 - productType - com.apple.product-type.library.static - - D6D6D28D37442BAAA468A18D - - fileRef - 8DCB4D41A489D80F71A9D029 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - D76DB4316F4A2BBC29B6E2E7 - - fileRef - 222F9FE85B6C3B610407F404 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - D79E955756AA01C364E52FE8 - - fileRef - 379D3CCD2FFBB2698E6A788E - isa - PBXBuildFile - - D88A7258E9903DD9091947B3 + CD4A5D420DBD6E66570EB0DF - fileRef - 7E1CD1AAAE86E52A5E55A54C + containerPortal + 81D979F3E87416F4B4516D5F isa - PBXBuildFile + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 577435415A323B682400D54D + remoteInfo + Pods-Mantle - D8F1FDF888DD2382AECC30C3 + CD8349A3F4BF18C038579DC6 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - SWTableViewCell.m + NSError+MTLModelException.h path - SWTableViewCell/PodFiles/SWTableViewCell.m + Mantle/NSError+MTLModelException.h sourceTree <group> - D9813C4AEDC5894EE1B3451F + CD8984A1672C44CD6FA8B455 + + fileRef + D1404AB4AA7E3E03EECDBA21 + isa + PBXBuildFile + + CD8D1F166166902627915896 includeInIndex 1 isa PBXFileReference - lastKnownFileType - sourcecode.c.h name - SVWebViewControllerActivityChrome.h + SVWebViewControllerActivitySafari-iPad.png path - SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png sourceTree <group> - D9CF805123DCF31BD815B4BB + CD9137A020694A9525101FB3 includeInIndex 1 @@ -6234,19 +6177,17 @@ PBXFileReference lastKnownFileType sourcecode.c.h - name - AFHTTPSessionManager.h path - AFNetworking/AFHTTPSessionManager.h + Pods-MJRefresh-prefix.pch sourceTree <group> - DB34CB5D53D03543A81CD43D + CDE387D2836914F846D77F58 buildConfigurations - B9011D79C925C7A071C4D24A - B37092B574E47123FA62F48A + DEFB338749E8A45D995F47E6 + 73538EEEADB1058CDECEF95C defaultConfigurationIsVisible 0 @@ -6255,29 +6196,69 @@ isa XCConfigurationList - DB5A704B96D04FBF9549DA3B + CE3EDC27205A31036EFD90B8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-MJRefresh.xcconfig + sourceTree + <group> + + CF1457A202FBD3FC56768EB1 + + fileRef + 017B14BC9F461EE2E432473F + isa + PBXBuildFile + + CF29DC3C94D7344966D490D7 fileRef - 2D3A6D4FA7D703DF6C8A7450 + 7D3DFDFFF6AA0103584F02A3 isa PBXBuildFile - DC332F6A26805C987939E79B + CFC410BCCACA205D410F13B3 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - FMDatabaseQueue.h + MTLReflection.m path - src/fmdb/FMDatabaseQueue.h + Mantle/MTLReflection.m sourceTree <group> - DC50FB9ACAC3D68AE360BF5F + CFD8C4C6DCFA8E784A826866 + + fileRef + 86EB9A08B9B6E1267BD57145 + isa + PBXBuildFile + + CFDFBCB4455A036E8112FA54 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods.a + sourceTree + BUILT_PRODUCTS_DIR + + D1404AB4AA7E3E03EECDBA21 includeInIndex 1 @@ -6286,13 +6267,20 @@ lastKnownFileType sourcecode.c.objc name - UIScrollView+MJExtension.m + SVProgressHUD.m path - MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m + SVProgressHUD/SVProgressHUD.m sourceTree <group> - DC6959F6B0389433A846F09B + D14C1D38F4697374B779ED66 + + fileRef + 86EB9A08B9B6E1267BD57145 + isa + PBXBuildFile + + D15DE4AB72E69F69799EE587 includeInIndex 1 @@ -6301,107 +6289,158 @@ lastKnownFileType sourcecode.c.h name - MJRefreshHeaderView.h + SDWebImageDownloaderOperation.h path - MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h + SDWebImage/SDWebImageDownloaderOperation.h sourceTree <group> - DCFD647287A6F3DEE53059EB + D21098B980D4B99BBE4EBCB0 + includeInIndex + 1 isa - PBXTargetDependency + PBXFileReference + lastKnownFileType + sourcecode.c.objc name - Pods-Mantle - target - EA053313AC9B201518E824AF - targetProxy - 2C5859609EFA12DBF8041624 + NSMutableArray+SWUtilityButtons.m + path + SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m + sourceTree + <group> - DD72EA41B8BD0DC998006611 + D2D8B6939934DB2DEE11DAA4 - children - - A98547DB16A7BA47C179FA8D - + fileRef + 0FB12360D6BEA877E224ADA1 + isa + PBXBuildFile + + D2FB14DD6996DA5416AAD4A7 + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + NO + ENABLE_NS_ASSERTIONS + NO + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PREPROCESSOR_DEFINITIONS + + RELEASE=1 + + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + STRIP_INSTALLED_PRODUCT + NO + VALIDATE_PRODUCT + YES + isa - PBXGroup + XCBuildConfiguration name - Frameworks - sourceTree - <group> + Release - DD8F1007201AC5D9E168DE32 + D3C132A00F42F9F9F8C19476 fileRef - AC6F1AA84590ACFF61BAAD60 + AF470BA25B4AEDD098801E35 isa PBXBuildFile - DDA12FA0A07A90423DAC2DAF + D3CE7AF1CEF858F829394CC8 fileRef - F0D0B8FA1F237AF39207A58C + 6813759A3D4B289309C65CC8 isa PBXBuildFile - DDCF5122548DF51242583A68 + D4597DB6B6075E95AAE77F0F fileRef - D2F8B867A02B15A8D833E6E7 + A90F74085A3775EED69FD854 isa PBXBuildFile - DE2CEF2D7F7D4D643900FCE5 + D4C3346C10EF1BC04F58673E fileRef - 846C466F2240C4C93CD6C24C + AD8E2E838E28925DC440CEB5 isa PBXBuildFile - DF3027E5A4AB1DC95FB5EA9D + D4DB003F66931D9E0941ED7A fileRef - B3C85AC9AFD3294AE7C56106 + 878766D5C2D02668B15FED39 isa PBXBuildFile - DFFAC01197AE918D4C9DFD66 + D57B5B10F635C06744DD1C8C - fileRef - A95D82B9D1D2BEFE3D2DAB00 isa - PBXBuildFile + PBXTargetDependency + name + Pods-MJRefresh + target + 6CE6AFC3F8CD70241EF59AB9 + targetProxy + 231F0312ABE7BE7661B60810 - E047647F1042A54423864302 + D644D20C4E3C77F3E6A6C450 fileRef - C5B29E7C81D4C77334248AA5 + C37FB122D4C23F324D71F0B7 isa PBXBuildFile - E0E9DDEE088E41C8CF4C003D - - includeInIndex - 1 - isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - Pods.release.xcconfig - sourceTree - <group> - - E0F50EA1905F2A7094812973 + D68D040FBA01D62A8E3F21CF buildConfigurationList - DB34CB5D53D03543A81CD43D + F46C4F7613F3810FDE30F27C buildPhases - 273E8CC1B7A1DF52553B76D7 - 26D05A8A28DCD60C1CA8EC7E - 59C305ABE1A25B9CB62E5D80 + AEE0860D1763213A0AFE6929 + DBC2E3B10BD01C44AB7DCF06 + 7216C951E31F705D623F936A buildRules @@ -6410,33 +6449,32 @@ isa PBXNativeTarget name - Pods-AFNetworking + Pods-SVProgressHUD productName - Pods-AFNetworking + Pods-SVProgressHUD productReference - 47C11AD21FEAD8A5CAA86FC0 + 7BF20CB8E89FE06EA149B817 productType com.apple.product-type.library.static - E11A8E6E65928AF83EDA8DEF + D6B3D84E7C40115C6F32A34A - children - - 404F813C33EA2B5B22382ED6 - 585F33F75FFBDB5A2D635BC5 - 16BE2A454A10A0FFBBFDD201 - C7236453AB69F2D92E70EC3B - + includeInIndex + 1 isa - PBXGroup + PBXFileReference + lastKnownFileType + text name - Support Files + Podfile path - ../Target Support Files/Pods-AFNetworking + ../Podfile sourceTree - <group> + SOURCE_ROOT + xcLanguageSpecificationIdentifier + xcode.lang.ruby - E1AD240F7028E1A092DCBEDC + D6CB1F2691B16FB9B1701C9C includeInIndex 1 @@ -6445,44 +6483,54 @@ lastKnownFileType sourcecode.c.h name - AFSecurityPolicy.h + UIActivityIndicatorView+AFNetworking.h path - AFNetworking/AFSecurityPolicy.h + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h sourceTree <group> - E29DFA8F7F2E89354CECB6C3 + D7880C07AA847B66E17F9F0A - includeInIndex - 1 + fileRef + 12F59C763943F4966B45BFB4 isa - PBXFileReference - name - SVWebViewControllerActivityChrome-iPad@2x.png - path - SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png - sourceTree - <group> + PBXBuildFile + + D7989D1C30764BC7F9C80624 + + buildConfigurations + + 1A142289B602EBE69D1249B4 + 6588A0868BCC4183CA3B6A86 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList - E2D8E0AC81FFF45B5643EB4C + D7FD3BD46B1CABD2F2AE50EE buildActionMask 2147483647 files - A0EB66A861D7F9BE99167595 - F8219A50BB91E25BFDDAA0AD - 37B990D486EB877EA36E8C25 - F6E91A553C49F4862B78C4F1 - D76DB4316F4A2BBC29B6E2E7 - 613007691409B9A6751D3737 + 1EE3FDF8E269928BE3CA0FD8 isa - PBXSourcesBuildPhase + PBXFrameworksBuildPhase runOnlyForDeploymentPostprocessing 0 - E32EAF52CDE8541AAA86F6A0 + D9AC5E5A7FD9CD228B2E0E9E + + fileRef + 1C92FEB632B8CFF036BFBDBE + isa + PBXBuildFile + + D9BC1825A20D16596316B079 includeInIndex 1 @@ -6491,651 +6539,545 @@ lastKnownFileType sourcecode.c.objc name - SDWebImageCompat.m + SVWebViewController.m path - SDWebImage/SDWebImageCompat.m + SVWebViewController/SVWebViewController.m sourceTree <group> - E3C180F70C4829EC3E7C8741 + DA2341FB44DCAD22E128F6E1 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + EXTRuntimeExtensions.h path - Pods-FMDB-Private.xcconfig + Mantle/extobjc/EXTRuntimeExtensions.h sourceTree <group> - E45958CE3CBD11F1707F441C - - fileRef - BFCFD346B7D3A14BA3BA069B - isa - PBXBuildFile - - E4F17FDA9A2004644DE362D1 + DA466A036868C7B919F43216 - fileRef - DC332F6A26805C987939E79B + children + + 35A704D283AC845C1F7D3779 + isa - PBXBuildFile + PBXGroup + name + Resources + sourceTree + <group> - E62260C013619653C0C58B3D + DACCC598E67DEDF2B964152C - includeInIndex - 1 + children + + CFDFBCB4455A036E8112FA54 + 8FE9BF5050F6FC295DDC2348 + 942FFA243C26063337A25F3C + 9CEFCB11A62BDBC8D6BA730C + 079C8DABD90354174F62579C + 7BF20CB8E89FE06EA149B817 + 7B223D387702971DA08CD4D7 + A6AD37D8B00F8892C4806CF5 + 5EEA0F052F38C601F48496AB + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - EXTScope.m - path - Mantle/extobjc/EXTScope.m + Products sourceTree <group> - E6D38302A5F37DB5658C41BB + DBC2E3B10BD01C44AB7DCF06 buildActionMask 2147483647 files - 21E3949570212F296A98F3C3 + A087CA9E108E9E21024C9172 + F470B44B4B1CE055518D6169 isa - PBXSourcesBuildPhase + PBXFrameworksBuildPhase runOnlyForDeploymentPostprocessing 0 - E7926F44F6DD7675C4CAB292 + DC8F3FCA873B6D58BD536AEC - includeInIndex - 1 + buildActionMask + 2147483647 + files + + CFD8C4C6DCFA8E784A826866 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - MTLValueTransformer.h - path - Mantle/MTLValueTransformer.h - sourceTree - <group> + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 - E8D5D18DAA535CA6B08AA393 + DD032B17044D0D8A8AC9BE55 - includeInIndex - 1 + fileRef + 0249F3F32ECE11C31DA2A281 isa - PBXFileReference - lastKnownFileType - text.xcconfig - path - Pods-SVWebViewController-Private.xcconfig - sourceTree - <group> + PBXBuildFile - E96F46F8A984911D7538CA63 + DDF77BFDA744563444169FA8 - includeInIndex - 1 + fileRef + 3D75C65180AD411A4D968C06 isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - UIImageView+WebCache.h - path - SDWebImage/UIImageView+WebCache.h - sourceTree - <group> + PBXBuildFile - E9A68AA93E6B24526C1517E5 + DEA466424653E70B8209013D - includeInIndex - 1 + children + + 0C2A438B42DC07E1A2B8E51B + 509DA73C428A64C02BF0B75C + D6CB1F2691B16FB9B1701C9C + 73F06571B260553C31103BC9 + 878766D5C2D02668B15FED39 + 8E04C8067D58420429F849D3 + 0FB12360D6BEA877E224ADA1 + A46D26FE67677E1BCCEC9648 + E3AB4479A70BBD8BEEB85735 + FB68A1B10C381EEFC0E105CA + B113FB03415126F4B88F2139 + 7CFB13291239474A4401636E + 70056B349FEB6A757345F167 + C3DEEAC6027984E1CCDE0A79 + 84FE7E230D2FC3B77F845364 + 12F59C763943F4966B45BFB4 + 2B388C41DBF1EEF5D24C15BD + isa - PBXFileReference - lastKnownFileType - sourcecode.c.h + PBXGroup name - SDWebImageOperation.h - path - SDWebImage/SDWebImageOperation.h + UIKit sourceTree <group> - EA053313AC9B201518E824AF + DEF1C98505E86E50864C1FC3 - buildConfigurationList - 31ED12F5CEA9A23F5663038A - buildPhases + children - 73866FD56D89AA5A3F622874 - 06B18C667B34A3836288B3E6 - 9F745963084D8E9E216392E2 + D6B3D84E7C40115C6F32A34A + 28008C3054989A0ECB72D888 + AE9AE9605C535FD64A7E4136 + DACCC598E67DEDF2B964152C + 4B8BFDE18D1FCA43E9E5BB32 - buildRules - - dependencies - isa - PBXNativeTarget - name - Pods-Mantle - productName - Pods-Mantle - productReference - 0DDB7686E187F3FC19D520AC - productType - com.apple.product-type.library.static + PBXGroup + sourceTree + <group> + + DEFB338749E8A45D995F47E6 + + baseConfigurationReference + 51CF2F2FD419BD460AFE8089 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug - EA063A5FA969AA2475F21918 + E0064455F987AA18ECC111F4 - children - - 94D197FD4192DB667B6E9A51 - 34A0A9B27EF8487D6B85D039 - + fileRef + 03161642A68CD1941BFCCA57 isa - PBXGroup - name - Reachability - sourceTree - <group> + PBXBuildFile - EA98CE819CDC3A1C462DA862 + E05AA74B831F33187A80AFB2 - includeInIndex - 1 isa PBXFileReference lastKnownFileType - text.xcconfig + wrapper.framework + name + ImageIO.framework path - Pods-SDWebImage.xcconfig + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/ImageIO.framework sourceTree - <group> - - EAABEB6BACA94FCEFBA11DFD - - fileRef - A8C971E5B6D1D6B34B5C9A1B - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - + DEVELOPER_DIR - EB111D63CDEEB43E08195847 + E19E6C14D588684CC18224AE - includeInIndex - 1 + children + + 4D6BEC56F9F00A366232143C + 76B7796A1EB6299CE260128F + 4436096DFAA117FC404F08AE + A90F74085A3775EED69FD854 + C9AF7C2EC59374EA95C53E40 + FB82277D905C9A6A87D36F9E + isa - PBXFileReference - lastKnownFileType - wrapper.plug-in + PBXGroup name - SVProgressHUD.bundle + Shimmer path - SVProgressHUD/SVProgressHUD.bundle + Shimmer sourceTree <group> - EB394718051F19102CEA333B + E1D5FA92C24CAD6F429DBC36 fileRef - BB46AB577CB11E2DEC496B53 + 9D641BF01B9DCB3759BB7650 isa PBXBuildFile - EBB725B945B1732ECF3A9006 + E280590722CB57FBB839C5F4 + + containerPortal + 81D979F3E87416F4B4516D5F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 1E803AD000DE2CF76ED8A078 + remoteInfo + Pods-SVWebViewController + + E2B6D58F73771CA96B3C2820 buildActionMask 2147483647 files - C55BDF5794C4C27E7A69A131 - 7F117C1078DB1AD4F3B4FE11 - A2EBB8311F6F713C23AA9103 - DF3027E5A4AB1DC95FB5EA9D - 9F4821AF45F02268E44D0C1D - 9EFF5CE823942564335B0542 - 92D1A0BBD0D2B1EA721B084C - 65D19C9FCE68CD267930EF33 - 662A98C63D4A25AEDD5B5EC8 - 379C4A4E6343D5622A38206E - B0F31E9D675CDD8EF475F4A7 - 4639EC1DFC9BDEE03FCECD28 - 2E82A19ADA9D6FA582DFA1B8 - 6C883654D7A0A3023FD1840D - 5C59B57AC630CD73AB5E2D1E + D14C1D38F4697374B779ED66 isa - PBXHeadersBuildPhase + PBXFrameworksBuildPhase runOnlyForDeploymentPostprocessing 0 - ECDFCA3A35CD6A95747B8E90 + E38AA2650B16052F84F74A50 includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.h + name + SDWebImageOperation.h path - Pods.debug.xcconfig + SDWebImage/SDWebImageOperation.h sourceTree <group> - ECFFA56C6B3F8AC988E09B43 - - fileRef - A19B2B715041A76AD22B7BB7 - isa - PBXBuildFile - - EDA79BFF36ED8CC66472C4B4 + E39092337355ABB89F457406 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc - name - AFURLResponseSerialization.m + text.xcconfig path - AFNetworking/AFURLResponseSerialization.m + Pods-SWTableViewCell.xcconfig sourceTree <group> - EDCDF1F1A409A8EF63058261 - - fileRef - FD93687F5220E28F92C0D41E - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - EF04ADF8DBB1227D34EBBEEA + E3AB4479A70BBD8BEEB85735 includeInIndex 1 isa PBXFileReference lastKnownFileType - text + sourcecode.c.h name - Podfile + UIImageView+AFNetworking.h path - ../Podfile + UIKit+AFNetworking/UIImageView+AFNetworking.h sourceTree - SOURCE_ROOT - xcLanguageSpecificationIdentifier - xcode.lang.ruby - - EF1605A5BAD020789C0D6DCD - - buildConfigurations - - 24200E9BAE5616D614E3BA14 - 3886D77C2964260BA24AC311 - - defaultConfigurationIsVisible - 0 - defaultConfigurationName - Release - isa - XCConfigurationList + <group> - F02AEA09DBE0E12AF360F35D + E4CEE3D142701517931AC844 fileRef - 94D197FD4192DB667B6E9A51 + 3798DEA0FAA541D316F5FE1C isa PBXBuildFile - F0D0B8FA1F237AF39207A58C + E68153ED11688501908927F4 + buildActionMask + 2147483647 + files + + F21DD7368E6A3809F212B2BE + isa - PBXFileReference - lastKnownFileType - wrapper.framework - name - Foundation.framework - path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework - sourceTree - DEVELOPER_DIR + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 - F0DD19AA7C01867C1769DBE1 + E6C8436A64906E61F0ACBEB8 - includeInIndex - 1 + containerPortal + 81D979F3E87416F4B4516D5F isa - PBXFileReference - lastKnownFileType - sourcecode.c.h - name - NSArray+MTLManipulationAdditions.h - path - Mantle/NSArray+MTLManipulationAdditions.h - sourceTree - <group> + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 70CDF1B0FB6B3C3599FC5BDD + remoteInfo + Pods-AFNetworking - F19082954117D5EC4CBF111A + E775B6493ABD67E0B9F1A83E includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SDWebImageCompat.h + NSObject+MTLComparisonAdditions.m path - SDWebImage/SDWebImageCompat.h + Mantle/NSObject+MTLComparisonAdditions.m sourceTree <group> - F20B4E0EAAA530D24685A4E2 + E841AAF06ED6A0CAC0CC05ED includeInIndex 1 isa PBXFileReference lastKnownFileType - text.xcconfig + sourcecode.c.objc + name + MTLModel.m path - Pods-SVProgressHUD-Private.xcconfig + Mantle/MTLModel.m sourceTree <group> - F38473E10FE10739CC22000B - - fileRef - 8E7746C93B5A382A8BFB31C8 - isa - PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - - F3B157F0A7C5AE48DEF99006 - - fileRef - 290221507373808ABAA4054B - isa - PBXBuildFile - - F3B7C44428DC09B4933F043E - - buildActionMask - 2147483647 - files - - 531197FDF80BC84527CCAF02 - - isa - PBXFrameworksBuildPhase - runOnlyForDeploymentPostprocessing - 0 - - F3E77A78BED9A830D2670005 + E89A849D5C7F06D308A3B1A9 - includeInIndex - 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + wrapper.framework name - SWUtilityButtonView.m + QuartzCore.framework path - SWTableViewCell/PodFiles/SWUtilityButtonView.m + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/QuartzCore.framework sourceTree - <group> + DEVELOPER_DIR - F44EDFC44AEF1BC95DB7FA7D + E941B207D74922475F8D6E73 fileRef - 15C57B0A0D754AA9967330DF + BF004A408F3B27648FC59EC5 isa PBXBuildFile - F49B17CD5DB7BF511AD95FE0 + E9A7BB0F66E56933CE58368F fileRef - FC45931EABC40836F3C02FDB + CA17115300376D75D26440F2 isa PBXBuildFile - F5336FA18F2792224B01F5AD + EA8986163F9F6442BA8F993E fileRef - 971BBE7FBC532FD0C3684E99 + 701F96ACC76C74D7DBFE587B isa PBXBuildFile - F5AD41E8F4E3CBFFE9D0A6AD - - buildConfigurationList - 82D7942CFFB4B5F9A8039B0E - buildPhases - - E2D8E0AC81FFF45B5643EB4C - 0E941574580314BABC46EF00 - 59DD36BD9A4D804D5A701ED2 - - buildRules - - dependencies - - isa - PBXNativeTarget - name - Pods-FMDB - productName - Pods-FMDB - productReference - 0398B69338481EC817F6F6EB - productType - com.apple.product-type.library.static - - F5FB40E1554F5686F97998FA + EAF234E3AA32CB7DAE26A06F + includeInIndex + 1 isa PBXFileReference lastKnownFileType - wrapper.framework - name - QuartzCore.framework + text.xcconfig path - Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/QuartzCore.framework + Pods-SVWebViewController.xcconfig sourceTree - DEVELOPER_DIR - - F6CDC7E60CF17930F7262034 - - baseConfigurationReference - F20B4E0EAAA530D24685A4E2 - buildSettings - - ALWAYS_SEARCH_USER_PATHS - NO - COPY_PHASE_STRIP - NO - DSTROOT - /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 - GCC_PRECOMPILE_PREFIX_HEADER - YES - GCC_PREFIX_HEADER - Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO - INSTALL_PATH - $(BUILT_PRODUCTS_DIR) - IPHONEOS_DEPLOYMENT_TARGET - 7.0 - OTHER_LDFLAGS - - OTHER_LIBTOOLFLAGS - - PRODUCT_NAME - $(TARGET_NAME) - PUBLIC_HEADERS_FOLDER_PATH - $(TARGET_NAME) - SDKROOT - iphoneos - SKIP_INSTALL - YES - + <group> + + EB2A2DDC51A4FD1EBBF8BA79 + isa - XCBuildConfiguration + PBXTargetDependency name - Debug + Pods-Shimmer + target + 606339BB1F98D18E401A0055 + targetProxy + F6F4E9AB3AFDABFA6931ACA7 + + ED63151D6E956C666D9BD14F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLJSONAdapter.m + path + Mantle/MTLJSONAdapter.m + sourceTree + <group> + + EE34B75B8433DF4D70F5200D + + isa + PBXTargetDependency + name + Pods-SVWebViewController + target + 1E803AD000DE2CF76ED8A078 + targetProxy + E280590722CB57FBB839C5F4 - F6E91A553C49F4862B78C4F1 + EF5E0E26F44584766F139292 fileRef - FFF0E1F586F1C9698F168012 + 87D9BF752A70DA83F123E5E7 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - F7446765000306425A8653CB + F037D782B4ADF73E592EBDE5 - children - - 9AC054684C72878BFD1354BD - 54AF66B17C0AEFF7AE1E5828 - B49FB948DC12B27713617596 - EA063A5FA969AA2475F21918 - 060110539E4022EC7547DC8A - 76F2FB474F9C57ED0AB606BB - E11A8E6E65928AF83EDA8DEF - 071305CB59F3D8E013288619 - isa - PBXGroup + PBXFileReference + lastKnownFileType + wrapper.framework name - AFNetworking + Security.framework path - AFNetworking + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Security.framework sourceTree - <group> + DEVELOPER_DIR - F78D23F252315D98B9BE3FA6 + F095602FA7AC56B1A442458D fileRef - 7A75EF39F7B6094E98E9D58F + 335361E3B7EBFEF025533997 isa PBXBuildFile - F8219A50BB91E25BFDDAA0AD + F12F8D2E100E02797A7DC981 fileRef - 96B82497505EF98401B50E1D + 9E9D0D9F98C6F64688498FA0 isa PBXBuildFile - settings - - COMPILER_FLAGS - -DOS_OBJECT_USE_OBJC=0 - - F85DB5D3718ADE63303C06E7 + F21CB8120EF2D5EE038E22B2 - children - - 74ED67273EBDF1D93351D598 - F20B4E0EAAA530D24685A4E2 - 3FE2CB4E3BF724BF9DADD804 - 5161C757881F6F6873559967 - + includeInIndex + 1 isa - PBXGroup - name - Support Files + PBXFileReference + lastKnownFileType + sourcecode.c.objc path - ../Target Support Files/Pods-SVProgressHUD + Pods-SWTableViewCell-dummy.m sourceTree <group> - FA2858642D021A2940D97851 + F21DD7368E6A3809F212B2BE fileRef - 63B65631DCD63B55E53DCE03 + 6516689B190F38FDE8D21843 isa PBXBuildFile - FA9D9250626EDCE049F74048 + F2DF18E782B13E13F56BD784 includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - SVModalWebViewController.h + MJRefreshGifFooter.m path - SVWebViewController/SVModalWebViewController.h + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshGifFooter.m sourceTree <group> - FAFFA27183B7E1544DC2D54D + F3527D318E9B0FE341C39FD3 - buildActionMask - 2147483647 - files - - 3396072C759A0E898549D6E7 - 97959B6C405A6219826BAFBE - DE2CEF2D7F7D4D643900FCE5 - 96E033AF44F3F21FB871FC01 - 730266F29F62BC3EB931952F - 9C079AF4CCEEC69481F2BF10 - + fileRef + 288C837B4AE7323562462C3A isa - PBXSourcesBuildPhase - runOnlyForDeploymentPostprocessing - 0 + PBXBuildFile - FB388FD7B6E8D0EC4EFA5D58 + F462B3022831473DDF26EA18 + + fileRef + 8689A3CC3FD222309ED05ACB + isa + PBXBuildFile + + F46C4F7613F3810FDE30F27C buildConfigurations - 47BC372C33FCDDB0603FF870 - A19CDB887CB102ECC06C0723 + 0F41C1FA82ED1CE863ACA0D2 + B4D86A148E61EDCE85A2F9CF defaultConfigurationIsVisible 0 @@ -7144,17 +7086,24 @@ isa XCConfigurationList - FB392C3A7B8813F8724C2732 + F470B44B4B1CE055518D6169 + + fileRef + E89A849D5C7F06D308A3B1A9 + isa + PBXBuildFile + + F4A2225775DD229E3C63BECD fileRef - 6D6492CFDFC03E3EEED90937 + F037D782B4ADF73E592EBDE5 isa PBXBuildFile - FB6C8948A46CF245ECD20949 + F4CF5630FC9C35B1117974BD fileRef - 573C8CC99C8641490B222C89 + 4C8B4F9E0751276ACBFFACEA isa PBXBuildFile settings @@ -7163,7 +7112,67 @@ -DOS_OBJECT_USE_OBJC=0 - FC45931EABC40836F3C02FDB + F6093A0B5FB224E073CD4A9C + + fileRef + 95FF2B992C0CBC462AC1C0EF + isa + PBXBuildFile + + F615D1D36012176EAC77C67D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-Mantle-dummy.m + sourceTree + <group> + + F684B190D03659D4947FEA45 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + MobileCoreServices.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/MobileCoreServices.framework + sourceTree + DEVELOPER_DIR + + F6F4E9AB3AFDABFA6931ACA7 + + containerPortal + 81D979F3E87416F4B4516D5F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 606339BB1F98D18E401A0055 + remoteInfo + Pods-Shimmer + + F722582AF97F8BC79D022EB9 + + fileRef + 53CF4E2FFFD543ABD0F1621C + isa + PBXBuildFile + + F99B71AC8E9B4C2925D0F0BF + + fileRef + 15C59580BF2B4473B05F415D + isa + PBXBuildFile + + F9BA8200CBE82E1229395A4D includeInIndex 1 @@ -7178,37 +7187,54 @@ sourceTree <group> - FC51B49E4686DFD82E09DE0B + F9D859481550E0BAAFC49F8D + + buildActionMask + 2147483647 + files + + D3C132A00F42F9F9F8C19476 + BC3B5779BE0E0FCD39A14E06 + 6B37248339C21DF24CD921DE + C180BFF717BA5B8A67FFFE53 + C05C776692313812C3B4C2B4 + C4B0E3A997266DC86B2EF69E + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + FA0452B54E39A5441282340D baseConfigurationReference - E3C180F70C4829EC3E7C8741 + 4D975F3E0C5580B245740BA7 buildSettings ALWAYS_SEARCH_USER_PATHS NO COPY_PHASE_STRIP - NO + YES DSTROOT /tmp/xcodeproj.dst - GCC_DYNAMIC_NO_PIC - NO - GCC_OPTIMIZATION_LEVEL - 0 GCC_PRECOMPILE_PREFIX_HEADER YES GCC_PREFIX_HEADER - Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch - GCC_PREPROCESSOR_DEFINITIONS - - DEBUG=1 - $(inherited) - - GCC_SYMBOLS_PRIVATE_EXTERN - NO + Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch INSTALL_PATH $(BUILT_PRODUCTS_DIR) IPHONEOS_DEPLOYMENT_TARGET 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + OTHER_LDFLAGS OTHER_LIBTOOLFLAGS @@ -7221,66 +7247,130 @@ iphoneos SKIP_INSTALL YES + VALIDATE_PRODUCT + YES isa XCBuildConfiguration name - Debug + Release + + FA1529D54F26EFCAE13119BE + + fileRef + 2BA319B679FD7E5367F430C6 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + FA558F36CA5D6AE7D715CF7A + + fileRef + 1740A3C059CD9E1542403D15 + isa + PBXBuildFile - FC5FC75F692847F3591B34B3 + FA622950AEB141300BCA6B1F includeInIndex 1 isa PBXFileReference lastKnownFileType - text.script.sh + sourcecode.c.h + name + UIButton+WebCache.h path - Pods-resources.sh + SDWebImage/UIButton+WebCache.h sourceTree <group> - FC77BBB341E0605E8ED130FB + FAA80B71B5EAE806B91F3C3A fileRef - A6D689B150BE62B7DB1AC767 + 86EB9A08B9B6E1267BD57145 isa PBXBuildFile - FD317A4CDFFEF6932C841E62 + FB68A1B10C381EEFC0E105CA includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.h + sourcecode.c.objc name - UIImage+MultiFormat.h + UIImageView+AFNetworking.m path - SDWebImage/UIImage+MultiFormat.h + UIKit+AFNetworking/UIImageView+AFNetworking.m sourceTree <group> - FD93687F5220E28F92C0D41E + FB82277D905C9A6A87D36F9E - includeInIndex - 1 + children + + 52216402BFA370AED72D91F1 + 766E6FD13340EAC7CA2A74C0 + 5E76D0C8307E26EBB442C355 + 60217EF2C452852C1A0BAB32 + isa - PBXFileReference - lastKnownFileType - sourcecode.c.objc + PBXGroup name - SDWebImageManager.m + Support Files path - SDWebImage/SDWebImageManager.m + ../Target Support Files/Pods-Shimmer sourceTree <group> - FDAFE1F6255ECC888D7503AB + FB840FFD2E5B875EC18E84DE + + fileRef + 22E579B322935331734637C9 + isa + PBXBuildFile + + FB8D9C35B856FEED38800CB1 + + buildActionMask + 2147483647 + files + + 84A9291CE1BE9DD63DB2034A + 8ABA1813E160CE5AB0761F51 + E4CEE3D142701517931AC844 + E1D5FA92C24CAD6F429DBC36 + FA558F36CA5D6AE7D715CF7A + 5DFCBC9D949176E5760EC64E + 6C9BB6BBF80FB04842296734 + 0CD662ED08D8060D2C191872 + 842CCB76DC43252D77BC0631 + 4850BE745D5CA828C6557D72 + 59CCB50AEA5DFB9086E74FAE + F3527D318E9B0FE341C39FD3 + C2F2047F3A09455A94637A0D + CF1457A202FBD3FC56768EB1 + 08790C72DA11E17D2FBBCF0D + A93E13864D80CA2BBDF0CE3B + 038E0DFD617BDE9429BF052D + 06EFFA518FDEBA01C2EE99EE + 86E430012FC510D92AFD64FF + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + FBC45023CA1F858225841F8C fileRef - AADE27D38FBFB33465D0DA5F + 51AFD4B392A31A2289544A18 isa PBXBuildFile settings @@ -7289,37 +7379,63 @@ -DOS_OBJECT_USE_OBJC=0 - FE4113033936F46AED1AC492 + FC41A5A6C2DA7175CC3736A2 fileRef - 217FA4FB15D4EDE83A84233D + 7E60A67D22F82309B3B23922 isa PBXBuildFile - FED8EC57D00423F3832AA2A9 + FC6DA76B60E9169D68FB7BCB fileRef - AF131B236DD5AB2E742ADEF2 + 516C932F9D2EA6FCFA72DA5C isa PBXBuildFile - FFF0E1F586F1C9698F168012 + FD73A2A295E8C736206A0CFB includeInIndex 1 isa PBXFileReference lastKnownFileType - sourcecode.c.objc + sourcecode.c.h name - FMDatabaseQueue.m + UIImageView+WebCache.h path - src/fmdb/FMDatabaseQueue.m + SDWebImage/UIImageView+WebCache.h sourceTree <group> + FDDB69BCEA27A3D2EAF6260B + + fileRef + 815759C5B0D9D8181BED265B + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + FEAE6DA63CEC5559503A25DA + + fileRef + E38AA2650B16052F84F74A50 + isa + PBXBuildFile + + FEEA599D4AD5EEB6BFEE8A7D + + fileRef + BCE701251DF69F3F6F83B283 + isa + PBXBuildFile + rootObject - 003A31C6AADD74836B88341F + 81D979F3E87416F4B4516D5F diff --git a/iOSStudy/Pods/SDWebImage/README.md b/iOSStudy/Pods/SDWebImage/README.md index 9bbcca5..771c627 100644 --- a/iOSStudy/Pods/SDWebImage/README.md +++ b/iOSStudy/Pods/SDWebImage/README.md @@ -4,6 +4,8 @@ Web Image [![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) [![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) [![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) +[![Dependency Status](https://www.versioneye.com/objective-c/sdwebimage/3.3/badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/3.3) +[![Reference Status](https://www.versioneye.com/objective-c/sdwebimage/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/references) This library provides a category for UIImageView with support for remote images coming from the web. @@ -35,11 +37,11 @@ Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SD How To Use ---------- -API documentation is available at [http://hackemist.com/SDWebImage/doc/](http://hackemist.com/SDWebImage/doc/) +API documentation is available at [CocoaDocs - SDWebImage](http://cocoadocs.org/docsets/SDWebImage/) ### Using UIImageView+WebCache category with UITableView -Just #import the UIImageView+WebCache.h header, and call the setImageWithURL:placeholderImage: +Just #import the UIImageView+WebCache.h header, and call the sd_setImageWithURL:placeholderImage: method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be handled for you, from async downloads to caching management. @@ -60,9 +62,9 @@ handled for you, from async downloads to caching management. reuseIdentifier:MyIdentifier] autorelease]; } - // Here we use the new provided setImageWithURL: method to load the web image - [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] - placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; + // Here we use the new provided sd_setImageWithURL: method to load the web image + [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; cell.textLabel.text = @"My Text"; return cell; @@ -75,10 +77,10 @@ With blocks, you can be notified about the image download progress and whenever has completed with success or not: ```objective-c -// Here we use the new provided setImageWithURL: method to load the web image -[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] - placeholderImage:[UIImage imageNamed:@"placeholder.png"] - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}]; +// Here we use the new provided sd_setImageWithURL: method to load the web image +[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"] + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {... completion code here ...}]; ``` Note: neither your success nor failure block will be call if your image request is canceled before completion. @@ -93,19 +95,18 @@ Here is a simple example of how to use SDWebImageManager: ```objective-c SDWebImageManager *manager = [SDWebImageManager sharedManager]; -[manager downloadWithURL:imageURL - options:0 - progress:^(NSInteger receivedSize, NSInteger expectedSize) - { - // progression tracking code - } - completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) - { - if (image) - { - // do something with image - } - }]; +[manager downloadImageWithURL:imageURL + options:0 + progress:^(NSInteger receivedSize, NSInteger expectedSize) + { + // progression tracking code + } + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) + { + if (image) { + // do something with image + } + }]; ``` ### Using Asynchronous Image Downloader Independently @@ -175,9 +176,8 @@ the URL before to use it as a cache key: ```objective-c - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { - SDWebImageManager.sharedManager.cacheKeyFilter:^(NSURL *url) - { - url = [[[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path] autorelease]; + SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) { + url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; return [url absoluteString]; }; @@ -192,7 +192,7 @@ Common Problems ### Using dynamic image size with UITableViewCell -UITableView determins the size of the image by the first image set for a cell. If your remote images +UITableView determines the size of the image by the first image set for a cell. If your remote images don't have the same size as your placeholder image, you may experience strange anamorphic scaling issue. The following article gives a way to workaround this issue: @@ -206,9 +206,9 @@ SDWebImage does very aggressive caching by default. It ignores all kind of cachi If you don't control the image server you're using, you may not be able to change the URL when its content is updated. This is the case for Facebook avatar URLs for instance. In such case, you may use the `SDWebImageRefreshCached` flag. This will slightly degrade the performance but will respect the HTTP caching control headers: ``` objective-c -[imageView setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"] - placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"] - options:SDWebImageRefreshCached]; +[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"] + placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"] + options:SDWebImageRefreshCached]; ``` ### Add a progress indicator @@ -233,6 +233,13 @@ platform :ios, '6.1' pod 'SDWebImage', '~>3.6' ``` +### Installation by cloning the repository + +In order to gain access to all the files from the repository, you should clone it. +``` +git clone --recursive https://github.com/rs/SDWebImage.git +``` + ### Add the SDWebImage project to your project - Download and unzip the last version of the framework from the [download page](https://github.com/rs/SDWebImage/releases) @@ -252,11 +259,15 @@ Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linke ![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg) Alternatively, if this causes compilation problems with frameworks that extend optional libraries, such as Parse, RestKit or opencv2, instead of the -ObjC flag use: - ``` -force_load SDWebImage.framework/Versions/Current/SDWebImage ``` +If you're using Cocoa Pods and have any frameworks that extend optional libraries, such as Parsen RestKit or opencv2, instead of the -ObjC flag use: +``` +-force_load $(TARGET_BUILD_DIR)/libPods.a +``` + ### Import headers in your source files In the source files where you need to use the library, import the header file: diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h b/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h index bde9d5d..f639dd6 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h @@ -36,6 +36,12 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot */ @interface SDImageCache : NSObject +/** + * Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. + * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. + */ +@property (assign, nonatomic) BOOL shouldDecompressImages; + /** * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory. */ @@ -136,7 +142,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot * Remove the image from memory and disk cache synchronously * * @param key The unique image cache key - * @param completionBlock An block that should be executed after the image has been removed (optional) + * @param completion An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion; @@ -153,7 +159,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot * * @param key The unique image cache key * @param fromDisk Also remove cache entry from disk if YES - * @param completionBlock An block that should be executed after the image has been removed (optional) + * @param completion An block that should be executed after the image has been removed (optional) */ - (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion; @@ -164,7 +170,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot /** * Clear all disk cached images. Non-blocking method - returns immediately. - * @param completionBlock An block that should be executed after cache expiration completes (optional) + * @param completion An block that should be executed after cache expiration completes (optional) */ - (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion; diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m b/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m index 59c3471..0052903 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m @@ -48,7 +48,6 @@ + (SDImageCache *)sharedImageCache { static id instance; dispatch_once(&once, ^{ instance = [self new]; - kPNGSignatureData = [NSData dataWithBytes:kPNGSignatureBytes length:8]; }); return instance; } @@ -61,6 +60,9 @@ - (id)initWithNamespace:(NSString *)ns { if ((self = [super init])) { NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns]; + // initialise PNG signature data + kPNGSignatureData = [NSData dataWithBytes:kPNGSignatureBytes length:8]; + // Create IO serial queue _ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL); @@ -75,6 +77,9 @@ - (id)initWithNamespace:(NSString *)ns { NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); _diskCachePath = [paths[0] stringByAppendingPathComponent:fullNamespace]; + // Set decompression to YES + _shouldDecompressImages = YES; + dispatch_sync(_ioQueue, ^{ _fileManager = [NSFileManager new]; }); @@ -147,7 +152,7 @@ - (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate image return; } - [self.memCache setObject:image forKey:key cost:image.size.height * image.size.width * image.scale]; + [self.memCache setObject:image forKey:key cost:image.size.height * image.size.width * image.scale * image.scale]; if (toDisk) { dispatch_async(self.ioQueue, ^{ @@ -234,7 +239,7 @@ - (UIImage *)imageFromDiskCacheForKey:(NSString *)key { // Second check the disk cache... UIImage *diskImage = [self diskImageForKey:key]; if (diskImage) { - CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale; + CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale * diskImage.scale; [self.memCache setObject:diskImage forKey:key cost:cost]; } @@ -264,7 +269,9 @@ - (UIImage *)diskImageForKey:(NSString *)key { if (data) { UIImage *image = [UIImage sd_imageWithData:data]; image = [self scaledImageForKey:key image:image]; - image = [UIImage decodedImageWithImage:image]; + if (self.shouldDecompressImages) { + image = [UIImage decodedImageWithImage:image]; + } return image; } else { @@ -302,7 +309,7 @@ - (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompl @autoreleasepool { UIImage *diskImage = [self diskImageForKey:key]; if (diskImage) { - CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale; + CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale * diskImage.scale; [self.memCache setObject:diskImage forKey:key cost:cost]; } diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h index 008231a..b8db86f 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h @@ -49,8 +49,6 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) { * Put the image in the high priority queue. */ SDWebImageDownloaderHighPriority = 1 << 7, - - }; typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) { @@ -79,12 +77,17 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi */ @interface SDWebImageDownloader : NSObject +/** + * Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. + * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. + */ +@property (assign, nonatomic) BOOL shouldDecompressImages; + @property (assign, nonatomic) NSInteger maxConcurrentDownloads; /** * Shows the current amount of downloads that still need to be downloaded */ - @property (readonly, nonatomic) NSUInteger currentDownloadCount; @@ -139,6 +142,16 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi */ - (NSString *)valueForHTTPHeaderField:(NSString *)field; +/** + * Sets a subclass of `SDWebImageDownloaderOperation` as the default + * `NSOperation` to be used each time SDWebImage constructs a request + * operation to download an image. + * + * @param operationClass The subclass of `SDWebImageDownloaderOperation` to set + * as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`. + */ +- (void)setOperationClass:(Class)operationClass; + /** * Creates a SDWebImageDownloader async downloader instance with a given URL * diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m index 60914db..aa3f1cb 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m @@ -20,6 +20,7 @@ @interface SDWebImageDownloader () @property (strong, nonatomic) NSOperationQueue *downloadQueue; @property (weak, nonatomic) NSOperation *lastAddedOperation; +@property (assign, nonatomic) Class operationClass; @property (strong, nonatomic) NSMutableDictionary *URLCallbacks; @property (strong, nonatomic) NSMutableDictionary *HTTPHeaders; // This queue is used to serialize the handling of the network responses of all the download operation in a single queue @@ -63,9 +64,11 @@ + (SDWebImageDownloader *)sharedDownloader { - (id)init { if ((self = [super init])) { + _operationClass = [SDWebImageDownloaderOperation class]; + _shouldDecompressImages = YES; _executionOrder = SDWebImageDownloaderFIFOExecutionOrder; _downloadQueue = [NSOperationQueue new]; - _downloadQueue.maxConcurrentOperationCount = 2; + _downloadQueue.maxConcurrentOperationCount = 6; _URLCallbacks = [NSMutableDictionary new]; _HTTPHeaders = [NSMutableDictionary dictionaryWithObject:@"image/webp,image/*;q=0.8" forKey:@"Accept"]; _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT); @@ -104,6 +107,10 @@ - (NSInteger)maxConcurrentDownloads { return _downloadQueue.maxConcurrentOperationCount; } +- (void)setOperationClass:(Class)operationClass { + _operationClass = operationClass ?: [SDWebImageDownloaderOperation class]; +} + - (id )downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock { __block SDWebImageDownloaderOperation *operation; __weak SDWebImageDownloader *wself = self; @@ -124,34 +131,43 @@ - (NSInteger)maxConcurrentDownloads { else { request.allHTTPHeaderFields = wself.HTTPHeaders; } - operation = [[SDWebImageDownloaderOperation alloc] initWithRequest:request - options:options - progress:^(NSInteger receivedSize, NSInteger expectedSize) { - SDWebImageDownloader *sself = wself; - if (!sself) return; - NSArray *callbacksForURL = [sself callbacksForURL:url]; - for (NSDictionary *callbacks in callbacksForURL) { - SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey]; - if (callback) callback(receivedSize, expectedSize); - } - } - completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { - SDWebImageDownloader *sself = wself; - if (!sself) return; - NSArray *callbacksForURL = [sself callbacksForURL:url]; - if (finished) { - [sself removeCallbacksForURL:url]; - } - for (NSDictionary *callbacks in callbacksForURL) { - SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey]; - if (callback) callback(image, data, error, finished); - } - } - cancelled:^{ - SDWebImageDownloader *sself = wself; - if (!sself) return; - [sself removeCallbacksForURL:url]; - }]; + operation = [[wself.operationClass alloc] initWithRequest:request + options:options + progress:^(NSInteger receivedSize, NSInteger expectedSize) { + SDWebImageDownloader *sself = wself; + if (!sself) return; + __block NSArray *callbacksForURL; + dispatch_sync(sself.barrierQueue, ^{ + callbacksForURL = [sself.URLCallbacks[url] copy]; + }); + for (NSDictionary *callbacks in callbacksForURL) { + SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey]; + if (callback) callback(receivedSize, expectedSize); + } + } + completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { + SDWebImageDownloader *sself = wself; + if (!sself) return; + __block NSArray *callbacksForURL; + dispatch_barrier_sync(sself.barrierQueue, ^{ + callbacksForURL = [sself.URLCallbacks[url] copy]; + if (finished) { + [sself.URLCallbacks removeObjectForKey:url]; + } + }); + for (NSDictionary *callbacks in callbacksForURL) { + SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey]; + if (callback) callback(image, data, error, finished); + } + } + cancelled:^{ + SDWebImageDownloader *sself = wself; + if (!sself) return; + dispatch_barrier_async(sself.barrierQueue, ^{ + [sself.URLCallbacks removeObjectForKey:url]; + }); + }]; + operation.shouldDecompressImages = wself.shouldDecompressImages; if (wself.username && wself.password) { operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession]; @@ -204,20 +220,6 @@ - (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock and }); } -- (NSArray *)callbacksForURL:(NSURL *)url { - __block NSArray *callbacksForURL; - dispatch_sync(self.barrierQueue, ^{ - callbacksForURL = self.URLCallbacks[url]; - }); - return [callbacksForURL copy]; -} - -- (void)removeCallbacksForURL:(NSURL *)url { - dispatch_barrier_async(self.barrierQueue, ^{ - [self.URLCallbacks removeObjectForKey:url]; - }); -} - - (void)setSuspended:(BOOL)suspended { [self.downloadQueue setSuspended:suspended]; } diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h index 21a3106..fd70b48 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h @@ -17,6 +17,9 @@ */ @property (strong, nonatomic, readonly) NSURLRequest *request; + +@property (assign, nonatomic) BOOL shouldDecompressImages; + /** * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. * diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m index 333e316..025a080 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m @@ -47,6 +47,7 @@ - (id)initWithRequest:(NSURLRequest *)request cancelled:(SDWebImageNoParamsBlock)cancelBlock { if ((self = [super init])) { _request = request; + _shouldDecompressImages = YES; _shouldUseCredentialStorage = YES; _options = options; _progressBlock = [progressBlock copy]; @@ -95,7 +96,9 @@ - (void)start { if (self.progressBlock) { self.progressBlock(0, NSURLResponseUnknownLength); } - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self]; + }); if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) { // Make sure to run the runloop in our background thread so it can process downloaded data @@ -150,7 +153,9 @@ - (void)cancelInternal { if (self.connection) { [self.connection cancel]; - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; + }); // As we cancelled the connection, its callback won't be called and thus won't // maintain the isFinished and isExecuting flags. @@ -195,7 +200,9 @@ - (BOOL)isConcurrent { #pragma mark NSURLConnection (delegate) - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { - if (![response respondsToSelector:@selector(statusCode)] || [((NSHTTPURLResponse *)response) statusCode] < 400) { + + //'304 Not Modified' is an exceptional one + if ((![response respondsToSelector:@selector(statusCode)] || [((NSHTTPURLResponse *)response) statusCode] < 400) && [((NSHTTPURLResponse *)response) statusCode] != 304) { NSInteger expected = response.expectedContentLength > 0 ? (NSInteger)response.expectedContentLength : 0; self.expectedSize = expected; if (self.progressBlock) { @@ -205,9 +212,18 @@ - (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLRespon self.imageData = [[NSMutableData alloc] initWithCapacity:expected]; } else { - [self.connection cancel]; - - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + NSUInteger code = [((NSHTTPURLResponse *)response) statusCode]; + + //This is the case when server returns '304 Not Modified'. It means that remote image is not changed. + //In case of 304 we need just cancel the operation and return cached image from the cache. + if (code == 304) { + [self cancelInternal]; + } else { + [self.connection cancel]; + } + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + }); if (self.completedBlock) { self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); @@ -228,8 +244,7 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { const NSInteger totalSize = self.imageData.length; // Update the data source, we must pass ALL the data, not just the new bytes - CGImageSourceRef imageSource = CGImageSourceCreateIncremental(NULL); - CGImageSourceUpdateData(imageSource, (__bridge CFDataRef)self.imageData, totalSize == self.expectedSize); + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)self.imageData, NULL); if (width + height == 0) { CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); @@ -280,7 +295,12 @@ - (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { UIImage *image = [UIImage imageWithCGImage:partialImageRef scale:1 orientation:orientation]; NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; UIImage *scaledImage = [self scaledImageForKey:key image:image]; - image = [UIImage decodedImageWithImage:scaledImage]; + if (self.shouldDecompressImages) { + image = [UIImage decodedImageWithImage:scaledImage]; + } + else { + image = scaledImage; + } CGImageRelease(partialImageRef); dispatch_main_sync_safe(^{ if (self.completedBlock) { @@ -331,15 +351,16 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { CFRunLoopStop(CFRunLoopGetCurrent()); self.thread = nil; self.connection = nil; - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + }); } if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) { responseFromCached = NO; } - if (completionBlock) - { + if (completionBlock) { if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { completionBlock(nil, nil, nil, YES); } @@ -350,7 +371,9 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { // Do not force decoding animated GIFs if (!image.images) { - image = [UIImage decodedImageWithImage:image]; + if (self.shouldDecompressImages) { + image = [UIImage decodedImageWithImage:image]; + } } if (CGSizeEqualToSize(image.size, CGSizeZero)) { completionBlock(nil, nil, [NSError errorWithDomain:@"SDWebImageErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES); @@ -365,13 +388,19 @@ - (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { } - (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - CFRunLoopStop(CFRunLoopGetCurrent()); - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + @synchronized(self) { + CFRunLoopStop(CFRunLoopGetCurrent()); + self.thread = nil; + self.connection = nil; + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + }); + } if (self.completedBlock) { self.completedBlock(nil, nil, error, YES); } - + self.completionBlock = nil; [self done]; } @@ -396,8 +425,13 @@ - (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connect - (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { - NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; - [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates) && + [challenge.sender respondsToSelector:@selector(performDefaultHandlingForAuthenticationChallenge:)]) { + [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; + } else { + NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + } } else { if ([challenge previousFailureCount] == 0) { if (self.credential) { diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h index 6bb0dcf..9a630a7 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h @@ -74,7 +74,14 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { * By default, placeholder images are loaded while the image is loading. This flag will delay the loading * of the placeholder image until after the image has finished loading. */ - SDWebImageDelayPlaceholder = 1 << 9 + SDWebImageDelayPlaceholder = 1 << 9, + + /** + * We usually don't call transformDownloadedImage delegate method on animated images, + * as most transformation code would mangle it. + * Use this flag to transform them anyway. + */ + SDWebImageTransformAnimatedImage = 1 << 10, }; typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); @@ -159,7 +166,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; * @endcode */ -@property (copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter; +@property (nonatomic, copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter; /** * Returns global SDWebImageManager instance. diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m index 2781ec8..24167c1 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m @@ -112,7 +112,7 @@ - (void)diskImageExistsForURL:(NSURL *)url progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { // Invoking this method without a completedBlock is pointless - NSParameterAssert(completedBlock); + NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead"); // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. @@ -194,7 +194,9 @@ - (void)diskImageExistsForURL:(NSURL *)url if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { @synchronized (self.failedURLs) { - [self.failedURLs addObject:url]; + if (![self.failedURLs containsObject:url]) { + [self.failedURLs addObject:url]; + } } } } @@ -204,8 +206,7 @@ - (void)diskImageExistsForURL:(NSURL *)url if (options & SDWebImageRefreshCached && image && !downloadedImage) { // Image refresh hit the NSURLCache cache, do not call the completion block } - // NOTE: We don't call transformDownloadedImage delegate method on animated images as most transformation code would mangle it - else if (downloadedImage && !downloadedImage.images && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { + else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url]; @@ -283,8 +284,9 @@ - (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url { - (void)cancelAll { @synchronized (self.runningOperations) { - [self.runningOperations makeObjectsPerformSelector:@selector(cancel)]; - [self.runningOperations removeAllObjects]; + NSArray *copiedOperations = [self.runningOperations copy]; + [copiedOperations makeObjectsPerformSelector:@selector(cancel)]; + [self.runningOperations removeObjectsInArray:copiedOperations]; } } diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h index 4f14fa2..7bb67ac 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h @@ -58,6 +58,11 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, */ @property (nonatomic, assign) SDWebImageOptions options; +/** + * Queue options for Prefetcher. Defaults to Main Queue. + */ +@property (nonatomic, assign) dispatch_queue_t prefetcherQueue; + @property (weak, nonatomic) id delegate; /** diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m index 4087e4a..235a0a5 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m @@ -8,7 +8,7 @@ #import "SDWebImagePrefetcher.h" -#if !defined(DEBUG) && !defined (SD_VERBOSE) +#if (!defined(DEBUG) && !defined (SD_VERBOSE)) || defined(SD_LOG_NONE) #define NSLog(...) #endif @@ -40,6 +40,7 @@ - (id)init { if ((self = [super init])) { _manager = [SDWebImageManager new]; _options = SDWebImageLowPriority; + _prefetcherQueue = dispatch_get_main_queue(); self.maxConcurrentDownloads = 3; } return self; @@ -82,9 +83,8 @@ - (void)startPrefetchingAtIndex:(NSUInteger)index { totalCount:self.prefetchURLs.count ]; } - if (self.prefetchURLs.count > self.requestedCount) { - dispatch_async(dispatch_get_main_queue(), ^{ + dispatch_async(self.prefetcherQueue, ^{ [self startPrefetchingAtIndex:self.requestedCount]; }); } @@ -120,10 +120,16 @@ - (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock self.completionBlock = completionBlock; self.progressBlock = progressBlock; - // Starts prefetching from the very first image on the list with the max allowed concurrency - NSUInteger listCount = self.prefetchURLs.count; - for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { - [self startPrefetchingAtIndex:i]; + if(urls.count == 0){ + if(completionBlock){ + completionBlock(0,0); + } + }else{ + // Starts prefetching from the very first image on the list with the max allowed concurrency + NSUInteger listCount = self.prefetchURLs.count; + for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { + [self startPrefetchingAtIndex:i]; + } } } diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h b/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h index 7a6e867..48ad0d5 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h @@ -70,8 +70,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; @@ -86,8 +86,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; @@ -103,8 +103,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; @@ -152,8 +152,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; @@ -168,8 +168,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; @@ -184,8 +184,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h index 6b00366..57f708f 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h @@ -43,8 +43,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; @@ -58,8 +58,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; @@ -74,8 +74,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h index 717d393..e7489f4 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h @@ -92,8 +92,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; @@ -107,8 +107,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; @@ -123,8 +123,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; @@ -140,8 +140,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; @@ -157,8 +157,8 @@ * @param completedBlock A block called when operation has been completed. This block has no return value * and takes the requested UIImage as first parameter. In case of error the image parameter * is nil and the second parameter may contain an NSError. The third parameter is a Boolean - * indicating if the image was retrived from the local cache of from the network. - * The forth parameter is the original image url. + * indicating if the image was retrived from the local cache or from the network. + * The fourth parameter is the original image url. */ - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; diff --git a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m index 51663dd..1e225eb 100644 --- a/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m +++ b/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m @@ -43,7 +43,9 @@ - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); if (!(options & SDWebImageDelayPlaceholder)) { - self.image = placeholder; + dispatch_main_async_safe(^{ + self.image = placeholder; + }); } if (url) { diff --git a/iOSStudy/Pods/SVProgressHUD/README.md b/iOSStudy/Pods/SVProgressHUD/README.md index 214d2a4..10ca5bf 100644 --- a/iOSStudy/Pods/SVProgressHUD/README.md +++ b/iOSStudy/Pods/SVProgressHUD/README.md @@ -22,6 +22,12 @@ pod 'SVProgressHUD', :head This pulls from the `master` branch directly. We are usually careful about what we push there and this is the version we use ourselves in all of our projects. +### Carthage + +[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/TransitApp/SVProgressHUD) + +You can install SVProgressHUD with Carthage + ### Manually * Drag the `SVProgressHUD/SVProgressHUD` folder into your project. @@ -109,6 +115,7 @@ Or show a confirmation glyph before before getting dismissed a little bit later. + (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Freepik + (void)setErrorImage:(UIImage*)image; // default is bundled error image from Freepik + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone ++ (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set ``` ## Notifications @@ -123,6 +130,10 @@ Each notification passes a `userInfo` dictionary holding the HUD's status string `SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For this notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. +## App Extensions + +When using `SVProgressHUD` in an App Extension, #define SV_APP_EXTENSIONS to avoid using unavailable APIs. Additionally call `setViewForExtension:` from your extensions view controller with `self.view`. + ## Contributing to this project If you have feature requests or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/samvermette/SVProgressHUD/issues/new). Please take a moment to diff --git a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m index 7cad180..2a74fbb 100644 --- a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m +++ b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m @@ -56,7 +56,13 @@ - (CAShapeLayer*)indefiniteAnimatedLayer { _indefiniteAnimatedLayer.path = smoothedPath.CGPath; CALayer *maskLayer = [CALayer layer]; - maskLayer.contents = (id)[[UIImage imageNamed:@"SVProgressHUD.bundle/angle-mask"] CGImage]; + + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; + NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + NSString *path = [imageBundle pathForResource:@"angle-mask" ofType:@"png"]; + + maskLayer.contents = (id)[[UIImage imageWithContentsOfFile:path] CGImage];; maskLayer.frame = _indefiniteAnimatedLayer.bounds; _indefiniteAnimatedLayer.mask = maskLayer; diff --git a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h index da2992d..c916ff4 100644 --- a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h +++ b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h @@ -37,6 +37,7 @@ typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { + (void)setSuccessImage:(UIImage*)image; // default is the bundled success image provided by Freepik + (void)setErrorImage:(UIImage*)image; // default is the bundled error image provided by Freepik + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone ++ (void)setViewForExtension:(UIView*)view; // default is nil, only used if #define SV_APP_EXTENSIONS is set #pragma mark - Show Methods diff --git a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m index 43c6c6a..1d735d2 100644 --- a/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m +++ b/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m @@ -31,6 +31,7 @@ static UIImage *SVProgressHUDSuccessImage; static UIImage *SVProgressHUDErrorImage; static SVProgressHUDMaskType SVProgressHUDDefaultMaskType; +static UIView *SVProgressHUDExtensionView; static const CGFloat SVProgressHUDRingRadius = 18; static const CGFloat SVProgressHUDRingNoTextRadius = 24; @@ -129,6 +130,11 @@ + (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType{ SVProgressHUDDefaultMaskType = maskType; } ++ (void)setViewForExtension:(UIView *)view{ + [self sharedView]; + SVProgressHUDExtensionView = view; +} + #pragma mark - Show Methods @@ -255,15 +261,25 @@ - (id)initWithFrame:(CGRect)frame { SVProgressHUDBackgroundColor = [UIColor colorWithWhite:0.0f alpha:0.8f]; SVProgressHUDForegroundColor = [UIColor whiteColor]; } + + NSBundle *bundle = [NSBundle bundleForClass:self.class]; + NSURL *url = [bundle URLForResource:@"SVProgressHUD" withExtension:@"bundle"]; + NSBundle *imageBundle = [NSBundle bundleWithURL:url]; + + UIImage* infoImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"info" ofType:@"png"]]; + UIImage* successImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"success" ofType:@"png"]]; + UIImage* errorImage = [UIImage imageWithContentsOfFile:[imageBundle pathForResource:@"error" ofType:@"png"]]; + if ([[UIImage class] instancesRespondToSelector:@selector(imageWithRenderingMode:)]) { - SVProgressHUDInfoImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/info"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - SVProgressHUDSuccessImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/success"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; - SVProgressHUDErrorImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/error"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + SVProgressHUDInfoImage = [infoImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + SVProgressHUDSuccessImage = [successImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + SVProgressHUDErrorImage = [errorImage imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; } else { - SVProgressHUDInfoImage = [UIImage imageNamed:@"SVProgressHUD.bundle/info"]; - SVProgressHUDSuccessImage = [UIImage imageNamed:@"SVProgressHUD.bundle/success"]; - SVProgressHUDErrorImage = [UIImage imageNamed:@"SVProgressHUD.bundle/error"]; + SVProgressHUDInfoImage = infoImage; + SVProgressHUDSuccessImage = successImage; + SVProgressHUDErrorImage = errorImage; } + SVProgressHUDRingThickness = 2; SVProgressHUDDefaultMaskType = SVProgressHUDMaskTypeNone; } @@ -456,7 +472,11 @@ - (void)positionHUD:(NSNotification*)notification { self.frame = UIScreen.mainScreen.bounds; +#if !defined(SV_APP_EXTENSIONS) UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation; +#else + UIInterfaceOrientation orientation = CGRectGetWidth(self.frame) > CGRectGetHeight(self.frame) ? UIInterfaceOrientationLandscapeLeft : UIInterfaceOrientationPortrait; +#endif // no transforms applied to window in iOS 8, but only if compiled with iOS 8 sdk as base sdk, otherwise system supports old rotation logic. BOOL ignoreOrientation = NO; #if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 @@ -481,7 +501,11 @@ - (void)positionHUD:(NSNotification*)notification { } CGRect orientationFrame = self.bounds; +#if !defined(SV_APP_EXTENSIONS) CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame; +#else + CGRect statusBarFrame = CGRectZero; +#endif if(!ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) { float temp = CGRectGetWidth(orientationFrame); @@ -565,14 +589,23 @@ - (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent *)event { - (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType { if(!self.overlayView.superview){ +#if !defined(SV_APP_EXTENSIONS) NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator]; - UIScreen *mainScreen = UIScreen.mainScreen; - - for (UIWindow *window in frontToBackWindows) - if (window.screen == mainScreen && window.windowLevel == UIWindowLevelNormal) { + for (UIWindow *window in frontToBackWindows){ + BOOL windowOnMainScreen = window.screen == UIScreen.mainScreen; + BOOL windowIsVisible = !window.hidden && window.alpha > 0; + BOOL windowLevelNormal = window.windowLevel == UIWindowLevelNormal; + + if (windowOnMainScreen && windowIsVisible && windowLevelNormal) { [window addSubview:self.overlayView]; break; } + } +#else + if(SVProgressHUDExtensionView){ + [SVProgressHUDExtensionView addSubview:self.overlayView]; + } +#endif } else { // Ensure that overlay will be exactly on top of rootViewController (which may be changed during runtime). [self.overlayView.superview bringSubviewToFront:self.overlayView]; @@ -671,10 +704,11 @@ - (UIImage *)image:(UIImage *)image withTintColor:(UIColor *)color{ - (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType { self.progress = SVProgressHUDUndefinedProgress; + self.maskType = hudMaskType; [self cancelRingLayerAnimation]; if(![self.class isVisible]) - [self.class show]; + [self.class showWithMaskType:self.maskType]; if ([self.imageView respondsToSelector:@selector(setTintColor:)]) { self.imageView.tintColor = SVProgressHUDForegroundColor; @@ -683,16 +717,17 @@ - (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInt } self.imageView.image = image; self.imageView.hidden = NO; - self.maskType = hudMaskType; - + self.stringLabel.text = string; [self updatePosition]; [self.indefiniteAnimatedView removeFromSuperview]; if(self.maskType != SVProgressHUDMaskTypeNone) { + self.overlayView.userInteractionEnabled = YES; self.accessibilityLabel = string; self.isAccessibilityElement = YES; } else { + self.overlayView.userInteractionEnabled = NO; self.hudView.accessibilityLabel = string; self.hudView.isAccessibilityElement = YES; } @@ -744,10 +779,12 @@ - (void)dismiss { userInfo:userInfo]; // Tell the rootViewController to update the StatusBar appearance +#if !defined(SV_APP_EXTENSIONS) UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; if ([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { [rootController setNeedsStatusBarAppearanceUpdate]; } +#endif // uncomment to make sure UIWindow is gone from app.windows //NSLog(@"%@", [UIApplication sharedApplication].windows); //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow); @@ -919,6 +956,7 @@ - (UIImageView *)imageView { - (CGFloat)visibleKeyboardHeight { +#if !defined(SV_APP_EXTENSIONS) UIWindow *keyboardWindow = nil; for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { if(![[testWindow class] isEqual:[UIWindow class]]) { @@ -938,7 +976,7 @@ - (CGFloat)visibleKeyboardHeight { } } } - +#endif return 0; } diff --git a/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h b/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h index fc904ae..42e9dfe 100644 --- a/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h +++ b/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h @@ -9,7 +9,7 @@ #import "SVModalWebViewController.h" @interface SVWebViewController : UIViewController -@property(nonatomic,copy)NSString*urlString; + - (id)initWithAddress:(NSString*)urlString; - (id)initWithURL:(NSURL*)URL; diff --git a/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m b/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m index 80d97d6..ce577d3 100644 --- a/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m +++ b/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m @@ -9,7 +9,7 @@ #import "SVWebViewControllerActivityChrome.h" #import "SVWebViewControllerActivitySafari.h" #import "SVWebViewController.h" -#import +#import "SVProgressHUD.h" @interface SVWebViewController () @property (nonatomic, strong) UIBarButtonItem *backBarButtonItem; @@ -47,22 +47,11 @@ - (void)dealloc { } - (id)initWithAddress:(NSString *)urlString { - - if (urlString) { - urlString = _urlString; - } return [self initWithURL:[NSURL URLWithString:urlString]]; } --(void)setUrlString:(NSString *)urlString{ - if (urlString) { - _urlString = urlString; - } -} - - (id)initWithURL:(NSURL*)pageURL { - if(self = [super init]) { self.URL = pageURL; } @@ -112,6 +101,7 @@ - (void)viewWillDisappear:(BOOL)animated { if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { [self.navigationController setToolbarHidden:YES animated:animated]; } + [SVProgressHUD dismiss]; } - (void)viewDidDisappear:(BOOL)animated { @@ -236,31 +226,24 @@ - (void)updateToolbarItems { #pragma mark - UIWebViewDelegate - (void)webViewDidStartLoad:(UIWebView *)webView { - - [SVProgressHUD show]; - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; [self updateToolbarItems]; + [SVProgressHUD show]; + } - (void)webViewDidFinishLoad:(UIWebView *)webView { - - [SVProgressHUD dismiss]; - [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; self.navigationItem.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"]; [self updateToolbarItems]; - - + [SVProgressHUD dismiss]; } - (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; [self updateToolbarItems]; - - [SVProgressHUD dismiss]; } #pragma mark - Target actions @@ -290,7 +273,6 @@ - (void)actionButtonClicked:(id)sender { } - (void)doneButtonClicked:(id)sender { - [SVProgressHUD dismiss]; [self dismissViewControllerAnimated:YES completion:NULL]; } diff --git a/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmering.h b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmering.h new file mode 100644 index 0000000..c57b4ae --- /dev/null +++ b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmering.h @@ -0,0 +1,58 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +typedef NS_ENUM(NSInteger, FBShimmerDirection) { + FBShimmerDirectionRight, // Shimmer animation goes from left to right + FBShimmerDirectionLeft, // Shimmer animation goes from right to left + FBShimmerDirectionUp, // Shimmer animation goes from below to above + FBShimmerDirectionDown, // Shimmer animation goes from above to below +}; + +@protocol FBShimmering + +//! @abstract Set this to YES to start shimming and NO to stop. Defaults to NO. +@property (nonatomic, assign, readwrite, getter = isShimmering) BOOL shimmering; + +//! @abstract The time interval between shimmerings in seconds. Defaults to 0.4. +@property (assign, nonatomic, readwrite) CFTimeInterval shimmeringPauseDuration; + +//! @abstract The opacity of the content while it is shimmering. Defaults to 1.0. +@property (assign, nonatomic, readwrite) CGFloat shimmeringAnimationOpacity; + +//! @abstract The opacity of the content before it is shimmering. Defaults to 0.5. +@property (assign, nonatomic, readwrite) CGFloat shimmeringOpacity; + +//! @abstract The speed of shimmering, in points per second. Defaults to 230. +@property (assign, nonatomic, readwrite) CGFloat shimmeringSpeed; + +//! @abstract The highlight length of shimmering. Range of [0,1], defaults to 0.33. +@property (assign, nonatomic, readwrite) CGFloat shimmeringHighlightLength; + +//! @abstract @deprecated Same as "shimmeringHighlightLength", just for downward compatibility +@property (assign, nonatomic, readwrite, getter = shimmeringHighlightLength, setter = setShimmeringHighlightLength:) CGFloat shimmeringHighlightWidth; + +//! @abstract The direction of shimmering animation. Defaults to FBShimmerDirectionRight. +@property (assign, nonatomic, readwrite) FBShimmerDirection shimmeringDirection; + +//! @abstract The duration of the fade used when shimmer begins. Defaults to 0.1. +@property (assign, nonatomic, readwrite) CFTimeInterval shimmeringBeginFadeDuration; + +//! @abstract The duration of the fade used when shimmer ends. Defaults to 0.3. +@property (assign, nonatomic, readwrite) CFTimeInterval shimmeringEndFadeDuration; + +/** + @abstract The absolute CoreAnimation media time when the shimmer will fade in. + @discussion Only valid after setting {@ref shimmering} to NO. + */ +@property (assign, nonatomic, readonly) CFTimeInterval shimmeringFadeTime; + +@end + diff --git a/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.h b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.h new file mode 100644 index 0000000..8e74179 --- /dev/null +++ b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.h @@ -0,0 +1,22 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "FBShimmering.h" + +/** + @abstract Lightweight, generic shimmering layer. + */ +@interface FBShimmeringLayer : CALayer + +//! @abstract The content layer to be shimmered. +@property (strong, nonatomic) CALayer *contentLayer; + +@end diff --git a/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.m b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.m new file mode 100644 index 0000000..3d615e6 --- /dev/null +++ b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringLayer.m @@ -0,0 +1,468 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "FBShimmeringLayer.h" + +#import +#import +#import + +#import +#import + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Convert your project to ARC or specify the -fobjc-arc flag. +#endif + +#if TARGET_IPHONE_SIMULATOR +UIKIT_EXTERN float UIAnimationDragCoefficient(void); // UIKit private drag coeffient, use judiciously +#endif + +static CGFloat FBShimmeringLayerDragCoefficient(void) +{ +#if TARGET_IPHONE_SIMULATOR + return UIAnimationDragCoefficient(); +#else + return 1.0; +#endif +} + +static void FBShimmeringLayerAnimationApplyDragCoefficient(CAAnimation *animation) +{ + CGFloat k = FBShimmeringLayerDragCoefficient(); + + if (k != 0 && k != 1) { + animation.speed = 1 / k; + } +} + +// animations keys +static NSString *const kFBShimmerSlideAnimationKey = @"slide"; +static NSString *const kFBFadeAnimationKey = @"fade"; +static NSString *const kFBEndFadeAnimationKey = @"fade-end"; + +static CABasicAnimation *fade_animation(id delegate, CALayer *layer, CGFloat opacity, CFTimeInterval duration) +{ + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"opacity"]; + animation.delegate = delegate; + animation.fromValue = @([(layer.presentationLayer ?: layer) opacity]); + animation.toValue = @(opacity); + animation.fillMode = kCAFillModeBoth; + animation.removedOnCompletion = NO; + animation.duration = duration; + FBShimmeringLayerAnimationApplyDragCoefficient(animation); + return animation; +} + +static CABasicAnimation *shimmer_begin_fade_animation(id delegate, CALayer *layer, CGFloat opacity, CGFloat duration) +{ + return fade_animation(delegate, layer, opacity, duration); +} + +static CABasicAnimation *shimmer_end_fade_animation(id delegate, CALayer *layer, CGFloat opacity, CGFloat duration) +{ + CABasicAnimation *animation = fade_animation(delegate, layer, opacity, duration); + [animation setValue:@YES forKey:kFBEndFadeAnimationKey]; + return animation; +} + +static CABasicAnimation *shimmer_slide_animation(id delegate, CFTimeInterval duration, FBShimmerDirection direction) +{ + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"position"]; + animation.delegate = delegate; + animation.toValue = [NSValue valueWithCGPoint:CGPointZero]; + animation.duration = duration; + animation.repeatCount = HUGE_VALF; + FBShimmeringLayerAnimationApplyDragCoefficient(animation); + if (direction == FBShimmerDirectionLeft || + direction == FBShimmerDirectionUp) { + animation.speed = -fabsf(animation.speed); + } + return animation; +} + +// take a shimmer slide animation and turns into repeating +static CAAnimation *shimmer_slide_repeat(CAAnimation *a, CFTimeInterval duration, FBShimmerDirection direction) +{ + CAAnimation *anim = [a copy]; + anim.repeatCount = HUGE_VALF; + anim.duration = duration; + anim.speed = (direction == FBShimmerDirectionRight || direction == FBShimmerDirectionDown) ? fabsf(anim.speed) : -fabsf(anim.speed); + return anim; +} + +// take a shimmer slide animation and turns into finish +static CAAnimation *shimmer_slide_finish(CAAnimation *a) +{ + CAAnimation *anim = [a copy]; + anim.repeatCount = 0; + return anim; +} + +@interface FBShimmeringMaskLayer : CAGradientLayer +@property (readonly, nonatomic) CALayer *fadeLayer; +@end + +@implementation FBShimmeringMaskLayer + +- (instancetype)init +{ + self = [super init]; + if (nil != self) { + _fadeLayer = [[CALayer alloc] init]; + _fadeLayer.backgroundColor = [UIColor whiteColor].CGColor; + [self addSublayer:_fadeLayer]; + } + return self; +} + +- (void)layoutSublayers +{ + [super layoutSublayers]; + CGRect r = self.bounds; + _fadeLayer.bounds = r; + _fadeLayer.position = CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r)); +} + +@end + +@interface FBShimmeringLayer () +@property (strong, nonatomic) FBShimmeringMaskLayer *maskLayer; +@end + +@implementation FBShimmeringLayer +{ + CALayer *_contentLayer; + FBShimmeringMaskLayer *_maskLayer; +} + +#pragma mark - Lifecycle + +@synthesize shimmering = _shimmering; +@synthesize shimmeringPauseDuration = _shimmeringPauseDuration; +@synthesize shimmeringAnimationOpacity = _shimmeringAnimationOpacity; +@synthesize shimmeringOpacity = _shimmeringOpacity; +@synthesize shimmeringSpeed = _shimmeringSpeed; +@synthesize shimmeringHighlightLength = _shimmeringHighlightLength; +@synthesize shimmeringDirection = _shimmeringDirection; +@synthesize shimmeringFadeTime = _shimmeringFadeTime; +@synthesize shimmeringBeginFadeDuration = _shimmeringBeginFadeDuration; +@synthesize shimmeringEndFadeDuration = _shimmeringEndFadeDuration; +@dynamic shimmeringHighlightWidth; + +- (instancetype)init +{ + self = [super init]; + if (nil != self) { + // default configuration + _shimmeringPauseDuration = 0.4; + _shimmeringSpeed = 230.0; + _shimmeringHighlightLength = 1.0; + _shimmeringAnimationOpacity = 0.5; + _shimmeringOpacity = 1.0; + _shimmeringDirection = FBShimmerDirectionRight; + _shimmeringBeginFadeDuration = 0.1; + _shimmeringEndFadeDuration = 0.3; + } + return self; +} + +#pragma mark - Properties + +- (void)setContentLayer:(CALayer *)contentLayer +{ + // reset mask + self.maskLayer = nil; + + // note content layer and add for display + _contentLayer = contentLayer; + self.sublayers = contentLayer ? @[contentLayer] : nil; + + // update shimmering animation + [self _updateShimmering]; +} + +- (void)setShimmering:(BOOL)shimmering +{ + if (shimmering != _shimmering) { + _shimmering = shimmering; + [self _updateShimmering]; + } +} + +- (void)setShimmeringSpeed:(CGFloat)speed +{ + if (speed != _shimmeringSpeed) { + _shimmeringSpeed = speed; + [self _updateShimmering]; + } +} + +- (void)setShimmeringHighlightLength:(CGFloat)length +{ + if (length != _shimmeringHighlightLength) { + _shimmeringHighlightLength = length; + [self _updateShimmering]; + } +} + +- (void)setShimmeringDirection:(FBShimmerDirection)direction +{ + if (direction != _shimmeringDirection) { + _shimmeringDirection = direction; + [self _updateShimmering]; + } +} + +- (void)setShimmeringPauseDuration:(CFTimeInterval)duration +{ + if (duration != _shimmeringPauseDuration) { + _shimmeringPauseDuration = duration; + [self _updateShimmering]; + } +} + +- (void)setShimmeringAnimationOpacity:(CGFloat)shimmeringAnimationOpacity +{ + if (shimmeringAnimationOpacity != _shimmeringAnimationOpacity) { + _shimmeringAnimationOpacity = shimmeringAnimationOpacity; + [self _updateMaskColors]; + } +} + +- (void)setShimmeringOpacity:(CGFloat)shimmeringOpacity +{ + if (shimmeringOpacity != _shimmeringOpacity) { + _shimmeringOpacity = shimmeringOpacity; + [self _updateMaskColors]; + } +} + +- (void)layoutSublayers +{ + [super layoutSublayers]; + CGRect r = self.bounds; + _contentLayer.anchorPoint = CGPointMake(0.5, 0.5); + _contentLayer.bounds = r; + _contentLayer.position = CGPointMake(CGRectGetMidX(r), CGRectGetMidY(r)); + + if (nil != _maskLayer) { + [self _updateMaskLayout]; + } +} + +- (void)setBounds:(CGRect)bounds +{ + if (!CGRectEqualToRect(self.bounds, bounds)) { + [super setBounds:bounds]; + + [self _updateShimmering]; + } +} + +#pragma mark - Internal + +- (void)_clearMask +{ + if (nil == _maskLayer) { + return; + } + + BOOL disableActions = [CATransaction disableActions]; + [CATransaction setDisableActions:YES]; + + self.maskLayer = nil; + _contentLayer.mask = nil; + + [CATransaction setDisableActions:disableActions]; +} + +- (void)_createMaskIfNeeded +{ + if (_shimmering && !_maskLayer) { + _maskLayer = [FBShimmeringMaskLayer layer]; + _maskLayer.delegate = self; + _contentLayer.mask = _maskLayer; + [self _updateMaskColors]; + [self _updateMaskLayout]; + } +} + +- (void)_updateMaskColors +{ + if (nil == _maskLayer) { + return; + } + + // We create a gradient to be used as a mask. + // In a mask, the colors do not matter, it's the alpha that decides the degree of masking. + UIColor *maskedColor = [UIColor colorWithWhite:1.0 alpha:_shimmeringOpacity]; + UIColor *unmaskedColor = [UIColor colorWithWhite:1.0 alpha:_shimmeringAnimationOpacity]; + + // Create a gradient from masked to unmasked to masked. + _maskLayer.colors = @[(__bridge id)maskedColor.CGColor, (__bridge id)unmaskedColor.CGColor, (__bridge id)maskedColor.CGColor]; +} + +- (void)_updateMaskLayout +{ + // Everything outside the mask layer is hidden, so we need to create a mask long enough for the shimmered layer to be always covered by the mask. + CGFloat length = 0.0f; + if (_shimmeringDirection == FBShimmerDirectionDown || + _shimmeringDirection == FBShimmerDirectionUp) { + length = CGRectGetHeight(_contentLayer.bounds); + } else { + length = CGRectGetWidth(_contentLayer.bounds); + } + if (0 == length) { + return; + } + + // extra distance for the gradient to travel during the pause. + CGFloat extraDistance = length + _shimmeringSpeed * _shimmeringPauseDuration; + + // compute how far the shimmering goes + CGFloat fullShimmerLength = length * 3.0f + extraDistance; + CGFloat travelDistance = length * 2.0f + extraDistance; + + // position the gradient for the desired width + CGFloat highlightOutsideLength = (1.0 - _shimmeringHighlightLength) / 2.0; + _maskLayer.locations = @[@(highlightOutsideLength), + @(0.5), + @(1.0 - highlightOutsideLength)]; + + CGFloat startPoint = (length + extraDistance) / fullShimmerLength; + CGFloat endPoint = travelDistance / fullShimmerLength; + + // position for the start of the animation + _maskLayer.anchorPoint = CGPointZero; + if (_shimmeringDirection == FBShimmerDirectionDown || + _shimmeringDirection == FBShimmerDirectionUp) { + _maskLayer.startPoint = CGPointMake(0.0, startPoint); + _maskLayer.endPoint = CGPointMake(0.0, endPoint); + _maskLayer.position = CGPointMake(0.0, -travelDistance); + _maskLayer.bounds = CGRectMake(0.0, 0.0, CGRectGetWidth(_contentLayer.bounds), fullShimmerLength); + } else { + _maskLayer.startPoint = CGPointMake(startPoint, 0.0); + _maskLayer.endPoint = CGPointMake(endPoint, 0.0); + _maskLayer.position = CGPointMake(-travelDistance, 0.0); + _maskLayer.bounds = CGRectMake(0.0, 0.0, fullShimmerLength, CGRectGetHeight(_contentLayer.bounds)); + } +} + +- (void)_updateShimmering +{ + // create mask if needed + [self _createMaskIfNeeded]; + + // if not shimmering and no mask, noop + if (!_shimmering && !_maskLayer) { + return; + } + + // ensure layed out + [self layoutIfNeeded]; + + BOOL disableActions = [CATransaction disableActions]; + if (!_shimmering) { + if (disableActions) { + // simply remove mask + [self _clearMask]; + } else { + // end slide + CFTimeInterval slideEndTime = 0; + + CAAnimation *slideAnimation = [_maskLayer animationForKey:kFBShimmerSlideAnimationKey]; + if (slideAnimation != nil) { + // determing total time sliding + CFTimeInterval now = CACurrentMediaTime(); + CFTimeInterval slideTotalDuration = now - slideAnimation.beginTime; + + // determine time offset into current slide + CFTimeInterval slideTimeOffset = fmod(slideTotalDuration, slideAnimation.duration); + + // transition to non-repeating slide + CAAnimation *finishAnimation = shimmer_slide_finish(slideAnimation); + + // adjust begin time to now - offset + finishAnimation.beginTime = now - slideTimeOffset; + + // note slide end time and begin + slideEndTime = finishAnimation.beginTime + slideAnimation.duration; + [_maskLayer addAnimation:finishAnimation forKey:kFBShimmerSlideAnimationKey]; + } + + // fade in text at slideEndTime + CABasicAnimation *fadeInAnimation = shimmer_end_fade_animation(self, _maskLayer.fadeLayer, 1.0, _shimmeringEndFadeDuration); + fadeInAnimation.beginTime = slideEndTime; + [_maskLayer.fadeLayer addAnimation:fadeInAnimation forKey:kFBFadeAnimationKey]; + + // expose end time for synchronization + _shimmeringFadeTime = slideEndTime; + } + } else { + // fade out text, optionally animated + CABasicAnimation *fadeOutAnimation = nil; + if (_shimmeringBeginFadeDuration > 0.0 && !disableActions) { + fadeOutAnimation = shimmer_begin_fade_animation(self, _maskLayer.fadeLayer, 0.0, _shimmeringBeginFadeDuration); + [_maskLayer.fadeLayer addAnimation:fadeOutAnimation forKey:kFBFadeAnimationKey]; + } else { + BOOL innerDisableActions = [CATransaction disableActions]; + [CATransaction setDisableActions:YES]; + + _maskLayer.fadeLayer.opacity = 0.0; + [_maskLayer.fadeLayer removeAllAnimations]; + + [CATransaction setDisableActions:innerDisableActions]; + } + + // begin slide animation + CAAnimation *slideAnimation = [_maskLayer animationForKey:kFBShimmerSlideAnimationKey]; + + // compute shimmer duration + CGFloat length = 0.0f; + if (_shimmeringDirection == FBShimmerDirectionDown || + _shimmeringDirection == FBShimmerDirectionUp) { + length = CGRectGetHeight(_contentLayer.bounds); + } else { + length = CGRectGetWidth(_contentLayer.bounds); + } + CFTimeInterval animationDuration = (length / _shimmeringSpeed) + _shimmeringPauseDuration; + + if (slideAnimation != nil) { + // ensure existing slide animation repeats + [_maskLayer addAnimation:shimmer_slide_repeat(slideAnimation, animationDuration, _shimmeringDirection) forKey:kFBShimmerSlideAnimationKey]; + } else { + // add slide animation + slideAnimation = shimmer_slide_animation(self, animationDuration, _shimmeringDirection); + slideAnimation.fillMode = kCAFillModeForwards; + slideAnimation.removedOnCompletion = NO; + slideAnimation.beginTime = CACurrentMediaTime() + fadeOutAnimation.duration; + [_maskLayer addAnimation:slideAnimation forKey:kFBShimmerSlideAnimationKey]; + } + } +} + +#pragma mark - CALayerDelegate + +- (id)actionForLayer:(CALayer *)layer forKey:(NSString *)event +{ + // no associated actions + return (id)kCFNull; +} + +#pragma mark - CAAnimationDelegate + +- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag +{ + if (flag && [[anim valueForKey:kFBEndFadeAnimationKey] boolValue]) { + [self _clearMask]; + } +} + +@end diff --git a/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.h b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.h new file mode 100644 index 0000000..5431668 --- /dev/null +++ b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.h @@ -0,0 +1,22 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import + +#import "FBShimmering.h" + +/** + @abstract Lightweight, generic shimmering view. + */ +@interface FBShimmeringView : UIView + +//! @abstract The content view to be shimmered. +@property (strong, nonatomic) UIView *contentView; + +@end diff --git a/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.m b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.m new file mode 100644 index 0000000..7bb9e04 --- /dev/null +++ b/iOSStudy/Pods/Shimmer/FBShimmering/FBShimmeringView.m @@ -0,0 +1,61 @@ +/** + Copyright (c) 2014-present, Facebook, Inc. + All rights reserved. + + This source code is licensed under the BSD-style license found in the + LICENSE file in the root directory of this source tree. An additional grant + of patent rights can be found in the PATENTS file in the same directory. + */ + +#import "FBShimmeringView.h" + +#import "FBShimmeringLayer.h" + +#if !__has_feature(objc_arc) +#error This file must be compiled with ARC. Convert your project to ARC or specify the -fobjc-arc flag. +#endif + +@implementation FBShimmeringView + ++ (Class)layerClass +{ + return [FBShimmeringLayer class]; +} + +#define __layer ((FBShimmeringLayer *)self.layer) + +#define LAYER_ACCESSOR(accessor, ctype) \ +- (ctype)accessor { \ + return [__layer accessor]; \ +} + +#define LAYER_MUTATOR(mutator, ctype) \ +- (void)mutator (ctype)value { \ + [__layer mutator value]; \ +} + +#define LAYER_RW_PROPERTY(accessor, mutator, ctype) \ + LAYER_ACCESSOR (accessor, ctype) \ + LAYER_MUTATOR (mutator, ctype) + +LAYER_RW_PROPERTY(isShimmering, setShimmering:, BOOL) +LAYER_RW_PROPERTY(shimmeringPauseDuration, setShimmeringPauseDuration:, CFTimeInterval) +LAYER_RW_PROPERTY(shimmeringAnimationOpacity, setShimmeringAnimationOpacity:, CGFloat) +LAYER_RW_PROPERTY(shimmeringOpacity, setShimmeringOpacity:, CGFloat) +LAYER_RW_PROPERTY(shimmeringSpeed, setShimmeringSpeed:, CGFloat) +LAYER_RW_PROPERTY(shimmeringHighlightLength, setShimmeringHighlightLength:, CGFloat) +LAYER_RW_PROPERTY(shimmeringDirection, setShimmeringDirection:, FBShimmerDirection) +LAYER_ACCESSOR(shimmeringFadeTime, CFTimeInterval) +LAYER_RW_PROPERTY(shimmeringBeginFadeDuration, setShimmeringBeginFadeDuration:, CFTimeInterval) +LAYER_RW_PROPERTY(shimmeringEndFadeDuration, setShimmeringEndFadeDuration:, CFTimeInterval) + +- (void)setContentView:(UIView *)contentView +{ + if (contentView != _contentView) { + _contentView = contentView; + [self addSubview:contentView]; + __layer.contentLayer = contentView.layer; + } +} + +@end diff --git a/iOSStudy/Pods/Shimmer/LICENSE b/iOSStudy/Pods/Shimmer/LICENSE new file mode 100644 index 0000000..fb34f0c --- /dev/null +++ b/iOSStudy/Pods/Shimmer/LICENSE @@ -0,0 +1,30 @@ +BSD License + +For Shimmer software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/iOSStudy/Pods/Shimmer/README.md b/iOSStudy/Pods/Shimmer/README.md new file mode 100644 index 0000000..42fde97 --- /dev/null +++ b/iOSStudy/Pods/Shimmer/README.md @@ -0,0 +1,44 @@ +# Shimmer +Shimmer is an easy way to add a shimmering effect to any view in your app. It's useful as an unobtrusive loading indicator. + +Shimmer was originally developed to show loading status in [Paper](http://facebook.com/paper). + +![Shimmer](https://github.com/facebook/Shimmer/blob/master/shimmer.gif?raw=true) + +## Usage +To use Shimmer, create a `FBShimmeringView` or `FBShimmeringLayer` and add your content. To start shimmering, set the `shimmering` property to `YES`. + +An example of making a label shimmer: + +```objective-c +FBShimmeringView *shimmeringView = [[FBShimmeringView alloc] initWithFrame:self.view.bounds]; +[self.view addSubview:shimmeringView]; + +UILabel *loadingLabel = [[UILabel alloc] initWithFrame:shimmeringView.bounds]; +loadingLabel.textAlignment = NSTextAlignmentCenter; +loadingLabel.text = NSLocalizedString(@"Shimmer", nil); +shimmeringView.contentView = loadingLabel; + +// Start shimmering. +shimmeringView.shimmering = YES; +``` + +There's also an example project. In the example, you can swipe horizontally and vertically to try various shimmering parameters, or tap to start or stop shimmering. (To build the example locally, you'll need to open `FBShimmering.xcworkpace` rather than the `.xcodeproj`.) + +## Installation +There are two options: + + 1. Shimmer is available as `Shimmer` in [Cocoapods](http://cocoapods.org). + 2. Manually add the files into your Xcode project. Slightly simpler, but updates are also manual. + +Shimmer requires iOS 6 or later. + +## How it works +Shimmer uses the `-[CALayer mask]` property to enable shimmering, similar to what's described in John Harper's 2009 WWDC talk (unfortunately no longer online). Shimmer uses CoreAnimation's timing features to smoothly transition "on-beat" when starting and stopping the shimmer. + +## Contributing +See the CONTRIBUTING file for how to help out. + +## License +Shimmer is BSD-licensed. We also provide an additional patent grant. + diff --git a/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig index 1b0bf9d..7fe4d45 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-AFNetworking.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/AFNetworking" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/AFNetworking" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = ${PODS_AFNETWORKING_OTHER_LDFLAGS} -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig index 82c7242..d871d3a 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-MJRefresh.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/MJRefresh" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/MJRefresh" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig index 757ac0c..4ce8560 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-Mantle.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/Mantle" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/Mantle" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = ${PODS_MANTLE_OTHER_LDFLAGS} -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig index 5cff63d..9253287 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-SDWebImage.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = ${PODS_SDWEBIMAGE_OTHER_LDFLAGS} -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig index ad76ac9..a353705 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-SVProgressHUD.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVProgressHUD" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVProgressHUD" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = ${PODS_SVPROGRESSHUD_OTHER_LDFLAGS} -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig index efe0096..2bf9c60 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-SVWebViewController.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVWebViewController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVWebViewController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig index b29e583..c85ddcc 100644 --- a/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig @@ -1,5 +1,5 @@ #include "Pods-SWTableViewCell.xcconfig" GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SWTableViewCell" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SWTableViewCell" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" OTHER_LDFLAGS = -ObjC PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-Private.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-Private.xcconfig new file mode 100644 index 0000000..a0d7352 --- /dev/null +++ b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-Shimmer.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/Shimmer" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-dummy.m b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-dummy.m new file mode 100644 index 0000000..ad33922 --- /dev/null +++ b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_Shimmer : NSObject +@end +@implementation PodsDummy_Pods_Shimmer +@end diff --git a/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-prefix.pch similarity index 100% rename from iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch rename to iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer-prefix.pch diff --git a/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer.xcconfig b/iOSStudy/Pods/Target Support Files/Pods-Shimmer/Pods-Shimmer.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown b/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown index 3b2ec91..b55e015 100644 --- a/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown +++ b/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown @@ -24,40 +24,9 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -## FMDB - -If you are using FMDB in your project, I'd love to hear about it. Let Gus know -by sending an email to gus@flyingmeat.com. - -And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you -might consider purchasing a drink of their choosing if FMDB has been useful to -you. - -Finally, and shortly, this is the MIT License. - -Copyright (c) 2008-2014 Flying Meat Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - ## MJRefresh -Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) +Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -80,7 +49,7 @@ THE SOFTWARE. ## Mantle -**Copyright (c) 2012 - 2014, GitHub, Inc.** +**Copyright (c) GitHub, Inc.** **All rights reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -202,4 +171,38 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +## Shimmer + +BSD License + +For Shimmer software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + Generated by CocoaPods - http://cocoapods.org diff --git a/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist b/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist index b34b32a..468f2c8 100644 --- a/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist +++ b/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist @@ -41,42 +41,7 @@ THE SOFTWARE. FooterText - If you are using FMDB in your project, I'd love to hear about it. Let Gus know -by sending an email to gus@flyingmeat.com. - -And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you -might consider purchasing a drink of their choosing if FMDB has been useful to -you. - -Finally, and shortly, this is the MIT License. - -Copyright (c) 2008-2014 Flying Meat Inc. - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. - Title - FMDB - Type - PSGroupSpecifier - - - FooterText - Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh) Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -103,7 +68,7 @@ THE SOFTWARE. FooterText - **Copyright (c) 2012 - 2014, GitHub, Inc.** + **Copyright (c) GitHub, Inc.** **All rights reserved.** Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: @@ -246,6 +211,44 @@ THE SOFTWARE. Type PSGroupSpecifier + + FooterText + BSD License + +For Shimmer software + +Copyright (c) 2014, Facebook, Inc. All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name Facebook nor the names of its contributors may be used to + endorse or promote products derived from this software without specific + prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR +ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + Shimmer + Type + PSGroupSpecifier + FooterText Generated by CocoaPods - http://cocoapods.org diff --git a/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h b/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h index 9ec3fd4..918b0dd 100644 --- a/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h +++ b/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h @@ -10,97 +10,79 @@ #define COCOAPODS_POD_AVAILABLE_AFNetworking #define COCOAPODS_VERSION_MAJOR_AFNetworking 2 #define COCOAPODS_VERSION_MINOR_AFNetworking 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking 3 // AFNetworking/NSURLConnection #define COCOAPODS_POD_AVAILABLE_AFNetworking_NSURLConnection #define COCOAPODS_VERSION_MAJOR_AFNetworking_NSURLConnection 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_NSURLConnection 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLConnection 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLConnection 3 // AFNetworking/NSURLSession #define COCOAPODS_POD_AVAILABLE_AFNetworking_NSURLSession #define COCOAPODS_VERSION_MAJOR_AFNetworking_NSURLSession 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_NSURLSession 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLSession 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLSession 3 // AFNetworking/Reachability #define COCOAPODS_POD_AVAILABLE_AFNetworking_Reachability #define COCOAPODS_VERSION_MAJOR_AFNetworking_Reachability 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_Reachability 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_Reachability 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Reachability 3 // AFNetworking/Security #define COCOAPODS_POD_AVAILABLE_AFNetworking_Security #define COCOAPODS_VERSION_MAJOR_AFNetworking_Security 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_Security 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_Security 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Security 3 // AFNetworking/Serialization #define COCOAPODS_POD_AVAILABLE_AFNetworking_Serialization #define COCOAPODS_VERSION_MAJOR_AFNetworking_Serialization 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_Serialization 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_Serialization 1 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Serialization 3 // AFNetworking/UIKit #define COCOAPODS_POD_AVAILABLE_AFNetworking_UIKit #define COCOAPODS_VERSION_MAJOR_AFNetworking_UIKit 2 #define COCOAPODS_VERSION_MINOR_AFNetworking_UIKit 5 -#define COCOAPODS_VERSION_PATCH_AFNetworking_UIKit 1 - -// FMDB -#define COCOAPODS_POD_AVAILABLE_FMDB -#define COCOAPODS_VERSION_MAJOR_FMDB 2 -#define COCOAPODS_VERSION_MINOR_FMDB 5 -#define COCOAPODS_VERSION_PATCH_FMDB 0 - -// FMDB/common -#define COCOAPODS_POD_AVAILABLE_FMDB_common -#define COCOAPODS_VERSION_MAJOR_FMDB_common 2 -#define COCOAPODS_VERSION_MINOR_FMDB_common 5 -#define COCOAPODS_VERSION_PATCH_FMDB_common 0 - -// FMDB/standard -#define COCOAPODS_POD_AVAILABLE_FMDB_standard -#define COCOAPODS_VERSION_MAJOR_FMDB_standard 2 -#define COCOAPODS_VERSION_MINOR_FMDB_standard 5 -#define COCOAPODS_VERSION_PATCH_FMDB_standard 0 +#define COCOAPODS_VERSION_PATCH_AFNetworking_UIKit 3 // MJRefresh #define COCOAPODS_POD_AVAILABLE_MJRefresh -#define COCOAPODS_VERSION_MAJOR_MJRefresh 0 -#define COCOAPODS_VERSION_MINOR_MJRefresh 0 -#define COCOAPODS_VERSION_PATCH_MJRefresh 1 +#define COCOAPODS_VERSION_MAJOR_MJRefresh 1 +#define COCOAPODS_VERSION_MINOR_MJRefresh 4 +#define COCOAPODS_VERSION_PATCH_MJRefresh 6 // Mantle #define COCOAPODS_POD_AVAILABLE_Mantle -#define COCOAPODS_VERSION_MAJOR_Mantle 1 -#define COCOAPODS_VERSION_MINOR_Mantle 5 -#define COCOAPODS_VERSION_PATCH_Mantle 4 +#define COCOAPODS_VERSION_MAJOR_Mantle 2 +#define COCOAPODS_VERSION_MINOR_Mantle 0 +#define COCOAPODS_VERSION_PATCH_Mantle 0 // Mantle/extobjc #define COCOAPODS_POD_AVAILABLE_Mantle_extobjc -#define COCOAPODS_VERSION_MAJOR_Mantle_extobjc 1 -#define COCOAPODS_VERSION_MINOR_Mantle_extobjc 5 -#define COCOAPODS_VERSION_PATCH_Mantle_extobjc 4 +#define COCOAPODS_VERSION_MAJOR_Mantle_extobjc 2 +#define COCOAPODS_VERSION_MINOR_Mantle_extobjc 0 +#define COCOAPODS_VERSION_PATCH_Mantle_extobjc 0 // SDWebImage #define COCOAPODS_POD_AVAILABLE_SDWebImage #define COCOAPODS_VERSION_MAJOR_SDWebImage 3 #define COCOAPODS_VERSION_MINOR_SDWebImage 7 -#define COCOAPODS_VERSION_PATCH_SDWebImage 1 +#define COCOAPODS_VERSION_PATCH_SDWebImage 2 // SDWebImage/Core #define COCOAPODS_POD_AVAILABLE_SDWebImage_Core #define COCOAPODS_VERSION_MAJOR_SDWebImage_Core 3 #define COCOAPODS_VERSION_MINOR_SDWebImage_Core 7 -#define COCOAPODS_VERSION_PATCH_SDWebImage_Core 1 +#define COCOAPODS_VERSION_PATCH_SDWebImage_Core 2 // SVProgressHUD #define COCOAPODS_POD_AVAILABLE_SVProgressHUD #define COCOAPODS_VERSION_MAJOR_SVProgressHUD 1 #define COCOAPODS_VERSION_MINOR_SVProgressHUD 1 -#define COCOAPODS_VERSION_PATCH_SVProgressHUD 2 +#define COCOAPODS_VERSION_PATCH_SVProgressHUD 3 // SVWebViewController #define COCOAPODS_POD_AVAILABLE_SVWebViewController @@ -114,3 +96,9 @@ #define COCOAPODS_VERSION_MINOR_SWTableViewCell 3 #define COCOAPODS_VERSION_PATCH_SWTableViewCell 7 +// Shimmer +#define COCOAPODS_POD_AVAILABLE_Shimmer +#define COCOAPODS_VERSION_MAJOR_Shimmer 1 +#define COCOAPODS_VERSION_MINOR_Shimmer 0 +#define COCOAPODS_VERSION_PATCH_Shimmer 2 + diff --git a/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig b/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig index 0d3ecc7..a9ebf03 100644 --- a/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig @@ -1,6 +1,6 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/FMDB" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" -OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-FMDB" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"sqlite3" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" -isystem "${PODS_ROOT}/Headers/Public/Shimmer" +OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"Pods-Shimmer" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig b/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig index 0d3ecc7..a9ebf03 100644 --- a/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig +++ b/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig @@ -1,6 +1,6 @@ GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 -HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" -OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/FMDB" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" -OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-FMDB" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"sqlite3" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" "${PODS_ROOT}/Headers/Public/Shimmer" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" -isystem "${PODS_ROOT}/Headers/Public/Shimmer" +OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"Pods-Shimmer" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/iOSStudy/README.md b/iOSStudy/README.md new file mode 100644 index 0000000..5e7dc73 --- /dev/null +++ b/iOSStudy/README.md @@ -0,0 +1,2 @@ +# iOSStudy +iOSStudy是一个开源的iOS应用内容是致力于帮助iOS开发者找到适合自己的学习资源 diff --git a/iOSStudy/Tools/CoreDataUtils.h b/iOSStudy/Tools/CoreDataUtils.h new file mode 100644 index 0000000..5dd64a9 --- /dev/null +++ b/iOSStudy/Tools/CoreDataUtils.h @@ -0,0 +1,41 @@ +// +// CoreDataUtils.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface CoreDataUtils : NSObject +/** + * 检查数据是否在表中已经存在 + * + * @param tableName 表名 + * @param predicate 查询条件 + * + * @return YES 存在 NO不存在 + */ ++(BOOL)dataisExistTableName:(NSString*)tableName withPredicate:(NSPredicate*)predicate; + + +/** + * 查询数据 + * @param tableName 查询的表明称 + * @param predicate NSPredicate 查询条件 nil时表示没有查询条件 + * + * @return NSManagedObject 集合 + */ ++(NSArray*)queryDataFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)predicate; + + +/** + * 删除指定表中的数据 + + * + * @param tableName 表名 + * @param andNSPredicate 删除条件 为nil 删除所有数据 + */ ++(void)deleteDateFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)andNSPredicate; +@end diff --git a/iOSStudy/Tools/CoreDataUtils.m b/iOSStudy/Tools/CoreDataUtils.m new file mode 100644 index 0000000..c1fe7ec --- /dev/null +++ b/iOSStudy/Tools/CoreDataUtils.m @@ -0,0 +1,108 @@ +// +// CoreDataUtils.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "CoreDataUtils.h" +#import +#import "Constants .h" +@implementation CoreDataUtils + +/** + * 检查数据是否在表中已经存在 + * + * @param url http地址 + * @param tableName 表名 + * @param rowName 数据所在的列名 + * + * @return YES 存在 NO 不存在 + */ ++(BOOL)dataisExistTableName:(NSString*)tableName withPredicate:(NSPredicate*)predicate{ + + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:tableName inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + if (predicate) { + fetchRequest.predicate = predicate; + } + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + + //NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"%@ = %@",rowName, url]; + + + if (fetchedObjects.count!=0) { + // NSLog(@"111%lu",resultArr.count); + return YES; + }else{ + // NSLog(@"222%lu",resultArr.count); + return NO; + } + + +} + +/** + * 查询数据 + * @param tableName 查询的表明称 + * @param predicate NSPredicate 查询条件 nil时表示没有查询条件 + * + * @return NSManagedObject 集合 + */ ++(NSArray*)queryDataFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)predicate{ + + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:tableName inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + // NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url= %@", url]; + if (predicate) { + fetchRequest.predicate = predicate; + } + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + return [fetchedObjects filteredArrayUsingPredicate:predicate]; + + +} + + +/** + * 删除指定表中的数据 + + * + * @param tableName 表名 + * @param andNSPredicate 删除条件 为nil 删除所有数据 + */ ++(void)deleteDateFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)andNSPredicate{ + //存储之前先删除原来的数据 + + //NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", @"11"]; + + NSArray* managerObjtList = [CoreDataUtils queryDataFromTableName:tableName andNSPredicate:andNSPredicate]; + + for (NSManagedObject *obct in managerObjtList) { + [SharedApp.managedObjectContext deleteObject:obct]; + } + + + NSError *error = nil; + if (![SharedApp.managedObjectContext save:&error]) { + NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); + return; + } + +} +@end diff --git a/iOSStudy/Tools/HttpVersionTools.h b/iOSStudy/Tools/HttpVersionTools.h new file mode 100644 index 0000000..fbb382d --- /dev/null +++ b/iOSStudy/Tools/HttpVersionTools.h @@ -0,0 +1,79 @@ +// +// HttpVersionTools.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + + +/** + * 网络请求成功回调 + */ +typedef void (^versionSuccess)(NSArray*versionLists); +/** + * 网络请求失败回调 + */ +typedef void (^versionError)(); + +/** + * 网络是否链接回调 + * + * @param isNetWorking YES 有网络 NO 没有网络 + */ +typedef void (^versionNetWorking)(BOOL isNetWorking); + + +@interface HttpVersionTools : NSObject + + +/** + * 得到当前服务器版本号列表 + * + * @return 服务器版本号列表 + */ ++(void)getVersions:(versionSuccess)v_success v_error:(versionError)v_error v_netWork:(versionNetWorking)v_netWork; + + +/** + * 判断版本号是否向服务器请求最新数据 + * + * @param url http请求地址 + * + * @return YES 发送请求 NO 不发送请求 + */ ++(BOOL)checkHttpVersion:(NSString*)url nowVersion:(NSString*)nowVersion; + + +/** + * 返回服务器当前url版本号 + * + * @param url http请求地址 + * + * @return 服务器当前url版本号 + */ ++(NSString*)getNowHttpVersion:(NSString*)url; + + +/** + * 得到URL本地版本号 + * + * @param url URL地址 + * + * @return !nil 本地版本号 nil 没有本地版本号 + */ ++(NSString*)getLocalHttpVersion:(NSString*)url; + + + +/** + * 存储当前服务器返回的版本号 + * + * @param url http 请求地址 + * @param version 版本号 + */ ++(void)saveNowHttpVersion:(NSString*)url version:(NSString*)version; + +@end diff --git a/iOSStudy/Tools/HttpVersionTools.m b/iOSStudy/Tools/HttpVersionTools.m new file mode 100644 index 0000000..087f8b6 --- /dev/null +++ b/iOSStudy/Tools/HttpVersionTools.m @@ -0,0 +1,204 @@ +// +// HttpVersionTools.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "HttpVersionTools.h" +#import "NetWorkTools.h" +#import "JsonTools.h" +#import +#import "VersionBean.h" +#import "CoreDataUtils.h" +@implementation HttpVersionTools + ++(void)getVersions:(versionSuccess)v_success v_error:(versionError)v_error v_netWork:(versionNetWorking)v_netWork{ + + + __block NSMutableArray*versionArr = [NSMutableArray arrayWithCapacity:5]; + + [NetWorkTools postHttp:Adress_versions success:^(AFHTTPRequestOperation *operation, id responseObject) { + + NSLog(@"JSON: %@", [operation responseString]); + + NSArray *dic = [JsonTools getJsonNSDictionary:[operation responseString]]; + + //将JSON数据和Model的属性进行绑定 + + NSArray *arr = [MTLJSONAdapter modelsOfClass:[VersionBean class] fromJSONArray:dic error:nil]; + + versionArr = [arr copy]; + +// for (VersionBean *vBean in versionArr) { +// NSLog(@"version =%@",vBean.urlVersion); +// } + + v_success(versionArr); + + } error:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + + v_error(); + + } isNetworking:^(BOOL isNetwork) { + + + v_netWork(isNetwork); + }]; + + +} + +/** + * 返回服务器当前url版本号 + * + * @param url http请求地址 + * + * @return 服务器当前url版本号 + */ ++(NSString*)getNowHttpVersion:(NSString*)url{ + + NSString *versionStr ; + for (VersionBean *vBean in SharedApp.versionLists) { + + + if ([vBean.url isEqualToString:url]) { + + versionStr = vBean.urlVersion; + return versionStr; + }else{ + versionStr = nil; + } + } + NSLog(@"nowVersion = %@",versionStr); + return versionStr; +} + + +/** + * 存储当前服务器返回的版本号 + * + * @param url http 请求地址 + * @param version 版本号 + */ ++(void)saveNowHttpVersion:(NSString*)url version:(NSString*)version{ + + NSString *log ; + + //当数据存在事后执行更新操作 + //[CoreDataUtils dataisExist:url inTable:CD_VersionsEntity tableRowName:@"url"] + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"url = %@", url]; + if ( + [CoreDataUtils dataisExistTableName:CD_VersionsEntity withPredicate:urlPredicate] + ) + + { + + + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"url= %@", url]; + + NSArray *managerList = [CoreDataUtils queryDataFromTableName:CD_VersionsEntity andNSPredicate:urlPredicate]; + + if (managerList.count!=0) { + NSManagedObject *updateObjt= managerList.firstObject; + [updateObjt setValue:url forKey:@"url"]; + [updateObjt setValue:version forKey:@"url_version"]; + } + + log = @"版本更新成功"; + + } + else + //当数据不存在的事后执行插入操作 + { + NSManagedObject *managerObjt =[NSEntityDescription insertNewObjectForEntityForName:CD_VersionsEntity inManagedObjectContext:SharedApp.managedObjectContext]; + + + [managerObjt setValue:url forKey:@"url"]; + [managerObjt setValue:version forKey:@"url_version"];; + + log = @"版本插入成功"; + + } + + NSError *error; + if (![SharedApp.managedObjectContext save:&error]) + { + NSLog(@"%@: %@", log,[error localizedDescription]); + + } + + +} + + + +/** + * 判断版本号是否向服务器请求最新数据 + * + * @param url http请求地址 + * + * @return YES 发送请求 NO 不发送请求 + */ ++(BOOL)checkHttpVersion:(NSString*)url nowVersion:(NSString*)nowVersion{ + + + + + if (nowVersion!=nil) { + //从数据库拿到URL 版本号 如果没有说明第一次请求 直接发送请求 + + if ([[self getLocalHttpVersion:url]floatValue]!=[nowVersion floatValue]) { + + + + return YES; + }else{ + return NO; + } + }else{ + return YES; + } + + +} + +/** + * 得到URL本地版本号 + * + * @param url URL地址 + * + * @return !nil 本地版本号 nil 没有本地版本号 + */ ++(NSString*)getLocalHttpVersion:(NSString*)url{ + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:CD_VersionsEntity inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url = %@", url]; + + + NSArray *resultArr = [fetchedObjects filteredArrayUsingPredicate:titlePredicate]; + if (resultArr.count!=0) { + NSLog(@"111%lu",resultArr.count); + + NSManagedObject *objt = resultArr[0]; + + + return [objt valueForKey:@"url_version"]; + }else{ + NSLog(@"没有查到本地版本%lu",resultArr.count); + return nil; + } + + +} + +@end diff --git a/iOSStudy/Tools/NetWorkTools.m b/iOSStudy/Tools/NetWorkTools.m index 0b30257..1f35168 100644 --- a/iOSStudy/Tools/NetWorkTools.m +++ b/iOSStudy/Tools/NetWorkTools.m @@ -24,6 +24,7 @@ + (instancetype)sharedInstance { +(void)postHttp:(NSString*)httpUrl success:(success)success error:(error)error isNetworking:(isNetwork)isNetworking{ + if (SharedApp.isNetworking) { AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; @@ -50,56 +51,7 @@ +(void)postHttp:(NSString*)httpUrl success:(success)success error:(error)error i +(void)checkNetworking{ - - - - // Allocate a reachability object - Reachability* reach = [Reachability reachabilityWithHostname:@"http://www.baidu.com"]; - - // Set the blocks - reach.reachableBlock = ^(Reachability*reach) - { - // keep in mind this is called on a background thread - // and if you are updating the UI it needs to happen - // on the main thread, like this: - - NSLog(@"网络已经连接!"); - - - SharedApp.isNetworking = YES; - - [SVProgressHUD dismiss]; - - - }; - - reach.unreachableBlock = ^(Reachability*reach) - { - NSLog(@"网络断开!"); - - SharedApp.isNetworking = YES; - - dispatch_async(dispatch_get_main_queue(), ^{ - - [SVProgressHUD showErrorWithStatus:@"无网络连接" maskType:SVProgressHUDMaskTypeGradient]; - - double delayInSeconds = 2.0; - dispatch_time_t - popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); - dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ - // code to be executed on the main queue after delay - - [SVProgressHUD dismiss]; - }); - }); - - }; - - // Start the notifier, which will cause the reachability object to retain itself! - [reach startNotifier]; - - - + } diff --git a/iOSStudy/Tools/WelcomeTools.h b/iOSStudy/Tools/WelcomeTools.h new file mode 100644 index 0000000..e01fd95 --- /dev/null +++ b/iOSStudy/Tools/WelcomeTools.h @@ -0,0 +1,18 @@ +// +// WelcomeTools.h +// iOSStudy +// +// Created by chenguandong on 15/4/10. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "Reachability.h" + +static Reachability *reach; +@interface WelcomeTools : NSObject + ++ (instancetype)sharedInstance ; + + +@end diff --git a/iOSStudy/Tools/WelcomeTools.m b/iOSStudy/Tools/WelcomeTools.m new file mode 100644 index 0000000..13a4447 --- /dev/null +++ b/iOSStudy/Tools/WelcomeTools.m @@ -0,0 +1,108 @@ +// +// WelcomeTools.m +// iOSStudy +// +// Created by chenguandong on 15/4/10. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WelcomeTools.h" +#import "HttpVersionTools.h" +#import "Constants .h" +#import "NetWorkTools.h" +#import +#import "Reachability.h" +#import "NotificationCenterConstants.h" +@implementation WelcomeTools +{ + +} ++ (instancetype)sharedInstance { + static dispatch_once_t once; + static id sharedInstance; + dispatch_once(&once, ^{ + sharedInstance = [[self alloc] init]; + + [self initNetWork]; + + }); + return sharedInstance; +} + + ++(void)initNetWork{ + // Allocate a reachability object + reach = [Reachability reachabilityWithHostname:@"www.baidu.com"]; + + // Set the blocks + reach.reachableBlock = ^(Reachability*reach) + { + // keep in mind this is called on a background thread + // and if you are updating the UI it needs to happen + // on the main thread, like this: + + NSLog(@"网络已经连接!"); + + + SharedApp.isNetworking = YES; + + [SVProgressHUD dismiss]; + + if (!SharedApp.versionLists) { + [self regetHttpVersion]; + } + + + }; + + reach.unreachableBlock = ^(Reachability*reach) + { + NSLog(@"网络断开!"); + + SharedApp.isNetworking = NO; + + dispatch_async(dispatch_get_main_queue(), ^{ + + [SVProgressHUD showErrorWithStatus:@"无网络连接" maskType:SVProgressHUDMaskTypeGradient]; + + double delayInSeconds = 2.0; + dispatch_time_t + popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + // code to be executed on the main queue after delay + [self sendVersionSuccess]; + [SVProgressHUD dismiss]; + }); + }); + + }; + + // Start the notifier, which will cause the reachability object to retain itself! + [reach startNotifier]; + + + +} + +-(void)dealloc{ + [reach stopNotifier]; +} + ++(void)regetHttpVersion{ + //获取服务器HTTP当前版本号 + + [HttpVersionTools getVersions:^(NSArray *versionLists) { + SharedApp.versionLists = versionLists; + [self sendVersionSuccess]; + } v_error:^{ + [self sendVersionSuccess]; + } v_netWork:^(BOOL isNetWorking) { + [self sendVersionSuccess]; + }]; +} + ++(void)sendVersionSuccess{ + [[NSNotificationCenter defaultCenter]postNotificationName:notifacationVersionSuccess object:nil userInfo:nil]; +} + +@end diff --git a/iOSStudy/ViewColl/BlogDetailViewController.m b/iOSStudy/ViewColl/BlogDetailViewController.m index d1e511c..16b36ab 100644 --- a/iOSStudy/ViewColl/BlogDetailViewController.m +++ b/iOSStudy/ViewColl/BlogDetailViewController.m @@ -7,7 +7,6 @@ // #import "BlogDetailViewController.h" -#import "DBUtils.h" @interface BlogDetailViewController () @end @@ -17,9 +16,7 @@ @implementation BlogDetailViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. - [DBUtils executeSQL:^(FMDatabase *db) { - - }]; + } - (void)didReceiveMemoryWarning { diff --git a/iOSStudy/iOSStudy.xcodeproj/project.pbxproj b/iOSStudy/iOSStudy.xcodeproj/project.pbxproj index 77fbb5b..2a6ae61 100644 --- a/iOSStudy/iOSStudy.xcodeproj/project.pbxproj +++ b/iOSStudy/iOSStudy.xcodeproj/project.pbxproj @@ -7,33 +7,46 @@ objects = { /* Begin PBXBuildFile section */ - 184F48AF1A93321700C5C22F /* SecondViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */; }; + 1839702E1B0182720098318E /* Info.plist in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B231A7A14D100E80854 /* Info.plist */; }; + 183970351B01A6C50098318E /* Localizable.strings in Resources */ = {isa = PBXBuildFile; fileRef = 183970371B01A6C50098318E /* Localizable.strings */; }; + 184F48AF1A93321700C5C22F /* WebViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F48AE1A93321700C5C22F /* WebViewControllerViewModel.m */; }; 184F48B41A93340F00C5C22F /* WebBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F48B31A93340F00C5C22F /* WebBean.m */; }; 185EEB4B1A98DC9900BFDB79 /* SettingTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185EEB4A1A98DC9900BFDB79 /* SettingTableViewController.m */; }; 185EEB4F1A98E0BA00BFDB79 /* tabbar_setting.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */; }; 185EEB501A98E0BA00BFDB79 /* tabbar_setting@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */; }; 185EEB511A98E0BA00BFDB79 /* tabbar_setting@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */; }; + 187E96991AD6BED500D164FA /* NotificationCenterConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 187E96981AD6BED500D164FA /* NotificationCenterConstants.m */; }; + 189BC7DC1AE4ED7C0051EDCD /* UINavigationBar+Awesome.m in Sources */ = {isa = PBXBuildFile; fileRef = 189BC7DB1AE4ED7C0051EDCD /* UINavigationBar+Awesome.m */; }; 189EF8331A8399B100F19327 /* BlogBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8321A8399B100F19327 /* BlogBean.m */; }; 189EF8361A839FC600F19327 /* JsonTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8351A839FC600F19327 /* JsonTools.m */; }; 189EF83A1A83C3AF00F19327 /* BlogDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8391A83C3AF00F19327 /* BlogDetailViewController.m */; }; 18A998931A7C77D0002E7219 /* NetWorkTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 18A998921A7C77D0002E7219 /* NetWorkTools.m */; }; 18AB47951A99969600E4C030 /* VideoBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47941A99969600E4C030 /* VideoBean.m */; }; - 18AB47981A99A51200E4C030 /* BaseTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */; }; 18AB479B1A9C59CB00E4C030 /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */; }; - 18AB479F1A9C5E3300E4C030 /* VideoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB479E1A9C5E3300E4C030 /* VideoCell.m */; }; - 18AB47A51A9C82FA00E4C030 /* AddBlogTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */; }; - 18AB47A81A9DA40500E4C030 /* DBUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47A71A9DA40500E4C030 /* DBUtils.m */; }; 18AB47AB1AA415A400E4C030 /* FavouriteBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47AA1AA415A400E4C030 /* FavouriteBean.m */; }; 18B23B251A7A14D100E80854 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B241A7A14D100E80854 /* main.m */; }; 18B23B281A7A14D100E80854 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B271A7A14D100E80854 /* AppDelegate.m */; }; - 18B23B2B1A7A14D100E80854 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2A1A7A14D100E80854 /* FirstViewController.m */; }; - 18B23B2E1A7A14D100E80854 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2D1A7A14D100E80854 /* SecondViewController.m */; }; + 18B23B2B1A7A14D100E80854 /* BlogViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2A1A7A14D100E80854 /* BlogViewController.m */; }; + 18B23B2E1A7A14D100E80854 /* WebViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2D1A7A14D100E80854 /* WebViewController.m */; }; 18B23B311A7A14D100E80854 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B2F1A7A14D100E80854 /* Main.storyboard */; }; 18B23B331A7A14D100E80854 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B321A7A14D100E80854 /* Images.xcassets */; }; - 18B23B361A7A14D100E80854 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B341A7A14D100E80854 /* LaunchScreen.xib */; }; 18B23B421A7A14D100E80854 /* iOSStudyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B411A7A14D100E80854 /* iOSStudyTests.m */; }; 18B23B4D1A7A234800E80854 /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B4C1A7A234800E80854 /* BaseViewController.m */; }; - 18CECC0A1A91ACB7005598E4 /* FirstViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */; }; + 18C845091ACCFC690053884F /* HttpVersionTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845081ACCFC690053884F /* HttpVersionTools.m */; }; + 18C8450C1ACD41C40053884F /* BlogJsonBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C8450B1ACD41C40053884F /* BlogJsonBean.m */; }; + 18C8450F1ACE3E580053884F /* CoreDataUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C8450E1ACE3E580053884F /* CoreDataUtils.m */; }; + 18C845121ACE4A580053884F /* WelcomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845111ACE4A580053884F /* WelcomeViewController.m */; }; + 18C845151ACE56150053884F /* MainTabBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845141ACE56150053884F /* MainTabBarViewController.m */; }; + 18CB71211AD55BFD00D72204 /* libPushSDK-1.8.3.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB71201AD55BFD00D72204 /* libPushSDK-1.8.3.a */; }; + 18CB71241AD56C2100D72204 /* CFNetwork.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB71231AD56C2000D72204 /* CFNetwork.framework */; }; + 18CB71261AD56C3000D72204 /* CoreFoundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB71251AD56C3000D72204 /* CoreFoundation.framework */; }; + 18CB71281AD56C4000D72204 /* CoreTelephony.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB71271AD56C4000D72204 /* CoreTelephony.framework */; }; + 18CB712A1AD56C6200D72204 /* libz.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 18CB71291AD56C6200D72204 /* libz.dylib */; }; + 18CB712C1AD570B200D72204 /* PushConfig.plist in Resources */ = {isa = PBXBuildFile; fileRef = 18CB712B1AD570B200D72204 /* PushConfig.plist */; }; + 18CECC0A1A91ACB7005598E4 /* BlogViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CECC091A91ACB7005598E4 /* BlogViewControllerViewModel.m */; }; + 18D184821AD28D1900188C3C /* FavouriteTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D184811AD28D1900188C3C /* FavouriteTableViewController.m */; }; + 18D184851AD2904900188C3C /* FavouriteViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D184841AD2904900188C3C /* FavouriteViewControllerViewModel.m */; }; + 18D184871AD2E0B700188C3C /* MessageUI.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18D184861AD2E0B700188C3C /* MessageUI.framework */; }; 18D201161A95A6F400D5F095 /* icon_29.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010D1A95A6F400D5F095 /* icon_29.png */; }; 18D201171A95A6F400D5F095 /* icon_40.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010E1A95A6F400D5F095 /* icon_40.png */; }; 18D201181A95A6F400D5F095 /* icon_58.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010F1A95A6F400D5F095 /* icon_58.png */; }; @@ -52,19 +65,56 @@ 18D2012E1A95A9D600D5F095 /* tabbar_web.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201281A95A9D600D5F095 /* tabbar_web.png */; }; 18D2012F1A95A9D600D5F095 /* tabbar_web@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201291A95A9D600D5F095 /* tabbar_web@2x.png */; }; 18D201301A95A9D600D5F095 /* tabbar_web@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2012A1A95A9D600D5F095 /* tabbar_web@3x.png */; }; - 18D201351A96090A00D5F095 /* app_img_640.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201321A96090A00D5F095 /* app_img_640.png */; }; - 18D201361A96090A00D5F095 /* app_img_1136.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201331A96090A00D5F095 /* app_img_1136.png */; }; - 18D201371A96090A00D5F095 /* app_img_iOS8.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201341A96090A00D5F095 /* app_img_iOS8.png */; }; - 18D2013C1A960B6100D5F095 /* app_img_768x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201381A960B6100D5F095 /* app_img_768x1024.png */; }; - 18D2013D1A960B6100D5F095 /* app_img_1024x768.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201391A960B6100D5F095 /* app_img_1024x768.png */; }; - 18D2013E1A960B6100D5F095 /* app_img_1536x2048.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */; }; - 18D2013F1A960B6100D5F095 /* app_img_2048x1536.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */; }; - 18D201421A96143300D5F095 /* ThirdViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */; }; - 18D908A71A8A205600B42A42 /* ThirdTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */; }; + 18D201421A96143300D5F095 /* VideoViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D201411A96143300D5F095 /* VideoViewControllerViewModel.m */; }; + 18D4ECA61AD17F56009FE9F0 /* EntityConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */; }; + 18D908A71A8A205600B42A42 /* VideoTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D908A61A8A205600B42A42 /* VideoTableViewController.m */; }; 18DF6D3D1A80D3BC005751E8 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 18DF6D3C1A80D3BC005751E8 /* Reachability.m */; }; 18DF6D3F1A80D40D005751E8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */; }; 18E016AA1ACAA898002A6E59 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18E016A91ACAA898002A6E59 /* CoreData.framework */; }; 18E016E51ACAAB35002A6E59 /* iOSStudy.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 18E016E31ACAAB35002A6E59 /* iOSStudy.xcdatamodeld */; }; + 18E2796A1AD61AD50056CC5F /* iRate.bundle in Resources */ = {isa = PBXBuildFile; fileRef = 18E279671AD61AD50056CC5F /* iRate.bundle */; }; + 18E2796B1AD61AD50056CC5F /* iRate.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E279691AD61AD50056CC5F /* iRate.m */; }; + 18E2796E1AD6206F0056CC5F /* LicenesViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E2796D1AD6206F0056CC5F /* LicenesViewController.m */; }; + 18E279711AD62CD80056CC5F /* licenes.html in Resources */ = {isa = PBXBuildFile; fileRef = 18E279701AD62CD80056CC5F /* licenes.html */; }; + 18E3600A1AD67BB500A077B2 /* STBaseTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E360081AD67BB500A077B2 /* STBaseTableViewCell.m */; }; + 18E3600B1AD67BB500A077B2 /* STBaseTableViewCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18E360091AD67BB500A077B2 /* STBaseTableViewCell.xib */; }; + 18E6A0B51ACCF7FD00B28D32 /* VersionBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */; }; + 18EC479E1AD773A200C397E5 /* WelcomeTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 18EC479D1AD773A200C397E5 /* WelcomeTools.m */; }; + 18EC47A81AD7949100C397E5 /* img_640x960.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC479F1AD7949100C397E5 /* img_640x960.png */; }; + 18EC47A91AD7949100C397E5 /* img_640x1136.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A01AD7949100C397E5 /* img_640x1136.png */; }; + 18EC47AA1AD7949100C397E5 /* img_750x1334.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A11AD7949100C397E5 /* img_750x1334.png */; }; + 18EC47AB1AD7949100C397E5 /* img_768x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A21AD7949100C397E5 /* img_768x1024.png */; }; + 18EC47AC1AD7949100C397E5 /* img_1024x768.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A31AD7949100C397E5 /* img_1024x768.png */; }; + 18EC47AD1AD7949100C397E5 /* img_1242x2208.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A41AD7949100C397E5 /* img_1242x2208.png */; }; + 18EC47AE1AD7949100C397E5 /* img_1536x2048.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A51AD7949100C397E5 /* img_1536x2048.png */; }; + 18EC47AF1AD7949100C397E5 /* img_2048x1536.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A61AD7949100C397E5 /* img_2048x1536.png */; }; + 18EC47B01AD7949100C397E5 /* img_2208x1242.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47A71AD7949100C397E5 /* img_2208x1242.png */; }; + 18EC47B91AD7AE3200C397E5 /* welcome_bg.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47B71AD7AE3200C397E5 /* welcome_bg.png */; }; + 18EC47BA1AD7AE3200C397E5 /* welcome_icon.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47B81AD7AE3200C397E5 /* welcome_icon.png */; }; + 18EC47BE1AD7C22300C397E5 /* about_us.html in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47BD1AD7C22300C397E5 /* about_us.html */; }; + 18EC47D41AD7C62F00C397E5 /* anim_01.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C01AD7C62F00C397E5 /* anim_01.png */; }; + 18EC47D51AD7C62F00C397E5 /* anim_02.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C11AD7C62F00C397E5 /* anim_02.png */; }; + 18EC47D61AD7C62F00C397E5 /* anim_03.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C21AD7C62F00C397E5 /* anim_03.png */; }; + 18EC47D71AD7C62F00C397E5 /* anim_04.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C31AD7C62F00C397E5 /* anim_04.png */; }; + 18EC47D81AD7C62F00C397E5 /* anim_05.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C41AD7C62F00C397E5 /* anim_05.png */; }; + 18EC47D91AD7C62F00C397E5 /* anim_06.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C51AD7C62F00C397E5 /* anim_06.png */; }; + 18EC47DA1AD7C62F00C397E5 /* anim_07.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C61AD7C62F00C397E5 /* anim_07.png */; }; + 18EC47DB1AD7C62F00C397E5 /* anim_08.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C71AD7C62F00C397E5 /* anim_08.png */; }; + 18EC47DC1AD7C62F00C397E5 /* anim_09.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C81AD7C62F00C397E5 /* anim_09.png */; }; + 18EC47DD1AD7C62F00C397E5 /* anim_10.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47C91AD7C62F00C397E5 /* anim_10.png */; }; + 18EC47DE1AD7C62F00C397E5 /* anim_11.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CA1AD7C62F00C397E5 /* anim_11.png */; }; + 18EC47DF1AD7C62F00C397E5 /* anim_12.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CB1AD7C62F00C397E5 /* anim_12.png */; }; + 18EC47E01AD7C62F00C397E5 /* anim_13.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CC1AD7C62F00C397E5 /* anim_13.png */; }; + 18EC47E11AD7C62F00C397E5 /* anim_14.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CD1AD7C62F00C397E5 /* anim_14.png */; }; + 18EC47E21AD7C62F00C397E5 /* anim_15.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CE1AD7C62F00C397E5 /* anim_15.png */; }; + 18EC47E31AD7C62F00C397E5 /* anim_16.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47CF1AD7C62F00C397E5 /* anim_16.png */; }; + 18EC47E41AD7C62F00C397E5 /* anim_17.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47D01AD7C62F00C397E5 /* anim_17.png */; }; + 18EC47E51AD7C62F00C397E5 /* anim_18.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47D11AD7C62F00C397E5 /* anim_18.png */; }; + 18EC47E61AD7C62F00C397E5 /* anim_19.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47D21AD7C62F00C397E5 /* anim_19.png */; }; + 18EC47E71AD7C62F00C397E5 /* anim_20.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47D31AD7C62F00C397E5 /* anim_20.png */; }; + 18EC47EB1AD7FE8200C397E5 /* tabbar_ favourite.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47E81AD7FE8200C397E5 /* tabbar_ favourite.png */; }; + 18EC47EC1AD7FE8200C397E5 /* tabbar_ favourite@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47E91AD7FE8200C397E5 /* tabbar_ favourite@2x.png */; }; + 18EC47ED1AD7FE8200C397E5 /* tabbar_ favourite@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18EC47EA1AD7FE8200C397E5 /* tabbar_ favourite@3x.png */; }; 54A0444849F1931415392FC1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E83ED1B8EA89BC57ACF91BA5 /* libPods.a */; }; /* End PBXBuildFile section */ @@ -80,8 +130,12 @@ /* Begin PBXFileReference section */ 05EB633B553B549AA5102110 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; - 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecondViewControllerViewModel.m; path = iOSStudy/ViewModel/SecondViewControllerViewModel.m; sourceTree = ""; }; - 184F48B01A93323F00C5C22F /* SecondViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecondViewControllerViewModel.h; path = iOSStudy/ViewModel/SecondViewControllerViewModel.h; sourceTree = ""; }; + 183970301B0182A00098318E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Main.strings; sourceTree = ""; }; + 183970321B0182A60098318E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Main.strings"; sourceTree = ""; }; + 183970361B01A6C50098318E /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/Localizable.strings; sourceTree = ""; }; + 183970381B01A6C70098318E /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/Localizable.strings"; sourceTree = ""; }; + 184F48AE1A93321700C5C22F /* WebViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WebViewControllerViewModel.m; path = iOSStudy/ViewModel/WebViewControllerViewModel.m; sourceTree = ""; }; + 184F48B01A93323F00C5C22F /* WebViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebViewControllerViewModel.h; path = iOSStudy/ViewModel/WebViewControllerViewModel.h; sourceTree = ""; }; 184F48B21A93340F00C5C22F /* WebBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebBean.h; path = Bean/webBean/WebBean.h; sourceTree = ""; }; 184F48B31A93340F00C5C22F /* WebBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WebBean.m; path = Bean/webBean/WebBean.m; sourceTree = ""; }; 185EEB491A98DC9900BFDB79 /* SettingTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingTableViewController.h; sourceTree = ""; }; @@ -89,6 +143,10 @@ 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_setting.png; path = " Resource/images/tabbar/tabbar_setting.png"; sourceTree = ""; }; 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_setting@2x.png"; path = " Resource/images/tabbar/tabbar_setting@2x.png"; sourceTree = ""; }; 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_setting@3x.png"; path = " Resource/images/tabbar/tabbar_setting@3x.png"; sourceTree = ""; }; + 187E96971AD6BED500D164FA /* NotificationCenterConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NotificationCenterConstants.h; path = libs/NotificationCenterConstants.h; sourceTree = ""; }; + 187E96981AD6BED500D164FA /* NotificationCenterConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NotificationCenterConstants.m; path = libs/NotificationCenterConstants.m; sourceTree = ""; }; + 189BC7DA1AE4ED7C0051EDCD /* UINavigationBar+Awesome.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UINavigationBar+Awesome.h"; path = "libs/UINavigationBar+Awesome.h"; sourceTree = ""; }; + 189BC7DB1AE4ED7C0051EDCD /* UINavigationBar+Awesome.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UINavigationBar+Awesome.m"; path = "libs/UINavigationBar+Awesome.m"; sourceTree = ""; }; 189EF8311A8399B100F19327 /* BlogBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogBean.h; path = Bean/blogBean/BlogBean.h; sourceTree = ""; }; 189EF8321A8399B100F19327 /* BlogBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogBean.m; path = Bean/blogBean/BlogBean.m; sourceTree = ""; }; 189EF8341A839FC600F19327 /* JsonTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JsonTools.h; path = Tools/JsonTools.h; sourceTree = ""; }; @@ -99,16 +157,8 @@ 18A998921A7C77D0002E7219 /* NetWorkTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetWorkTools.m; path = Tools/NetWorkTools.m; sourceTree = ""; }; 18AB47931A99969600E4C030 /* VideoBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoBean.h; path = Bean/videoBean/VideoBean.h; sourceTree = ""; }; 18AB47941A99969600E4C030 /* VideoBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoBean.m; path = Bean/videoBean/VideoBean.m; sourceTree = ""; }; - 18AB47961A99A51200E4C030 /* BaseTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseTableViewCell.h; path = Base/BaseTableViewCell.h; sourceTree = ""; }; - 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BaseTableViewCell.m; path = Base/BaseTableViewCell.m; sourceTree = ""; }; 18AB47991A9C59CB00E4C030 /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Resize.h"; path = "libs/UIImage+Resize.h"; sourceTree = ""; }; 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Resize.m"; path = "libs/UIImage+Resize.m"; sourceTree = ""; }; - 18AB479D1A9C5E3300E4C030 /* VideoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoCell.h; path = Cell/VideoCell.h; sourceTree = ""; }; - 18AB479E1A9C5E3300E4C030 /* VideoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoCell.m; path = Cell/VideoCell.m; sourceTree = ""; }; - 18AB47A31A9C82FA00E4C030 /* AddBlogTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddBlogTableViewController.h; sourceTree = ""; }; - 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddBlogTableViewController.m; sourceTree = ""; }; - 18AB47A61A9DA40500E4C030 /* DBUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DBUtils.h; path = Tools/DBUtils.h; sourceTree = ""; }; - 18AB47A71A9DA40500E4C030 /* DBUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DBUtils.m; path = Tools/DBUtils.m; sourceTree = ""; }; 18AB47A91AA415A400E4C030 /* FavouriteBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FavouriteBean.h; path = Bean/FavouriteBean.h; sourceTree = ""; }; 18AB47AA1AA415A400E4C030 /* FavouriteBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FavouriteBean.m; path = Bean/FavouriteBean.m; sourceTree = ""; }; 18B23B1F1A7A14D000E80854 /* iOSStudy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSStudy.app; sourceTree = BUILT_PRODUCTS_DIR; }; @@ -116,21 +166,41 @@ 18B23B241A7A14D100E80854 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 18B23B261A7A14D100E80854 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 18B23B271A7A14D100E80854 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; - 18B23B291A7A14D100E80854 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; - 18B23B2A1A7A14D100E80854 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; - 18B23B2C1A7A14D100E80854 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; - 18B23B2D1A7A14D100E80854 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; + 18B23B291A7A14D100E80854 /* BlogViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = BlogViewController.h; sourceTree = ""; }; + 18B23B2A1A7A14D100E80854 /* BlogViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = BlogViewController.m; sourceTree = ""; }; + 18B23B2C1A7A14D100E80854 /* WebViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = WebViewController.h; sourceTree = ""; }; + 18B23B2D1A7A14D100E80854 /* WebViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = WebViewController.m; sourceTree = ""; }; 18B23B301A7A14D100E80854 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 18B23B321A7A14D100E80854 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; - 18B23B351A7A14D100E80854 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; 18B23B3B1A7A14D100E80854 /* iOSStudyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSStudyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 18B23B401A7A14D100E80854 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 18B23B411A7A14D100E80854 /* iOSStudyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSStudyTests.m; sourceTree = ""; }; 18B23B4B1A7A234800E80854 /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseViewController.h; path = Base/BaseViewController.h; sourceTree = ""; }; 18B23B4C1A7A234800E80854 /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BaseViewController.m; path = Base/BaseViewController.m; sourceTree = ""; }; - 18CECC081A91ACB6005598E4 /* FirstViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FirstViewControllerViewModel.h; path = iOSStudy/ViewModel/FirstViewControllerViewModel.h; sourceTree = ""; }; - 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FirstViewControllerViewModel.m; path = iOSStudy/ViewModel/FirstViewControllerViewModel.m; sourceTree = ""; }; - 18CECC101A921272005598E4 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; + 18C845071ACCFC690053884F /* HttpVersionTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HttpVersionTools.h; path = Tools/HttpVersionTools.h; sourceTree = ""; }; + 18C845081ACCFC690053884F /* HttpVersionTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HttpVersionTools.m; path = Tools/HttpVersionTools.m; sourceTree = ""; }; + 18C8450A1ACD41C40053884F /* BlogJsonBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogJsonBean.h; path = Bean/blogBean/BlogJsonBean.h; sourceTree = ""; }; + 18C8450B1ACD41C40053884F /* BlogJsonBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogJsonBean.m; path = Bean/blogBean/BlogJsonBean.m; sourceTree = ""; }; + 18C8450D1ACE3E580053884F /* CoreDataUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreDataUtils.h; path = Tools/CoreDataUtils.h; sourceTree = ""; }; + 18C8450E1ACE3E580053884F /* CoreDataUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CoreDataUtils.m; path = Tools/CoreDataUtils.m; sourceTree = ""; }; + 18C845101ACE4A580053884F /* WelcomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WelcomeViewController.h; sourceTree = ""; }; + 18C845111ACE4A580053884F /* WelcomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WelcomeViewController.m; sourceTree = ""; }; + 18C845131ACE56150053884F /* MainTabBarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainTabBarViewController.h; sourceTree = ""; }; + 18C845141ACE56150053884F /* MainTabBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainTabBarViewController.m; sourceTree = ""; }; + 18CB71201AD55BFD00D72204 /* libPushSDK-1.8.3.a */ = {isa = PBXFileReference; lastKnownFileType = archive.ar; path = "libPushSDK-1.8.3.a"; sourceTree = ""; }; + 18CB71221AD55C0C00D72204 /* APService.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = APService.h; sourceTree = ""; }; + 18CB71231AD56C2000D72204 /* CFNetwork.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CFNetwork.framework; path = System/Library/Frameworks/CFNetwork.framework; sourceTree = SDKROOT; }; + 18CB71251AD56C3000D72204 /* CoreFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreFoundation.framework; path = System/Library/Frameworks/CoreFoundation.framework; sourceTree = SDKROOT; }; + 18CB71271AD56C4000D72204 /* CoreTelephony.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreTelephony.framework; path = System/Library/Frameworks/CoreTelephony.framework; sourceTree = SDKROOT; }; + 18CB71291AD56C6200D72204 /* libz.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libz.dylib; path = usr/lib/libz.dylib; sourceTree = SDKROOT; }; + 18CB712B1AD570B200D72204 /* PushConfig.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = PushConfig.plist; sourceTree = ""; }; + 18CECC081A91ACB6005598E4 /* BlogViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogViewControllerViewModel.h; path = iOSStudy/ViewModel/BlogViewControllerViewModel.h; sourceTree = ""; }; + 18CECC091A91ACB7005598E4 /* BlogViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogViewControllerViewModel.m; path = iOSStudy/ViewModel/BlogViewControllerViewModel.m; sourceTree = ""; }; + 18D184801AD28D1900188C3C /* FavouriteTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FavouriteTableViewController.h; path = iOSStudy/FavouriteTableViewController.h; sourceTree = ""; }; + 18D184811AD28D1900188C3C /* FavouriteTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FavouriteTableViewController.m; path = iOSStudy/FavouriteTableViewController.m; sourceTree = ""; }; + 18D184831AD2904900188C3C /* FavouriteViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FavouriteViewControllerViewModel.h; path = iOSStudy/ViewModel/FavouriteViewControllerViewModel.h; sourceTree = ""; }; + 18D184841AD2904900188C3C /* FavouriteViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FavouriteViewControllerViewModel.m; path = iOSStudy/ViewModel/FavouriteViewControllerViewModel.m; sourceTree = ""; }; + 18D184861AD2E0B700188C3C /* MessageUI.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MessageUI.framework; path = System/Library/Frameworks/MessageUI.framework; sourceTree = SDKROOT; }; 18D2010D1A95A6F400D5F095 /* icon_29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_29.png; path = " Resource/images/appicon/icon_29.png"; sourceTree = ""; }; 18D2010E1A95A6F400D5F095 /* icon_40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_40.png; path = " Resource/images/appicon/icon_40.png"; sourceTree = ""; }; 18D2010F1A95A6F400D5F095 /* icon_58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_58.png; path = " Resource/images/appicon/icon_58.png"; sourceTree = ""; }; @@ -149,23 +219,66 @@ 18D201281A95A9D600D5F095 /* tabbar_web.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_web.png; path = " Resource/images/tabbar/tabbar_web.png"; sourceTree = ""; }; 18D201291A95A9D600D5F095 /* tabbar_web@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_web@2x.png"; path = " Resource/images/tabbar/tabbar_web@2x.png"; sourceTree = ""; }; 18D2012A1A95A9D600D5F095 /* tabbar_web@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_web@3x.png"; path = " Resource/images/tabbar/tabbar_web@3x.png"; sourceTree = ""; }; - 18D201321A96090A00D5F095 /* app_img_640.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_640.png; path = " Resource/images/start_img/app_img_640.png"; sourceTree = ""; }; - 18D201331A96090A00D5F095 /* app_img_1136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1136.png; path = " Resource/images/start_img/app_img_1136.png"; sourceTree = ""; }; - 18D201341A96090A00D5F095 /* app_img_iOS8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_iOS8.png; path = " Resource/images/start_img/app_img_iOS8.png"; sourceTree = ""; }; - 18D201381A960B6100D5F095 /* app_img_768x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_768x1024.png; path = " Resource/images/start_img/app_img_768x1024.png"; sourceTree = ""; }; - 18D201391A960B6100D5F095 /* app_img_1024x768.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1024x768.png; path = " Resource/images/start_img/app_img_1024x768.png"; sourceTree = ""; }; - 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1536x2048.png; path = " Resource/images/start_img/app_img_1536x2048.png"; sourceTree = ""; }; - 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_2048x1536.png; path = " Resource/images/start_img/app_img_2048x1536.png"; sourceTree = ""; }; - 18D201401A96143300D5F095 /* ThirdViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThirdViewControllerViewModel.h; path = iOSStudy/ViewModel/ThirdViewControllerViewModel.h; sourceTree = ""; }; - 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ThirdViewControllerViewModel.m; path = iOSStudy/ViewModel/ThirdViewControllerViewModel.m; sourceTree = ""; }; - 18D908A51A8A205600B42A42 /* ThirdTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThirdTableViewController.h; sourceTree = ""; }; - 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThirdTableViewController.m; sourceTree = ""; }; + 18D201401A96143300D5F095 /* VideoViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoViewControllerViewModel.h; path = iOSStudy/ViewModel/VideoViewControllerViewModel.h; sourceTree = ""; }; + 18D201411A96143300D5F095 /* VideoViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoViewControllerViewModel.m; path = iOSStudy/ViewModel/VideoViewControllerViewModel.m; sourceTree = ""; }; + 18D4ECA41AD17F56009FE9F0 /* EntityConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EntityConstants.h; path = Constants/EntityConstants.h; sourceTree = ""; }; + 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EntityConstants.m; path = Constants/EntityConstants.m; sourceTree = ""; }; + 18D908A51A8A205600B42A42 /* VideoTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VideoTableViewController.h; sourceTree = ""; }; + 18D908A61A8A205600B42A42 /* VideoTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = VideoTableViewController.m; sourceTree = ""; }; 18DF6D391A80CF76005751E8 /* Constants .h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Constants .h"; path = "iOSStudy/Constants .h"; sourceTree = ""; }; 18DF6D3B1A80D3BC005751E8 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; 18DF6D3C1A80D3BC005751E8 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; 18E016A91ACAA898002A6E59 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; 18E016E41ACAAB35002A6E59 /* iOSStudy.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = iOSStudy.xcdatamodel; sourceTree = ""; }; + 18E279671AD61AD50056CC5F /* iRate.bundle */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.plug-in"; path = iRate.bundle; sourceTree = ""; }; + 18E279681AD61AD50056CC5F /* iRate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = iRate.h; sourceTree = ""; }; + 18E279691AD61AD50056CC5F /* iRate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = iRate.m; sourceTree = ""; }; + 18E2796C1AD6206F0056CC5F /* LicenesViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = LicenesViewController.h; path = iOSStudy/LicenesViewController.h; sourceTree = ""; }; + 18E2796D1AD6206F0056CC5F /* LicenesViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = LicenesViewController.m; path = iOSStudy/LicenesViewController.m; sourceTree = ""; }; + 18E279701AD62CD80056CC5F /* licenes.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = licenes.html; sourceTree = ""; }; + 18E360071AD67BB500A077B2 /* STBaseTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = STBaseTableViewCell.h; path = Cell/STBaseTableViewCell.h; sourceTree = ""; }; + 18E360081AD67BB500A077B2 /* STBaseTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = STBaseTableViewCell.m; path = Cell/STBaseTableViewCell.m; sourceTree = ""; }; + 18E360091AD67BB500A077B2 /* STBaseTableViewCell.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; name = STBaseTableViewCell.xib; path = Cell/STBaseTableViewCell.xib; sourceTree = ""; }; + 18E6A0B31ACCF7FD00B28D32 /* VersionBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VersionBean.h; path = Bean/versionBean/VersionBean.h; sourceTree = ""; }; + 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VersionBean.m; path = Bean/versionBean/VersionBean.m; sourceTree = ""; }; + 18EC479C1AD773A200C397E5 /* WelcomeTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WelcomeTools.h; path = Tools/WelcomeTools.h; sourceTree = ""; }; + 18EC479D1AD773A200C397E5 /* WelcomeTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WelcomeTools.m; path = Tools/WelcomeTools.m; sourceTree = ""; }; + 18EC479F1AD7949100C397E5 /* img_640x960.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_640x960.png; path = " Resource/images/start_img/img_640x960.png"; sourceTree = ""; }; + 18EC47A01AD7949100C397E5 /* img_640x1136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_640x1136.png; path = " Resource/images/start_img/img_640x1136.png"; sourceTree = ""; }; + 18EC47A11AD7949100C397E5 /* img_750x1334.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_750x1334.png; path = " Resource/images/start_img/img_750x1334.png"; sourceTree = ""; }; + 18EC47A21AD7949100C397E5 /* img_768x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_768x1024.png; path = " Resource/images/start_img/img_768x1024.png"; sourceTree = ""; }; + 18EC47A31AD7949100C397E5 /* img_1024x768.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_1024x768.png; path = " Resource/images/start_img/img_1024x768.png"; sourceTree = ""; }; + 18EC47A41AD7949100C397E5 /* img_1242x2208.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_1242x2208.png; path = " Resource/images/start_img/img_1242x2208.png"; sourceTree = ""; }; + 18EC47A51AD7949100C397E5 /* img_1536x2048.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_1536x2048.png; path = " Resource/images/start_img/img_1536x2048.png"; sourceTree = ""; }; + 18EC47A61AD7949100C397E5 /* img_2048x1536.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_2048x1536.png; path = " Resource/images/start_img/img_2048x1536.png"; sourceTree = ""; }; + 18EC47A71AD7949100C397E5 /* img_2208x1242.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = img_2208x1242.png; path = " Resource/images/start_img/img_2208x1242.png"; sourceTree = ""; }; + 18EC47B71AD7AE3200C397E5 /* welcome_bg.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = welcome_bg.png; path = " Resource/images/start_img/welcome_bg.png"; sourceTree = ""; }; + 18EC47B81AD7AE3200C397E5 /* welcome_icon.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = welcome_icon.png; path = " Resource/images/start_img/welcome_icon.png"; sourceTree = ""; }; + 18EC47BD1AD7C22300C397E5 /* about_us.html */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.html; path = about_us.html; sourceTree = ""; }; + 18EC47C01AD7C62F00C397E5 /* anim_01.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_01.png; sourceTree = ""; }; + 18EC47C11AD7C62F00C397E5 /* anim_02.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_02.png; sourceTree = ""; }; + 18EC47C21AD7C62F00C397E5 /* anim_03.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_03.png; sourceTree = ""; }; + 18EC47C31AD7C62F00C397E5 /* anim_04.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_04.png; sourceTree = ""; }; + 18EC47C41AD7C62F00C397E5 /* anim_05.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_05.png; sourceTree = ""; }; + 18EC47C51AD7C62F00C397E5 /* anim_06.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_06.png; sourceTree = ""; }; + 18EC47C61AD7C62F00C397E5 /* anim_07.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_07.png; sourceTree = ""; }; + 18EC47C71AD7C62F00C397E5 /* anim_08.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_08.png; sourceTree = ""; }; + 18EC47C81AD7C62F00C397E5 /* anim_09.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_09.png; sourceTree = ""; }; + 18EC47C91AD7C62F00C397E5 /* anim_10.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_10.png; sourceTree = ""; }; + 18EC47CA1AD7C62F00C397E5 /* anim_11.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_11.png; sourceTree = ""; }; + 18EC47CB1AD7C62F00C397E5 /* anim_12.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_12.png; sourceTree = ""; }; + 18EC47CC1AD7C62F00C397E5 /* anim_13.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_13.png; sourceTree = ""; }; + 18EC47CD1AD7C62F00C397E5 /* anim_14.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_14.png; sourceTree = ""; }; + 18EC47CE1AD7C62F00C397E5 /* anim_15.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_15.png; sourceTree = ""; }; + 18EC47CF1AD7C62F00C397E5 /* anim_16.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_16.png; sourceTree = ""; }; + 18EC47D01AD7C62F00C397E5 /* anim_17.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_17.png; sourceTree = ""; }; + 18EC47D11AD7C62F00C397E5 /* anim_18.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_18.png; sourceTree = ""; }; + 18EC47D21AD7C62F00C397E5 /* anim_19.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_19.png; sourceTree = ""; }; + 18EC47D31AD7C62F00C397E5 /* anim_20.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = anim_20.png; sourceTree = ""; }; + 18EC47E81AD7FE8200C397E5 /* tabbar_ favourite.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_ favourite.png"; path = " Resource/images/tabbar/tabbar_ favourite.png"; sourceTree = ""; }; + 18EC47E91AD7FE8200C397E5 /* tabbar_ favourite@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_ favourite@2x.png"; path = " Resource/images/tabbar/tabbar_ favourite@2x.png"; sourceTree = ""; }; + 18EC47EA1AD7FE8200C397E5 /* tabbar_ favourite@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_ favourite@3x.png"; path = " Resource/images/tabbar/tabbar_ favourite@3x.png"; sourceTree = ""; }; 2E2CC00A58FD0A745C574BAD /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; E83ED1B8EA89BC57ACF91BA5 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ @@ -175,8 +288,14 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + 18CB712A1AD56C6200D72204 /* libz.dylib in Frameworks */, + 18CB71281AD56C4000D72204 /* CoreTelephony.framework in Frameworks */, + 18CB71261AD56C3000D72204 /* CoreFoundation.framework in Frameworks */, + 18CB71241AD56C2100D72204 /* CFNetwork.framework in Frameworks */, + 18D184871AD2E0B700188C3C /* MessageUI.framework in Frameworks */, 18E016AA1ACAA898002A6E59 /* CoreData.framework in Frameworks */, 18DF6D3F1A80D40D005751E8 /* SystemConfiguration.framework in Frameworks */, + 18CB71211AD55BFD00D72204 /* libPushSDK-1.8.3.a in Frameworks */, 54A0444849F1931415392FC1 /* libPods.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; @@ -203,6 +322,7 @@ 189EF82F1A83994B00F19327 /* Bean */ = { isa = PBXGroup; children = ( + 18E6A0B21ACCF7C600B28D32 /* VersionBean */, 18AB47921A99965A00E4C030 /* videoBean */, 184F48B51A93341B00C5C22F /* webBean */, 189EF8301A83996500F19327 /* blogBean */, @@ -217,6 +337,8 @@ children = ( 189EF8311A8399B100F19327 /* BlogBean.h */, 189EF8321A8399B100F19327 /* BlogBean.m */, + 18C8450A1ACD41C40053884F /* BlogJsonBean.h */, + 18C8450B1ACD41C40053884F /* BlogJsonBean.m */, ); name = blogBean; sourceTree = ""; @@ -237,8 +359,12 @@ 18A998921A7C77D0002E7219 /* NetWorkTools.m */, 189EF8341A839FC600F19327 /* JsonTools.h */, 189EF8351A839FC600F19327 /* JsonTools.m */, - 18AB47A61A9DA40500E4C030 /* DBUtils.h */, - 18AB47A71A9DA40500E4C030 /* DBUtils.m */, + 18C845071ACCFC690053884F /* HttpVersionTools.h */, + 18C845081ACCFC690053884F /* HttpVersionTools.m */, + 18C8450D1ACE3E580053884F /* CoreDataUtils.h */, + 18C8450E1ACE3E580053884F /* CoreDataUtils.m */, + 18EC479C1AD773A200C397E5 /* WelcomeTools.h */, + 18EC479D1AD773A200C397E5 /* WelcomeTools.m */, ); name = Tools; sourceTree = ""; @@ -255,8 +381,9 @@ 18AB479C1A9C5D7300E4C030 /* Cell */ = { isa = PBXGroup; children = ( - 18AB479D1A9C5E3300E4C030 /* VideoCell.h */, - 18AB479E1A9C5E3300E4C030 /* VideoCell.m */, + 18E360071AD67BB500A077B2 /* STBaseTableViewCell.h */, + 18E360081AD67BB500A077B2 /* STBaseTableViewCell.m */, + 18E360091AD67BB500A077B2 /* STBaseTableViewCell.xib */, ); name = Cell; sourceTree = ""; @@ -270,6 +397,8 @@ 189EF82F1A83994B00F19327 /* Bean */, 18DF6D3A1A80D3A4005751E8 /* libs */, 18DF6D391A80CF76005751E8 /* Constants .h */, + 18D4ECA41AD17F56009FE9F0 /* EntityConstants.h */, + 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */, 18A998901A7C7772002E7219 /* Tools */, 18B23B4E1A7A235E00E80854 /* Base */, 18B23B211A7A14D000E80854 /* iOSStudy */, @@ -292,21 +421,26 @@ 18B23B211A7A14D000E80854 /* iOSStudy */ = { isa = PBXGroup; children = ( + 18C845101ACE4A580053884F /* WelcomeViewController.h */, + 18C845111ACE4A580053884F /* WelcomeViewController.m */, 18B23B261A7A14D100E80854 /* AppDelegate.h */, 18B23B271A7A14D100E80854 /* AppDelegate.m */, - 18B23B291A7A14D100E80854 /* FirstViewController.h */, - 18B23B2A1A7A14D100E80854 /* FirstViewController.m */, - 18B23B2C1A7A14D100E80854 /* SecondViewController.h */, - 18B23B2D1A7A14D100E80854 /* SecondViewController.m */, - 18D908A51A8A205600B42A42 /* ThirdTableViewController.h */, - 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */, + 18B23B291A7A14D100E80854 /* BlogViewController.h */, + 18B23B2A1A7A14D100E80854 /* BlogViewController.m */, + 18B23B2C1A7A14D100E80854 /* WebViewController.h */, + 18B23B2D1A7A14D100E80854 /* WebViewController.m */, + 18D908A51A8A205600B42A42 /* VideoTableViewController.h */, + 18D908A61A8A205600B42A42 /* VideoTableViewController.m */, 185EEB491A98DC9900BFDB79 /* SettingTableViewController.h */, 185EEB4A1A98DC9900BFDB79 /* SettingTableViewController.m */, - 18AB47A31A9C82FA00E4C030 /* AddBlogTableViewController.h */, - 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */, + 18C845131ACE56150053884F /* MainTabBarViewController.h */, + 18C845141ACE56150053884F /* MainTabBarViewController.m */, + 18D184801AD28D1900188C3C /* FavouriteTableViewController.h */, + 18D184811AD28D1900188C3C /* FavouriteTableViewController.m */, + 18E2796C1AD6206F0056CC5F /* LicenesViewController.h */, + 18E2796D1AD6206F0056CC5F /* LicenesViewController.m */, 18B23B2F1A7A14D100E80854 /* Main.storyboard */, 18B23B321A7A14D100E80854 /* Images.xcassets */, - 18B23B341A7A14D100E80854 /* LaunchScreen.xib */, 18B23B221A7A14D000E80854 /* Supporting Files */, 18E016E31ACAAB35002A6E59 /* iOSStudy.xcdatamodeld */, ); @@ -316,9 +450,11 @@ 18B23B221A7A14D000E80854 /* Supporting Files */ = { isa = PBXGroup; children = ( + 18CB712B1AD570B200D72204 /* PushConfig.plist */, 18D200F71A95A1FB00D5F095 /* Resource */, 18B23B231A7A14D100E80854 /* Info.plist */, 18B23B241A7A14D100E80854 /* main.m */, + 183970371B01A6C50098318E /* Localizable.strings */, ); name = "Supporting Files"; sourceTree = ""; @@ -345,8 +481,6 @@ children = ( 18B23B4B1A7A234800E80854 /* BaseViewController.h */, 18B23B4C1A7A234800E80854 /* BaseViewController.m */, - 18AB47961A99A51200E4C030 /* BaseTableViewCell.h */, - 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */, ); name = Base; sourceTree = ""; @@ -354,12 +488,14 @@ 18CECC0B1A91ACD6005598E4 /* ViewModel */ = { isa = PBXGroup; children = ( - 18D201401A96143300D5F095 /* ThirdViewControllerViewModel.h */, - 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */, - 18CECC081A91ACB6005598E4 /* FirstViewControllerViewModel.h */, - 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */, - 184F48B01A93323F00C5C22F /* SecondViewControllerViewModel.h */, - 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */, + 18D201401A96143300D5F095 /* VideoViewControllerViewModel.h */, + 18D201411A96143300D5F095 /* VideoViewControllerViewModel.m */, + 18CECC081A91ACB6005598E4 /* BlogViewControllerViewModel.h */, + 18CECC091A91ACB7005598E4 /* BlogViewControllerViewModel.m */, + 184F48B01A93323F00C5C22F /* WebViewControllerViewModel.h */, + 184F48AE1A93321700C5C22F /* WebViewControllerViewModel.m */, + 18D184831AD2904900188C3C /* FavouriteViewControllerViewModel.h */, + 18D184841AD2904900188C3C /* FavouriteViewControllerViewModel.m */, ); name = ViewModel; sourceTree = ""; @@ -367,6 +503,7 @@ 18D200F71A95A1FB00D5F095 /* Resource */ = { isa = PBXGroup; children = ( + 18E2796F1AD62CD80056CC5F /* html */, 18D200F81A95A21A00D5F095 /* images */, ); name = " Resource"; @@ -375,6 +512,7 @@ 18D200F81A95A21A00D5F095 /* images */ = { isa = PBXGroup; children = ( + 18EC47BF1AD7C62F00C397E5 /* anim */, 18D201311A9608E600D5F095 /* startImg */, 18D2010C1A95A6D500D5F095 /* tabBar */, 18D2010B1A95A6C800D5F095 /* appIcon */, @@ -401,6 +539,9 @@ 18D2010C1A95A6D500D5F095 /* tabBar */ = { isa = PBXGroup; children = ( + 18EC47E81AD7FE8200C397E5 /* tabbar_ favourite.png */, + 18EC47E91AD7FE8200C397E5 /* tabbar_ favourite@2x.png */, + 18EC47EA1AD7FE8200C397E5 /* tabbar_ favourite@3x.png */, 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */, 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */, 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */, @@ -420,13 +561,17 @@ 18D201311A9608E600D5F095 /* startImg */ = { isa = PBXGroup; children = ( - 18D201381A960B6100D5F095 /* app_img_768x1024.png */, - 18D201391A960B6100D5F095 /* app_img_1024x768.png */, - 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */, - 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */, - 18D201321A96090A00D5F095 /* app_img_640.png */, - 18D201331A96090A00D5F095 /* app_img_1136.png */, - 18D201341A96090A00D5F095 /* app_img_iOS8.png */, + 18EC47B71AD7AE3200C397E5 /* welcome_bg.png */, + 18EC47B81AD7AE3200C397E5 /* welcome_icon.png */, + 18EC479F1AD7949100C397E5 /* img_640x960.png */, + 18EC47A01AD7949100C397E5 /* img_640x1136.png */, + 18EC47A11AD7949100C397E5 /* img_750x1334.png */, + 18EC47A21AD7949100C397E5 /* img_768x1024.png */, + 18EC47A31AD7949100C397E5 /* img_1024x768.png */, + 18EC47A41AD7949100C397E5 /* img_1242x2208.png */, + 18EC47A51AD7949100C397E5 /* img_1536x2048.png */, + 18EC47A61AD7949100C397E5 /* img_2048x1536.png */, + 18EC47A71AD7949100C397E5 /* img_2208x1242.png */, ); name = startImg; sourceTree = ""; @@ -434,17 +579,87 @@ 18DF6D3A1A80D3A4005751E8 /* libs */ = { isa = PBXGroup; children = ( + 189BC7DA1AE4ED7C0051EDCD /* UINavigationBar+Awesome.h */, + 189BC7DB1AE4ED7C0051EDCD /* UINavigationBar+Awesome.m */, + 18E279661AD61AD50056CC5F /* iRate */, + 18CB71221AD55C0C00D72204 /* APService.h */, 18AB47991A9C59CB00E4C030 /* UIImage+Resize.h */, 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */, 18DF6D3B1A80D3BC005751E8 /* Reachability.h */, 18DF6D3C1A80D3BC005751E8 /* Reachability.m */, + 187E96971AD6BED500D164FA /* NotificationCenterConstants.h */, + 187E96981AD6BED500D164FA /* NotificationCenterConstants.m */, ); name = libs; sourceTree = ""; }; + 18E279661AD61AD50056CC5F /* iRate */ = { + isa = PBXGroup; + children = ( + 18E279671AD61AD50056CC5F /* iRate.bundle */, + 18E279681AD61AD50056CC5F /* iRate.h */, + 18E279691AD61AD50056CC5F /* iRate.m */, + ); + name = iRate; + path = libs/iRate; + sourceTree = ""; + }; + 18E2796F1AD62CD80056CC5F /* html */ = { + isa = PBXGroup; + children = ( + 18EC47BD1AD7C22300C397E5 /* about_us.html */, + 18E279701AD62CD80056CC5F /* licenes.html */, + ); + name = html; + path = " Resource/html"; + sourceTree = ""; + }; + 18E6A0B21ACCF7C600B28D32 /* VersionBean */ = { + isa = PBXGroup; + children = ( + 18E6A0B31ACCF7FD00B28D32 /* VersionBean.h */, + 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */, + ); + name = VersionBean; + sourceTree = ""; + }; + 18EC47BF1AD7C62F00C397E5 /* anim */ = { + isa = PBXGroup; + children = ( + 18EC47C01AD7C62F00C397E5 /* anim_01.png */, + 18EC47C11AD7C62F00C397E5 /* anim_02.png */, + 18EC47C21AD7C62F00C397E5 /* anim_03.png */, + 18EC47C31AD7C62F00C397E5 /* anim_04.png */, + 18EC47C41AD7C62F00C397E5 /* anim_05.png */, + 18EC47C51AD7C62F00C397E5 /* anim_06.png */, + 18EC47C61AD7C62F00C397E5 /* anim_07.png */, + 18EC47C71AD7C62F00C397E5 /* anim_08.png */, + 18EC47C81AD7C62F00C397E5 /* anim_09.png */, + 18EC47C91AD7C62F00C397E5 /* anim_10.png */, + 18EC47CA1AD7C62F00C397E5 /* anim_11.png */, + 18EC47CB1AD7C62F00C397E5 /* anim_12.png */, + 18EC47CC1AD7C62F00C397E5 /* anim_13.png */, + 18EC47CD1AD7C62F00C397E5 /* anim_14.png */, + 18EC47CE1AD7C62F00C397E5 /* anim_15.png */, + 18EC47CF1AD7C62F00C397E5 /* anim_16.png */, + 18EC47D01AD7C62F00C397E5 /* anim_17.png */, + 18EC47D11AD7C62F00C397E5 /* anim_18.png */, + 18EC47D21AD7C62F00C397E5 /* anim_19.png */, + 18EC47D31AD7C62F00C397E5 /* anim_20.png */, + ); + name = anim; + path = "iOSStudy/ Resource/images/anim"; + sourceTree = ""; + }; 910A021243EF9C731476BCA9 /* Frameworks */ = { isa = PBXGroup; children = ( + 18CB71291AD56C6200D72204 /* libz.dylib */, + 18CB71271AD56C4000D72204 /* CoreTelephony.framework */, + 18CB71251AD56C3000D72204 /* CoreFoundation.framework */, + 18CB71231AD56C2000D72204 /* CFNetwork.framework */, + 18CB71201AD55BFD00D72204 /* libPushSDK-1.8.3.a */, + 18D184861AD2E0B700188C3C /* MessageUI.framework */, 18E016A91ACAA898002A6E59 /* CoreData.framework */, 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */, E83ED1B8EA89BC57ACF91BA5 /* libPods.a */, @@ -512,9 +727,15 @@ TargetAttributes = { 18B23B1E1A7A14D000E80854 = { CreatedOnToolsVersion = 6.1.1; + SystemCapabilities = { + com.apple.BackgroundModes = { + enabled = 1; + }; + }; }; 18B23B3A1A7A14D100E80854 = { CreatedOnToolsVersion = 6.1.1; + DevelopmentTeam = BU39DT6VD4; TestTargetID = 18B23B1E1A7A14D000E80854; }; }; @@ -526,6 +747,7 @@ knownRegions = ( en, Base, + "zh-Hans", ); mainGroup = 18B23B161A7A14D000E80854; productRefGroup = 18B23B201A7A14D000E80854 /* Products */; @@ -543,37 +765,70 @@ isa = PBXResourcesBuildPhase; buildActionMask = 2147483647; files = ( - 18D201351A96090A00D5F095 /* app_img_640.png in Resources */, + 18CB712C1AD570B200D72204 /* PushConfig.plist in Resources */, 18B23B311A7A14D100E80854 /* Main.storyboard in Resources */, - 18D201371A96090A00D5F095 /* app_img_iOS8.png in Resources */, 185EEB501A98E0BA00BFDB79 /* tabbar_setting@2x.png in Resources */, + 18EC47D51AD7C62F00C397E5 /* anim_02.png in Resources */, + 18EC47AB1AD7949100C397E5 /* img_768x1024.png in Resources */, + 18EC47DD1AD7C62F00C397E5 /* anim_10.png in Resources */, + 18EC47E01AD7C62F00C397E5 /* anim_13.png in Resources */, 18D2012D1A95A9D600D5F095 /* tabbar_video@3x.png in Resources */, 18D201181A95A6F400D5F095 /* icon_58.png in Resources */, 185EEB511A98E0BA00BFDB79 /* tabbar_setting@3x.png in Resources */, + 18E2796A1AD61AD50056CC5F /* iRate.bundle in Resources */, + 18EC47E51AD7C62F00C397E5 /* anim_18.png in Resources */, + 18EC47AC1AD7949100C397E5 /* img_1024x768.png in Resources */, + 18EC47B91AD7AE3200C397E5 /* welcome_bg.png in Resources */, + 18EC47ED1AD7FE8200C397E5 /* tabbar_ favourite@3x.png in Resources */, + 18EC47DC1AD7C62F00C397E5 /* anim_09.png in Resources */, 18D2011D1A95A6F400D5F095 /* icon_152.png in Resources */, 18D201191A95A6F400D5F095 /* icon_76.png in Resources */, + 18EC47DA1AD7C62F00C397E5 /* anim_07.png in Resources */, + 18EC47B01AD7949100C397E5 /* img_2208x1242.png in Resources */, + 1839702E1B0182720098318E /* Info.plist in Resources */, 18D2011E1A95A6F400D5F095 /* icon_180.png in Resources */, 18D2012B1A95A9D600D5F095 /* tabbar_video.png in Resources */, - 18D2013F1A960B6100D5F095 /* app_img_2048x1536.png in Resources */, + 18EC47BA1AD7AE3200C397E5 /* welcome_icon.png in Resources */, + 18EC47E71AD7C62F00C397E5 /* anim_20.png in Resources */, + 18E279711AD62CD80056CC5F /* licenes.html in Resources */, 185EEB4F1A98E0BA00BFDB79 /* tabbar_setting.png in Resources */, - 18D2013D1A960B6100D5F095 /* app_img_1024x768.png in Resources */, + 18EC47D81AD7C62F00C397E5 /* anim_05.png in Resources */, + 18EC47DB1AD7C62F00C397E5 /* anim_08.png in Resources */, + 18EC47AD1AD7949100C397E5 /* img_1242x2208.png in Resources */, + 18EC47E41AD7C62F00C397E5 /* anim_17.png in Resources */, + 18EC47D41AD7C62F00C397E5 /* anim_01.png in Resources */, 18D201161A95A6F400D5F095 /* icon_29.png in Resources */, - 18D2013C1A960B6100D5F095 /* app_img_768x1024.png in Resources */, + 18EC47EC1AD7FE8200C397E5 /* tabbar_ favourite@2x.png in Resources */, + 18EC47BE1AD7C22300C397E5 /* about_us.html in Resources */, 18D2011B1A95A6F400D5F095 /* icon_87.png in Resources */, + 18EC47DF1AD7C62F00C397E5 /* anim_12.png in Resources */, 18D2012E1A95A9D600D5F095 /* tabbar_web.png in Resources */, + 18E3600B1AD67BB500A077B2 /* STBaseTableViewCell.xib in Resources */, + 18EC47AE1AD7949100C397E5 /* img_1536x2048.png in Resources */, + 18EC47DE1AD7C62F00C397E5 /* anim_11.png in Resources */, + 18EC47D71AD7C62F00C397E5 /* anim_04.png in Resources */, + 18EC47D91AD7C62F00C397E5 /* anim_06.png in Resources */, 18D201301A95A9D600D5F095 /* tabbar_web@3x.png in Resources */, 18D2012C1A95A9D600D5F095 /* tabbar_video@2x.png in Resources */, + 183970351B01A6C50098318E /* Localizable.strings in Resources */, 18D2012F1A95A9D600D5F095 /* tabbar_web@2x.png in Resources */, + 18EC47AA1AD7949100C397E5 /* img_750x1334.png in Resources */, 18D201171A95A6F400D5F095 /* icon_40.png in Resources */, - 18D201361A96090A00D5F095 /* app_img_1136.png in Resources */, + 18EC47E31AD7C62F00C397E5 /* anim_16.png in Resources */, 18D2011C1A95A6F400D5F095 /* icon_120.png in Resources */, + 18EC47A91AD7949100C397E5 /* img_640x1136.png in Resources */, + 18EC47EB1AD7FE8200C397E5 /* tabbar_ favourite.png in Resources */, + 18EC47E21AD7C62F00C397E5 /* anim_15.png in Resources */, 18D201221A95A70900D5F095 /* tabbar_blog.png in Resources */, - 18B23B361A7A14D100E80854 /* LaunchScreen.xib in Resources */, + 18EC47A81AD7949100C397E5 /* img_640x960.png in Resources */, 18D2011A1A95A6F400D5F095 /* icon_80.png in Resources */, - 18D2013E1A960B6100D5F095 /* app_img_1536x2048.png in Resources */, 18D201241A95A70900D5F095 /* tabbar_blog@3x.png in Resources */, + 18EC47E11AD7C62F00C397E5 /* anim_14.png in Resources */, + 18EC47AF1AD7949100C397E5 /* img_2048x1536.png in Resources */, 18D201231A95A70900D5F095 /* tabbar_blog@2x.png in Resources */, 18B23B331A7A14D100E80854 /* Images.xcassets in Resources */, + 18EC47E61AD7C62F00C397E5 /* anim_19.png in Resources */, + 18EC47D61AD7C62F00C397E5 /* anim_03.png in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -624,30 +879,41 @@ isa = PBXSourcesBuildPhase; buildActionMask = 2147483647; files = ( - 18AB47981A99A51200E4C030 /* BaseTableViewCell.m in Sources */, 18E016E51ACAAB35002A6E59 /* iOSStudy.xcdatamodeld in Sources */, - 18AB479F1A9C5E3300E4C030 /* VideoCell.m in Sources */, - 18B23B2E1A7A14D100E80854 /* SecondViewController.m in Sources */, + 18B23B2E1A7A14D100E80854 /* WebViewController.m in Sources */, + 18E3600A1AD67BB500A077B2 /* STBaseTableViewCell.m in Sources */, 18B23B4D1A7A234800E80854 /* BaseViewController.m in Sources */, + 18E2796B1AD61AD50056CC5F /* iRate.m in Sources */, 18A998931A7C77D0002E7219 /* NetWorkTools.m in Sources */, - 18AB47A81A9DA40500E4C030 /* DBUtils.m in Sources */, - 18AB47A51A9C82FA00E4C030 /* AddBlogTableViewController.m in Sources */, - 18D908A71A8A205600B42A42 /* ThirdTableViewController.m in Sources */, + 18E2796E1AD6206F0056CC5F /* LicenesViewController.m in Sources */, + 18D908A71A8A205600B42A42 /* VideoTableViewController.m in Sources */, + 18C8450C1ACD41C40053884F /* BlogJsonBean.m in Sources */, 18AB479B1A9C59CB00E4C030 /* UIImage+Resize.m in Sources */, - 18D201421A96143300D5F095 /* ThirdViewControllerViewModel.m in Sources */, + 18D201421A96143300D5F095 /* VideoViewControllerViewModel.m in Sources */, 18AB47951A99969600E4C030 /* VideoBean.m in Sources */, - 18CECC0A1A91ACB7005598E4 /* FirstViewControllerViewModel.m in Sources */, + 18CECC0A1A91ACB7005598E4 /* BlogViewControllerViewModel.m in Sources */, 189EF8361A839FC600F19327 /* JsonTools.m in Sources */, + 18D4ECA61AD17F56009FE9F0 /* EntityConstants.m in Sources */, + 18C845091ACCFC690053884F /* HttpVersionTools.m in Sources */, + 18E6A0B51ACCF7FD00B28D32 /* VersionBean.m in Sources */, 18DF6D3D1A80D3BC005751E8 /* Reachability.m in Sources */, 18B23B281A7A14D100E80854 /* AppDelegate.m in Sources */, - 184F48AF1A93321700C5C22F /* SecondViewControllerViewModel.m in Sources */, - 18B23B2B1A7A14D100E80854 /* FirstViewController.m in Sources */, + 184F48AF1A93321700C5C22F /* WebViewControllerViewModel.m in Sources */, + 18EC479E1AD773A200C397E5 /* WelcomeTools.m in Sources */, + 18D184821AD28D1900188C3C /* FavouriteTableViewController.m in Sources */, + 18B23B2B1A7A14D100E80854 /* BlogViewController.m in Sources */, 189EF83A1A83C3AF00F19327 /* BlogDetailViewController.m in Sources */, + 189BC7DC1AE4ED7C0051EDCD /* UINavigationBar+Awesome.m in Sources */, 185EEB4B1A98DC9900BFDB79 /* SettingTableViewController.m in Sources */, + 187E96991AD6BED500D164FA /* NotificationCenterConstants.m in Sources */, + 18C845121ACE4A580053884F /* WelcomeViewController.m in Sources */, 18B23B251A7A14D100E80854 /* main.m in Sources */, 18AB47AB1AA415A400E4C030 /* FavouriteBean.m in Sources */, 184F48B41A93340F00C5C22F /* WebBean.m in Sources */, + 18C845151ACE56150053884F /* MainTabBarViewController.m in Sources */, + 18C8450F1ACE3E580053884F /* CoreDataUtils.m in Sources */, 189EF8331A8399B100F19327 /* BlogBean.m in Sources */, + 18D184851AD2904900188C3C /* FavouriteViewControllerViewModel.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -670,21 +936,23 @@ /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ - 18B23B2F1A7A14D100E80854 /* Main.storyboard */ = { + 183970371B01A6C50098318E /* Localizable.strings */ = { isa = PBXVariantGroup; children = ( - 18B23B301A7A14D100E80854 /* Base */, + 183970361B01A6C50098318E /* en */, + 183970381B01A6C70098318E /* zh-Hans */, ); - name = Main.storyboard; + name = Localizable.strings; sourceTree = ""; }; - 18B23B341A7A14D100E80854 /* LaunchScreen.xib */ = { + 18B23B2F1A7A14D100E80854 /* Main.storyboard */ = { isa = PBXVariantGroup; children = ( - 18B23B351A7A14D100E80854 /* Base */, - 18CECC101A921272005598E4 /* zh-Hans */, + 18B23B301A7A14D100E80854 /* Base */, + 183970301B0182A00098318E /* en */, + 183970321B0182A60098318E /* zh-Hans */, ); - name = LaunchScreen.xib; + name = Main.storyboard; sourceTree = ""; }; /* End PBXVariantGroup section */ @@ -707,7 +975,8 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: guandong chen (BU39DT6VD4)"; COPY_PHASE_STRIP = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; GCC_C_LANGUAGE_STANDARD = gnu99; @@ -725,9 +994,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; + PROVISIONING_PROFILE = "7ede2157-30b8-44eb-8161-e3a71f95fec4"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; }; @@ -750,7 +1020,8 @@ CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; - "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + CODE_SIGN_IDENTITY = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: guandong chen (BU39DT6VD4)"; COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; ENABLE_STRICT_OBJC_MSGSEND = YES; @@ -762,8 +1033,10 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.1; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; MTL_ENABLE_DEBUG_INFO = NO; + ONLY_ACTIVE_ARCH = NO; + PROVISIONING_PROFILE = "7ede2157-30b8-44eb-8161-e3a71f95fec4"; SDKROOT = iphoneos; TARGETED_DEVICE_FAMILY = "1,2"; VALIDATE_PRODUCT = YES; @@ -776,10 +1049,30 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + HEADER_SEARCH_PATHS = ( + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/AFNetworking\"", + "\"${PODS_ROOT}/Headers/Public/FMDB\"", + "\"${PODS_ROOT}/Headers/Public/MJRefresh\"", + "\"${PODS_ROOT}/Headers/Public/Mantle\"", + "\"${PODS_ROOT}/Headers/Public/NJKWebViewProgress\"", + "\"${PODS_ROOT}/Headers/Public/SDWebImage\"", + "\"${PODS_ROOT}/Headers/Public/SVProgressHUD\"", + "\"${PODS_ROOT}/Headers/Public/SVWebViewController\"", + "\"${PODS_ROOT}/Headers/Public/SWTableViewCell\"", + ); INFOPLIST_FILE = iOSStudy/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = "7ede2157-30b8-44eb-8161-e3a71f95fec4"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Debug; }; @@ -789,10 +1082,31 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + CODE_SIGN_IDENTITY = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Distribution: guandong chen (BU39DT6VD4)"; + HEADER_SEARCH_PATHS = ( + "\"${PODS_ROOT}/Headers/Public\"", + "\"${PODS_ROOT}/Headers/Public/AFNetworking\"", + "\"${PODS_ROOT}/Headers/Public/FMDB\"", + "\"${PODS_ROOT}/Headers/Public/MJRefresh\"", + "\"${PODS_ROOT}/Headers/Public/Mantle\"", + "\"${PODS_ROOT}/Headers/Public/NJKWebViewProgress\"", + "\"${PODS_ROOT}/Headers/Public/SDWebImage\"", + "\"${PODS_ROOT}/Headers/Public/SVProgressHUD\"", + "\"${PODS_ROOT}/Headers/Public/SVWebViewController\"", + "\"${PODS_ROOT}/Headers/Public/SWTableViewCell\"", + ); INFOPLIST_FILE = iOSStudy/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 7.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + LIBRARY_SEARCH_PATHS = ( + "$(inherited)", + "$(PROJECT_DIR)", + ); + ONLY_ACTIVE_ARCH = NO; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = "7ede2157-30b8-44eb-8161-e3a71f95fec4"; + TARGETED_DEVICE_FAMILY = "1,2"; }; name = Release; }; @@ -800,6 +1114,8 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", @@ -811,6 +1127,7 @@ INFOPLIST_FILE = iOSStudyTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSStudy.app/iOSStudy"; }; name = Debug; @@ -819,6 +1136,8 @@ isa = XCBuildConfiguration; buildSettings = { BUNDLE_LOADER = "$(TEST_HOST)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; FRAMEWORK_SEARCH_PATHS = ( "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", @@ -826,6 +1145,7 @@ INFOPLIST_FILE = iOSStudyTests/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; PRODUCT_NAME = "$(TARGET_NAME)"; + PROVISIONING_PROFILE = ""; TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSStudy.app/iOSStudy"; }; name = Release; diff --git a/iOSStudy/iOSStudy/ Resource/html/about_us.html b/iOSStudy/iOSStudy/ Resource/html/about_us.html new file mode 100644 index 0000000..10785da --- /dev/null +++ b/iOSStudy/iOSStudy/ Resource/html/about_us.html @@ -0,0 +1,147 @@ + + + + + iOSStudy + + + + + + + + + +
+

关于iOSStudy

+ + + +

+iOSStudy 灵感来源于作者自学iOS开发的经验,收藏了一些博客视频网站等内容,希望可以帮助初学者找到更好的学习资源,作者也会不断的更新完善软件和内容,如果本软件对您的学习有所帮助欢迎到评分界面深深地点个赞,您的支持将是我前进的动力↖(^ω^)↗
+
+ + +

下一步计划

+ +

+1,加入开源软件推荐模块
+2,加入iCloud对收藏的支持
+
+ + +

联系我

+ +

+邮箱: chenguandong@163.com
+QQ: 787725000
+
+ + + + +

开源地址

+ +

+    https://github.com/chenguandong/iOSStudy
+
+

官方博客

+ + + + + + + +

特别感谢

+ + +

+李辉 QQ:949843687 对该软件图标设计与制作
+龚凡凡 QQ:825244415 对该软件的技术支持
+
+ + + + +
+ + +
\ No newline at end of file diff --git a/iOSStudy/iOSStudy/ Resource/html/licenes.html b/iOSStudy/iOSStudy/ Resource/html/licenes.html new file mode 100644 index 0000000..5cd1dd2 --- /dev/null +++ b/iOSStudy/iOSStudy/ Resource/html/licenes.html @@ -0,0 +1,313 @@ + + + + + iOSStudy + + + + + + + + + +
+

iOSStudy 使用的开源组件

+

iOSStudy 在开发过程中使用了下列开源库,组件,感谢开源社区对我们的帮助和对整个互联网的贡献.

+

AFNetworking

+

+    Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com/)
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+ + +

SDWebImage

+

+    Copyright (c) 2009 Olivier Poitrey 
+        
+        Permission is hereby granted, free of charge, to any person obtaining a copy
+        of this software and associated documentation files (the "Software"), to deal
+        in the Software without restriction, including without limitation the rights
+        to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+        copies of the Software, and to permit persons to whom the Software is furnished
+        to do so, subject to the following conditions:
+        
+        The above copyright notice and this permission notice shall be included in all
+        copies or substantial portions of the Software.
+        
+        THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+        IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+        FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+        AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+        LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+        OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+        THE SOFTWARE.
+    
+
+ +

Mantle

+

+    Copyright (c) GitHub, Inc. All rights reserved.
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+    
+    This project uses portions of code from the Proton framework. Proton is copyright (c) 2012, Bitswift, Inc. All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+    
+    Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+    Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+    
+
+ + +

SVProgressHUD

+

+    Copyright (c) 2011-2014 Sam Vermette
+    
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use,
+    copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following
+    conditions:
+    
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+    
+    A different license may apply to other resources included in this package,
+    including Freepik Icons. Please consult their
+    respective headers for the terms of their individual licenses.
+    
+
+ +

SVWebViewController

+

+    Copyright (c) 2011 Sam Vermette
+    
+    Permission is hereby granted, free of charge, to any person
+    obtaining a copy of this software and associated documentation
+    files (the "Software"), to deal in the Software without
+    restriction, including without limitation the rights to use,
+    copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the
+    Software is furnished to do so, subject to the following
+    conditions:
+    
+    The above copyright notice and this permission notice shall be
+    included in all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+    OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+    NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+    HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+    WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+    FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+    OTHER DEALINGS IN THE SOFTWARE.
+
+ +

MJRefresh

+

+    Copyright (c) 2013-2015 MJRefresh (https://github.com/CoderMJLee/MJRefresh)
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+ +

SWTableViewCell

+

+    Copyright (c) 2013 Christopher Wendel
+    
+    Permission is hereby granted, free of charge, to any person obtaining a copy
+    of this software and associated documentation files (the "Software"), to deal
+    in the Software without restriction, including without limitation the rights
+    to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+    copies of the Software, and to permit persons to whom the Software is
+    furnished to do so, subject to the following conditions:
+    
+    The above copyright notice and this permission notice shall be included in
+    all copies or substantial portions of the Software.
+    
+    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+    IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+    FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+    AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+    LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+    OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+    THE SOFTWARE.
+
+ +

iRate

+

+    Version 1.11.3, October 24th, 2014
+    
+    Copyright (C) 2011 Charcoal Design
+    
+    This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages arising from the use of this software.
+    
+    Permission is granted to anyone to use this software for any purpose, including commercial applications, and to alter it and redistribute it freely, subject to the following restrictions:
+    
+    The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
+    
+    Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
+    
+    This notice may not be removed or altered from any source distribution.
+
+ +

Reachability

+

+    Copyright (c) 2011-2013, Tony Million.
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    
+    1. Redistributions of source code must retain the above copyright notice, this
+    list of conditions and the following disclaimer.
+    
+    2. Redistributions in binary form must reproduce the above copyright notice,
+    this list of conditions and the following disclaimer in the documentation
+    and/or other materials provided with the distribution.
+    
+    THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+    AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+    IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+    ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+    LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+    CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+
+ +
+ + +
\ No newline at end of file diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png index aa81067..5c1c93f 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png index cc11df5..2356a36 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png index 90fbb4c..c93794f 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png index 9b8269a..5b01d7f 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png index 8992f31..a7c45c3 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png index da710e0..e60863e 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png index 43305f9..032ab00 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png index 7e1939c..833dd54 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png index 72333c2..2b5f10f 100644 Binary files a/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png and b/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_1024x768.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1024x768.png new file mode 100644 index 0000000..d17d300 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1024x768.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_1242x2208.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1242x2208.png new file mode 100644 index 0000000..c11b311 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1242x2208.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_1536x2048.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1536x2048.png new file mode 100644 index 0000000..fd96761 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_1536x2048.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_2048x1536.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_2048x1536.png new file mode 100644 index 0000000..c74442a Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_2048x1536.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_2208x1242.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_2208x1242.png new file mode 100644 index 0000000..b917875 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_2208x1242.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x1136.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x1136.png new file mode 100644 index 0000000..1fbe35b Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x1136.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x960.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x960.png new file mode 100644 index 0000000..08622f4 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_640x960.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_750x1334.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_750x1334.png new file mode 100644 index 0000000..95c579a Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_750x1334.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/img_768x1024.png b/iOSStudy/iOSStudy/ Resource/images/start_img/img_768x1024.png new file mode 100644 index 0000000..0644a11 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/img_768x1024.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_bg.png b/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_bg.png new file mode 100644 index 0000000..02fb105 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_bg.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_icon.png b/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_icon.png new file mode 100644 index 0000000..1dcd560 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/start_img/welcome_icon.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite.png b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite.png new file mode 100644 index 0000000..2af50a1 Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@2x.png b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@2x.png new file mode 100644 index 0000000..c59f70d Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@2x.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@3x.png b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@3x.png new file mode 100644 index 0000000..6662d8e Binary files /dev/null and b/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_ favourite@3x.png differ diff --git a/iOSStudy/iOSStudy/AppDelegate.h b/iOSStudy/iOSStudy/AppDelegate.h index a86a54a..5c21979 100644 --- a/iOSStudy/iOSStudy/AppDelegate.h +++ b/iOSStudy/iOSStudy/AppDelegate.h @@ -14,6 +14,10 @@ @property(nonatomic,assign)__block BOOL isNetworking; @property(nonatomic,copy)NSString *str; +#pragma mark --version list +@property(nonatomic,strong)NSArray *versionLists; + + #pragma mark --coreData @property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; @property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; diff --git a/iOSStudy/iOSStudy/AppDelegate.m b/iOSStudy/iOSStudy/AppDelegate.m index 5ae2306..18140f0 100644 --- a/iOSStudy/iOSStudy/AppDelegate.m +++ b/iOSStudy/iOSStudy/AppDelegate.m @@ -7,7 +7,8 @@ // #import "AppDelegate.h" -#import "NetWorkTools.h" +#import "APService.h" +#import "WelcomeTools.h" @interface AppDelegate () @@ -18,11 +19,46 @@ @implementation AppDelegate - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { // Override point for customization after application launch. - NSLog(@"------checkNetworking"); - - [NetWorkTools checkNetworking]; + // Do any additional setup after loading the view. + [WelcomeTools sharedInstance]; [self setGlobalStyle]; + + + //setUrl cache + NSURLCache *URLCache = [[NSURLCache alloc] initWithMemoryCapacity:4 * 1024 * 1024 + diskCapacity:20 * 1024 * 1024 + diskPath:nil]; + [NSURLCache setSharedURLCache:URLCache]; + + + // Required +#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1 + if ([[UIDevice currentDevice].systemVersion floatValue] >= 8.0) { + //可以添加自定义categories + [APService registerForRemoteNotificationTypes:(UIUserNotificationTypeBadge | + UIUserNotificationTypeSound | + UIUserNotificationTypeAlert) + categories:nil]; + } else { + //categories 必须为nil + [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | + UIRemoteNotificationTypeSound | + UIRemoteNotificationTypeAlert) + categories:nil]; + } +#else + //categories 必须为nil + [APService registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | + UIRemoteNotificationTypeSound | + UIRemoteNotificationTypeAlert) + categories:nil]; +#endif + // Required + [APService setupWithOption:launchOptions]; + + + return YES; } @@ -54,6 +90,10 @@ -(void)setGlobalStyle{ //导航返回按钮颜色 [[UINavigationBar appearance] setTintColor:[UIColor redColor]]; + + + [[UIApplication sharedApplication] setStatusBarStyle:UIStatusBarStyleLightContent]; + } @@ -63,10 +103,73 @@ -(void)dealloc{ } +- (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken { + + // Required + [APService registerDeviceToken:deviceToken]; +} + + + + +- (void)application:(UIApplication *)application handleActionWithIdentifier:(NSString *)identifier forRemoteNotification:(NSDictionary *)userInfo completionHandler:(void(^)())completionHandler NS_AVAILABLE_IOS(8_0){ + + NSLog(@"%s",__func__); + NSLog(@"%@",[self logDic:userInfo]); + +} + +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo { + + + + NSLog(@"%s",__func__); + NSLog(@"%@",[self logDic:userInfo]); + + // Required + [APService handleRemoteNotification:userInfo]; +} + +- (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler { + + + NSLog(@"%s",__func__); + + NSLog(@"%@",[self logDic:userInfo]); + // IOS 7 Support Required + [APService handleRemoteNotification:userInfo]; + completionHandler(UIBackgroundFetchResultNewData); +} +// log NSSet with UTF8 +// if not ,log will be \Uxxx +- (NSString *)logDic:(NSDictionary *)dic { + if (![dic count]) { + return nil; + } + NSString *tempStr1 = + [[dic description] stringByReplacingOccurrencesOfString:@"\\u" + withString:@"\\U"]; + NSString *tempStr2 = + [tempStr1 stringByReplacingOccurrencesOfString:@"\"" withString:@"\\\""]; + NSString *tempStr3 = + [[@"\"" stringByAppendingString:tempStr2] stringByAppendingString:@"\""]; + NSData *tempData = [tempStr3 dataUsingEncoding:NSUTF8StringEncoding]; + NSString *str = + [NSPropertyListSerialization propertyListFromData:tempData + mutabilityOption:NSPropertyListImmutable + format:NULL + errorDescription:NULL]; + return str; +} + + + + - (void)applicationWillResignActive:(UIApplication *)application { // 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. // 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. + } - (void)applicationDidEnterBackground:(UIApplication *)application { @@ -82,6 +185,8 @@ - (void)applicationWillEnterForeground:(UIApplication *)application { - (void)applicationDidBecomeActive:(UIApplication *)application { // 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. + + } - (void)applicationWillTerminate:(UIApplication *)application { diff --git a/iOSStudy/iOSStudy/Base.lproj/Main.storyboard b/iOSStudy/iOSStudy/Base.lproj/Main.storyboard index 20f14c6..45ea5bb 100644 --- a/iOSStudy/iOSStudy/Base.lproj/Main.storyboard +++ b/iOSStudy/iOSStudy/Base.lproj/Main.storyboard @@ -1,15 +1,14 @@ - + - - + - + @@ -22,25 +21,11 @@ - + - - - - @@ -58,14 +43,7 @@ - - - - - - - - + @@ -74,130 +52,10 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -209,28 +67,11 @@ - + - - - - - - - @@ -248,11 +89,7 @@ - - - - - + @@ -264,7 +101,7 @@ - + @@ -287,7 +124,7 @@ - + @@ -326,74 +163,17 @@ - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - @@ -408,7 +188,7 @@ - + @@ -436,7 +216,7 @@ - + @@ -450,7 +230,7 @@ @@ -465,7 +245,7 @@ @@ -473,41 +253,7 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -518,11 +264,14 @@ + + + @@ -530,14 +279,17 @@ - + + + @@ -553,71 +305,117 @@ - - + + + + + + + + + + + + + + + + + + + + + - + - - + + - + - + - + + - - - - + + + + - - - - - - - - - - - - + + + + - + - + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + - - + + - + - + - + @@ -625,20 +423,80 @@ - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + + + + + + diff --git a/iOSStudy/Base/BaseTableViewCell.h b/iOSStudy/iOSStudy/Base/BaseTableViewCell.h similarity index 100% rename from iOSStudy/Base/BaseTableViewCell.h rename to iOSStudy/iOSStudy/Base/BaseTableViewCell.h diff --git a/iOSStudy/Base/BaseTableViewCell.m b/iOSStudy/iOSStudy/Base/BaseTableViewCell.m similarity index 100% rename from iOSStudy/Base/BaseTableViewCell.m rename to iOSStudy/iOSStudy/Base/BaseTableViewCell.m diff --git a/iOSStudy/iOSStudy/Base/BaseViewController.h b/iOSStudy/iOSStudy/Base/BaseViewController.h new file mode 100644 index 0000000..7b5c39a --- /dev/null +++ b/iOSStudy/iOSStudy/Base/BaseViewController.h @@ -0,0 +1,13 @@ +// +// BaseViewController.h +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface BaseViewController : UIViewController + +@end diff --git a/iOSStudy/iOSStudy/Base/BaseViewController.m b/iOSStudy/iOSStudy/Base/BaseViewController.m new file mode 100644 index 0000000..c6773d2 --- /dev/null +++ b/iOSStudy/iOSStudy/Base/BaseViewController.m @@ -0,0 +1,42 @@ +// +// BaseViewController.m +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BaseViewController.h" + +@interface BaseViewController () + +@end + +@implementation BaseViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + + +} +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/Bean/FavouriteBean.h b/iOSStudy/iOSStudy/Bean/FavouriteBean.h new file mode 100644 index 0000000..5ebd56e --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/FavouriteBean.h @@ -0,0 +1,38 @@ +// +// FavouriteBean.h +// iOSStudy +// +// Created by chenguandong on 15/3/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +typedef NS_ENUM(NSInteger, FAVOURITE_TYPE) { + BLOG_TYPE = 1, + WEB_TYPE = 2, + VIDEO_TYPE = 3 +}; + +@interface FavouriteBean : NSObject +/** + * 标题 + */ +@property(nonatomic,copy)NSString *title; +/** + * 描述 + */ +@property(nonatomic,copy)NSString *subtitle; +/** + * 图片地址 + */ +@property(nonatomic,copy)NSString *image_name; +/** + * 网络连接 + */ +@property(nonatomic,copy)NSString *url; +/** + * 类型 1 收藏博客 2 收藏网站 3 收藏视频 11,持久化博客 22,持久化网站 33,持久化视频 + */ +@property(nonatomic,copy)NSString* type; +@end diff --git a/iOSStudy/iOSStudy/Bean/FavouriteBean.m b/iOSStudy/iOSStudy/Bean/FavouriteBean.m new file mode 100644 index 0000000..e254b44 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/FavouriteBean.m @@ -0,0 +1,13 @@ +// +// FavouriteBean.m +// iOSStudy +// +// Created by chenguandong on 15/3/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "FavouriteBean.h" + +@implementation FavouriteBean + +@end diff --git a/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.h b/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.h new file mode 100644 index 0000000..5e4d6ae --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.h @@ -0,0 +1,43 @@ +// +// BlogBean.h +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface BlogBean : MTLModel +/** + * 博客名字 + */ +@property(nonatomic,copy)NSString*name; +/** + * 博客标题 + */ +@property(nonatomic,copy)NSString*title; +/** + * 博客描述 + */ +@property(nonatomic,copy)NSString*subTitle; +/** + * 博客图片 + */ +@property(nonatomic,copy)NSString*image; +/** + * 博客地址 + */ +@property(nonatomic,copy)NSString*url; +/** + * 博客RSS地址 + */ +@property(nonatomic,copy)NSString*rssUrl; +/** + * 博客地址 + */ +@property(nonatomic,copy)NSString*date; + +@property(nonatomic,copy)NSString*version; +@end diff --git a/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.m b/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.m new file mode 100644 index 0000000..c0152c9 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/blogBean/BlogBean.m @@ -0,0 +1,27 @@ +// +// BlogBean.m +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogBean.h" + +@implementation BlogBean ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"version":@"version", + @"name": @"name", + @"title": @"title", + @"subTitle": @"subTitle", + @"image": @"image", + @"url": @"url", + @"rssUrl": @"rssUrl", + @"date": @"date" + + }; +} +@end diff --git a/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.h b/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.h new file mode 100644 index 0000000..c8b122e --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.h @@ -0,0 +1,15 @@ +// +// BlogJsonBean.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface BlogJsonBean : MTLModel +@property(nonatomic,copy)NSString *version; +@property(nonatomic,strong)NSArray *bloglists; +@end diff --git a/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.m b/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.m new file mode 100644 index 0000000..11ecbd3 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/blogBean/BlogJsonBean.m @@ -0,0 +1,22 @@ +// +// BlogJsonBean.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogJsonBean.h" + +@implementation BlogJsonBean + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"version": @"version", + @"bloglists": @"bloglists" + }; +} + +@end diff --git a/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.h b/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.h new file mode 100644 index 0000000..8866057 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.h @@ -0,0 +1,23 @@ +// +// VersionBean.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface VersionBean : MTLModel +/** + * 当前请求地址的URL + */ +@property(nonatomic,copy)NSString *url; + +/** + * 当前请求地址URL版本号 + */ +@property(nonatomic,copy)NSString *urlVersion; + +@end diff --git a/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.m b/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.m new file mode 100644 index 0000000..7c7641c --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/versionBean/VersionBean.m @@ -0,0 +1,24 @@ +// +// VersionBean.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "VersionBean.h" + +@implementation VersionBean + + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"url": @"url", + @"urlVersion": @"urlVersion" + }; +} + + +@end diff --git a/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.h b/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.h new file mode 100644 index 0000000..c31da43 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.h @@ -0,0 +1,16 @@ +// +// VideoBean.h +// iOSStudy +// +// Created by chenguandong on 15/2/22. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WebBean.h" + +@interface VideoBean : WebBean +/** + * zh 中文 us 英文 + */ +@property(nonatomic,copy)NSString *videoLanguageType; +@end diff --git a/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.m b/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.m new file mode 100644 index 0000000..06d43ef --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/videoBean/VideoBean.m @@ -0,0 +1,20 @@ +// +// VideoBean.m +// iOSStudy +// +// Created by chenguandong on 15/2/22. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "VideoBean.h" + +@implementation VideoBean + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + [super JSONKeyPathsByPropertyKey]; + return @{ + @"videoLanguageType": @"videoLanguageType", + }; +} +@end diff --git a/iOSStudy/iOSStudy/Bean/webBean/WebBean.h b/iOSStudy/iOSStudy/Bean/webBean/WebBean.h new file mode 100644 index 0000000..979b753 --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/webBean/WebBean.h @@ -0,0 +1,33 @@ +// +// WebBean.h +// iOSStudy +// +// Created by chenguandong on 15/2/17. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import +@interface WebBean : MTLModel +/** + * 网站名字 + */ +@property(nonatomic,copy)NSString*name; +/** + * 网站标题 + */ +@property(nonatomic,copy)NSString*title; +/** + * 网站描述 + */ +@property(nonatomic,copy)NSString*subTitle; +/** + * 网站图片 + */ +@property(nonatomic,copy)NSString*webImage; +/** + * 网站地址 + */ +@property(nonatomic,copy)NSString*webUrl; +@end diff --git a/iOSStudy/iOSStudy/Bean/webBean/WebBean.m b/iOSStudy/iOSStudy/Bean/webBean/WebBean.m new file mode 100644 index 0000000..2adc3ea --- /dev/null +++ b/iOSStudy/iOSStudy/Bean/webBean/WebBean.m @@ -0,0 +1,25 @@ +// +// WebBean.m +// iOSStudy +// +// Created by chenguandong on 15/2/17. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WebBean.h" + +@implementation WebBean + ++ (NSDictionary *)JSONKeyPathsByPropertyKey{ + + + return @{ + @"name": @"name", + @"title": @"title", + @"subTitle": @"subTitile", + @"webImage": @"webImage", + @"webUrl": @"webUrl" + }; +} + +@end diff --git a/iOSStudy/iOSStudy/BlogViewController.h b/iOSStudy/iOSStudy/BlogViewController.h new file mode 100644 index 0000000..d51e4de --- /dev/null +++ b/iOSStudy/iOSStudy/BlogViewController.h @@ -0,0 +1,24 @@ +// +// FirstViewController.h +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "BaseViewController.h" +#import "BlogViewControllerViewModel.h" +#import +@interface BlogViewController : BaseViewController +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property(nonatomic,strong)BlogViewControllerViewModel *viewModel; +@property(nonatomic,copy)NSString *favouriteType ; +-(void)initViewData; + +/** + * 停止UITableView刷新 + */ +-(void)stopTableRefreshing; +@end + diff --git a/iOSStudy/iOSStudy/BlogViewController.m b/iOSStudy/iOSStudy/BlogViewController.m new file mode 100644 index 0000000..f8cad3d --- /dev/null +++ b/iOSStudy/iOSStudy/BlogViewController.m @@ -0,0 +1,225 @@ +// +// FirstViewController.m +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogViewController.h" +#import "NetWorkTools.h" +#import "Constants .h" +#import +#import "JsonTools.h" +#import "BlogBean.h" +#import +#import "BlogDetailViewController.h" +#import +#import +#import "EntityConstants.h" +#import "STBaseTableViewCell.h" +#import "UINavigationBar+Awesome.h" + +#define NAVBAR_CHANGE_POINT 50 +@interface BlogViewController () + +@end + +@implementation BlogViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + + + + _tableView.delegate = self; + _tableView.dataSource = self; + + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notificationReloadData:) name:notifacationBlogReload object:nil]; + + [self initViewData]; + + // [self.navigationController.navigationBar lt_setBackgroundColor:[UIColor orangeColor]]; + +} + +-(void)notificationReloadData:(NSNotification*)notifacation{ + + + [_tableView reloadData]; +} + +-(void)initViewData{ + + _favouriteType = TYPE_BLOG_FAVOURITE_TYPE; + + _viewModel = [[BlogViewControllerViewModel alloc]init]; + + + + [self.tableView addLegendHeaderWithRefreshingBlock:^{ + [_viewModel getDate:^{ + [_tableView reloadData]; + + [self stopTableRefreshing]; + } modelDataReload:^{ + [_tableView reloadData]; + } modelDataErrors:^{ + [self stopTableRefreshing]; + } modelDataIsNetworking:^(BOOL isNetWorking) { + [self stopTableRefreshing]; + } httpAdress:Address_blogs dataType:TYPE_BLOG_SIMPLE_TYPE jsonClass:[BlogBean class]]; + }]; + + // 隐藏时间 + self.tableView.header.updatedTimeHidden = YES; + // 隐藏状态 + self.tableView.header.stateHidden = YES; + + [self.tableView.header beginRefreshing]; + + _tableView.rowHeight = 60; + + [self.tableView registerNib:[UINib nibWithNibName:@"STBaseTableViewCell" bundle:nil] forCellReuseIdentifier:@"Cell"]; +} + +/** + * 停止UITableView刷新 + */ +-(void)stopTableRefreshing{ + if ([_tableView.header isRefreshing]) { + [_tableView.header endRefreshing]; + } +} + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + +} + +/* +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + UIColor * color = [UIColor colorWithRed:0/255.0 green:175/255.0 blue:240/255.0 alpha:1]; + CGFloat offsetY = scrollView.contentOffset.y; + if (offsetY > NAVBAR_CHANGE_POINT) { + CGFloat alpha = 1 - ((NAVBAR_CHANGE_POINT + 64 - offsetY) / 64); + + [self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:alpha]]; + } else { + [self.navigationController.navigationBar lt_setBackgroundColor:[color colorWithAlphaComponent:0]]; + } +} +*/ + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return [_viewModel getNumberOfRowsInSection]; +} + +// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: +// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + + static NSString *CellIdentifier = @"Cell"; + STBaseTableViewCell *cell = (STBaseTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier + forIndexPath:indexPath]; + + cell.delegate = self; + + + cell.title.text = [[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_title]; + cell.subtitle.text = [[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_subtitle]; + + + + cell.rightUtilityButtons =[_viewModel setRightSWCellButtons:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url] withType:TYPE_BLOG_FAVOURITE_TYPE]; + + + [cell.imageIcon setImageWithURL:[NSURL URLWithString:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_image_name]] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; + + + + + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + return cell; +} + + + + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + + + SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_url]]; + [self presentViewController:webViewController animated:NO completion:NULL]; + +} + +-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ + + if ([segue.identifier isEqualToString:@"SVWebViewController"]) { + + + } +} + + +#pragma mark-- SWTableViewCell delagate + +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell +{ + + return YES; +} +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ + + return YES; + +} + +- (void)swipeableTableViewCellDidEndScrolling:(SWTableViewCell *)cell{ + + //根据侧滑按钮是否显示设置箭头标志 + if (cell.isUtilityButtonsHidden) { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + }else{ + cell.accessoryType = UITableViewCellAccessoryNone; + + } +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + + + NSIndexPath *indexPath = [_tableView indexPathForCell:cell]; + + + [_viewModel saveFavourite:indexPath favouriteType:_favouriteType]; + + + [cell hideUtilityButtonsAnimated:YES]; + + [_tableView reloadData]; + + + +} + + +-(void)dealloc{ + _tableView.delegate = nil; + _tableView.dataSource = nil; + _viewModel = nil; + + [[NSNotificationCenter defaultCenter]removeObserver:self name:notifacationBlogReload object:nil]; + +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +@end diff --git a/iOSStudy/Cell/VideoCell.h b/iOSStudy/iOSStudy/Cell/VideoCell.h similarity index 100% rename from iOSStudy/Cell/VideoCell.h rename to iOSStudy/iOSStudy/Cell/VideoCell.h diff --git a/iOSStudy/Cell/VideoCell.m b/iOSStudy/iOSStudy/Cell/VideoCell.m similarity index 100% rename from iOSStudy/Cell/VideoCell.m rename to iOSStudy/iOSStudy/Cell/VideoCell.m diff --git a/iOSStudy/iOSStudy/Constants .h b/iOSStudy/iOSStudy/Constants .h index c7e120e..3a19509 100644 --- a/iOSStudy/iOSStudy/Constants .h +++ b/iOSStudy/iOSStudy/Constants .h @@ -8,15 +8,60 @@ #import "AppDelegate.h" +#import #ifndef iOSStudy_Constants__h #define iOSStudy_Constants__h -#define Address_blogs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/blogs.json" -#define Adress_webs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/webs.json" -#define Adress_videos @"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/videos.json" +//1 OSchina 0 github + +#define kHttpSource 0 + +#if kHttpSource + +/****OSChina数据源地址*****/ +#define Address_blogs @"https://git.oschina.net/FooKaa/helloworld/raw/master/blogs.json" +#define Adress_webs @"https://git.oschina.net/FooKaa/helloworld/raw/master/webs.json" +#define Adress_videos @"https://git.oschina.net/FooKaa/helloworld/raw/master/videos.json" + +#define Adress_versions @"https://git.oschina.net/FooKaa/helloworld/raw/master/versions.json" + + +#else +/** + github 数据源地址**/ + + #define Address_blogs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/blogs.json" + #define Adress_webs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/webs.json" + #define Adress_videos @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/videos.json" + + #define Adress_versions @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/versions.json" + +#endif + + #define SharedApp ((AppDelegate *)[[UIApplication sharedApplication] delegate]) #define PATH_OF_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] - +/** + * 收藏的数据库表明 + */ #define CD_FAVOURITE_BEAN @"FavouriteBean" + +/** + * http版本号数据库表明 + */ +#define CD_VersionsEntity @"VersionsEntity" + + + +static NSString *const TYPE_BLOG_SIMPLE_TYPE = @"1"; +static NSString *const TYPE_WEB_SIMPLE_TYPE = @"2"; +static NSString *const TYPE_VIDEO_SIMPLE_TYPE = @"3"; + +static NSString *const TYPE_BLOG_FAVOURITE_TYPE = @"11"; +static NSString *const TYPE_WEB_FAVOURITE_TYPE = @"22"; +static NSString *const TYPE_VIDEO_FAVOURITE_TYPE = @"33"; + + + #endif diff --git a/iOSStudy/iOSStudy/Constants/EntityConstants.h b/iOSStudy/iOSStudy/Constants/EntityConstants.h new file mode 100644 index 0000000..97defe3 --- /dev/null +++ b/iOSStudy/iOSStudy/Constants/EntityConstants.h @@ -0,0 +1,15 @@ +// +// EntityConstants.h +// iOSStudy +// +// Created by chenguandong on 15/4/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +extern NSString *const FavouriteBean_title; +extern NSString *const FavouriteBean_subtitle; +extern NSString *const FavouriteBean_image_name; +extern NSString *const FavouriteBean_type; +extern NSString *const FavouriteBean_url; diff --git a/iOSStudy/iOSStudy/Constants/EntityConstants.m b/iOSStudy/iOSStudy/Constants/EntityConstants.m new file mode 100644 index 0000000..dfcdd0d --- /dev/null +++ b/iOSStudy/iOSStudy/Constants/EntityConstants.m @@ -0,0 +1,15 @@ +// +// EntityConstants.m +// iOSStudy +// +// Created by chenguandong on 15/4/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "EntityConstants.h" + +NSString *const FavouriteBean_title = @"title"; +NSString *const FavouriteBean_subtitle = @"subtitle"; +NSString *const FavouriteBean_image_name = @"image_name"; +NSString *const FavouriteBean_type = @"type"; +NSString *const FavouriteBean_url = @"url"; diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png index aa81067..5c1c93f 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png index aa81067..5c1c93f 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png index cc11df5..2356a36 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png index 90fbb4c..c93794f 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png index 9b8269a..5b01d7f 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png index 8992f31..a7c45c3 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png index da710e0..e60863e 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png index da710e0..e60863e 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png index 43305f9..032ab00 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png index 7e1939c..833dd54 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png index 7e1939c..833dd54 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png index 72333c2..2b5f10f 100644 Binary files a/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png and b/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json index 851f4f0..2a15007 100644 --- a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json +++ b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -1,18 +1,45 @@ { "images" : [ + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "img_1242x2208.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "736h", + "filename" : "img_2208x1242.png", + "minimum-system-version" : "8.0", + "orientation" : "landscape", + "scale" : "3x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "667h", + "filename" : "img_750x1334.png", + "minimum-system-version" : "8.0", + "orientation" : "portrait", + "scale" : "2x" + }, { "orientation" : "portrait", "idiom" : "iphone", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "app_img_640.png", + "filename" : "img_640x960.png", "scale" : "2x" }, { "extent" : "full-screen", "idiom" : "iphone", "subtype" : "retina4", - "filename" : "app_img_1136.png", + "filename" : "img_640x1136.png", "minimum-system-version" : "7.0", "orientation" : "portrait", "scale" : "2x" @@ -22,7 +49,7 @@ "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "app_img_768x1024.png", + "filename" : "img_768x1024.png", "scale" : "1x" }, { @@ -30,7 +57,7 @@ "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "app_img_1024x768.png", + "filename" : "img_1024x768.png", "scale" : "1x" }, { @@ -38,7 +65,7 @@ "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "app_img_1536x2048.png", + "filename" : "img_1536x2048.png", "scale" : "2x" }, { @@ -46,7 +73,7 @@ "idiom" : "ipad", "extent" : "full-screen", "minimum-system-version" : "7.0", - "filename" : "app_img_2048x1536.png", + "filename" : "img_2048x1536.png", "scale" : "2x" } ], diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1024x768.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1024x768.png new file mode 100644 index 0000000..d17d300 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1024x768.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1242x2208.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1242x2208.png new file mode 100644 index 0000000..c11b311 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1242x2208.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1536x2048.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1536x2048.png new file mode 100644 index 0000000..fd96761 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_1536x2048.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2048x1536.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2048x1536.png new file mode 100644 index 0000000..c74442a Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2048x1536.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2208x1242.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2208x1242.png new file mode 100644 index 0000000..b917875 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_2208x1242.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x1136.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x1136.png new file mode 100644 index 0000000..1fbe35b Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x1136.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x960.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x960.png new file mode 100644 index 0000000..08622f4 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_640x960.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_750x1334.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_750x1334.png new file mode 100644 index 0000000..95c579a Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_750x1334.png differ diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_768x1024.png b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_768x1024.png new file mode 100644 index 0000000..0644a11 Binary files /dev/null and b/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/img_768x1024.png differ diff --git a/iOSStudy/iOSStudy/Info.plist b/iOSStudy/iOSStudy/Info.plist index d666dd9..0de2aeb 100644 --- a/iOSStudy/iOSStudy/Info.plist +++ b/iOSStudy/iOSStudy/Info.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - en + zh_CN CFBundleExecutable $(EXECUTABLE_NAME) CFBundleIdentifier @@ -11,19 +11,21 @@ CFBundleInfoDictionaryVersion 6.0 CFBundleName - $(PRODUCT_NAME) + Study for iOS CFBundlePackageType APPL CFBundleShortVersionString - 1.0 + 1.0.0 CFBundleSignature ???? CFBundleVersion - 1 + 8 LSRequiresIPhoneOS - UILaunchStoryboardName - LaunchScreen + UIBackgroundModes + + remote-notification + UIMainStoryboardFile Main UIRequiredDeviceCapabilities diff --git a/iOSStudy/iOSStudy/MainTabBarViewController.h b/iOSStudy/iOSStudy/MainTabBarViewController.h new file mode 100644 index 0000000..73bb465 --- /dev/null +++ b/iOSStudy/iOSStudy/MainTabBarViewController.h @@ -0,0 +1,13 @@ +// +// MainTabBarViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface MainTabBarViewController : UITabBarController + +@end diff --git a/iOSStudy/iOSStudy/MainTabBarViewController.m b/iOSStudy/iOSStudy/MainTabBarViewController.m new file mode 100644 index 0000000..88a0ece --- /dev/null +++ b/iOSStudy/iOSStudy/MainTabBarViewController.m @@ -0,0 +1,64 @@ +// +// MainTabBarViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "MainTabBarViewController.h" +#import "AppDelegate.h" +@interface MainTabBarViewController () + +@end + +@implementation MainTabBarViewController + + +-(void)viewWillAppear:(BOOL)animated{ + + [super viewWillAppear:YES]; + [[UIApplication sharedApplication]setApplicationIconBadgeNumber:0]; + +} +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + + +/* + + -(void)pushBage{ + + + NSUserDefaults *defalut = [NSUserDefaults standardUserDefaults]; + + NSInteger i = [defalut integerForKey:@"bage"]; + i++; + + [defalut setInteger:i forKey:@"bage"]; + + [defalut synchronize]; + + [[UIApplication sharedApplication]setApplicationIconBadgeNumber:i]; + } + */ + + +@end diff --git a/iOSStudy/iOSStudy/Podfile b/iOSStudy/iOSStudy/Podfile new file mode 100644 index 0000000..c770198 --- /dev/null +++ b/iOSStudy/iOSStudy/Podfile @@ -0,0 +1,9 @@ +platform :ios, '7.0' +pod "AFNetworking", "~> 2.0" +pod "SDWebImage" +pod 'FMDB' +pod 'Mantle' +pod 'SVProgressHUD' +pod 'SVWebViewController' +pod 'MJRefresh' +pod 'SWTableViewCell', '~> 0.3.7' diff --git a/iOSStudy/iOSStudy/Podfile.lock b/iOSStudy/iOSStudy/Podfile.lock new file mode 100644 index 0000000..ee61b81 --- /dev/null +++ b/iOSStudy/iOSStudy/Podfile.lock @@ -0,0 +1,59 @@ +PODS: + - AFNetworking (2.5.1): + - AFNetworking/NSURLConnection (= 2.5.1) + - AFNetworking/NSURLSession (= 2.5.1) + - AFNetworking/Reachability (= 2.5.1) + - AFNetworking/Security (= 2.5.1) + - AFNetworking/Serialization (= 2.5.1) + - AFNetworking/UIKit (= 2.5.1) + - AFNetworking/NSURLConnection (2.5.1): + - AFNetworking/Reachability + - AFNetworking/Security + - AFNetworking/Serialization + - AFNetworking/NSURLSession (2.5.1): + - AFNetworking/Reachability + - AFNetworking/Security + - AFNetworking/Serialization + - AFNetworking/Reachability (2.5.1) + - AFNetworking/Security (2.5.1) + - AFNetworking/Serialization (2.5.1) + - AFNetworking/UIKit (2.5.1): + - AFNetworking/NSURLConnection + - AFNetworking/NSURLSession + - FMDB (2.5): + - FMDB/standard (= 2.5) + - FMDB/common (2.5) + - FMDB/standard (2.5): + - FMDB/common + - Mantle (1.5.4): + - Mantle/extobjc (= 1.5.4) + - Mantle/extobjc (1.5.4) + - MJRefresh (0.0.1) + - SDWebImage (3.7.1): + - SDWebImage/Core (= 3.7.1) + - SDWebImage/Core (3.7.1) + - SVProgressHUD (1.1.2) + - SVWebViewController (1.0) + - SWTableViewCell (0.3.7) + +DEPENDENCIES: + - AFNetworking (~> 2.0) + - FMDB + - Mantle + - MJRefresh + - SDWebImage + - SVProgressHUD + - SVWebViewController + - SWTableViewCell (~> 0.3.7) + +SPEC CHECKSUMS: + AFNetworking: 8bee59492a6ff15d69130efa4d0dc67e0094a52a + FMDB: 0efa188cf0dd1ce82c27a478cd5f5fa245308677 + Mantle: d5fbaf30fbc58031223af13812c060e15934a1fe + MJRefresh: 02638d90855109026754562b7507e5c5eabfcc65 + SDWebImage: 116e88633b5b416ea0ca4b334a4ac59cf72dd38d + SVProgressHUD: da7a49e789af645d9279ffbca62318945a832438 + SVWebViewController: fbf917baa92744c54cfb89a52a4c056e409973a4 + SWTableViewCell: 25de71898e3fcd11cf75707ef90245acf990ec03 + +COCOAPODS: 0.35.0 diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h new file mode 100644 index 0000000..c1e37f6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.h @@ -0,0 +1,67 @@ +// AFHTTPRequestOperation.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import "AFURLConnectionOperation.h" + +/** + `AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. + */ +@interface AFHTTPRequestOperation : AFURLConnectionOperation + +///------------------------------------------------ +/// @name Getting HTTP URL Connection Information +///------------------------------------------------ + +/** + The last HTTP response received by the operation's connection. + */ +@property (readonly, nonatomic, strong) NSHTTPURLResponse *response; + +/** + Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an AFHTTPResponse serializer, which uses the raw data as its response object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. + + @warning `responseSerializer` must not be `nil`. Setting a response serializer will clear out any cached value + */ +@property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; + +/** + An object constructed by the `responseSerializer` from the response and response data. Returns `nil` unless the operation `isFinished`, has a `response`, and has `responseData` with non-zero content length. If an error occurs during serialization, `nil` will be returned, and the `error` property will be populated with the serialization error. + */ +@property (readonly, nonatomic, strong) id responseObject; + +///----------------------------------------------------------- +/// @name Setting Completion Block Success / Failure Callbacks +///----------------------------------------------------------- + +/** + Sets the `completionBlock` property with a block that executes either the specified success or failure block, depending on the state of the request on completion. If `error` returns a value, which can be caused by an unacceptable status code or content type, then `failure` is executed. Otherwise, `success` is executed. + + This method should be overridden in subclasses in order to specify the response object passed into the success block. + + @param success The block to be executed on the completion of a successful request. This block has no return value and takes two arguments: the receiver operation and the object constructed from the response data of the request. + @param failure The block to be executed on the completion of an unsuccessful request. This block has no return value and takes two arguments: the receiver operation and the error that occurred during the request. + */ +- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m new file mode 100644 index 0000000..e536f5d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperation.m @@ -0,0 +1,206 @@ +// AFHTTPRequestOperation.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFHTTPRequestOperation.h" + +static dispatch_queue_t http_request_operation_processing_queue() { + static dispatch_queue_t af_http_request_operation_processing_queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_http_request_operation_processing_queue = dispatch_queue_create("com.alamofire.networking.http-request.processing", DISPATCH_QUEUE_CONCURRENT); + }); + + return af_http_request_operation_processing_queue; +} + +static dispatch_group_t http_request_operation_completion_group() { + static dispatch_group_t af_http_request_operation_completion_group; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_http_request_operation_completion_group = dispatch_group_create(); + }); + + return af_http_request_operation_completion_group; +} + +#pragma mark - + +@interface AFURLConnectionOperation () +@property (readwrite, nonatomic, strong) NSURLRequest *request; +@property (readwrite, nonatomic, strong) NSURLResponse *response; +@end + +@interface AFHTTPRequestOperation () +@property (readwrite, nonatomic, strong) NSHTTPURLResponse *response; +@property (readwrite, nonatomic, strong) id responseObject; +@property (readwrite, nonatomic, strong) NSError *responseSerializationError; +@property (readwrite, nonatomic, strong) NSRecursiveLock *lock; +@end + +@implementation AFHTTPRequestOperation +@dynamic lock; + +- (instancetype)initWithRequest:(NSURLRequest *)urlRequest { + self = [super initWithRequest:urlRequest]; + if (!self) { + return nil; + } + + self.responseSerializer = [AFHTTPResponseSerializer serializer]; + + return self; +} + +- (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { + NSParameterAssert(responseSerializer); + + [self.lock lock]; + _responseSerializer = responseSerializer; + self.responseObject = nil; + self.responseSerializationError = nil; + [self.lock unlock]; +} + +- (id)responseObject { + [self.lock lock]; + if (!_responseObject && [self isFinished] && !self.error) { + NSError *error = nil; + self.responseObject = [self.responseSerializer responseObjectForResponse:self.response data:self.responseData error:&error]; + if (error) { + self.responseSerializationError = error; + } + } + [self.lock unlock]; + + return _responseObject; +} + +- (NSError *)error { + if (_responseSerializationError) { + return _responseSerializationError; + } else { + return [super error]; + } +} + +#pragma mark - AFHTTPRequestOperation + +- (void)setCompletionBlockWithSuccess:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + // completionBlock is manually nilled out in AFURLConnectionOperation to break the retain cycle. +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-retain-cycles" +#pragma clang diagnostic ignored "-Wgnu" + self.completionBlock = ^{ + if (self.completionGroup) { + dispatch_group_enter(self.completionGroup); + } + + dispatch_async(http_request_operation_processing_queue(), ^{ + if (self.error) { + if (failure) { + dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(self, self.error); + }); + } + } else { + id responseObject = self.responseObject; + if (self.error) { + if (failure) { + dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(self, self.error); + }); + } + } else { + if (success) { + dispatch_group_async(self.completionGroup ?: http_request_operation_completion_group(), self.completionQueue ?: dispatch_get_main_queue(), ^{ + success(self, responseObject); + }); + } + } + } + + if (self.completionGroup) { + dispatch_group_leave(self.completionGroup); + } + }); + }; +#pragma clang diagnostic pop +} + +#pragma mark - AFURLRequestOperation + +- (void)pause { + [super pause]; + + u_int64_t offset = 0; + if ([self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey]) { + offset = [(NSNumber *)[self.outputStream propertyForKey:NSStreamFileCurrentOffsetKey] unsignedLongLongValue]; + } else { + offset = [(NSData *)[self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey] length]; + } + + NSMutableURLRequest *mutableURLRequest = [self.request mutableCopy]; + if ([self.response respondsToSelector:@selector(allHeaderFields)] && [[self.response allHeaderFields] valueForKey:@"ETag"]) { + [mutableURLRequest setValue:[[self.response allHeaderFields] valueForKey:@"ETag"] forHTTPHeaderField:@"If-Range"]; + } + [mutableURLRequest setValue:[NSString stringWithFormat:@"bytes=%llu-", offset] forHTTPHeaderField:@"Range"]; + self.request = mutableURLRequest; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPRequestOperation *operation = [super copyWithZone:zone]; + + operation.responseSerializer = [self.responseSerializer copyWithZone:zone]; + operation.completionQueue = self.completionQueue; + operation.completionGroup = self.completionGroup; + + return operation; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h new file mode 100644 index 0000000..e1fb041 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h @@ -0,0 +1,308 @@ +// AFHTTPRequestOperationManager.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import +#import + +#if __IPHONE_OS_VERSION_MIN_REQUIRED +#import +#else +#import +#endif + +#import "AFHTTPRequestOperation.h" +#import "AFURLResponseSerialization.h" +#import "AFURLRequestSerialization.h" +#import "AFSecurityPolicy.h" +#import "AFNetworkReachabilityManager.h" + +/** + `AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management. + + ## Subclassing Notes + + Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. + + For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. + + ## Methods to Override + + To change the behavior of all request operation construction for an `AFHTTPRequestOperationManager` subclass, override `HTTPRequestOperationWithRequest:success:failure`. + + ## Serialization + + Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. + + Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` + + ## URL Construction Using Relative Paths + + For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. + + Below are a few examples of how `baseURL` and relative paths interact: + + NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; + [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz + [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo + [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ + [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + + Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. + + ## Network Reachability Monitoring + + Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. + + ## NSSecureCoding & NSCopying Caveats + + `AFHTTPRequestOperationManager` conforms to the `NSSecureCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. There are a few minor caveats to keep in mind, however: + + - Archives and copies of HTTP clients will be initialized with an empty operation queue. + - NSSecureCoding cannot serialize / deserialize block properties, so an archive of an HTTP client will not include any reachability callback block that may be set. + */ +@interface AFHTTPRequestOperationManager : NSObject + +/** + The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. + */ +@property (readonly, nonatomic, strong) NSURL *baseURL; + +/** + Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. + + @warning `requestSerializer` must not be `nil`. + */ +@property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; + +/** + Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to a JSON serializer, which serializes data from responses with a `application/json` MIME type, and falls back to the raw data object. The serializer validates the status code to be in the `2XX` range, denoting success. If the response serializer generates an error in `-responseObjectForResponse:data:error:`, the `failure` callback of the session task or request operation will be executed; otherwise, the `success` callback will be executed. + + @warning `responseSerializer` must not be `nil`. + */ +@property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; + +/** + The operation queue on which request operations are scheduled and run. + */ +@property (nonatomic, strong) NSOperationQueue *operationQueue; + +///------------------------------- +/// @name Managing URL Credentials +///------------------------------- + +/** + Whether request operations should consult the credential storage for authenticating the connection. `YES` by default. + + @see AFURLConnectionOperation -shouldUseCredentialStorage + */ +@property (nonatomic, assign) BOOL shouldUseCredentialStorage; + +/** + The credential used by request operations for authentication challenges. + + @see AFURLConnectionOperation -credential + */ +@property (nonatomic, strong) NSURLCredential *credential; + +///------------------------------- +/// @name Managing Security Policy +///------------------------------- + +/** + The security policy used by created request operations to evaluate server trust for secure connections. `AFHTTPRequestOperationManager` uses the `defaultPolicy` unless otherwise specified. + */ +@property (nonatomic, strong) AFSecurityPolicy *securityPolicy; + +///------------------------------------ +/// @name Managing Network Reachability +///------------------------------------ + +/** + The network reachability manager. `AFHTTPRequestOperationManager` uses the `sharedManager` by default. + */ +@property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; + +///------------------------------- +/// @name Managing Callback Queues +///------------------------------- + +/** + The dispatch queue for the `completionBlock` of request operations. If `NULL` (default), the main queue is used. + */ +@property (nonatomic, strong) dispatch_queue_t completionQueue; + +/** + The dispatch group for the `completionBlock` of request operations. If `NULL` (default), a private dispatch group is used. + */ +@property (nonatomic, strong) dispatch_group_t completionGroup; + +///--------------------------------------------- +/// @name Creating and Initializing HTTP Clients +///--------------------------------------------- + +/** + Creates and returns an `AFHTTPRequestOperationManager` object. + */ ++ (instancetype)manager; + +/** + Initializes an `AFHTTPRequestOperationManager` object with the specified base URL. + + This is the designated initializer. + + @param url The base URL for the HTTP client. + + @return The newly-initialized HTTP client + */ +- (instancetype)initWithBaseURL:(NSURL *)url NS_DESIGNATED_INITIALIZER; + +///--------------------------------------- +/// @name Managing HTTP Request Operations +///--------------------------------------- + +/** + Creates an `AFHTTPRequestOperation`, and sets the response serializers to that of the HTTP client. + + @param request The request object to be loaded asynchronously during execution of the operation. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the created request operation and the object created from the response data of request. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes two arguments:, the created request operation and the `NSError` object describing the network or parsing error that occurred. + */ +- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +///--------------------------- +/// @name Making HTTP Requests +///--------------------------- + +/** + Creates and runs an `AFHTTPRequestOperation` with a `GET` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)GET:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a `HEAD` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes a single arguments: the request operation. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)HEAD:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)POST:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a multipart `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)POST:(NSString *)URLString + parameters:(id)parameters + constructingBodyWithBlock:(void (^)(id formData))block + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a `PUT` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)PUT:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a `PATCH` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)PATCH:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +/** + Creates and runs an `AFHTTPRequestOperation` with a `DELETE` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the request operation finishes successfully. This block has no return value and takes two arguments: the request operation, and the response object created by the client response serializer. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the request operation and the error describing the network or parsing error that occurred. + + @see -HTTPRequestOperationWithRequest:success:failure: + */ +- (AFHTTPRequestOperation *)DELETE:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure; + +@end + diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.m new file mode 100644 index 0000000..665111f --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPRequestOperationManager.m @@ -0,0 +1,285 @@ +// AFHTTPRequestOperationManager.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import "AFHTTPRequestOperationManager.h" +#import "AFHTTPRequestOperation.h" + +#import +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import +#endif + +@interface AFHTTPRequestOperationManager () +@property (readwrite, nonatomic, strong) NSURL *baseURL; +@end + +@implementation AFHTTPRequestOperationManager + ++ (instancetype)manager { + return [[self alloc] initWithBaseURL:nil]; +} + +- (instancetype)init { + return [self initWithBaseURL:nil]; +} + +- (instancetype)initWithBaseURL:(NSURL *)url { + self = [super init]; + if (!self) { + return nil; + } + + // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected + if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { + url = [url URLByAppendingPathComponent:@""]; + } + + self.baseURL = url; + + self.requestSerializer = [AFHTTPRequestSerializer serializer]; + self.responseSerializer = [AFJSONResponseSerializer serializer]; + + self.securityPolicy = [AFSecurityPolicy defaultPolicy]; + + self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; + + self.operationQueue = [[NSOperationQueue alloc] init]; + + self.shouldUseCredentialStorage = YES; + + return self; +} + +#pragma mark - + +#ifdef _SYSTEMCONFIGURATION_H +#endif + +- (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { + NSParameterAssert(requestSerializer); + + _requestSerializer = requestSerializer; +} + +- (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { + NSParameterAssert(responseSerializer); + + _responseSerializer = responseSerializer; +} + +#pragma mark - + +- (AFHTTPRequestOperation *)HTTPRequestOperationWithHTTPMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + NSError *serializationError = nil; + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; + if (serializationError) { + if (failure) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(nil, serializationError); + }); +#pragma clang diagnostic pop + } + + return nil; + } + + return [self HTTPRequestOperationWithRequest:request success:success failure:failure]; +} + +- (AFHTTPRequestOperation *)HTTPRequestOperationWithRequest:(NSURLRequest *)request + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; + operation.responseSerializer = self.responseSerializer; + operation.shouldUseCredentialStorage = self.shouldUseCredentialStorage; + operation.credential = self.credential; + operation.securityPolicy = self.securityPolicy; + + [operation setCompletionBlockWithSuccess:success failure:failure]; + operation.completionQueue = self.completionQueue; + operation.completionGroup = self.completionGroup; + + return operation; +} + +#pragma mark - + +- (AFHTTPRequestOperation *)GET:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)HEAD:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(AFHTTPRequestOperation *requestOperation, __unused id responseObject) { + if (success) { + success(requestOperation); + } + } failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)POST:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)POST:(NSString *)URLString + parameters:(id)parameters + constructingBodyWithBlock:(void (^)(id formData))block + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + NSError *serializationError = nil; + NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; + if (serializationError) { + if (failure) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(nil, serializationError); + }); +#pragma clang diagnostic pop + } + + return nil; + } + + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithRequest:request success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)PUT:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)PATCH:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +- (AFHTTPRequestOperation *)DELETE:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(AFHTTPRequestOperation *operation, id responseObject))success + failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))failure +{ + AFHTTPRequestOperation *operation = [self HTTPRequestOperationWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure]; + + [self.operationQueue addOperation:operation]; + + return operation; +} + +#pragma mark - NSObject + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.operationQueue]; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + NSURL *baseURL = [decoder decodeObjectForKey:NSStringFromSelector(@selector(baseURL))]; + + self = [self initWithBaseURL:baseURL]; + if (!self) { + return nil; + } + + self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))]; + self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; + [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; + [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPRequestOperationManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL]; + + HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; + HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; + + return HTTPClient; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h new file mode 100644 index 0000000..bab8245 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.h @@ -0,0 +1,240 @@ +// AFHTTPSessionManager.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import +#import + +#if __IPHONE_OS_VERSION_MIN_REQUIRED +#import +#else +#import +#endif + +#import "AFURLSessionManager.h" + +/** + `AFHTTPSessionManager` is a subclass of `AFURLSessionManager` with convenience methods for making HTTP requests. When a `baseURL` is provided, requests made with the `GET` / `POST` / et al. convenience methods can be made with relative paths. + + ## Subclassing Notes + + Developers targeting iOS 7 or Mac OS X 10.9 or later that deal extensively with a web service are encouraged to subclass `AFHTTPSessionManager`, providing a class method that returns a shared singleton object on which authentication and other configuration can be shared across the application. + + For developers targeting iOS 6 or Mac OS X 10.8 or earlier, `AFHTTPRequestOperationManager` may be used to similar effect. + + ## Methods to Override + + To change the behavior of all data task operation construction, which is also used in the `GET` / `POST` / et al. convenience methods, override `dataTaskWithRequest:completionHandler:`. + + ## Serialization + + Requests created by an HTTP client will contain default headers and encode parameters according to the `requestSerializer` property, which is an object conforming to ``. + + Responses received from the server are automatically validated and serialized by the `responseSerializers` property, which is an object conforming to `` + + ## URL Construction Using Relative Paths + + For HTTP convenience methods, the request serializer constructs URLs from the path relative to the `-baseURL`, using `NSURL +URLWithString:relativeToURL:`, when provided. If `baseURL` is `nil`, `path` needs to resolve to a valid `NSURL` object using `NSURL +URLWithString:`. + + Below are a few examples of how `baseURL` and relative paths interact: + + NSURL *baseURL = [NSURL URLWithString:@"http://example.com/v1/"]; + [NSURL URLWithString:@"foo" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"foo?bar=baz" relativeToURL:baseURL]; // http://example.com/v1/foo?bar=baz + [NSURL URLWithString:@"/foo" relativeToURL:baseURL]; // http://example.com/foo + [NSURL URLWithString:@"foo/" relativeToURL:baseURL]; // http://example.com/v1/foo + [NSURL URLWithString:@"/foo/" relativeToURL:baseURL]; // http://example.com/foo/ + [NSURL URLWithString:@"http://example2.com/" relativeToURL:baseURL]; // http://example2.com/ + + Also important to note is that a trailing slash will be added to any `baseURL` without one. This would otherwise cause unexpected behavior when constructing URLs using paths without a leading slash. + + @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. + */ + +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) + +@interface AFHTTPSessionManager : AFURLSessionManager + +/** + The URL used to monitor reachability, and construct requests from relative paths in methods like `requestWithMethod:URLString:parameters:`, and the `GET` / `POST` / et al. convenience methods. + */ +@property (readonly, nonatomic, strong) NSURL *baseURL; + +/** + Requests created with `requestWithMethod:URLString:parameters:` & `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:` are constructed with a set of default headers using a parameter serialization specified by this property. By default, this is set to an instance of `AFHTTPRequestSerializer`, which serializes query string parameters for `GET`, `HEAD`, and `DELETE` requests, or otherwise URL-form-encodes HTTP message bodies. + + @warning `requestSerializer` must not be `nil`. + */ +@property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; + +/** + Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. + + @warning `responseSerializer` must not be `nil`. + */ +@property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; + +///--------------------- +/// @name Initialization +///--------------------- + +/** + Creates and returns an `AFHTTPSessionManager` object. + */ ++ (instancetype)manager; + +/** + Initializes an `AFHTTPSessionManager` object with the specified base URL. + + @param url The base URL for the HTTP client. + + @return The newly-initialized HTTP client + */ +- (instancetype)initWithBaseURL:(NSURL *)url; + +/** + Initializes an `AFHTTPSessionManager` object with the specified base URL. + + This is the designated initializer. + + @param url The base URL for the HTTP client. + @param configuration The configuration used to create the managed session. + + @return The newly-initialized HTTP client + */ +- (instancetype)initWithBaseURL:(NSURL *)url + sessionConfiguration:(NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; + +///--------------------------- +/// @name Making HTTP Requests +///--------------------------- + +/** + Creates and runs an `NSURLSessionDataTask` with a `GET` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)GET:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a `HEAD` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes a single arguments: the data task. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)HEAD:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)POST:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a multipart `POST` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)POST:(NSString *)URLString + parameters:(id)parameters + constructingBodyWithBlock:(void (^)(id formData))block + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a `PUT` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)PUT:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a `PATCH` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)PATCH:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +/** + Creates and runs an `NSURLSessionDataTask` with a `DELETE` request. + + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded according to the client request serializer. + @param success A block object to be executed when the task finishes successfully. This block has no return value and takes two arguments: the data task, and the response object created by the client response serializer. + @param failure A block object to be executed when the task finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a two arguments: the data task and the error describing the network or parsing error that occurred. + + @see -dataTaskWithRequest:completionHandler: + */ +- (NSURLSessionDataTask *)DELETE:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m new file mode 100644 index 0000000..3a2323e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFHTTPSessionManager.m @@ -0,0 +1,321 @@ +// AFHTTPSessionManager.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFHTTPSessionManager.h" + +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) + +#import "AFURLRequestSerialization.h" +#import "AFURLResponseSerialization.h" + +#import +#import + +#ifdef _SYSTEMCONFIGURATION_H +#import +#import +#import +#import +#import +#endif + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import +#endif + +@interface AFHTTPSessionManager () +@property (readwrite, nonatomic, strong) NSURL *baseURL; +@end + +@implementation AFHTTPSessionManager + ++ (instancetype)manager { + return [[[self class] alloc] initWithBaseURL:nil]; +} + +- (instancetype)init { + return [self initWithBaseURL:nil]; +} + +- (instancetype)initWithBaseURL:(NSURL *)url { + return [self initWithBaseURL:url sessionConfiguration:nil]; +} + +- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { + return [self initWithBaseURL:nil sessionConfiguration:configuration]; +} + +- (instancetype)initWithBaseURL:(NSURL *)url + sessionConfiguration:(NSURLSessionConfiguration *)configuration +{ + self = [super initWithSessionConfiguration:configuration]; + if (!self) { + return nil; + } + + // Ensure terminal slash for baseURL path, so that NSURL +URLWithString:relativeToURL: works as expected + if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) { + url = [url URLByAppendingPathComponent:@""]; + } + + self.baseURL = url; + + self.requestSerializer = [AFHTTPRequestSerializer serializer]; + self.responseSerializer = [AFJSONResponseSerializer serializer]; + + return self; +} + +#pragma mark - + +#ifdef _SYSTEMCONFIGURATION_H +#endif + +- (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { + NSParameterAssert(requestSerializer); + + _requestSerializer = requestSerializer; +} + +- (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { + NSParameterAssert(responseSerializer); + + [super setResponseSerializer:responseSerializer]; +} + +#pragma mark - + +- (NSURLSessionDataTask *)GET:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET" URLString:URLString parameters:parameters success:success failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)HEAD:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"HEAD" URLString:URLString parameters:parameters success:^(NSURLSessionDataTask *task, __unused id responseObject) { + if (success) { + success(task); + } + } failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)POST:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST" URLString:URLString parameters:parameters success:success failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)POST:(NSString *)URLString + parameters:(id)parameters + constructingBodyWithBlock:(void (^)(id formData))block + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSError *serializationError = nil; + NSMutableURLRequest *request = [self.requestSerializer multipartFormRequestWithMethod:@"POST" URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters constructingBodyWithBlock:block error:&serializationError]; + if (serializationError) { + if (failure) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(nil, serializationError); + }); +#pragma clang diagnostic pop + } + + return nil; + } + + __block NSURLSessionDataTask *task = [self uploadTaskWithStreamedRequest:request progress:nil completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { + if (error) { + if (failure) { + failure(task, error); + } + } else { + if (success) { + success(task, responseObject); + } + } + }]; + + [task resume]; + + return task; +} + +- (NSURLSessionDataTask *)PUT:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PUT" URLString:URLString parameters:parameters success:success failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)PATCH:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"PATCH" URLString:URLString parameters:parameters success:success failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)DELETE:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *task, id responseObject))success + failure:(void (^)(NSURLSessionDataTask *task, NSError *error))failure +{ + NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"DELETE" URLString:URLString parameters:parameters success:success failure:failure]; + + [dataTask resume]; + + return dataTask; +} + +- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters + success:(void (^)(NSURLSessionDataTask *, id))success + failure:(void (^)(NSURLSessionDataTask *, NSError *))failure +{ + NSError *serializationError = nil; + NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError]; + if (serializationError) { + if (failure) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{ + failure(nil, serializationError); + }); +#pragma clang diagnostic pop + } + + return nil; + } + + __block NSURLSessionDataTask *dataTask = nil; + dataTask = [self dataTaskWithRequest:request completionHandler:^(NSURLResponse * __unused response, id responseObject, NSError *error) { + if (error) { + if (failure) { + failure(dataTask, error); + } + } else { + if (success) { + success(dataTask, responseObject); + } + } + }]; + + return dataTask; +} + +#pragma mark - NSObject + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@: %p, baseURL: %@, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, [self.baseURL absoluteString], self.session, self.operationQueue]; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + NSURL *baseURL = [decoder decodeObjectOfClass:[NSURL class] forKey:NSStringFromSelector(@selector(baseURL))]; + NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; + if (!configuration) { + NSString *configurationIdentifier = [decoder decodeObjectOfClass:[NSString class] forKey:@"identifier"]; + if (configurationIdentifier) { +#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000) || (defined(__MAC_OS_X_VERSION_MIN_REQUIRED) && __MAC_OS_X_VERSION_MIN_REQUIRED >= 1100) + configuration = [NSURLSessionConfiguration backgroundSessionConfigurationWithIdentifier:configurationIdentifier]; +#else + configuration = [NSURLSessionConfiguration backgroundSessionConfiguration:configurationIdentifier]; +#endif + } + } + + self = [self initWithBaseURL:baseURL sessionConfiguration:configuration]; + if (!self) { + return nil; + } + + self.requestSerializer = [decoder decodeObjectOfClass:[AFHTTPRequestSerializer class] forKey:NSStringFromSelector(@selector(requestSerializer))]; + self.responseSerializer = [decoder decodeObjectOfClass:[AFHTTPResponseSerializer class] forKey:NSStringFromSelector(@selector(responseSerializer))]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:self.baseURL forKey:NSStringFromSelector(@selector(baseURL))]; + if ([self.session.configuration conformsToProtocol:@protocol(NSCoding)]) { + [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; + } else { + [coder encodeObject:self.session.configuration.identifier forKey:@"identifier"]; + } + [coder encodeObject:self.requestSerializer forKey:NSStringFromSelector(@selector(requestSerializer))]; + [coder encodeObject:self.responseSerializer forKey:NSStringFromSelector(@selector(responseSerializer))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPSessionManager *HTTPClient = [[[self class] allocWithZone:zone] initWithBaseURL:self.baseURL sessionConfiguration:self.session.configuration]; + + HTTPClient.requestSerializer = [self.requestSerializer copyWithZone:zone]; + HTTPClient.responseSerializer = [self.responseSerializer copyWithZone:zone]; + + return HTTPClient; +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h new file mode 100644 index 0000000..31ab79b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.h @@ -0,0 +1,193 @@ +// AFNetworkReachabilityManager.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { + AFNetworkReachabilityStatusUnknown = -1, + AFNetworkReachabilityStatusNotReachable = 0, + AFNetworkReachabilityStatusReachableViaWWAN = 1, + AFNetworkReachabilityStatusReachableViaWiFi = 2, +}; + +/** + `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. + + Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability. + + See Apple's Reachability Sample Code (https://developer.apple.com/library/ios/samplecode/reachability/) + + @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined. + */ +@interface AFNetworkReachabilityManager : NSObject + +/** + The current network reachability status. + */ +@property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; + +/** + Whether or not the network is currently reachable. + */ +@property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable; + +/** + Whether or not the network is currently reachable via WWAN. + */ +@property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN; + +/** + Whether or not the network is currently reachable via WiFi. + */ +@property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi; + +///--------------------- +/// @name Initialization +///--------------------- + +/** + Returns the shared network reachability manager. + */ ++ (instancetype)sharedManager; + +/** + Creates and returns a network reachability manager for the specified domain. + + @param domain The domain used to evaluate network reachability. + + @return An initialized network reachability manager, actively monitoring the specified domain. + */ ++ (instancetype)managerForDomain:(NSString *)domain; + +/** + Creates and returns a network reachability manager for the socket address. + + @param address The socket address (`sockaddr_in`) used to evaluate network reachability. + + @return An initialized network reachability manager, actively monitoring the specified socket address. + */ ++ (instancetype)managerForAddress:(const void *)address; + +/** + Initializes an instance of a network reachability manager from the specified reachability object. + + @param reachability The reachability object to monitor. + + @return An initialized network reachability manager, actively monitoring the specified reachability. + */ +- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER; + +///-------------------------------------------------- +/// @name Starting & Stopping Reachability Monitoring +///-------------------------------------------------- + +/** + Starts monitoring for changes in network reachability status. + */ +- (void)startMonitoring; + +/** + Stops monitoring for changes in network reachability status. + */ +- (void)stopMonitoring; + +///------------------------------------------------- +/// @name Getting Localized Reachability Description +///------------------------------------------------- + +/** + Returns a localized string representation of the current network reachability status. + */ +- (NSString *)localizedNetworkReachabilityStatusString; + +///--------------------------------------------------- +/// @name Setting Network Reachability Change Callback +///--------------------------------------------------- + +/** + Sets a callback to be executed when the network availability of the `baseURL` host changes. + + @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. + */ +- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block; + +@end + +///---------------- +/// @name Constants +///---------------- + +/** + ## Network Reachability + + The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses. + + enum { + AFNetworkReachabilityStatusUnknown, + AFNetworkReachabilityStatusNotReachable, + AFNetworkReachabilityStatusReachableViaWWAN, + AFNetworkReachabilityStatusReachableViaWiFi, + } + + `AFNetworkReachabilityStatusUnknown` + The `baseURL` host reachability is not known. + + `AFNetworkReachabilityStatusNotReachable` + The `baseURL` host cannot be reached. + + `AFNetworkReachabilityStatusReachableViaWWAN` + The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. + + `AFNetworkReachabilityStatusReachableViaWiFi` + The `baseURL` host can be reached via a Wi-Fi connection. + + ### Keys for Notification UserInfo Dictionary + + Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. + + `AFNetworkingReachabilityNotificationStatusItem` + A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. + The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. + */ + +///-------------------- +/// @name Notifications +///-------------------- + +/** + Posted when network reachability changes. + This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. + + @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). + */ +extern NSString * const AFNetworkingReachabilityDidChangeNotification; +extern NSString * const AFNetworkingReachabilityNotificationStatusItem; + +///-------------------- +/// @name Functions +///-------------------- + +/** + Returns a localized string representation of an `AFNetworkReachabilityStatus` value. + */ +extern NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status); diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m new file mode 100644 index 0000000..3415e98 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworkReachabilityManager.m @@ -0,0 +1,259 @@ +// AFNetworkReachabilityManager.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFNetworkReachabilityManager.h" + +#import +#import +#import +#import +#import + +NSString * const AFNetworkingReachabilityDidChangeNotification = @"com.alamofire.networking.reachability.change"; +NSString * const AFNetworkingReachabilityNotificationStatusItem = @"AFNetworkingReachabilityNotificationStatusItem"; + +typedef void (^AFNetworkReachabilityStatusBlock)(AFNetworkReachabilityStatus status); + +typedef NS_ENUM(NSUInteger, AFNetworkReachabilityAssociation) { + AFNetworkReachabilityForAddress = 1, + AFNetworkReachabilityForAddressPair = 2, + AFNetworkReachabilityForName = 3, +}; + +NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusNotReachable: + return NSLocalizedStringFromTable(@"Not Reachable", @"AFNetworking", nil); + case AFNetworkReachabilityStatusReachableViaWWAN: + return NSLocalizedStringFromTable(@"Reachable via WWAN", @"AFNetworking", nil); + case AFNetworkReachabilityStatusReachableViaWiFi: + return NSLocalizedStringFromTable(@"Reachable via WiFi", @"AFNetworking", nil); + case AFNetworkReachabilityStatusUnknown: + default: + return NSLocalizedStringFromTable(@"Unknown", @"AFNetworking", nil); + } +} + +static AFNetworkReachabilityStatus AFNetworkReachabilityStatusForFlags(SCNetworkReachabilityFlags flags) { + BOOL isReachable = ((flags & kSCNetworkReachabilityFlagsReachable) != 0); + BOOL needsConnection = ((flags & kSCNetworkReachabilityFlagsConnectionRequired) != 0); + BOOL canConnectionAutomatically = (((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || ((flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)); + BOOL canConnectWithoutUserInteraction = (canConnectionAutomatically && (flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0); + BOOL isNetworkReachable = (isReachable && (!needsConnection || canConnectWithoutUserInteraction)); + + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusUnknown; + if (isNetworkReachable == NO) { + status = AFNetworkReachabilityStatusNotReachable; + } +#if TARGET_OS_IPHONE + else if ((flags & kSCNetworkReachabilityFlagsIsWWAN) != 0) { + status = AFNetworkReachabilityStatusReachableViaWWAN; + } +#endif + else { + status = AFNetworkReachabilityStatusReachableViaWiFi; + } + + return status; +} + +static void AFNetworkReachabilityCallback(SCNetworkReachabilityRef __unused target, SCNetworkReachabilityFlags flags, void *info) { + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); + AFNetworkReachabilityStatusBlock block = (__bridge AFNetworkReachabilityStatusBlock)info; + if (block) { + block(status); + } + + + dispatch_async(dispatch_get_main_queue(), ^{ + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; + }); + +} + +static const void * AFNetworkReachabilityRetainCallback(const void *info) { + return Block_copy(info); +} + +static void AFNetworkReachabilityReleaseCallback(const void *info) { + if (info) { + Block_release(info); + } +} + +@interface AFNetworkReachabilityManager () +@property (readwrite, nonatomic, assign) SCNetworkReachabilityRef networkReachability; +@property (readwrite, nonatomic, assign) AFNetworkReachabilityAssociation networkReachabilityAssociation; +@property (readwrite, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; +@property (readwrite, nonatomic, copy) AFNetworkReachabilityStatusBlock networkReachabilityStatusBlock; +@end + +@implementation AFNetworkReachabilityManager + ++ (instancetype)sharedManager { + static AFNetworkReachabilityManager *_sharedManager = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + struct sockaddr_in address; + bzero(&address, sizeof(address)); + address.sin_len = sizeof(address); + address.sin_family = AF_INET; + + _sharedManager = [self managerForAddress:&address]; + }); + + return _sharedManager; +} + ++ (instancetype)managerForDomain:(NSString *)domain { + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, [domain UTF8String]); + + AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; + manager.networkReachabilityAssociation = AFNetworkReachabilityForName; + + return manager; +} + ++ (instancetype)managerForAddress:(const void *)address { + SCNetworkReachabilityRef reachability = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr *)address); + + AFNetworkReachabilityManager *manager = [[self alloc] initWithReachability:reachability]; + manager.networkReachabilityAssociation = AFNetworkReachabilityForAddress; + + return manager; +} + +- (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability { + self = [super init]; + if (!self) { + return nil; + } + + self.networkReachability = reachability; + self.networkReachabilityStatus = AFNetworkReachabilityStatusUnknown; + + return self; +} + +- (void)dealloc { + [self stopMonitoring]; + + if (_networkReachability) { + CFRelease(_networkReachability); + _networkReachability = NULL; + } +} + +#pragma mark - + +- (BOOL)isReachable { + return [self isReachableViaWWAN] || [self isReachableViaWiFi]; +} + +- (BOOL)isReachableViaWWAN { + return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWWAN; +} + +- (BOOL)isReachableViaWiFi { + return self.networkReachabilityStatus == AFNetworkReachabilityStatusReachableViaWiFi; +} + +#pragma mark - + +- (void)startMonitoring { + [self stopMonitoring]; + + if (!self.networkReachability) { + return; + } + + __weak __typeof(self)weakSelf = self; + AFNetworkReachabilityStatusBlock callback = ^(AFNetworkReachabilityStatus status) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + + strongSelf.networkReachabilityStatus = status; + if (strongSelf.networkReachabilityStatusBlock) { + strongSelf.networkReachabilityStatusBlock(status); + } + + }; + + SCNetworkReachabilityContext context = {0, (__bridge void *)callback, AFNetworkReachabilityRetainCallback, AFNetworkReachabilityReleaseCallback, NULL}; + SCNetworkReachabilitySetCallback(self.networkReachability, AFNetworkReachabilityCallback, &context); + SCNetworkReachabilityScheduleWithRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); + + switch (self.networkReachabilityAssociation) { + case AFNetworkReachabilityForName: + break; + case AFNetworkReachabilityForAddress: + case AFNetworkReachabilityForAddressPair: + default: { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0),^{ + SCNetworkReachabilityFlags flags; + SCNetworkReachabilityGetFlags(self.networkReachability, &flags); + AFNetworkReachabilityStatus status = AFNetworkReachabilityStatusForFlags(flags); + dispatch_async(dispatch_get_main_queue(), ^{ + callback(status); + + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:AFNetworkingReachabilityDidChangeNotification object:nil userInfo:@{ AFNetworkingReachabilityNotificationStatusItem: @(status) }]; + + + }); + }); + } + break; + } +} + +- (void)stopMonitoring { + if (!self.networkReachability) { + return; + } + + SCNetworkReachabilityUnscheduleFromRunLoop(self.networkReachability, CFRunLoopGetMain(), kCFRunLoopCommonModes); +} + +#pragma mark - + +- (NSString *)localizedNetworkReachabilityStatusString { + return AFStringFromNetworkReachabilityStatus(self.networkReachabilityStatus); +} + +#pragma mark - + +- (void)setReachabilityStatusChangeBlock:(void (^)(AFNetworkReachabilityStatus status))block { + self.networkReachabilityStatusBlock = block; +} + +#pragma mark - NSKeyValueObserving + ++ (NSSet *)keyPathsForValuesAffectingValueForKey:(NSString *)key { + if ([key isEqualToString:@"reachable"] || [key isEqualToString:@"reachableViaWWAN"] || [key isEqualToString:@"reachableViaWiFi"]) { + return [NSSet setWithObject:@"networkReachabilityStatus"]; + } + + return [super keyPathsForValuesAffectingValueForKey:key]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworking.h new file mode 100644 index 0000000..68273da --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFNetworking.h @@ -0,0 +1,44 @@ +// AFNetworking.h +// +// Copyright (c) 2013 AFNetworking (http://afnetworking.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +#ifndef _AFNETWORKING_ + #define _AFNETWORKING_ + + #import "AFURLRequestSerialization.h" + #import "AFURLResponseSerialization.h" + #import "AFSecurityPolicy.h" + #import "AFNetworkReachabilityManager.h" + + #import "AFURLConnectionOperation.h" + #import "AFHTTPRequestOperation.h" + #import "AFHTTPRequestOperationManager.h" + +#if ( ( defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) || \ + ( defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 ) ) + #import "AFURLSessionManager.h" + #import "AFHTTPSessionManager.h" +#endif + +#endif /* _AFNETWORKING_ */ diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h new file mode 100644 index 0000000..4906f3b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.h @@ -0,0 +1,143 @@ +// AFSecurityPolicy.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { + AFSSLPinningModeNone, + AFSSLPinningModePublicKey, + AFSSLPinningModeCertificate, +}; + +/** + `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. + + Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. + */ +@interface AFSecurityPolicy : NSObject + +/** + The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`. + */ +@property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; + +/** + Whether to evaluate an entire SSL certificate chain, or just the leaf certificate. Defaults to `YES`. + */ +@property (nonatomic, assign) BOOL validatesCertificateChain; + +/** + The certificates used to evaluate server trust according to the SSL pinning mode. By default, this property is set to any (`.cer`) certificates included in the app bundle. + */ +@property (nonatomic, strong) NSArray *pinnedCertificates; + +/** + Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. + */ +@property (nonatomic, assign) BOOL allowInvalidCertificates; + +/** + Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES` for `AFSSLPinningModePublicKey` or `AFSSLPinningModeCertificate`, otherwise `NO`. + */ +@property (nonatomic, assign) BOOL validatesDomainName; + +///----------------------------------------- +/// @name Getting Specific Security Policies +///----------------------------------------- + +/** + Returns the shared default security policy, which does not allow invalid certificates, does not validate domain name, and does not validate against pinned certificates or public keys. + + @return The default security policy. + */ ++ (instancetype)defaultPolicy; + +///--------------------- +/// @name Initialization +///--------------------- + +/** + Creates and returns a security policy with the specified pinning mode. + + @param pinningMode The SSL pinning mode. + + @return A new security policy. + */ ++ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; + +///------------------------------ +/// @name Evaluating Server Trust +///------------------------------ + +/** + Whether or not the specified server trust should be accepted, based on the security policy. + + This method should be used when responding to an authentication challenge from a server. + + @param serverTrust The X.509 certificate trust of the server. + + @return Whether or not to trust the server. + + @warning This method has been deprecated in favor of `-evaluateServerTrust:forDomain:`. + */ +- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust DEPRECATED_ATTRIBUTE; + +/** + Whether or not the specified server trust should be accepted, based on the security policy. + + This method should be used when responding to an authentication challenge from a server. + + @param serverTrust The X.509 certificate trust of the server. + @param domain The domain of serverTrust. If `nil`, the domain will not be validated. + + @return Whether or not to trust the server. + */ +- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust + forDomain:(NSString *)domain; + +@end + +///---------------- +/// @name Constants +///---------------- + +/** + ## SSL Pinning Modes + + The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes. + + enum { + AFSSLPinningModeNone, + AFSSLPinningModePublicKey, + AFSSLPinningModeCertificate, + } + + `AFSSLPinningModeNone` + Do not used pinned certificates to validate servers. + + `AFSSLPinningModePublicKey` + Validate host certificates against public keys of pinned certificates. + + `AFSSLPinningModeCertificate` + Validate host certificates against pinned certificates. +*/ diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m new file mode 100644 index 0000000..41576bb --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFSecurityPolicy.m @@ -0,0 +1,317 @@ +// AFSecurityPolicy.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFSecurityPolicy.h" + +#import + +#if !defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +static NSData * AFSecKeyGetData(SecKeyRef key) { + CFDataRef data = NULL; + + __Require_noErr_Quiet(SecItemExport(key, kSecFormatUnknown, kSecItemPemArmour, NULL, &data), _out); + + return (__bridge_transfer NSData *)data; + +_out: + if (data) { + CFRelease(data); + } + + return nil; +} +#endif + +static BOOL AFSecKeyIsEqualToKey(SecKeyRef key1, SecKeyRef key2) { +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + return [(__bridge id)key1 isEqual:(__bridge id)key2]; +#else + return [AFSecKeyGetData(key1) isEqual:AFSecKeyGetData(key2)]; +#endif +} + +static id AFPublicKeyForCertificate(NSData *certificate) { + id allowedPublicKey = nil; + SecCertificateRef allowedCertificate; + SecCertificateRef allowedCertificates[1]; + CFArrayRef tempCertificates = nil; + SecPolicyRef policy = nil; + SecTrustRef allowedTrust = nil; + SecTrustResultType result; + + allowedCertificate = SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificate); + __Require_Quiet(allowedCertificate != NULL, _out); + + allowedCertificates[0] = allowedCertificate; + tempCertificates = CFArrayCreate(NULL, (const void **)allowedCertificates, 1, NULL); + + policy = SecPolicyCreateBasicX509(); + __Require_noErr_Quiet(SecTrustCreateWithCertificates(tempCertificates, policy, &allowedTrust), _out); + __Require_noErr_Quiet(SecTrustEvaluate(allowedTrust, &result), _out); + + allowedPublicKey = (__bridge_transfer id)SecTrustCopyPublicKey(allowedTrust); + +_out: + if (allowedTrust) { + CFRelease(allowedTrust); + } + + if (policy) { + CFRelease(policy); + } + + if (tempCertificates) { + CFRelease(tempCertificates); + } + + if (allowedCertificate) { + CFRelease(allowedCertificate); + } + + return allowedPublicKey; +} + +static BOOL AFServerTrustIsValid(SecTrustRef serverTrust) { + BOOL isValid = NO; + SecTrustResultType result; + __Require_noErr_Quiet(SecTrustEvaluate(serverTrust, &result), _out); + + isValid = (result == kSecTrustResultUnspecified || result == kSecTrustResultProceed); + +_out: + return isValid; +} + +static NSArray * AFCertificateTrustChainForServerTrust(SecTrustRef serverTrust) { + CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); + NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; + + for (CFIndex i = 0; i < certificateCount; i++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); + [trustChain addObject:(__bridge_transfer NSData *)SecCertificateCopyData(certificate)]; + } + + return [NSArray arrayWithArray:trustChain]; +} + +static NSArray * AFPublicKeyTrustChainForServerTrust(SecTrustRef serverTrust) { + SecPolicyRef policy = SecPolicyCreateBasicX509(); + CFIndex certificateCount = SecTrustGetCertificateCount(serverTrust); + NSMutableArray *trustChain = [NSMutableArray arrayWithCapacity:(NSUInteger)certificateCount]; + for (CFIndex i = 0; i < certificateCount; i++) { + SecCertificateRef certificate = SecTrustGetCertificateAtIndex(serverTrust, i); + + SecCertificateRef someCertificates[] = {certificate}; + CFArrayRef certificates = CFArrayCreate(NULL, (const void **)someCertificates, 1, NULL); + + SecTrustRef trust; + __Require_noErr_Quiet(SecTrustCreateWithCertificates(certificates, policy, &trust), _out); + + SecTrustResultType result; + __Require_noErr_Quiet(SecTrustEvaluate(trust, &result), _out); + + [trustChain addObject:(__bridge_transfer id)SecTrustCopyPublicKey(trust)]; + + _out: + if (trust) { + CFRelease(trust); + } + + if (certificates) { + CFRelease(certificates); + } + + continue; + } + CFRelease(policy); + + return [NSArray arrayWithArray:trustChain]; +} + +#pragma mark - + +@interface AFSecurityPolicy() +@property (readwrite, nonatomic, assign) AFSSLPinningMode SSLPinningMode; +@property (readwrite, nonatomic, strong) NSArray *pinnedPublicKeys; +@end + +@implementation AFSecurityPolicy + ++ (NSArray *)defaultPinnedCertificates { + static NSArray *_defaultPinnedCertificates = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + NSBundle *bundle = [NSBundle bundleForClass:[self class]]; + NSArray *paths = [bundle pathsForResourcesOfType:@"cer" inDirectory:@"."]; + + NSMutableArray *certificates = [NSMutableArray arrayWithCapacity:[paths count]]; + for (NSString *path in paths) { + NSData *certificateData = [NSData dataWithContentsOfFile:path]; + [certificates addObject:certificateData]; + } + + _defaultPinnedCertificates = [[NSArray alloc] initWithArray:certificates]; + }); + + return _defaultPinnedCertificates; +} + ++ (instancetype)defaultPolicy { + AFSecurityPolicy *securityPolicy = [[self alloc] init]; + securityPolicy.SSLPinningMode = AFSSLPinningModeNone; + + return securityPolicy; +} + ++ (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode { + AFSecurityPolicy *securityPolicy = [[self alloc] init]; + securityPolicy.SSLPinningMode = pinningMode; + + [securityPolicy setPinnedCertificates:[self defaultPinnedCertificates]]; + + return securityPolicy; +} + +- (id)init { + self = [super init]; + if (!self) { + return nil; + } + + self.validatesCertificateChain = YES; + + return self; +} + +#pragma mark - + +- (void)setSSLPinningMode:(AFSSLPinningMode)SSLPinningMode { + _SSLPinningMode = SSLPinningMode; + + switch (self.SSLPinningMode) { + case AFSSLPinningModePublicKey: + case AFSSLPinningModeCertificate: + self.validatesDomainName = YES; + break; + default: + self.validatesDomainName = NO; + break; + } +} + +- (void)setPinnedCertificates:(NSArray *)pinnedCertificates { + _pinnedCertificates = pinnedCertificates; + + if (self.pinnedCertificates) { + NSMutableArray *mutablePinnedPublicKeys = [NSMutableArray arrayWithCapacity:[self.pinnedCertificates count]]; + for (NSData *certificate in self.pinnedCertificates) { + id publicKey = AFPublicKeyForCertificate(certificate); + if (!publicKey) { + continue; + } + [mutablePinnedPublicKeys addObject:publicKey]; + } + self.pinnedPublicKeys = [NSArray arrayWithArray:mutablePinnedPublicKeys]; + } else { + self.pinnedPublicKeys = nil; + } +} + +#pragma mark - + +- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust { + return [self evaluateServerTrust:serverTrust forDomain:nil]; +} + +- (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust + forDomain:(NSString *)domain +{ + NSMutableArray *policies = [NSMutableArray array]; + if (self.validatesDomainName) { + [policies addObject:(__bridge_transfer id)SecPolicyCreateSSL(true, (__bridge CFStringRef)domain)]; + } else { + [policies addObject:(__bridge_transfer id)SecPolicyCreateBasicX509()]; + } + + SecTrustSetPolicies(serverTrust, (__bridge CFArrayRef)policies); + + if (self.SSLPinningMode != AFSSLPinningModeNone && !AFServerTrustIsValid(serverTrust) && !self.allowInvalidCertificates) { + return NO; + } + + NSArray *serverCertificates = AFCertificateTrustChainForServerTrust(serverTrust); + switch (self.SSLPinningMode) { + case AFSSLPinningModeNone: + return YES; + case AFSSLPinningModeCertificate: { + NSMutableArray *pinnedCertificates = [NSMutableArray array]; + for (NSData *certificateData in self.pinnedCertificates) { + [pinnedCertificates addObject:(__bridge_transfer id)SecCertificateCreateWithData(NULL, (__bridge CFDataRef)certificateData)]; + } + SecTrustSetAnchorCertificates(serverTrust, (__bridge CFArrayRef)pinnedCertificates); + + if (!AFServerTrustIsValid(serverTrust)) { + return NO; + } + + if (!self.validatesCertificateChain) { + return YES; + } + + NSUInteger trustedCertificateCount = 0; + for (NSData *trustChainCertificate in serverCertificates) { + if ([self.pinnedCertificates containsObject:trustChainCertificate]) { + trustedCertificateCount++; + } + } + + return trustedCertificateCount == [serverCertificates count]; + } + case AFSSLPinningModePublicKey: { + NSUInteger trustedPublicKeyCount = 0; + NSArray *publicKeys = AFPublicKeyTrustChainForServerTrust(serverTrust); + if (!self.validatesCertificateChain && [publicKeys count] > 0) { + publicKeys = @[[publicKeys firstObject]]; + } + + for (id trustChainPublicKey in publicKeys) { + for (id pinnedPublicKey in self.pinnedPublicKeys) { + if (AFSecKeyIsEqualToKey((__bridge SecKeyRef)trustChainPublicKey, (__bridge SecKeyRef)pinnedPublicKey)) { + trustedPublicKeyCount += 1; + } + } + } + + return trustedPublicKeyCount > 0 && ((self.validatesCertificateChain && trustedPublicKeyCount == [serverCertificates count]) || (!self.validatesCertificateChain && trustedPublicKeyCount >= 1)); + } + } + + return NO; +} + +#pragma mark - NSKeyValueObserving + ++ (NSSet *)keyPathsForValuesAffectingPinnedPublicKeys { + return [NSSet setWithObject:@"pinnedCertificates"]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h new file mode 100644 index 0000000..7a5eccf --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.h @@ -0,0 +1,328 @@ +// AFURLConnectionOperation.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import +#import "AFURLRequestSerialization.h" +#import "AFURLResponseSerialization.h" +#import "AFSecurityPolicy.h" + +/** + `AFURLConnectionOperation` is a subclass of `NSOperation` that implements `NSURLConnection` delegate methods. + + ## Subclassing Notes + + This is the base class of all network request operations. You may wish to create your own subclass in order to implement additional `NSURLConnection` delegate methods (see "`NSURLConnection` Delegate Methods" below), or to provide additional properties and/or class constructors. + + If you are creating a subclass that communicates over the HTTP or HTTPS protocols, you may want to consider subclassing `AFHTTPRequestOperation` instead, as it supports specifying acceptable content types or status codes. + + ## NSURLConnection Delegate Methods + + `AFURLConnectionOperation` implements the following `NSURLConnection` delegate methods: + + - `connection:didReceiveResponse:` + - `connection:didReceiveData:` + - `connectionDidFinishLoading:` + - `connection:didFailWithError:` + - `connection:didSendBodyData:totalBytesWritten:totalBytesExpectedToWrite:` + - `connection:willCacheResponse:` + - `connectionShouldUseCredentialStorage:` + - `connection:needNewBodyStream:` + - `connection:willSendRequestForAuthenticationChallenge:` + + If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. + + ## Callbacks and Completion Blocks + + The built-in `completionBlock` provided by `NSOperation` allows for custom behavior to be executed after the request finishes. It is a common pattern for class constructors in subclasses to take callback block parameters, and execute them conditionally in the body of its `completionBlock`. Make sure to handle cancelled operations appropriately when setting a `completionBlock` (i.e. returning early before parsing response data). See the implementation of any of the `AFHTTPRequestOperation` subclasses for an example of this. + + Subclasses are strongly discouraged from overriding `setCompletionBlock:`, as `AFURLConnectionOperation`'s implementation includes a workaround to mitigate retain cycles, and what Apple rather ominously refers to as ["The Deallocation Problem"](http://developer.apple.com/library/ios/#technotes/tn2109/). + + ## SSL Pinning + + Relying on the CA trust model to validate SSL certificates exposes your app to security vulnerabilities, such as man-in-the-middle attacks. For applications that connect to known servers, SSL certificate pinning provides an increased level of security, by checking server certificate validity against those specified in the app bundle. + + SSL with certificate pinning is strongly recommended for any application that transmits sensitive information to an external webservice. + + Connections will be validated on all matching certificates with a `.cer` extension in the bundle root. + + ## App Extensions + + When using AFNetworking in an App Extension, `#define AF_APP_EXTENSIONS` to avoid using unavailable APIs. + + ## NSCoding & NSCopying Conformance + + `AFURLConnectionOperation` conforms to the `NSCoding` and `NSCopying` protocols, allowing operations to be archived to disk, and copied in memory, respectively. However, because of the intrinsic limitations of capturing the exact state of an operation at a particular moment, there are some important caveats to keep in mind: + + ### NSCoding Caveats + + - Encoded operations do not include any block or stream properties. Be sure to set `completionBlock`, `outputStream`, and any callback blocks as necessary when using `-initWithCoder:` or `NSKeyedUnarchiver`. + - Operations are paused on `encodeWithCoder:`. If the operation was encoded while paused or still executing, its archived state will return `YES` for `isReady`. Otherwise, the state of an operation when encoding will remain unchanged. + + ### NSCopying Caveats + + - `-copy` and `-copyWithZone:` return a new operation with the `NSURLRequest` of the original. So rather than an exact copy of the operation at that particular instant, the copying mechanism returns a completely new instance, which can be useful for retrying operations. + - A copy of an operation will not include the `outputStream` of the original. + - Operation copies do not include `completionBlock`, as it often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ operation when copied. + */ + +@interface AFURLConnectionOperation : NSOperation + +///------------------------------- +/// @name Accessing Run Loop Modes +///------------------------------- + +/** + The run loop modes in which the operation will run on the network thread. By default, this is a single-member set containing `NSRunLoopCommonModes`. + */ +@property (nonatomic, strong) NSSet *runLoopModes; + +///----------------------------------------- +/// @name Getting URL Connection Information +///----------------------------------------- + +/** + The request used by the operation's connection. + */ +@property (readonly, nonatomic, strong) NSURLRequest *request; + +/** + The last response received by the operation's connection. + */ +@property (readonly, nonatomic, strong) NSURLResponse *response; + +/** + The error, if any, that occurred in the lifecycle of the request. + */ +@property (readonly, nonatomic, strong) NSError *error; + +///---------------------------- +/// @name Getting Response Data +///---------------------------- + +/** + The data received during the request. + */ +@property (readonly, nonatomic, strong) NSData *responseData; + +/** + The string representation of the response data. + */ +@property (readonly, nonatomic, copy) NSString *responseString; + +/** + The string encoding of the response. + + If the response does not specify a valid string encoding, `responseStringEncoding` will return `NSUTF8StringEncoding`. + */ +@property (readonly, nonatomic, assign) NSStringEncoding responseStringEncoding; + +///------------------------------- +/// @name Managing URL Credentials +///------------------------------- + +/** + Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. + + This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. + */ +@property (nonatomic, assign) BOOL shouldUseCredentialStorage; + +/** + The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. + + This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. + */ +@property (nonatomic, strong) NSURLCredential *credential; + +///------------------------------- +/// @name Managing Security Policy +///------------------------------- + +/** + The security policy used to evaluate server trust for secure connections. + */ +@property (nonatomic, strong) AFSecurityPolicy *securityPolicy; + +///------------------------ +/// @name Accessing Streams +///------------------------ + +/** + The input stream used to read data to be sent during the request. + + This property acts as a proxy to the `HTTPBodyStream` property of `request`. + */ +@property (nonatomic, strong) NSInputStream *inputStream; + +/** + The output stream that is used to write data received until the request is finished. + + By default, data is accumulated into a buffer that is stored into `responseData` upon completion of the request, with the intermediary `outputStream` property set to `nil`. When `outputStream` is set, the data will not be accumulated into an internal buffer, and as a result, the `responseData` property of the completed request will be `nil`. The output stream will be scheduled in the network thread runloop upon being set. + */ +@property (nonatomic, strong) NSOutputStream *outputStream; + +///--------------------------------- +/// @name Managing Callback Queues +///--------------------------------- + +/** + The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. + */ +@property (nonatomic, strong) dispatch_queue_t completionQueue; + +/** + The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. + */ +@property (nonatomic, strong) dispatch_group_t completionGroup; + +///--------------------------------------------- +/// @name Managing Request Operation Information +///--------------------------------------------- + +/** + The user info dictionary for the receiver. + */ +@property (nonatomic, strong) NSDictionary *userInfo; + +///------------------------------------------------------ +/// @name Initializing an AFURLConnectionOperation Object +///------------------------------------------------------ + +/** + Initializes and returns a newly allocated operation object with a url connection configured with the specified url request. + + This is the designated initializer. + + @param urlRequest The request object to be used by the operation connection. + */ +- (instancetype)initWithRequest:(NSURLRequest *)urlRequest NS_DESIGNATED_INITIALIZER; + +///---------------------------------- +/// @name Pausing / Resuming Requests +///---------------------------------- + +/** + Pauses the execution of the request operation. + + A paused operation returns `NO` for `-isReady`, `-isExecuting`, and `-isFinished`. As such, it will remain in an `NSOperationQueue` until it is either cancelled or resumed. Pausing a finished, cancelled, or paused operation has no effect. + */ +- (void)pause; + +/** + Whether the request operation is currently paused. + + @return `YES` if the operation is currently paused, otherwise `NO`. + */ +- (BOOL)isPaused; + +/** + Resumes the execution of the paused request operation. + + Pause/Resume behavior varies depending on the underlying implementation for the operation class. In its base implementation, resuming a paused requests restarts the original request. However, since HTTP defines a specification for how to request a specific content range, `AFHTTPRequestOperation` will resume downloading the request from where it left off, instead of restarting the original request. + */ +- (void)resume; + +///---------------------------------------------- +/// @name Configuring Backgrounding Task Behavior +///---------------------------------------------- + +/** + Specifies that the operation should continue execution after the app has entered the background, and the expiration handler for that background task. + + @param handler A handler to be called shortly before the application’s remaining background time reaches 0. The handler is wrapped in a block that cancels the operation, and cleans up and marks the end of execution, unlike the `handler` parameter in `UIApplication -beginBackgroundTaskWithExpirationHandler:`, which expects this to be done in the handler itself. The handler is called synchronously on the main thread, thus blocking the application’s suspension momentarily while the application is notified. + */ +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) +- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler; +#endif + +///--------------------------------- +/// @name Setting Progress Callbacks +///--------------------------------- + +/** + Sets a callback to be called when an undetermined number of bytes have been uploaded to the server. + + @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes three arguments: the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. + */ +- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block; + +/** + Sets a callback to be called when an undetermined number of bytes have been downloaded from the server. + + @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. + */ +- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block; + +///------------------------------------------------- +/// @name Setting NSURLConnection Delegate Callbacks +///------------------------------------------------- + +/** + Sets a block to be executed when the connection will authenticate a challenge in order to download its request, as handled by the `NSURLConnectionDelegate` method `connection:willSendRequestForAuthenticationChallenge:`. + + @param block A block object to be executed when the connection will authenticate a challenge in order to download its request. The block has no return type and takes two arguments: the URL connection object, and the challenge that must be authenticated. This block must invoke one of the challenge-responder methods (NSURLAuthenticationChallengeSender protocol). + + If `allowsInvalidSSLCertificate` is set to YES, `connection:willSendRequestForAuthenticationChallenge:` will attempt to have the challenge sender use credentials with invalid SSL certificates. + */ +- (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block; + +/** + Sets a block to be executed when the server redirects the request from one URL to another URL, or when the request URL changed by the `NSURLProtocol` subclass handling the request in order to standardize its format, as handled by the `NSURLConnectionDataDelegate` method `connection:willSendRequest:redirectResponse:`. + + @param block A block object to be executed when the request URL was changed. The block returns an `NSURLRequest` object, the URL request to redirect, and takes three arguments: the URL connection object, the the proposed redirected request, and the URL response that caused the redirect. + */ +- (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block; + + +/** + Sets a block to be executed to modify the response a connection will cache, if any, as handled by the `NSURLConnectionDelegate` method `connection:willCacheResponse:`. + + @param block A block object to be executed to determine what response a connection will cache, if any. The block returns an `NSCachedURLResponse` object, the cached response to store in memory or `nil` to prevent the response from being cached, and takes two arguments: the URL connection object, and the cached response provided for the request. + */ +- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block; + +/// + +/** + + */ ++ (NSArray *)batchOfRequestOperations:(NSArray *)operations + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock + completionBlock:(void (^)(NSArray *operations))completionBlock; + +@end + +///-------------------- +/// @name Notifications +///-------------------- + +/** + Posted when an operation begins executing. + */ +extern NSString * const AFNetworkingOperationDidStartNotification; + +/** + Posted when an operation finishes. + */ +extern NSString * const AFNetworkingOperationDidFinishNotification; diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m new file mode 100644 index 0000000..becfb83 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLConnectionOperation.m @@ -0,0 +1,789 @@ +// AFURLConnectionOperation.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFURLConnectionOperation.h" + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import +#endif + +#if !__has_feature(objc_arc) +#error AFNetworking must be built with ARC. +// You can turn on ARC for only AFNetworking files by adding -fobjc-arc to the build phase for each of its files. +#endif + +typedef NS_ENUM(NSInteger, AFOperationState) { + AFOperationPausedState = -1, + AFOperationReadyState = 1, + AFOperationExecutingState = 2, + AFOperationFinishedState = 3, +}; + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) +typedef UIBackgroundTaskIdentifier AFBackgroundTaskIdentifier; +#else +typedef id AFBackgroundTaskIdentifier; +#endif + +static dispatch_group_t url_request_operation_completion_group() { + static dispatch_group_t af_url_request_operation_completion_group; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_url_request_operation_completion_group = dispatch_group_create(); + }); + + return af_url_request_operation_completion_group; +} + +static dispatch_queue_t url_request_operation_completion_queue() { + static dispatch_queue_t af_url_request_operation_completion_queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_url_request_operation_completion_queue = dispatch_queue_create("com.alamofire.networking.operation.queue", DISPATCH_QUEUE_CONCURRENT ); + }); + + return af_url_request_operation_completion_queue; +} + +static NSString * const kAFNetworkingLockName = @"com.alamofire.networking.operation.lock"; + +NSString * const AFNetworkingOperationDidStartNotification = @"com.alamofire.networking.operation.start"; +NSString * const AFNetworkingOperationDidFinishNotification = @"com.alamofire.networking.operation.finish"; + +typedef void (^AFURLConnectionOperationProgressBlock)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected); +typedef void (^AFURLConnectionOperationAuthenticationChallengeBlock)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge); +typedef NSCachedURLResponse * (^AFURLConnectionOperationCacheResponseBlock)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse); +typedef NSURLRequest * (^AFURLConnectionOperationRedirectResponseBlock)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse); + +static inline NSString * AFKeyPathFromOperationState(AFOperationState state) { + switch (state) { + case AFOperationReadyState: + return @"isReady"; + case AFOperationExecutingState: + return @"isExecuting"; + case AFOperationFinishedState: + return @"isFinished"; + case AFOperationPausedState: + return @"isPaused"; + default: { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" + return @"state"; +#pragma clang diagnostic pop + } + } +} + +static inline BOOL AFStateTransitionIsValid(AFOperationState fromState, AFOperationState toState, BOOL isCancelled) { + switch (fromState) { + case AFOperationReadyState: + switch (toState) { + case AFOperationPausedState: + case AFOperationExecutingState: + return YES; + case AFOperationFinishedState: + return isCancelled; + default: + return NO; + } + case AFOperationExecutingState: + switch (toState) { + case AFOperationPausedState: + case AFOperationFinishedState: + return YES; + default: + return NO; + } + case AFOperationFinishedState: + return NO; + case AFOperationPausedState: + return toState == AFOperationReadyState; + default: { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunreachable-code" + switch (toState) { + case AFOperationPausedState: + case AFOperationReadyState: + case AFOperationExecutingState: + case AFOperationFinishedState: + return YES; + default: + return NO; + } + } +#pragma clang diagnostic pop + } +} + +@interface AFURLConnectionOperation () +@property (readwrite, nonatomic, assign) AFOperationState state; +@property (readwrite, nonatomic, strong) NSRecursiveLock *lock; +@property (readwrite, nonatomic, strong) NSURLConnection *connection; +@property (readwrite, nonatomic, strong) NSURLRequest *request; +@property (readwrite, nonatomic, strong) NSURLResponse *response; +@property (readwrite, nonatomic, strong) NSError *error; +@property (readwrite, nonatomic, strong) NSData *responseData; +@property (readwrite, nonatomic, copy) NSString *responseString; +@property (readwrite, nonatomic, assign) NSStringEncoding responseStringEncoding; +@property (readwrite, nonatomic, assign) long long totalBytesRead; +@property (readwrite, nonatomic, assign) AFBackgroundTaskIdentifier backgroundTaskIdentifier; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock uploadProgress; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationProgressBlock downloadProgress; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationAuthenticationChallengeBlock authenticationChallenge; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationCacheResponseBlock cacheResponse; +@property (readwrite, nonatomic, copy) AFURLConnectionOperationRedirectResponseBlock redirectResponse; + +- (void)operationDidStart; +- (void)finish; +- (void)cancelConnection; +@end + +@implementation AFURLConnectionOperation +@synthesize outputStream = _outputStream; + ++ (void)networkRequestThreadEntryPoint:(id)__unused object { + @autoreleasepool { + [[NSThread currentThread] setName:@"AFNetworking"]; + + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; + [runLoop run]; + } +} + ++ (NSThread *)networkRequestThread { + static NSThread *_networkRequestThread = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + _networkRequestThread = [[NSThread alloc] initWithTarget:self selector:@selector(networkRequestThreadEntryPoint:) object:nil]; + [_networkRequestThread start]; + }); + + return _networkRequestThread; +} + +- (instancetype)initWithRequest:(NSURLRequest *)urlRequest { + NSParameterAssert(urlRequest); + + self = [super init]; + if (!self) { + return nil; + } + + _state = AFOperationReadyState; + + self.lock = [[NSRecursiveLock alloc] init]; + self.lock.name = kAFNetworkingLockName; + + self.runLoopModes = [NSSet setWithObject:NSRunLoopCommonModes]; + + self.request = urlRequest; + + self.shouldUseCredentialStorage = YES; + + self.securityPolicy = [AFSecurityPolicy defaultPolicy]; + + return self; +} + +- (void)dealloc { + if (_outputStream) { + [_outputStream close]; + _outputStream = nil; + } + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) + if (_backgroundTaskIdentifier) { + [[UIApplication sharedApplication] endBackgroundTask:_backgroundTaskIdentifier]; + _backgroundTaskIdentifier = UIBackgroundTaskInvalid; + } +#endif +} + +#pragma mark - + +- (void)setResponseData:(NSData *)responseData { + [self.lock lock]; + if (!responseData) { + _responseData = nil; + } else { + _responseData = [NSData dataWithBytes:responseData.bytes length:responseData.length]; + } + [self.lock unlock]; +} + +- (NSString *)responseString { + [self.lock lock]; + if (!_responseString && self.response && self.responseData) { + self.responseString = [[NSString alloc] initWithData:self.responseData encoding:self.responseStringEncoding]; + } + [self.lock unlock]; + + return _responseString; +} + +- (NSStringEncoding)responseStringEncoding { + [self.lock lock]; + if (!_responseStringEncoding && self.response) { + NSStringEncoding stringEncoding = NSUTF8StringEncoding; + if (self.response.textEncodingName) { + CFStringEncoding IANAEncoding = CFStringConvertIANACharSetNameToEncoding((__bridge CFStringRef)self.response.textEncodingName); + if (IANAEncoding != kCFStringEncodingInvalidId) { + stringEncoding = CFStringConvertEncodingToNSStringEncoding(IANAEncoding); + } + } + + self.responseStringEncoding = stringEncoding; + } + [self.lock unlock]; + + return _responseStringEncoding; +} + +- (NSInputStream *)inputStream { + return self.request.HTTPBodyStream; +} + +- (void)setInputStream:(NSInputStream *)inputStream { + NSMutableURLRequest *mutableRequest = [self.request mutableCopy]; + mutableRequest.HTTPBodyStream = inputStream; + self.request = mutableRequest; +} + +- (NSOutputStream *)outputStream { + if (!_outputStream) { + self.outputStream = [NSOutputStream outputStreamToMemory]; + } + + return _outputStream; +} + +- (void)setOutputStream:(NSOutputStream *)outputStream { + [self.lock lock]; + if (outputStream != _outputStream) { + if (_outputStream) { + [_outputStream close]; + } + + _outputStream = outputStream; + } + [self.lock unlock]; +} + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && !defined(AF_APP_EXTENSIONS) +- (void)setShouldExecuteAsBackgroundTaskWithExpirationHandler:(void (^)(void))handler { + [self.lock lock]; + if (!self.backgroundTaskIdentifier) { + UIApplication *application = [UIApplication sharedApplication]; + __weak __typeof(self)weakSelf = self; + self.backgroundTaskIdentifier = [application beginBackgroundTaskWithExpirationHandler:^{ + __strong __typeof(weakSelf)strongSelf = weakSelf; + + if (handler) { + handler(); + } + + if (strongSelf) { + [strongSelf cancel]; + + [application endBackgroundTask:strongSelf.backgroundTaskIdentifier]; + strongSelf.backgroundTaskIdentifier = UIBackgroundTaskInvalid; + } + }]; + } + [self.lock unlock]; +} +#endif + +#pragma mark - + +- (void)setState:(AFOperationState)state { + if (!AFStateTransitionIsValid(self.state, state, [self isCancelled])) { + return; + } + + [self.lock lock]; + NSString *oldStateKey = AFKeyPathFromOperationState(self.state); + NSString *newStateKey = AFKeyPathFromOperationState(state); + + [self willChangeValueForKey:newStateKey]; + [self willChangeValueForKey:oldStateKey]; + _state = state; + [self didChangeValueForKey:oldStateKey]; + [self didChangeValueForKey:newStateKey]; + [self.lock unlock]; +} + +- (void)pause { + if ([self isPaused] || [self isFinished] || [self isCancelled]) { + return; + } + + [self.lock lock]; + if ([self isExecuting]) { + [self performSelector:@selector(operationDidPause) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; + + dispatch_async(dispatch_get_main_queue(), ^{ + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + [notificationCenter postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; + }); + } + + self.state = AFOperationPausedState; + [self.lock unlock]; +} + +- (void)operationDidPause { + [self.lock lock]; + [self.connection cancel]; + [self.lock unlock]; +} + +- (BOOL)isPaused { + return self.state == AFOperationPausedState; +} + +- (void)resume { + if (![self isPaused]) { + return; + } + + [self.lock lock]; + self.state = AFOperationReadyState; + + [self start]; + [self.lock unlock]; +} + +#pragma mark - + +- (void)setUploadProgressBlock:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))block { + self.uploadProgress = block; +} + +- (void)setDownloadProgressBlock:(void (^)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead))block { + self.downloadProgress = block; +} + +- (void)setWillSendRequestForAuthenticationChallengeBlock:(void (^)(NSURLConnection *connection, NSURLAuthenticationChallenge *challenge))block { + self.authenticationChallenge = block; +} + +- (void)setCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLConnection *connection, NSCachedURLResponse *cachedResponse))block { + self.cacheResponse = block; +} + +- (void)setRedirectResponseBlock:(NSURLRequest * (^)(NSURLConnection *connection, NSURLRequest *request, NSURLResponse *redirectResponse))block { + self.redirectResponse = block; +} + +#pragma mark - NSOperation + +- (void)setCompletionBlock:(void (^)(void))block { + [self.lock lock]; + if (!block) { + [super setCompletionBlock:nil]; + } else { + __weak __typeof(self)weakSelf = self; + [super setCompletionBlock:^ { + __strong __typeof(weakSelf)strongSelf = weakSelf; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_group_t group = strongSelf.completionGroup ?: url_request_operation_completion_group(); + dispatch_queue_t queue = strongSelf.completionQueue ?: dispatch_get_main_queue(); +#pragma clang diagnostic pop + + dispatch_group_async(group, queue, ^{ + block(); + }); + + dispatch_group_notify(group, url_request_operation_completion_queue(), ^{ + [strongSelf setCompletionBlock:nil]; + }); + }]; + } + [self.lock unlock]; +} + +- (BOOL)isReady { + return self.state == AFOperationReadyState && [super isReady]; +} + +- (BOOL)isExecuting { + return self.state == AFOperationExecutingState; +} + +- (BOOL)isFinished { + return self.state == AFOperationFinishedState; +} + +- (BOOL)isConcurrent { + return YES; +} + +- (void)start { + [self.lock lock]; + if ([self isCancelled]) { + [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; + } else if ([self isReady]) { + self.state = AFOperationExecutingState; + + [self performSelector:@selector(operationDidStart) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; + } + [self.lock unlock]; +} + +- (void)operationDidStart { + [self.lock lock]; + if (![self isCancelled]) { + self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO]; + + NSRunLoop *runLoop = [NSRunLoop currentRunLoop]; + for (NSString *runLoopMode in self.runLoopModes) { + [self.connection scheduleInRunLoop:runLoop forMode:runLoopMode]; + [self.outputStream scheduleInRunLoop:runLoop forMode:runLoopMode]; + } + + [self.outputStream open]; + [self.connection start]; + } + [self.lock unlock]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidStartNotification object:self]; + }); +} + +- (void)finish { + [self.lock lock]; + self.state = AFOperationFinishedState; + [self.lock unlock]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingOperationDidFinishNotification object:self]; + }); +} + +- (void)cancel { + [self.lock lock]; + if (![self isFinished] && ![self isCancelled]) { + [super cancel]; + + if ([self isExecuting]) { + [self performSelector:@selector(cancelConnection) onThread:[[self class] networkRequestThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]]; + } + } + [self.lock unlock]; +} + +- (void)cancelConnection { + NSDictionary *userInfo = nil; + if ([self.request URL]) { + userInfo = [NSDictionary dictionaryWithObject:[self.request URL] forKey:NSURLErrorFailingURLErrorKey]; + } + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:userInfo]; + + if (![self isFinished]) { + if (self.connection) { + [self.connection cancel]; + [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:error]; + } else { + // Accomodate race condition where `self.connection` has not yet been set before cancellation + self.error = error; + [self finish]; + } + } +} + +#pragma mark - + ++ (NSArray *)batchOfRequestOperations:(NSArray *)operations + progressBlock:(void (^)(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations))progressBlock + completionBlock:(void (^)(NSArray *operations))completionBlock +{ + if (!operations || [operations count] == 0) { + return @[[NSBlockOperation blockOperationWithBlock:^{ + dispatch_async(dispatch_get_main_queue(), ^{ + if (completionBlock) { + completionBlock(@[]); + } + }); + }]]; + } + + __block dispatch_group_t group = dispatch_group_create(); + NSBlockOperation *batchedOperation = [NSBlockOperation blockOperationWithBlock:^{ + dispatch_group_notify(group, dispatch_get_main_queue(), ^{ + if (completionBlock) { + completionBlock(operations); + } + }); + }]; + + for (AFURLConnectionOperation *operation in operations) { + operation.completionGroup = group; + void (^originalCompletionBlock)(void) = [operation.completionBlock copy]; + __weak __typeof(operation)weakOperation = operation; + operation.completionBlock = ^{ + __strong __typeof(weakOperation)strongOperation = weakOperation; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + dispatch_queue_t queue = strongOperation.completionQueue ?: dispatch_get_main_queue(); +#pragma clang diagnostic pop + dispatch_group_async(group, queue, ^{ + if (originalCompletionBlock) { + originalCompletionBlock(); + } + + NSUInteger numberOfFinishedOperations = [[operations indexesOfObjectsPassingTest:^BOOL(id op, NSUInteger __unused idx, BOOL __unused *stop) { + return [op isFinished]; + }] count]; + + if (progressBlock) { + progressBlock(numberOfFinishedOperations, [operations count]); + } + + dispatch_group_leave(group); + }); + }; + + dispatch_group_enter(group); + [batchedOperation addDependency:operation]; + } + + return [operations arrayByAddingObject:batchedOperation]; +} + +#pragma mark - NSObject + +- (NSString *)description { + [self.lock lock]; + NSString *description = [NSString stringWithFormat:@"<%@: %p, state: %@, cancelled: %@ request: %@, response: %@>", NSStringFromClass([self class]), self, AFKeyPathFromOperationState(self.state), ([self isCancelled] ? @"YES" : @"NO"), self.request, self.response]; + [self.lock unlock]; + return description; +} + +#pragma mark - NSURLConnectionDelegate + +- (void)connection:(NSURLConnection *)connection +willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge +{ + if (self.authenticationChallenge) { + self.authenticationChallenge(connection, challenge); + return; + } + + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { + NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + } else { + [[challenge sender] cancelAuthenticationChallenge:challenge]; + } + } else { + if ([challenge previousFailureCount] == 0) { + if (self.credential) { + [[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge]; + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } +} + +- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection { + return self.shouldUseCredentialStorage; +} + +- (NSURLRequest *)connection:(NSURLConnection *)connection + willSendRequest:(NSURLRequest *)request + redirectResponse:(NSURLResponse *)redirectResponse +{ + if (self.redirectResponse) { + return self.redirectResponse(connection, request, redirectResponse); + } else { + return request; + } +} + +- (void)connection:(NSURLConnection __unused *)connection + didSendBodyData:(NSInteger)bytesWritten + totalBytesWritten:(NSInteger)totalBytesWritten +totalBytesExpectedToWrite:(NSInteger)totalBytesExpectedToWrite +{ + dispatch_async(dispatch_get_main_queue(), ^{ + if (self.uploadProgress) { + self.uploadProgress((NSUInteger)bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } + }); +} + +- (void)connection:(NSURLConnection __unused *)connection +didReceiveResponse:(NSURLResponse *)response +{ + self.response = response; +} + +- (void)connection:(NSURLConnection __unused *)connection + didReceiveData:(NSData *)data +{ + NSUInteger length = [data length]; + while (YES) { + NSInteger totalNumberOfBytesWritten = 0; + if ([self.outputStream hasSpaceAvailable]) { + const uint8_t *dataBuffer = (uint8_t *)[data bytes]; + + NSInteger numberOfBytesWritten = 0; + while (totalNumberOfBytesWritten < (NSInteger)length) { + numberOfBytesWritten = [self.outputStream write:&dataBuffer[(NSUInteger)totalNumberOfBytesWritten] maxLength:(length - (NSUInteger)totalNumberOfBytesWritten)]; + if (numberOfBytesWritten == -1) { + break; + } + + totalNumberOfBytesWritten += numberOfBytesWritten; + } + + break; + } + + if (self.outputStream.streamError) { + [self.connection cancel]; + [self performSelector:@selector(connection:didFailWithError:) withObject:self.connection withObject:self.outputStream.streamError]; + return; + } + } + + dispatch_async(dispatch_get_main_queue(), ^{ + self.totalBytesRead += (long long)length; + + if (self.downloadProgress) { + self.downloadProgress(length, self.totalBytesRead, self.response.expectedContentLength); + } + }); +} + +- (void)connectionDidFinishLoading:(NSURLConnection __unused *)connection { + self.responseData = [self.outputStream propertyForKey:NSStreamDataWrittenToMemoryStreamKey]; + + [self.outputStream close]; + if (self.responseData) { + self.outputStream = nil; + } + + self.connection = nil; + + [self finish]; +} + +- (void)connection:(NSURLConnection __unused *)connection + didFailWithError:(NSError *)error +{ + self.error = error; + + [self.outputStream close]; + if (self.responseData) { + self.outputStream = nil; + } + + self.connection = nil; + + [self finish]; +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection + willCacheResponse:(NSCachedURLResponse *)cachedResponse +{ + if (self.cacheResponse) { + return self.cacheResponse(connection, cachedResponse); + } else { + if ([self isCancelled]) { + return nil; + } + + return cachedResponse; + } +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + NSURLRequest *request = [decoder decodeObjectOfClass:[NSURLRequest class] forKey:NSStringFromSelector(@selector(request))]; + + self = [self initWithRequest:request]; + if (!self) { + return nil; + } + + self.state = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(state))] integerValue]; + self.response = [decoder decodeObjectOfClass:[NSHTTPURLResponse class] forKey:NSStringFromSelector(@selector(response))]; + self.error = [decoder decodeObjectOfClass:[NSError class] forKey:NSStringFromSelector(@selector(error))]; + self.responseData = [decoder decodeObjectOfClass:[NSData class] forKey:NSStringFromSelector(@selector(responseData))]; + self.totalBytesRead = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(totalBytesRead))] longLongValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [self pause]; + + [coder encodeObject:self.request forKey:NSStringFromSelector(@selector(request))]; + + switch (self.state) { + case AFOperationExecutingState: + case AFOperationPausedState: + [coder encodeInteger:AFOperationReadyState forKey:NSStringFromSelector(@selector(state))]; + break; + default: + [coder encodeInteger:self.state forKey:NSStringFromSelector(@selector(state))]; + break; + } + + [coder encodeObject:self.response forKey:NSStringFromSelector(@selector(response))]; + [coder encodeObject:self.error forKey:NSStringFromSelector(@selector(error))]; + [coder encodeObject:self.responseData forKey:NSStringFromSelector(@selector(responseData))]; + [coder encodeInt64:self.totalBytesRead forKey:NSStringFromSelector(@selector(totalBytesRead))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFURLConnectionOperation *operation = [(AFURLConnectionOperation *)[[self class] allocWithZone:zone] initWithRequest:self.request]; + + operation.uploadProgress = self.uploadProgress; + operation.downloadProgress = self.downloadProgress; + operation.authenticationChallenge = self.authenticationChallenge; + operation.cacheResponse = self.cacheResponse; + operation.redirectResponse = self.redirectResponse; + operation.completionQueue = self.completionQueue; + operation.completionGroup = self.completionGroup; + + return operation; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.h new file mode 100644 index 0000000..e60a267 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.h @@ -0,0 +1,468 @@ +// AFURLRequestSerialization.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import +#endif + +/** + The `AFURLRequestSerialization` protocol is adopted by an object that encodes parameters for a specified HTTP requests. Request serializers may encode parameters as query strings, HTTP bodies, setting the appropriate HTTP header fields as necessary. + + For example, a JSON request serializer may set the HTTP body of the request to a JSON representation, and set the `Content-Type` HTTP header field value to `application/json`. + */ +@protocol AFURLRequestSerialization + +/** + Returns a request with the specified parameters encoded into a copy of the original request. + + @param request The original request. + @param parameters The parameters to be encoded. + @param error The error that occurred while attempting to encode the request parameters. + + @return A serialized request. + */ +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError * __autoreleasing *)error; + +@end + +#pragma mark - + +/** + + */ +typedef NS_ENUM(NSUInteger, AFHTTPRequestQueryStringSerializationStyle) { + AFHTTPRequestQueryStringDefaultStyle = 0, +}; + +@protocol AFMultipartFormData; + +/** + `AFHTTPRequestSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. + + Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPRequestSerializer` in order to ensure consistent default behavior. + */ +@interface AFHTTPRequestSerializer : NSObject + +/** + The string encoding used to serialize parameters. `NSUTF8StringEncoding` by default. + */ +@property (nonatomic, assign) NSStringEncoding stringEncoding; + +/** + Whether created requests can use the device’s cellular radio (if present). `YES` by default. + + @see NSMutableURLRequest -setAllowsCellularAccess: + */ +@property (nonatomic, assign) BOOL allowsCellularAccess; + +/** + The cache policy of created requests. `NSURLRequestUseProtocolCachePolicy` by default. + + @see NSMutableURLRequest -setCachePolicy: + */ +@property (nonatomic, assign) NSURLRequestCachePolicy cachePolicy; + +/** + Whether created requests should use the default cookie handling. `YES` by default. + + @see NSMutableURLRequest -setHTTPShouldHandleCookies: + */ +@property (nonatomic, assign) BOOL HTTPShouldHandleCookies; + +/** + Whether created requests can continue transmitting data before receiving a response from an earlier transmission. `NO` by default + + @see NSMutableURLRequest -setHTTPShouldUsePipelining: + */ +@property (nonatomic, assign) BOOL HTTPShouldUsePipelining; + +/** + The network service type for created requests. `NSURLNetworkServiceTypeDefault` by default. + + @see NSMutableURLRequest -setNetworkServiceType: + */ +@property (nonatomic, assign) NSURLRequestNetworkServiceType networkServiceType; + +/** + The timeout interval, in seconds, for created requests. The default timeout interval is 60 seconds. + + @see NSMutableURLRequest -setTimeoutInterval: + */ +@property (nonatomic, assign) NSTimeInterval timeoutInterval; + +///--------------------------------------- +/// @name Configuring HTTP Request Headers +///--------------------------------------- + +/** + Default HTTP header field values to be applied to serialized requests. By default, these include the following: + + - `Accept-Language` with the contents of `NSLocale +preferredLanguages` + - `User-Agent` with the contents of various bundle identifiers and OS designations + + @discussion To add or remove default request headers, use `setValue:forHTTPHeaderField:`. + */ +@property (readonly, nonatomic, strong) NSDictionary *HTTPRequestHeaders; + +/** + Creates and returns a serializer with default configuration. + */ ++ (instancetype)serializer; + +/** + Sets the value for the HTTP headers set in request objects made by the HTTP client. If `nil`, removes the existing value for that header. + + @param field The HTTP header to set a default value for + @param value The value set as default for the specified header, or `nil` + */ +- (void)setValue:(NSString *)value +forHTTPHeaderField:(NSString *)field; + +/** + Returns the value for the HTTP headers set in the request serializer. + + @param field The HTTP header to retrieve the default value for + + @return The value set as default for the specified header, or `nil` + */ +- (NSString *)valueForHTTPHeaderField:(NSString *)field; + +/** + Sets the "Authorization" HTTP header set in request objects made by the HTTP client to a basic authentication value with Base64-encoded username and password. This overwrites any existing value for this header. + + @param username The HTTP basic auth username + @param password The HTTP basic auth password + */ +- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username + password:(NSString *)password; + +/** + @deprecated This method has been deprecated. Use -setValue:forHTTPHeaderField: instead. + */ +- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token DEPRECATED_ATTRIBUTE; + + +/** + Clears any existing value for the "Authorization" HTTP header. + */ +- (void)clearAuthorizationHeader; + +///------------------------------------------------------- +/// @name Configuring Query String Parameter Serialization +///------------------------------------------------------- + +/** + HTTP methods for which serialized requests will encode parameters as a query string. `GET`, `HEAD`, and `DELETE` by default. + */ +@property (nonatomic, strong) NSSet *HTTPMethodsEncodingParametersInURI; + +/** + Set the method of query string serialization according to one of the pre-defined styles. + + @param style The serialization style. + + @see AFHTTPRequestQueryStringSerializationStyle + */ +- (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style; + +/** + Set the a custom method of query string serialization according to the specified block. + + @param block A block that defines a process of encoding parameters into a query string. This block returns the query string and takes three arguments: the request, the parameters to encode, and the error that occurred when attempting to encode parameters for the given request. + */ +- (void)setQueryStringSerializationWithBlock:(NSString * (^)(NSURLRequest *request, id parameters, NSError * __autoreleasing *error))block; + +///------------------------------- +/// @name Creating Request Objects +///------------------------------- + +/** + @deprecated This method has been deprecated. Use -requestWithMethod:URLString:parameters:error: instead. + */ +- (NSMutableURLRequest *)requestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters DEPRECATED_ATTRIBUTE; + +/** + Creates an `NSMutableURLRequest` object with the specified HTTP method and URL string. + + If the HTTP method is `GET`, `HEAD`, or `DELETE`, the parameters will be used to construct a url-encoded query string that is appended to the request's URL. Otherwise, the parameters will be encoded according to the value of the `parameterEncoding` property, and set as the request body. + + @param method The HTTP method for the request, such as `GET`, `POST`, `PUT`, or `DELETE`. This parameter must not be `nil`. + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be either set as a query string for `GET` requests, or the request HTTP body. + @param error The error that occured while constructing the request. + + @return An `NSMutableURLRequest` object. + */ +- (NSMutableURLRequest *)requestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters + error:(NSError * __autoreleasing *)error; + +/** + @deprecated This method has been deprecated. Use -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error: instead. + */ +- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(NSDictionary *)parameters + constructingBodyWithBlock:(void (^)(id formData))block DEPRECATED_ATTRIBUTE; + +/** + Creates an `NSMutableURLRequest` object with the specified HTTP method and URLString, and constructs a `multipart/form-data` HTTP body, using the specified parameters and multipart form data block. See http://www.w3.org/TR/html4/interact/forms.html#h-17.13.4.2 + + Multipart form requests are automatically streamed, reading files directly from disk along with in-memory data in a single HTTP body. The resulting `NSMutableURLRequest` object has an `HTTPBodyStream` property, so refrain from setting `HTTPBodyStream` or `HTTPBody` on this request object, as it will clear out the multipart form body stream. + + @param method The HTTP method for the request. This parameter must not be `GET` or `HEAD`, or `nil`. + @param URLString The URL string used to create the request URL. + @param parameters The parameters to be encoded and set in the request HTTP body. + @param block A block that takes a single argument and appends data to the HTTP body. The block argument is an object adopting the `AFMultipartFormData` protocol. + @param error The error that occured while constructing the request. + + @return An `NSMutableURLRequest` object + */ +- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(NSDictionary *)parameters + constructingBodyWithBlock:(void (^)(id formData))block + error:(NSError * __autoreleasing *)error; + +/** + Creates an `NSMutableURLRequest` by removing the `HTTPBodyStream` from a request, and asynchronously writing its contents into the specified file, invoking the completion handler when finished. + + @param request The multipart form request. The `HTTPBodyStream` property of `request` must not be `nil`. + @param fileURL The file URL to write multipart form contents to. + @param handler A handler block to execute. + + @discussion There is a bug in `NSURLSessionTask` that causes requests to not send a `Content-Length` header when streaming contents from an HTTP body, which is notably problematic when interacting with the Amazon S3 webservice. As a workaround, this method takes a request constructed with `multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:error:`, or any other request with an `HTTPBodyStream`, writes the contents to the specified file and returns a copy of the original request with the `HTTPBodyStream` property set to `nil`. From here, the file can either be passed to `AFURLSessionManager -uploadTaskWithRequest:fromFile:progress:completionHandler:`, or have its contents read into an `NSData` that's assigned to the `HTTPBody` property of the request. + + @see https://github.com/AFNetworking/AFNetworking/issues/1398 + */ +- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request + writingStreamContentsToFile:(NSURL *)fileURL + completionHandler:(void (^)(NSError *error))handler; + +@end + +#pragma mark - + +/** + The `AFMultipartFormData` protocol defines the methods supported by the parameter in the block argument of `AFHTTPRequestSerializer -multipartFormRequestWithMethod:URLString:parameters:constructingBodyWithBlock:`. + */ +@protocol AFMultipartFormData + +/** + Appends the HTTP header `Content-Disposition: file; filename=#{generated filename}; name=#{name}"` and `Content-Type: #{generated mimeType}`, followed by the encoded file data and the multipart form boundary. + + The filename and MIME type for this data in the form will be automatically generated, using the last path component of the `fileURL` and system associated MIME type for the `fileURL` extension, respectively. + + @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. + @param name The name to be associated with the specified data. This parameter must not be `nil`. + @param error If an error occurs, upon return contains an `NSError` object that describes the problem. + + @return `YES` if the file data was successfully appended, otherwise `NO`. + */ +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + error:(NSError * __autoreleasing *)error; + +/** + Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. + + @param fileURL The URL corresponding to the file whose content will be appended to the form. This parameter must not be `nil`. + @param name The name to be associated with the specified data. This parameter must not be `nil`. + @param fileName The file name to be used in the `Content-Disposition` header. This parameter must not be `nil`. + @param mimeType The declared MIME type of the file data. This parameter must not be `nil`. + @param error If an error occurs, upon return contains an `NSError` object that describes the problem. + + @return `YES` if the file data was successfully appended otherwise `NO`. + */ +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + fileName:(NSString *)fileName + mimeType:(NSString *)mimeType + error:(NSError * __autoreleasing *)error; + +/** + Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the data from the input stream and the multipart form boundary. + + @param inputStream The input stream to be appended to the form data + @param name The name to be associated with the specified input stream. This parameter must not be `nil`. + @param fileName The filename to be associated with the specified input stream. This parameter must not be `nil`. + @param length The length of the specified input stream in bytes. + @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. + */ +- (void)appendPartWithInputStream:(NSInputStream *)inputStream + name:(NSString *)name + fileName:(NSString *)fileName + length:(int64_t)length + mimeType:(NSString *)mimeType; + +/** + Appends the HTTP header `Content-Disposition: file; filename=#{filename}; name=#{name}"` and `Content-Type: #{mimeType}`, followed by the encoded file data and the multipart form boundary. + + @param data The data to be encoded and appended to the form data. + @param name The name to be associated with the specified data. This parameter must not be `nil`. + @param fileName The filename to be associated with the specified data. This parameter must not be `nil`. + @param mimeType The MIME type of the specified data. (For example, the MIME type for a JPEG image is image/jpeg.) For a list of valid MIME types, see http://www.iana.org/assignments/media-types/. This parameter must not be `nil`. + */ +- (void)appendPartWithFileData:(NSData *)data + name:(NSString *)name + fileName:(NSString *)fileName + mimeType:(NSString *)mimeType; + +/** + Appends the HTTP headers `Content-Disposition: form-data; name=#{name}"`, followed by the encoded data and the multipart form boundary. + + @param data The data to be encoded and appended to the form data. + @param name The name to be associated with the specified data. This parameter must not be `nil`. + */ + +- (void)appendPartWithFormData:(NSData *)data + name:(NSString *)name; + + +/** + Appends HTTP headers, followed by the encoded data and the multipart form boundary. + + @param headers The HTTP headers to be appended to the form data. + @param body The data to be encoded and appended to the form data. This parameter must not be `nil`. + */ +- (void)appendPartWithHeaders:(NSDictionary *)headers + body:(NSData *)body; + +/** + Throttles request bandwidth by limiting the packet size and adding a delay for each chunk read from the upload stream. + + When uploading over a 3G or EDGE connection, requests may fail with "request body stream exhausted". Setting a maximum packet size and delay according to the recommended values (`kAFUploadStream3GSuggestedPacketSize` and `kAFUploadStream3GSuggestedDelay`) lowers the risk of the input stream exceeding its allocated bandwidth. Unfortunately, there is no definite way to distinguish between a 3G, EDGE, or LTE connection over `NSURLConnection`. As such, it is not recommended that you throttle bandwidth based solely on network reachability. Instead, you should consider checking for the "request body stream exhausted" in a failure block, and then retrying the request with throttled bandwidth. + + @param numberOfBytes Maximum packet size, in number of bytes. The default packet size for an input stream is 16kb. + @param delay Duration of delay each time a packet is read. By default, no delay is set. + */ +- (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes + delay:(NSTimeInterval)delay; + +@end + +#pragma mark - + +/** + `AFJSONRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSJSONSerialization`, setting the `Content-Type` of the encoded request to `application/json`. + */ +@interface AFJSONRequestSerializer : AFHTTPRequestSerializer + +/** + Options for writing the request JSON data from Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONWritingOptions". `0` by default. + */ +@property (nonatomic, assign) NSJSONWritingOptions writingOptions; + +/** + Creates and returns a JSON serializer with specified reading and writing options. + + @param writingOptions The specified JSON writing options. + */ ++ (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions; + +@end + +#pragma mark - + +/** + `AFPropertyListRequestSerializer` is a subclass of `AFHTTPRequestSerializer` that encodes parameters as JSON using `NSPropertyListSerializer`, setting the `Content-Type` of the encoded request to `application/x-plist`. + */ +@interface AFPropertyListRequestSerializer : AFHTTPRequestSerializer + +/** + The property list format. Possible values are described in "NSPropertyListFormat". + */ +@property (nonatomic, assign) NSPropertyListFormat format; + +/** + @warning The `writeOptions` property is currently unused. + */ +@property (nonatomic, assign) NSPropertyListWriteOptions writeOptions; + +/** + Creates and returns a property list serializer with a specified format, read options, and write options. + + @param format The property list format. + @param writeOptions The property list write options. + + @warning The `writeOptions` property is currently unused. + */ ++ (instancetype)serializerWithFormat:(NSPropertyListFormat)format + writeOptions:(NSPropertyListWriteOptions)writeOptions; + +@end + +#pragma mark - + +///---------------- +/// @name Constants +///---------------- + +/** + ## Error Domains + + The following error domain is predefined. + + - `NSString * const AFURLRequestSerializationErrorDomain` + + ### Constants + + `AFURLRequestSerializationErrorDomain` + AFURLRequestSerializer errors. Error codes for `AFURLRequestSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. + */ +extern NSString * const AFURLRequestSerializationErrorDomain; + +/** + ## User info dictionary keys + + These keys may exist in the user info dictionary, in addition to those defined for NSError. + + - `NSString * const AFNetworkingOperationFailingURLRequestErrorKey` + + ### Constants + + `AFNetworkingOperationFailingURLRequestErrorKey` + The corresponding value is an `NSURLRequest` containing the request of the operation associated with an error. This key is only present in the `AFURLRequestSerializationErrorDomain`. + */ +extern NSString * const AFNetworkingOperationFailingURLRequestErrorKey; + +/** + ## Throttling Bandwidth for HTTP Request Input Streams + + @see -throttleBandwidthWithPacketSize:delay: + + ### Constants + + `kAFUploadStream3GSuggestedPacketSize` + Maximum packet size, in number of bytes. Equal to 16kb. + + `kAFUploadStream3GSuggestedDelay` + Duration of delay each time a packet is read. Equal to 0.2 seconds. + */ +extern NSUInteger const kAFUploadStream3GSuggestedPacketSize; +extern NSTimeInterval const kAFUploadStream3GSuggestedDelay; diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m new file mode 100644 index 0000000..4c1b9f3 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLRequestSerialization.m @@ -0,0 +1,1344 @@ +// AFURLRequestSerialization.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFURLRequestSerialization.h" + +#if __IPHONE_OS_VERSION_MIN_REQUIRED +#import +#else +#import +#endif + +NSString * const AFURLRequestSerializationErrorDomain = @"com.alamofire.error.serialization.request"; +NSString * const AFNetworkingOperationFailingURLRequestErrorKey = @"com.alamofire.serialization.request.error.response"; + +typedef NSString * (^AFQueryStringSerializationBlock)(NSURLRequest *request, id parameters, NSError *__autoreleasing *error); + +static NSString * AFBase64EncodedStringFromString(NSString *string) { + NSData *data = [NSData dataWithBytes:[string UTF8String] length:[string lengthOfBytesUsingEncoding:NSUTF8StringEncoding]]; + NSUInteger length = [data length]; + NSMutableData *mutableData = [NSMutableData dataWithLength:((length + 2) / 3) * 4]; + + uint8_t *input = (uint8_t *)[data bytes]; + uint8_t *output = (uint8_t *)[mutableData mutableBytes]; + + for (NSUInteger i = 0; i < length; i += 3) { + NSUInteger value = 0; + for (NSUInteger j = i; j < (i + 3); j++) { + value <<= 8; + if (j < length) { + value |= (0xFF & input[j]); + } + } + + static uint8_t const kAFBase64EncodingTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; + + NSUInteger idx = (i / 3) * 4; + output[idx + 0] = kAFBase64EncodingTable[(value >> 18) & 0x3F]; + output[idx + 1] = kAFBase64EncodingTable[(value >> 12) & 0x3F]; + output[idx + 2] = (i + 1) < length ? kAFBase64EncodingTable[(value >> 6) & 0x3F] : '='; + output[idx + 3] = (i + 2) < length ? kAFBase64EncodingTable[(value >> 0) & 0x3F] : '='; + } + + return [[NSString alloc] initWithData:mutableData encoding:NSASCIIStringEncoding]; +} + +static NSString * const kAFCharactersToBeEscapedInQueryString = @":/?&=;+!@#$()',*"; + +static NSString * AFPercentEscapedQueryStringKeyFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { + static NSString * const kAFCharactersToLeaveUnescapedInQueryStringPairKey = @"[]."; + + return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, (__bridge CFStringRef)kAFCharactersToLeaveUnescapedInQueryStringPairKey, (__bridge CFStringRef)kAFCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); +} + +static NSString * AFPercentEscapedQueryStringValueFromStringWithEncoding(NSString *string, NSStringEncoding encoding) { + return (__bridge_transfer NSString *)CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault, (__bridge CFStringRef)string, NULL, (__bridge CFStringRef)kAFCharactersToBeEscapedInQueryString, CFStringConvertNSStringEncodingToEncoding(encoding)); +} + +#pragma mark - + +@interface AFQueryStringPair : NSObject +@property (readwrite, nonatomic, strong) id field; +@property (readwrite, nonatomic, strong) id value; + +- (id)initWithField:(id)field value:(id)value; + +- (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding; +@end + +@implementation AFQueryStringPair + +- (id)initWithField:(id)field value:(id)value { + self = [super init]; + if (!self) { + return nil; + } + + self.field = field; + self.value = value; + + return self; +} + +- (NSString *)URLEncodedStringValueWithEncoding:(NSStringEncoding)stringEncoding { + if (!self.value || [self.value isEqual:[NSNull null]]) { + return AFPercentEscapedQueryStringKeyFromStringWithEncoding([self.field description], stringEncoding); + } else { + return [NSString stringWithFormat:@"%@=%@", AFPercentEscapedQueryStringKeyFromStringWithEncoding([self.field description], stringEncoding), AFPercentEscapedQueryStringValueFromStringWithEncoding([self.value description], stringEncoding)]; + } +} + +@end + +#pragma mark - + +extern NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary); +extern NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value); + +static NSString * AFQueryStringFromParametersWithEncoding(NSDictionary *parameters, NSStringEncoding stringEncoding) { + NSMutableArray *mutablePairs = [NSMutableArray array]; + for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { + [mutablePairs addObject:[pair URLEncodedStringValueWithEncoding:stringEncoding]]; + } + + return [mutablePairs componentsJoinedByString:@"&"]; +} + +NSArray * AFQueryStringPairsFromDictionary(NSDictionary *dictionary) { + return AFQueryStringPairsFromKeyAndValue(nil, dictionary); +} + +NSArray * AFQueryStringPairsFromKeyAndValue(NSString *key, id value) { + NSMutableArray *mutableQueryStringComponents = [NSMutableArray array]; + + NSSortDescriptor *sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:@"description" ascending:YES selector:@selector(compare:)]; + + if ([value isKindOfClass:[NSDictionary class]]) { + NSDictionary *dictionary = value; + // Sort dictionary keys to ensure consistent ordering in query string, which is important when deserializing potentially ambiguous sequences, such as an array of dictionaries + for (id nestedKey in [dictionary.allKeys sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { + id nestedValue = [dictionary objectForKey:nestedKey]; + if (nestedValue) { + [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue((key ? [NSString stringWithFormat:@"%@[%@]", key, nestedKey] : nestedKey), nestedValue)]; + } + } + } else if ([value isKindOfClass:[NSArray class]]) { + NSArray *array = value; + for (id nestedValue in array) { + [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue([NSString stringWithFormat:@"%@[]", key], nestedValue)]; + } + } else if ([value isKindOfClass:[NSSet class]]) { + NSSet *set = value; + for (id obj in [set sortedArrayUsingDescriptors:@[ sortDescriptor ]]) { + [mutableQueryStringComponents addObjectsFromArray:AFQueryStringPairsFromKeyAndValue(key, obj)]; + } + } else { + [mutableQueryStringComponents addObject:[[AFQueryStringPair alloc] initWithField:key value:value]]; + } + + return mutableQueryStringComponents; +} + +#pragma mark - + +@interface AFStreamingMultipartFormData : NSObject +- (instancetype)initWithURLRequest:(NSMutableURLRequest *)urlRequest + stringEncoding:(NSStringEncoding)encoding; + +- (NSMutableURLRequest *)requestByFinalizingMultipartFormData; +@end + +#pragma mark - + +static NSArray * AFHTTPRequestSerializerObservedKeyPaths() { + static NSArray *_AFHTTPRequestSerializerObservedKeyPaths = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _AFHTTPRequestSerializerObservedKeyPaths = @[NSStringFromSelector(@selector(allowsCellularAccess)), NSStringFromSelector(@selector(cachePolicy)), NSStringFromSelector(@selector(HTTPShouldHandleCookies)), NSStringFromSelector(@selector(HTTPShouldUsePipelining)), NSStringFromSelector(@selector(networkServiceType)), NSStringFromSelector(@selector(timeoutInterval))]; + }); + + return _AFHTTPRequestSerializerObservedKeyPaths; +} + +static void *AFHTTPRequestSerializerObserverContext = &AFHTTPRequestSerializerObserverContext; + +@interface AFHTTPRequestSerializer () +@property (readwrite, nonatomic, strong) NSMutableSet *mutableObservedChangedKeyPaths; +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableHTTPRequestHeaders; +@property (readwrite, nonatomic, assign) AFHTTPRequestQueryStringSerializationStyle queryStringSerializationStyle; +@property (readwrite, nonatomic, copy) AFQueryStringSerializationBlock queryStringSerialization; +@end + +@implementation AFHTTPRequestSerializer + ++ (instancetype)serializer { + return [[self alloc] init]; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.stringEncoding = NSUTF8StringEncoding; + + self.mutableHTTPRequestHeaders = [NSMutableDictionary dictionary]; + + // Accept-Language HTTP Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 + NSMutableArray *acceptLanguagesComponents = [NSMutableArray array]; + [[NSLocale preferredLanguages] enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) { + float q = 1.0f - (idx * 0.1f); + [acceptLanguagesComponents addObject:[NSString stringWithFormat:@"%@;q=%0.1g", obj, q]]; + *stop = q <= 0.5f; + }]; + [self setValue:[acceptLanguagesComponents componentsJoinedByString:@", "] forHTTPHeaderField:@"Accept-Language"]; + + NSString *userAgent = nil; +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + // User-Agent Header; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.43 + userAgent = [NSString stringWithFormat:@"%@/%@ (%@; iOS %@; Scale/%0.2f)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[UIDevice currentDevice] model], [[UIDevice currentDevice] systemVersion], [[UIScreen mainScreen] scale]]; +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) + userAgent = [NSString stringWithFormat:@"%@/%@ (Mac OS X %@)", [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleExecutableKey] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleIdentifierKey], [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleShortVersionString"] ?: [[[NSBundle mainBundle] infoDictionary] objectForKey:(__bridge NSString *)kCFBundleVersionKey], [[NSProcessInfo processInfo] operatingSystemVersionString]]; +#endif +#pragma clang diagnostic pop + if (userAgent) { + if (![userAgent canBeConvertedToEncoding:NSASCIIStringEncoding]) { + NSMutableString *mutableUserAgent = [userAgent mutableCopy]; + if (CFStringTransform((__bridge CFMutableStringRef)(mutableUserAgent), NULL, (__bridge CFStringRef)@"Any-Latin; Latin-ASCII; [:^ASCII:] Remove", false)) { + userAgent = mutableUserAgent; + } + } + [self setValue:userAgent forHTTPHeaderField:@"User-Agent"]; + } + + // HTTP Method Definitions; see http://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html + self.HTTPMethodsEncodingParametersInURI = [NSSet setWithObjects:@"GET", @"HEAD", @"DELETE", nil]; + + self.mutableObservedChangedKeyPaths = [NSMutableSet set]; + for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { + if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { + [self addObserver:self forKeyPath:keyPath options:NSKeyValueObservingOptionNew context:AFHTTPRequestSerializerObserverContext]; + } + } + + return self; +} + +- (void)dealloc { + for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { + if ([self respondsToSelector:NSSelectorFromString(keyPath)]) { + [self removeObserver:self forKeyPath:keyPath context:AFHTTPRequestSerializerObserverContext]; + } + } +} + +#pragma mark - + +- (NSDictionary *)HTTPRequestHeaders { + return [NSDictionary dictionaryWithDictionary:self.mutableHTTPRequestHeaders]; +} + +- (void)setValue:(NSString *)value +forHTTPHeaderField:(NSString *)field +{ + [self.mutableHTTPRequestHeaders setValue:value forKey:field]; +} + +- (NSString *)valueForHTTPHeaderField:(NSString *)field { + return [self.mutableHTTPRequestHeaders valueForKey:field]; +} + +- (void)setAuthorizationHeaderFieldWithUsername:(NSString *)username + password:(NSString *)password +{ + NSString *basicAuthCredentials = [NSString stringWithFormat:@"%@:%@", username, password]; + [self setValue:[NSString stringWithFormat:@"Basic %@", AFBase64EncodedStringFromString(basicAuthCredentials)] forHTTPHeaderField:@"Authorization"]; +} + +- (void)setAuthorizationHeaderFieldWithToken:(NSString *)token { + [self setValue:[NSString stringWithFormat:@"Token token=\"%@\"", token] forHTTPHeaderField:@"Authorization"]; +} + +- (void)clearAuthorizationHeader { + [self.mutableHTTPRequestHeaders removeObjectForKey:@"Authorization"]; +} + +#pragma mark - + +- (void)setQueryStringSerializationWithStyle:(AFHTTPRequestQueryStringSerializationStyle)style { + self.queryStringSerializationStyle = style; + self.queryStringSerialization = nil; +} + +- (void)setQueryStringSerializationWithBlock:(NSString *(^)(NSURLRequest *, id, NSError *__autoreleasing *))block { + self.queryStringSerialization = block; +} + +#pragma mark - + +- (NSMutableURLRequest *)requestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters +{ + return [self requestWithMethod:method URLString:URLString parameters:parameters error:nil]; +} + +- (NSMutableURLRequest *)requestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(method); + NSParameterAssert(URLString); + + NSURL *url = [NSURL URLWithString:URLString]; + + NSParameterAssert(url); + + NSMutableURLRequest *mutableRequest = [[NSMutableURLRequest alloc] initWithURL:url]; + mutableRequest.HTTPMethod = method; + + for (NSString *keyPath in AFHTTPRequestSerializerObservedKeyPaths()) { + if ([self.mutableObservedChangedKeyPaths containsObject:keyPath]) { + [mutableRequest setValue:[self valueForKeyPath:keyPath] forKey:keyPath]; + } + } + + mutableRequest = [[self requestBySerializingRequest:mutableRequest withParameters:parameters error:error] mutableCopy]; + + return mutableRequest; +} + +- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(NSDictionary *)parameters + constructingBodyWithBlock:(void (^)(id formData))block +{ + return [self multipartFormRequestWithMethod:method URLString:URLString parameters:parameters constructingBodyWithBlock:block error:nil]; +} + +- (NSMutableURLRequest *)multipartFormRequestWithMethod:(NSString *)method + URLString:(NSString *)URLString + parameters:(NSDictionary *)parameters + constructingBodyWithBlock:(void (^)(id formData))block + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(method); + NSParameterAssert(![method isEqualToString:@"GET"] && ![method isEqualToString:@"HEAD"]); + + NSMutableURLRequest *mutableRequest = [self requestWithMethod:method URLString:URLString parameters:nil error:error]; + + __block AFStreamingMultipartFormData *formData = [[AFStreamingMultipartFormData alloc] initWithURLRequest:mutableRequest stringEncoding:NSUTF8StringEncoding]; + + if (parameters) { + for (AFQueryStringPair *pair in AFQueryStringPairsFromDictionary(parameters)) { + NSData *data = nil; + if ([pair.value isKindOfClass:[NSData class]]) { + data = pair.value; + } else if ([pair.value isEqual:[NSNull null]]) { + data = [NSData data]; + } else { + data = [[pair.value description] dataUsingEncoding:self.stringEncoding]; + } + + if (data) { + [formData appendPartWithFormData:data name:[pair.field description]]; + } + } + } + + if (block) { + block(formData); + } + + return [formData requestByFinalizingMultipartFormData]; +} + +- (NSMutableURLRequest *)requestWithMultipartFormRequest:(NSURLRequest *)request + writingStreamContentsToFile:(NSURL *)fileURL + completionHandler:(void (^)(NSError *error))handler +{ + NSParameterAssert(request.HTTPBodyStream); + NSParameterAssert([fileURL isFileURL]); + + NSInputStream *inputStream = request.HTTPBodyStream; + NSOutputStream *outputStream = [[NSOutputStream alloc] initWithURL:fileURL append:NO]; + __block NSError *error = nil; + + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + [inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + [outputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSDefaultRunLoopMode]; + + [inputStream open]; + [outputStream open]; + + while ([inputStream hasBytesAvailable] && [outputStream hasSpaceAvailable]) { + uint8_t buffer[1024]; + + NSInteger bytesRead = [inputStream read:buffer maxLength:1024]; + if (inputStream.streamError || bytesRead < 0) { + error = inputStream.streamError; + break; + } + + NSInteger bytesWritten = [outputStream write:buffer maxLength:(NSUInteger)bytesRead]; + if (outputStream.streamError || bytesWritten < 0) { + error = outputStream.streamError; + break; + } + + if (bytesRead == 0 && bytesWritten == 0) { + break; + } + } + + [outputStream close]; + [inputStream close]; + + if (handler) { + dispatch_async(dispatch_get_main_queue(), ^{ + handler(error); + }); + } + }); + + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + mutableRequest.HTTPBodyStream = nil; + + return mutableRequest; +} + +#pragma mark - AFURLRequestSerialization + +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(request); + + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + + [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { + if (![request valueForHTTPHeaderField:field]) { + [mutableRequest setValue:value forHTTPHeaderField:field]; + } + }]; + + if (parameters) { + NSString *query = nil; + if (self.queryStringSerialization) { + NSError *serializationError; + query = self.queryStringSerialization(request, parameters, &serializationError); + + if (serializationError) { + if (error) { + *error = serializationError; + } + + return nil; + } + } else { + switch (self.queryStringSerializationStyle) { + case AFHTTPRequestQueryStringDefaultStyle: + query = AFQueryStringFromParametersWithEncoding(parameters, self.stringEncoding); + break; + } + } + + if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { + mutableRequest.URL = [NSURL URLWithString:[[mutableRequest.URL absoluteString] stringByAppendingFormat:mutableRequest.URL.query ? @"&%@" : @"?%@", query]]; + } else { + if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { + [mutableRequest setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"]; + } + [mutableRequest setHTTPBody:[query dataUsingEncoding:self.stringEncoding]]; + } + } + + return mutableRequest; +} + +#pragma mark - NSKeyValueObserving + ++ (BOOL)automaticallyNotifiesObserversForKey:(NSString *)key { + if ([AFHTTPRequestSerializerObservedKeyPaths() containsObject:key]) { + return NO; + } + + return [super automaticallyNotifiesObserversForKey:key]; +} + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(__unused id)object + change:(NSDictionary *)change + context:(void *)context +{ + if (context == AFHTTPRequestSerializerObserverContext) { + if ([change[NSKeyValueChangeNewKey] isEqual:[NSNull null]]) { + [self.mutableObservedChangedKeyPaths removeObject:keyPath]; + } else { + [self.mutableObservedChangedKeyPaths addObject:keyPath]; + } + } +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [self init]; + if (!self) { + return nil; + } + + self.mutableHTTPRequestHeaders = [[decoder decodeObjectOfClass:[NSDictionary class] forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))] mutableCopy]; + self.queryStringSerializationStyle = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))] unsignedIntegerValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.mutableHTTPRequestHeaders forKey:NSStringFromSelector(@selector(mutableHTTPRequestHeaders))]; + [coder encodeInteger:self.queryStringSerializationStyle forKey:NSStringFromSelector(@selector(queryStringSerializationStyle))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPRequestSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.mutableHTTPRequestHeaders = [self.mutableHTTPRequestHeaders mutableCopyWithZone:zone]; + serializer.queryStringSerializationStyle = self.queryStringSerializationStyle; + serializer.queryStringSerialization = self.queryStringSerialization; + + return serializer; +} + +@end + +#pragma mark - + +static NSString * AFCreateMultipartFormBoundary() { + return [NSString stringWithFormat:@"Boundary+%08X%08X", arc4random(), arc4random()]; +} + +static NSString * const kAFMultipartFormCRLF = @"\r\n"; + +static inline NSString * AFMultipartFormInitialBoundary(NSString *boundary) { + return [NSString stringWithFormat:@"--%@%@", boundary, kAFMultipartFormCRLF]; +} + +static inline NSString * AFMultipartFormEncapsulationBoundary(NSString *boundary) { + return [NSString stringWithFormat:@"%@--%@%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; +} + +static inline NSString * AFMultipartFormFinalBoundary(NSString *boundary) { + return [NSString stringWithFormat:@"%@--%@--%@", kAFMultipartFormCRLF, boundary, kAFMultipartFormCRLF]; +} + +static inline NSString * AFContentTypeForPathExtension(NSString *extension) { +#ifdef __UTTYPE__ + NSString *UTI = (__bridge_transfer NSString *)UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL); + NSString *contentType = (__bridge_transfer NSString *)UTTypeCopyPreferredTagWithClass((__bridge CFStringRef)UTI, kUTTagClassMIMEType); + if (!contentType) { + return @"application/octet-stream"; + } else { + return contentType; + } +#else +#pragma unused (extension) + return @"application/octet-stream"; +#endif +} + +NSUInteger const kAFUploadStream3GSuggestedPacketSize = 1024 * 16; +NSTimeInterval const kAFUploadStream3GSuggestedDelay = 0.2; + +@interface AFHTTPBodyPart : NSObject +@property (nonatomic, assign) NSStringEncoding stringEncoding; +@property (nonatomic, strong) NSDictionary *headers; +@property (nonatomic, copy) NSString *boundary; +@property (nonatomic, strong) id body; +@property (nonatomic, assign) unsigned long long bodyContentLength; +@property (nonatomic, strong) NSInputStream *inputStream; + +@property (nonatomic, assign) BOOL hasInitialBoundary; +@property (nonatomic, assign) BOOL hasFinalBoundary; + +@property (readonly, nonatomic, assign, getter = hasBytesAvailable) BOOL bytesAvailable; +@property (readonly, nonatomic, assign) unsigned long long contentLength; + +- (NSInteger)read:(uint8_t *)buffer + maxLength:(NSUInteger)length; +@end + +@interface AFMultipartBodyStream : NSInputStream +@property (nonatomic, assign) NSUInteger numberOfBytesInPacket; +@property (nonatomic, assign) NSTimeInterval delay; +@property (nonatomic, strong) NSInputStream *inputStream; +@property (readonly, nonatomic, assign) unsigned long long contentLength; +@property (readonly, nonatomic, assign, getter = isEmpty) BOOL empty; + +- (id)initWithStringEncoding:(NSStringEncoding)encoding; +- (void)setInitialAndFinalBoundaries; +- (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart; +@end + +#pragma mark - + +@interface AFStreamingMultipartFormData () +@property (readwrite, nonatomic, copy) NSMutableURLRequest *request; +@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; +@property (readwrite, nonatomic, copy) NSString *boundary; +@property (readwrite, nonatomic, strong) AFMultipartBodyStream *bodyStream; +@end + +@implementation AFStreamingMultipartFormData + +- (id)initWithURLRequest:(NSMutableURLRequest *)urlRequest + stringEncoding:(NSStringEncoding)encoding +{ + self = [super init]; + if (!self) { + return nil; + } + + self.request = urlRequest; + self.stringEncoding = encoding; + self.boundary = AFCreateMultipartFormBoundary(); + self.bodyStream = [[AFMultipartBodyStream alloc] initWithStringEncoding:encoding]; + + return self; +} + +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + error:(NSError * __autoreleasing *)error +{ + NSParameterAssert(fileURL); + NSParameterAssert(name); + + NSString *fileName = [fileURL lastPathComponent]; + NSString *mimeType = AFContentTypeForPathExtension([fileURL pathExtension]); + + return [self appendPartWithFileURL:fileURL name:name fileName:fileName mimeType:mimeType error:error]; +} + +- (BOOL)appendPartWithFileURL:(NSURL *)fileURL + name:(NSString *)name + fileName:(NSString *)fileName + mimeType:(NSString *)mimeType + error:(NSError * __autoreleasing *)error +{ + NSParameterAssert(fileURL); + NSParameterAssert(name); + NSParameterAssert(fileName); + NSParameterAssert(mimeType); + + if (![fileURL isFileURL]) { + NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"Expected URL to be a file URL", @"AFNetworking", nil)}; + if (error) { + *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; + } + + return NO; + } else if ([fileURL checkResourceIsReachableAndReturnError:error] == NO) { + NSDictionary *userInfo = @{NSLocalizedFailureReasonErrorKey: NSLocalizedStringFromTable(@"File URL not reachable.", @"AFNetworking", nil)}; + if (error) { + *error = [[NSError alloc] initWithDomain:AFURLRequestSerializationErrorDomain code:NSURLErrorBadURL userInfo:userInfo]; + } + + return NO; + } + + NSDictionary *fileAttributes = [[NSFileManager defaultManager] attributesOfItemAtPath:[fileURL path] error:error]; + if (!fileAttributes) { + return NO; + } + + NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; + [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; + [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; + + AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; + bodyPart.stringEncoding = self.stringEncoding; + bodyPart.headers = mutableHeaders; + bodyPart.boundary = self.boundary; + bodyPart.body = fileURL; + bodyPart.bodyContentLength = [[fileAttributes objectForKey:NSFileSize] unsignedLongLongValue]; + [self.bodyStream appendHTTPBodyPart:bodyPart]; + + return YES; +} + +- (void)appendPartWithInputStream:(NSInputStream *)inputStream + name:(NSString *)name + fileName:(NSString *)fileName + length:(int64_t)length + mimeType:(NSString *)mimeType +{ + NSParameterAssert(name); + NSParameterAssert(fileName); + NSParameterAssert(mimeType); + + NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; + [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; + [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; + + AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; + bodyPart.stringEncoding = self.stringEncoding; + bodyPart.headers = mutableHeaders; + bodyPart.boundary = self.boundary; + bodyPart.body = inputStream; + + bodyPart.bodyContentLength = (unsigned long long)length; + + [self.bodyStream appendHTTPBodyPart:bodyPart]; +} + +- (void)appendPartWithFileData:(NSData *)data + name:(NSString *)name + fileName:(NSString *)fileName + mimeType:(NSString *)mimeType +{ + NSParameterAssert(name); + NSParameterAssert(fileName); + NSParameterAssert(mimeType); + + NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; + [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"; filename=\"%@\"", name, fileName] forKey:@"Content-Disposition"]; + [mutableHeaders setValue:mimeType forKey:@"Content-Type"]; + + [self appendPartWithHeaders:mutableHeaders body:data]; +} + +- (void)appendPartWithFormData:(NSData *)data + name:(NSString *)name +{ + NSParameterAssert(name); + + NSMutableDictionary *mutableHeaders = [NSMutableDictionary dictionary]; + [mutableHeaders setValue:[NSString stringWithFormat:@"form-data; name=\"%@\"", name] forKey:@"Content-Disposition"]; + + [self appendPartWithHeaders:mutableHeaders body:data]; +} + +- (void)appendPartWithHeaders:(NSDictionary *)headers + body:(NSData *)body +{ + NSParameterAssert(body); + + AFHTTPBodyPart *bodyPart = [[AFHTTPBodyPart alloc] init]; + bodyPart.stringEncoding = self.stringEncoding; + bodyPart.headers = headers; + bodyPart.boundary = self.boundary; + bodyPart.bodyContentLength = [body length]; + bodyPart.body = body; + + [self.bodyStream appendHTTPBodyPart:bodyPart]; +} + +- (void)throttleBandwidthWithPacketSize:(NSUInteger)numberOfBytes + delay:(NSTimeInterval)delay +{ + self.bodyStream.numberOfBytesInPacket = numberOfBytes; + self.bodyStream.delay = delay; +} + +- (NSMutableURLRequest *)requestByFinalizingMultipartFormData { + if ([self.bodyStream isEmpty]) { + return self.request; + } + + // Reset the initial and final boundaries to ensure correct Content-Length + [self.bodyStream setInitialAndFinalBoundaries]; + [self.request setHTTPBodyStream:self.bodyStream]; + + [self.request setValue:[NSString stringWithFormat:@"multipart/form-data; boundary=%@", self.boundary] forHTTPHeaderField:@"Content-Type"]; + [self.request setValue:[NSString stringWithFormat:@"%llu", [self.bodyStream contentLength]] forHTTPHeaderField:@"Content-Length"]; + + return self.request; +} + +@end + +#pragma mark - + +@interface NSStream () +@property (readwrite) NSStreamStatus streamStatus; +@property (readwrite, copy) NSError *streamError; +@end + +@interface AFMultipartBodyStream () +@property (readwrite, nonatomic, assign) NSStringEncoding stringEncoding; +@property (readwrite, nonatomic, strong) NSMutableArray *HTTPBodyParts; +@property (readwrite, nonatomic, strong) NSEnumerator *HTTPBodyPartEnumerator; +@property (readwrite, nonatomic, strong) AFHTTPBodyPart *currentHTTPBodyPart; +@property (readwrite, nonatomic, strong) NSOutputStream *outputStream; +@property (readwrite, nonatomic, strong) NSMutableData *buffer; +@end + +@implementation AFMultipartBodyStream +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wimplicit-atomic-properties" +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1100) +@synthesize delegate; +#endif +@synthesize streamStatus; +@synthesize streamError; +#pragma clang diagnostic pop + +- (id)initWithStringEncoding:(NSStringEncoding)encoding { + self = [super init]; + if (!self) { + return nil; + } + + self.stringEncoding = encoding; + self.HTTPBodyParts = [NSMutableArray array]; + self.numberOfBytesInPacket = NSIntegerMax; + + return self; +} + +- (void)setInitialAndFinalBoundaries { + if ([self.HTTPBodyParts count] > 0) { + for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { + bodyPart.hasInitialBoundary = NO; + bodyPart.hasFinalBoundary = NO; + } + + [[self.HTTPBodyParts objectAtIndex:0] setHasInitialBoundary:YES]; + [[self.HTTPBodyParts lastObject] setHasFinalBoundary:YES]; + } +} + +- (void)appendHTTPBodyPart:(AFHTTPBodyPart *)bodyPart { + [self.HTTPBodyParts addObject:bodyPart]; +} + +- (BOOL)isEmpty { + return [self.HTTPBodyParts count] == 0; +} + +#pragma mark - NSInputStream + +- (NSInteger)read:(uint8_t *)buffer + maxLength:(NSUInteger)length +{ + if ([self streamStatus] == NSStreamStatusClosed) { + return 0; + } + + NSInteger totalNumberOfBytesRead = 0; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + while ((NSUInteger)totalNumberOfBytesRead < MIN(length, self.numberOfBytesInPacket)) { + if (!self.currentHTTPBodyPart || ![self.currentHTTPBodyPart hasBytesAvailable]) { + if (!(self.currentHTTPBodyPart = [self.HTTPBodyPartEnumerator nextObject])) { + break; + } + } else { + NSUInteger maxLength = length - (NSUInteger)totalNumberOfBytesRead; + NSInteger numberOfBytesRead = [self.currentHTTPBodyPart read:&buffer[totalNumberOfBytesRead] maxLength:maxLength]; + if (numberOfBytesRead == -1) { + self.streamError = self.currentHTTPBodyPart.inputStream.streamError; + break; + } else { + totalNumberOfBytesRead += numberOfBytesRead; + + if (self.delay > 0.0f) { + [NSThread sleepForTimeInterval:self.delay]; + } + } + } + } +#pragma clang diagnostic pop + + return totalNumberOfBytesRead; +} + +- (BOOL)getBuffer:(__unused uint8_t **)buffer + length:(__unused NSUInteger *)len +{ + return NO; +} + +- (BOOL)hasBytesAvailable { + return [self streamStatus] == NSStreamStatusOpen; +} + +#pragma mark - NSStream + +- (void)open { + if (self.streamStatus == NSStreamStatusOpen) { + return; + } + + self.streamStatus = NSStreamStatusOpen; + + [self setInitialAndFinalBoundaries]; + self.HTTPBodyPartEnumerator = [self.HTTPBodyParts objectEnumerator]; +} + +- (void)close { + self.streamStatus = NSStreamStatusClosed; +} + +- (id)propertyForKey:(__unused NSString *)key { + return nil; +} + +- (BOOL)setProperty:(__unused id)property + forKey:(__unused NSString *)key +{ + return NO; +} + +- (void)scheduleInRunLoop:(__unused NSRunLoop *)aRunLoop + forMode:(__unused NSString *)mode +{} + +- (void)removeFromRunLoop:(__unused NSRunLoop *)aRunLoop + forMode:(__unused NSString *)mode +{} + +- (unsigned long long)contentLength { + unsigned long long length = 0; + for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { + length += [bodyPart contentLength]; + } + + return length; +} + +#pragma mark - Undocumented CFReadStream Bridged Methods + +- (void)_scheduleInCFRunLoop:(__unused CFRunLoopRef)aRunLoop + forMode:(__unused CFStringRef)aMode +{} + +- (void)_unscheduleFromCFRunLoop:(__unused CFRunLoopRef)aRunLoop + forMode:(__unused CFStringRef)aMode +{} + +- (BOOL)_setCFClientFlags:(__unused CFOptionFlags)inFlags + callback:(__unused CFReadStreamClientCallBack)inCallback + context:(__unused CFStreamClientContext *)inContext { + return NO; +} + +#pragma mark - NSCopying + +-(id)copyWithZone:(NSZone *)zone { + AFMultipartBodyStream *bodyStreamCopy = [[[self class] allocWithZone:zone] initWithStringEncoding:self.stringEncoding]; + + for (AFHTTPBodyPart *bodyPart in self.HTTPBodyParts) { + [bodyStreamCopy appendHTTPBodyPart:[bodyPart copy]]; + } + + [bodyStreamCopy setInitialAndFinalBoundaries]; + + return bodyStreamCopy; +} + +@end + +#pragma mark - + +typedef enum { + AFEncapsulationBoundaryPhase = 1, + AFHeaderPhase = 2, + AFBodyPhase = 3, + AFFinalBoundaryPhase = 4, +} AFHTTPBodyPartReadPhase; + +@interface AFHTTPBodyPart () { + AFHTTPBodyPartReadPhase _phase; + NSInputStream *_inputStream; + unsigned long long _phaseReadOffset; +} + +- (BOOL)transitionToNextPhase; +- (NSInteger)readData:(NSData *)data + intoBuffer:(uint8_t *)buffer + maxLength:(NSUInteger)length; +@end + +@implementation AFHTTPBodyPart + +- (id)init { + self = [super init]; + if (!self) { + return nil; + } + + [self transitionToNextPhase]; + + return self; +} + +- (void)dealloc { + if (_inputStream) { + [_inputStream close]; + _inputStream = nil; + } +} + +- (NSInputStream *)inputStream { + if (!_inputStream) { + if ([self.body isKindOfClass:[NSData class]]) { + _inputStream = [NSInputStream inputStreamWithData:self.body]; + } else if ([self.body isKindOfClass:[NSURL class]]) { + _inputStream = [NSInputStream inputStreamWithURL:self.body]; + } else if ([self.body isKindOfClass:[NSInputStream class]]) { + _inputStream = self.body; + } else { + _inputStream = [NSInputStream inputStreamWithData:[NSData data]]; + } + } + + return _inputStream; +} + +- (NSString *)stringForHeaders { + NSMutableString *headerString = [NSMutableString string]; + for (NSString *field in [self.headers allKeys]) { + [headerString appendString:[NSString stringWithFormat:@"%@: %@%@", field, [self.headers valueForKey:field], kAFMultipartFormCRLF]]; + } + [headerString appendString:kAFMultipartFormCRLF]; + + return [NSString stringWithString:headerString]; +} + +- (unsigned long long)contentLength { + unsigned long long length = 0; + + NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; + length += [encapsulationBoundaryData length]; + + NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; + length += [headersData length]; + + length += _bodyContentLength; + + NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); + length += [closingBoundaryData length]; + + return length; +} + +- (BOOL)hasBytesAvailable { + // Allows `read:maxLength:` to be called again if `AFMultipartFormFinalBoundary` doesn't fit into the available buffer + if (_phase == AFFinalBoundaryPhase) { + return YES; + } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcovered-switch-default" + switch (self.inputStream.streamStatus) { + case NSStreamStatusNotOpen: + case NSStreamStatusOpening: + case NSStreamStatusOpen: + case NSStreamStatusReading: + case NSStreamStatusWriting: + return YES; + case NSStreamStatusAtEnd: + case NSStreamStatusClosed: + case NSStreamStatusError: + default: + return NO; + } +#pragma clang diagnostic pop +} + +- (NSInteger)read:(uint8_t *)buffer + maxLength:(NSUInteger)length +{ + NSInteger totalNumberOfBytesRead = 0; + + if (_phase == AFEncapsulationBoundaryPhase) { + NSData *encapsulationBoundaryData = [([self hasInitialBoundary] ? AFMultipartFormInitialBoundary(self.boundary) : AFMultipartFormEncapsulationBoundary(self.boundary)) dataUsingEncoding:self.stringEncoding]; + totalNumberOfBytesRead += [self readData:encapsulationBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; + } + + if (_phase == AFHeaderPhase) { + NSData *headersData = [[self stringForHeaders] dataUsingEncoding:self.stringEncoding]; + totalNumberOfBytesRead += [self readData:headersData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; + } + + if (_phase == AFBodyPhase) { + NSInteger numberOfBytesRead = 0; + + numberOfBytesRead = [self.inputStream read:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; + if (numberOfBytesRead == -1) { + return -1; + } else { + totalNumberOfBytesRead += numberOfBytesRead; + + if ([self.inputStream streamStatus] >= NSStreamStatusAtEnd) { + [self transitionToNextPhase]; + } + } + } + + if (_phase == AFFinalBoundaryPhase) { + NSData *closingBoundaryData = ([self hasFinalBoundary] ? [AFMultipartFormFinalBoundary(self.boundary) dataUsingEncoding:self.stringEncoding] : [NSData data]); + totalNumberOfBytesRead += [self readData:closingBoundaryData intoBuffer:&buffer[totalNumberOfBytesRead] maxLength:(length - (NSUInteger)totalNumberOfBytesRead)]; + } + + return totalNumberOfBytesRead; +} + +- (NSInteger)readData:(NSData *)data + intoBuffer:(uint8_t *)buffer + maxLength:(NSUInteger)length +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + NSRange range = NSMakeRange((NSUInteger)_phaseReadOffset, MIN([data length] - ((NSUInteger)_phaseReadOffset), length)); + [data getBytes:buffer range:range]; +#pragma clang diagnostic pop + + _phaseReadOffset += range.length; + + if (((NSUInteger)_phaseReadOffset) >= [data length]) { + [self transitionToNextPhase]; + } + + return (NSInteger)range.length; +} + +- (BOOL)transitionToNextPhase { + if (![[NSThread currentThread] isMainThread]) { + dispatch_sync(dispatch_get_main_queue(), ^{ + [self transitionToNextPhase]; + }); + return YES; + } + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wcovered-switch-default" + switch (_phase) { + case AFEncapsulationBoundaryPhase: + _phase = AFHeaderPhase; + break; + case AFHeaderPhase: + [self.inputStream scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; + [self.inputStream open]; + _phase = AFBodyPhase; + break; + case AFBodyPhase: + [self.inputStream close]; + _phase = AFFinalBoundaryPhase; + break; + case AFFinalBoundaryPhase: + default: + _phase = AFEncapsulationBoundaryPhase; + break; + } + _phaseReadOffset = 0; +#pragma clang diagnostic pop + + return YES; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPBodyPart *bodyPart = [[[self class] allocWithZone:zone] init]; + + bodyPart.stringEncoding = self.stringEncoding; + bodyPart.headers = self.headers; + bodyPart.bodyContentLength = self.bodyContentLength; + bodyPart.body = self.body; + bodyPart.boundary = self.boundary; + + return bodyPart; +} + +@end + +#pragma mark - + +@implementation AFJSONRequestSerializer + ++ (instancetype)serializer { + return [self serializerWithWritingOptions:(NSJSONWritingOptions)0]; +} + ++ (instancetype)serializerWithWritingOptions:(NSJSONWritingOptions)writingOptions +{ + AFJSONRequestSerializer *serializer = [[self alloc] init]; + serializer.writingOptions = writingOptions; + + return serializer; +} + +#pragma mark - AFURLRequestSerialization + +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(request); + + if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { + return [super requestBySerializingRequest:request withParameters:parameters error:error]; + } + + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + + [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { + if (![request valueForHTTPHeaderField:field]) { + [mutableRequest setValue:value forHTTPHeaderField:field]; + } + }]; + + if (parameters) { + if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { + [mutableRequest setValue:@"application/json" forHTTPHeaderField:@"Content-Type"]; + } + + [mutableRequest setHTTPBody:[NSJSONSerialization dataWithJSONObject:parameters options:self.writingOptions error:error]]; + } + + return mutableRequest; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.writingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writingOptions))] unsignedIntegerValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeInteger:self.writingOptions forKey:NSStringFromSelector(@selector(writingOptions))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFJSONRequestSerializer *serializer = [super copyWithZone:zone]; + serializer.writingOptions = self.writingOptions; + + return serializer; +} + +@end + +#pragma mark - + +@implementation AFPropertyListRequestSerializer + ++ (instancetype)serializer { + return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 writeOptions:0]; +} + ++ (instancetype)serializerWithFormat:(NSPropertyListFormat)format + writeOptions:(NSPropertyListWriteOptions)writeOptions +{ + AFPropertyListRequestSerializer *serializer = [[self alloc] init]; + serializer.format = format; + serializer.writeOptions = writeOptions; + + return serializer; +} + +#pragma mark - AFURLRequestSerializer + +- (NSURLRequest *)requestBySerializingRequest:(NSURLRequest *)request + withParameters:(id)parameters + error:(NSError *__autoreleasing *)error +{ + NSParameterAssert(request); + + if ([self.HTTPMethodsEncodingParametersInURI containsObject:[[request HTTPMethod] uppercaseString]]) { + return [super requestBySerializingRequest:request withParameters:parameters error:error]; + } + + NSMutableURLRequest *mutableRequest = [request mutableCopy]; + + [self.HTTPRequestHeaders enumerateKeysAndObjectsUsingBlock:^(id field, id value, BOOL * __unused stop) { + if (![request valueForHTTPHeaderField:field]) { + [mutableRequest setValue:value forHTTPHeaderField:field]; + } + }]; + + if (parameters) { + if (![mutableRequest valueForHTTPHeaderField:@"Content-Type"]) { + [mutableRequest setValue:@"application/x-plist" forHTTPHeaderField:@"Content-Type"]; + } + + [mutableRequest setHTTPBody:[NSPropertyListSerialization dataWithPropertyList:parameters format:self.format options:self.writeOptions error:error]]; + } + + return mutableRequest; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; + self.writeOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(writeOptions))] unsignedIntegerValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeInteger:self.format forKey:NSStringFromSelector(@selector(format))]; + [coder encodeObject:@(self.writeOptions) forKey:NSStringFromSelector(@selector(writeOptions))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFPropertyListRequestSerializer *serializer = [super copyWithZone:zone]; + serializer.format = self.format; + serializer.writeOptions = self.writeOptions; + + return serializer; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.h new file mode 100644 index 0000000..5eff8e6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.h @@ -0,0 +1,310 @@ +// AFURLResponseSerialization.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import +#import + +/** + The `AFURLResponseSerialization` protocol is adopted by an object that decodes data into a more useful object representation, according to details in the server response. Response serializers may additionally perform validation on the incoming response and data. + + For example, a JSON response serializer may check for an acceptable status code (`2XX` range) and content type (`application/json`), decoding a valid JSON response into an object. + */ +@protocol AFURLResponseSerialization + +/** + The response object decoded from the data associated with a specified response. + + @param response The response to be processed. + @param data The response data to be decoded. + @param error The error that occurred while attempting to decode the response data. + + @return The object decoded from the specified response data. + */ +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error; + +@end + +#pragma mark - + +/** + `AFHTTPResponseSerializer` conforms to the `AFURLRequestSerialization` & `AFURLResponseSerialization` protocols, offering a concrete base implementation of query string / URL form-encoded parameter serialization and default request headers, as well as response status code and content type validation. + + Any request or response serializer dealing with HTTP is encouraged to subclass `AFHTTPResponseSerializer` in order to ensure consistent default behavior. + */ +@interface AFHTTPResponseSerializer : NSObject + +- (instancetype) init; + +/** + The string encoding used to serialize data received from the server, when no string encoding is specified by the response. `NSUTF8StringEncoding` by default. + */ +@property (nonatomic, assign) NSStringEncoding stringEncoding; + +/** + Creates and returns a serializer with default configuration. + */ ++ (instancetype)serializer; + +///----------------------------------------- +/// @name Configuring Response Serialization +///----------------------------------------- + +/** + The acceptable HTTP status codes for responses. When non-`nil`, responses with status codes not contained by the set will result in an error during validation. + + See http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html + */ +@property (nonatomic, copy) NSIndexSet *acceptableStatusCodes; + +/** + The acceptable MIME types for responses. When non-`nil`, responses with a `Content-Type` with MIME types that do not intersect with the set will result in an error during validation. + */ +@property (nonatomic, copy) NSSet *acceptableContentTypes; + +/** + Validates the specified response and data. + + In its base implementation, this method checks for an acceptable status code and content type. Subclasses may wish to add other domain-specific checks. + + @param response The response to be validated. + @param data The data associated with the response. + @param error The error that occurred while attempting to validate the response. + + @return `YES` if the response is valid, otherwise `NO`. + */ +- (BOOL)validateResponse:(NSHTTPURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error; + +@end + +#pragma mark - + + +/** + `AFJSONResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes JSON responses. + + By default, `AFJSONResponseSerializer` accepts the following MIME types, which includes the official standard, `application/json`, as well as other commonly-used types: + + - `application/json` + - `text/json` + - `text/javascript` + */ +@interface AFJSONResponseSerializer : AFHTTPResponseSerializer + +- (instancetype) init; + +/** + Options for reading the response JSON data and creating the Foundation objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. + */ +@property (nonatomic, assign) NSJSONReadingOptions readingOptions; + +/** + Whether to remove keys with `NSNull` values from response JSON. Defaults to `NO`. + */ +@property (nonatomic, assign) BOOL removesKeysWithNullValues; + +/** + Creates and returns a JSON serializer with specified reading and writing options. + + @param readingOptions The specified JSON reading options. + */ ++ (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions; + +@end + +#pragma mark - + +/** + `AFXMLParserResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLParser` objects. + + By default, `AFXMLParserResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: + + - `application/xml` + - `text/xml` + */ +@interface AFXMLParserResponseSerializer : AFHTTPResponseSerializer + +@end + +#pragma mark - + +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED + +/** + `AFXMLDocumentResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. + + By default, `AFXMLDocumentResponseSerializer` accepts the following MIME types, which includes the official standard, `application/xml`, as well as other commonly-used types: + + - `application/xml` + - `text/xml` + */ +@interface AFXMLDocumentResponseSerializer : AFHTTPResponseSerializer + +- (instancetype) init; + +/** + Input and output options specifically intended for `NSXMLDocument` objects. For possible values, see the `NSJSONSerialization` documentation section "NSJSONReadingOptions". `0` by default. + */ +@property (nonatomic, assign) NSUInteger options; + +/** + Creates and returns an XML document serializer with the specified options. + + @param mask The XML document options. + */ ++ (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask; + +@end + +#endif + +#pragma mark - + +/** + `AFPropertyListResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes XML responses as an `NSXMLDocument` objects. + + By default, `AFPropertyListResponseSerializer` accepts the following MIME types: + + - `application/x-plist` + */ +@interface AFPropertyListResponseSerializer : AFHTTPResponseSerializer + +- (instancetype) init; + +/** + The property list format. Possible values are described in "NSPropertyListFormat". + */ +@property (nonatomic, assign) NSPropertyListFormat format; + +/** + The property list reading options. Possible values are described in "NSPropertyListMutabilityOptions." + */ +@property (nonatomic, assign) NSPropertyListReadOptions readOptions; + +/** + Creates and returns a property list serializer with a specified format, read options, and write options. + + @param format The property list format. + @param readOptions The property list reading options. + */ ++ (instancetype)serializerWithFormat:(NSPropertyListFormat)format + readOptions:(NSPropertyListReadOptions)readOptions; + +@end + +#pragma mark - + +/** + `AFImageResponseSerializer` is a subclass of `AFHTTPResponseSerializer` that validates and decodes image responses. + + By default, `AFImageResponseSerializer` accepts the following MIME types, which correspond to the image formats supported by UIImage or NSImage: + + - `image/tiff` + - `image/jpeg` + - `image/gif` + - `image/png` + - `image/ico` + - `image/x-icon` + - `image/bmp` + - `image/x-bmp` + - `image/x-xbitmap` + - `image/x-win-bitmap` + */ +@interface AFImageResponseSerializer : AFHTTPResponseSerializer + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +/** + The scale factor used when interpreting the image data to construct `responseImage`. Specifying a scale factor of 1.0 results in an image whose size matches the pixel-based dimensions of the image. Applying a different scale factor changes the size of the image as reported by the size property. This is set to the value of scale of the main screen by default, which automatically scales images for retina displays, for instance. + */ +@property (nonatomic, assign) CGFloat imageScale; + +/** + Whether to automatically inflate response image data for compressed formats (such as PNG or JPEG). Enabling this can significantly improve drawing performance on iOS when used with `setCompletionBlockWithSuccess:failure:`, as it allows a bitmap representation to be constructed in the background rather than on the main thread. `YES` by default. + */ +@property (nonatomic, assign) BOOL automaticallyInflatesResponseImage; +#endif + +@end + +#pragma mark - + +/** + `AFCompoundSerializer` is a subclass of `AFHTTPResponseSerializer` that delegates the response serialization to the first `AFHTTPResponseSerializer` object that returns an object for `responseObjectForResponse:data:error:`, falling back on the default behavior of `AFHTTPResponseSerializer`. This is useful for supporting multiple potential types and structures of server responses with a single serializer. + */ +@interface AFCompoundResponseSerializer : AFHTTPResponseSerializer + +/** + The component response serializers. + */ +@property (readonly, nonatomic, copy) NSArray *responseSerializers; + +/** + Creates and returns a compound serializer comprised of the specified response serializers. + + @warning Each response serializer specified must be a subclass of `AFHTTPResponseSerializer`, and response to `-validateResponse:data:error:`. + */ ++ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers; + +@end + +///---------------- +/// @name Constants +///---------------- + +/** + ## Error Domains + + The following error domain is predefined. + + - `NSString * const AFURLResponseSerializationErrorDomain` + + ### Constants + + `AFURLResponseSerializationErrorDomain` + AFURLResponseSerializer errors. Error codes for `AFURLResponseSerializationErrorDomain` correspond to codes in `NSURLErrorDomain`. + */ +extern NSString * const AFURLResponseSerializationErrorDomain; + +/** + ## User info dictionary keys + + These keys may exist in the user info dictionary, in addition to those defined for NSError. + + - `NSString * const AFNetworkingOperationFailingURLResponseErrorKey` + - `NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey` + + ### Constants + + `AFNetworkingOperationFailingURLResponseErrorKey` + The corresponding value is an `NSURLResponse` containing the response of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. + + `AFNetworkingOperationFailingURLResponseDataErrorKey` + The corresponding value is an `NSData` containing the original data of the operation associated with an error. This key is only present in the `AFURLResponseSerializationErrorDomain`. + */ +extern NSString * const AFNetworkingOperationFailingURLResponseErrorKey; + +extern NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey; + + diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m new file mode 100644 index 0000000..c5a8563 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLResponseSerialization.m @@ -0,0 +1,793 @@ +// AFURLResponseSerialization.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFURLResponseSerialization.h" + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) +#import +#endif + +NSString * const AFURLResponseSerializationErrorDomain = @"com.alamofire.error.serialization.response"; +NSString * const AFNetworkingOperationFailingURLResponseErrorKey = @"com.alamofire.serialization.response.error.response"; +NSString * const AFNetworkingOperationFailingURLResponseDataErrorKey = @"com.alamofire.serialization.response.error.data"; + +static NSError * AFErrorWithUnderlyingError(NSError *error, NSError *underlyingError) { + if (!error) { + return underlyingError; + } + + if (!underlyingError || error.userInfo[NSUnderlyingErrorKey]) { + return error; + } + + NSMutableDictionary *mutableUserInfo = [error.userInfo mutableCopy]; + mutableUserInfo[NSUnderlyingErrorKey] = underlyingError; + + return [[NSError alloc] initWithDomain:error.domain code:error.code userInfo:mutableUserInfo]; +} + +static BOOL AFErrorOrUnderlyingErrorHasCodeInDomain(NSError *error, NSInteger code, NSString *domain) { + if ([error.domain isEqualToString:domain] && error.code == code) { + return YES; + } else if (error.userInfo[NSUnderlyingErrorKey]) { + return AFErrorOrUnderlyingErrorHasCodeInDomain(error.userInfo[NSUnderlyingErrorKey], code, domain); + } + + return NO; +} + +static id AFJSONObjectByRemovingKeysWithNullValues(id JSONObject, NSJSONReadingOptions readingOptions) { + if ([JSONObject isKindOfClass:[NSArray class]]) { + NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:[(NSArray *)JSONObject count]]; + for (id value in (NSArray *)JSONObject) { + [mutableArray addObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions)]; + } + + return (readingOptions & NSJSONReadingMutableContainers) ? mutableArray : [NSArray arrayWithArray:mutableArray]; + } else if ([JSONObject isKindOfClass:[NSDictionary class]]) { + NSMutableDictionary *mutableDictionary = [NSMutableDictionary dictionaryWithDictionary:JSONObject]; + for (id key in [(NSDictionary *)JSONObject allKeys]) { + id value = [(NSDictionary *)JSONObject objectForKey:key]; + if (!value || [value isEqual:[NSNull null]]) { + [mutableDictionary removeObjectForKey:key]; + } else if ([value isKindOfClass:[NSArray class]] || [value isKindOfClass:[NSDictionary class]]) { + [mutableDictionary setObject:AFJSONObjectByRemovingKeysWithNullValues(value, readingOptions) forKey:key]; + } + } + + return (readingOptions & NSJSONReadingMutableContainers) ? mutableDictionary : [NSDictionary dictionaryWithDictionary:mutableDictionary]; + } + + return JSONObject; +} + +@implementation AFHTTPResponseSerializer + ++ (instancetype)serializer { + return [[self alloc] init]; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.stringEncoding = NSUTF8StringEncoding; + + self.acceptableStatusCodes = [NSIndexSet indexSetWithIndexesInRange:NSMakeRange(200, 100)]; + self.acceptableContentTypes = nil; + + return self; +} + +#pragma mark - + +- (BOOL)validateResponse:(NSHTTPURLResponse *)response + data:(NSData *)data + error:(NSError * __autoreleasing *)error +{ + BOOL responseIsValid = YES; + NSError *validationError = nil; + + if (response && [response isKindOfClass:[NSHTTPURLResponse class]]) { + if (self.acceptableContentTypes && ![self.acceptableContentTypes containsObject:[response MIMEType]]) { + if ([data length] > 0 && [response URL]) { + NSMutableDictionary *mutableUserInfo = [@{ + NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: unacceptable content-type: %@", @"AFNetworking", nil), [response MIMEType]], + NSURLErrorFailingURLErrorKey:[response URL], + AFNetworkingOperationFailingURLResponseErrorKey: response, + } mutableCopy]; + if (data) { + mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; + } + + validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:mutableUserInfo], validationError); + } + + responseIsValid = NO; + } + + if (self.acceptableStatusCodes && ![self.acceptableStatusCodes containsIndex:(NSUInteger)response.statusCode] && [response URL]) { + NSMutableDictionary *mutableUserInfo = [@{ + NSLocalizedDescriptionKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Request failed: %@ (%ld)", @"AFNetworking", nil), [NSHTTPURLResponse localizedStringForStatusCode:response.statusCode], (long)response.statusCode], + NSURLErrorFailingURLErrorKey:[response URL], + AFNetworkingOperationFailingURLResponseErrorKey: response, + } mutableCopy]; + + if (data) { + mutableUserInfo[AFNetworkingOperationFailingURLResponseDataErrorKey] = data; + } + + validationError = AFErrorWithUnderlyingError([NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorBadServerResponse userInfo:mutableUserInfo], validationError); + + responseIsValid = NO; + } + } + + if (error && !responseIsValid) { + *error = validationError; + } + + return responseIsValid; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + [self validateResponse:(NSHTTPURLResponse *)response data:data error:error]; + + return data; +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + self = [self init]; + if (!self) { + return nil; + } + + self.acceptableStatusCodes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; + self.acceptableContentTypes = [decoder decodeObjectOfClass:[NSIndexSet class] forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.acceptableStatusCodes forKey:NSStringFromSelector(@selector(acceptableStatusCodes))]; + [coder encodeObject:self.acceptableContentTypes forKey:NSStringFromSelector(@selector(acceptableContentTypes))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFHTTPResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.acceptableStatusCodes = [self.acceptableStatusCodes copyWithZone:zone]; + serializer.acceptableContentTypes = [self.acceptableContentTypes copyWithZone:zone]; + + return serializer; +} + +@end + +#pragma mark - + +@implementation AFJSONResponseSerializer + ++ (instancetype)serializer { + return [self serializerWithReadingOptions:(NSJSONReadingOptions)0]; +} + ++ (instancetype)serializerWithReadingOptions:(NSJSONReadingOptions)readingOptions { + AFJSONResponseSerializer *serializer = [[self alloc] init]; + serializer.readingOptions = readingOptions; + + return serializer; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", nil]; + + return self; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { + if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { + return nil; + } + } + + // Workaround for behavior of Rails to return a single space for `head :ok` (a workaround for a bug in Safari), which is not interpreted as valid input by NSJSONSerialization. + // See https://github.com/rails/rails/issues/1742 + NSStringEncoding stringEncoding = self.stringEncoding; + if (response.textEncodingName) { + CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); + if (encoding != kCFStringEncodingInvalidId) { + stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding); + } + } + + id responseObject = nil; + NSError *serializationError = nil; + @autoreleasepool { + NSString *responseString = [[NSString alloc] initWithData:data encoding:stringEncoding]; + if (responseString && ![responseString isEqualToString:@" "]) { + // Workaround for a bug in NSJSONSerialization when Unicode character escape codes are used instead of the actual character + // See http://stackoverflow.com/a/12843465/157142 + data = [responseString dataUsingEncoding:NSUTF8StringEncoding]; + + if (data) { + if ([data length] > 0) { + responseObject = [NSJSONSerialization JSONObjectWithData:data options:self.readingOptions error:&serializationError]; + } else { + return nil; + } + } else { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedStringFromTable(@"Data failed decoding as a UTF-8 string", @"AFNetworking", nil), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedStringFromTable(@"Could not decode string: %@", @"AFNetworking", nil), responseString] + }; + + serializationError = [NSError errorWithDomain:AFURLResponseSerializationErrorDomain code:NSURLErrorCannotDecodeContentData userInfo:userInfo]; + } + } + } + + if (self.removesKeysWithNullValues && responseObject) { + responseObject = AFJSONObjectByRemovingKeysWithNullValues(responseObject, self.readingOptions); + } + + if (error) { + *error = AFErrorWithUnderlyingError(serializationError, *error); + } + + return responseObject; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.readingOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readingOptions))] unsignedIntegerValue]; + self.removesKeysWithNullValues = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))] boolValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:@(self.readingOptions) forKey:NSStringFromSelector(@selector(readingOptions))]; + [coder encodeObject:@(self.removesKeysWithNullValues) forKey:NSStringFromSelector(@selector(removesKeysWithNullValues))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFJSONResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.readingOptions = self.readingOptions; + serializer.removesKeysWithNullValues = self.removesKeysWithNullValues; + + return serializer; +} + +@end + +#pragma mark - + +@implementation AFXMLParserResponseSerializer + ++ (instancetype)serializer { + AFXMLParserResponseSerializer *serializer = [[self alloc] init]; + + return serializer; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; + + return self; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSHTTPURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { + if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { + return nil; + } + } + + return [[NSXMLParser alloc] initWithData:data]; +} + +@end + +#pragma mark - + +#ifdef __MAC_OS_X_VERSION_MIN_REQUIRED + +@implementation AFXMLDocumentResponseSerializer + ++ (instancetype)serializer { + return [self serializerWithXMLDocumentOptions:0]; +} + ++ (instancetype)serializerWithXMLDocumentOptions:(NSUInteger)mask { + AFXMLDocumentResponseSerializer *serializer = [[self alloc] init]; + serializer.options = mask; + + return serializer; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/xml", @"text/xml", nil]; + + return self; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { + if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { + return nil; + } + } + + NSError *serializationError = nil; + NSXMLDocument *document = [[NSXMLDocument alloc] initWithData:data options:self.options error:&serializationError]; + + if (error) { + *error = AFErrorWithUnderlyingError(serializationError, *error); + } + + return document; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.options = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(options))] unsignedIntegerValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:@(self.options) forKey:NSStringFromSelector(@selector(options))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFXMLDocumentResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.options = self.options; + + return serializer; +} + +@end + +#endif + +#pragma mark - + +@implementation AFPropertyListResponseSerializer + ++ (instancetype)serializer { + return [self serializerWithFormat:NSPropertyListXMLFormat_v1_0 readOptions:0]; +} + ++ (instancetype)serializerWithFormat:(NSPropertyListFormat)format + readOptions:(NSPropertyListReadOptions)readOptions +{ + AFPropertyListResponseSerializer *serializer = [[self alloc] init]; + serializer.format = format; + serializer.readOptions = readOptions; + + return serializer; +} + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"application/x-plist", nil]; + + return self; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { + if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { + return nil; + } + } + + id responseObject; + NSError *serializationError = nil; + + if (data) { + responseObject = [NSPropertyListSerialization propertyListWithData:data options:self.readOptions format:NULL error:&serializationError]; + } + + if (error) { + *error = AFErrorWithUnderlyingError(serializationError, *error); + } + + return responseObject; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.format = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(format))] unsignedIntegerValue]; + self.readOptions = [[decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(readOptions))] unsignedIntegerValue]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:@(self.format) forKey:NSStringFromSelector(@selector(format))]; + [coder encodeObject:@(self.readOptions) forKey:NSStringFromSelector(@selector(readOptions))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFPropertyListResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.format = self.format; + serializer.readOptions = self.readOptions; + + return serializer; +} + +@end + +#pragma mark - + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) +#import + +static UIImage * AFImageWithDataAtScale(NSData *data, CGFloat scale) { + UIImage *image = [[UIImage alloc] initWithData:data]; + + return [[UIImage alloc] initWithCGImage:[image CGImage] scale:scale orientation:image.imageOrientation]; +} + +static UIImage * AFInflatedImageFromResponseWithDataAtScale(NSHTTPURLResponse *response, NSData *data, CGFloat scale) { + if (!data || [data length] == 0) { + return nil; + } + + CGImageRef imageRef = NULL; + CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data); + + if ([response.MIMEType isEqualToString:@"image/png"]) { + imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); + } else if ([response.MIMEType isEqualToString:@"image/jpeg"]) { + imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault); + + // CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so if so, fall back to AFImageWithDataAtScale + if (imageRef) { + CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef); + CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace); + if (imageColorSpaceModel == kCGColorSpaceModelCMYK) { + CGImageRelease(imageRef); + imageRef = NULL; + } + } + } + + CGDataProviderRelease(dataProvider); + + UIImage *image = AFImageWithDataAtScale(data, scale); + if (!imageRef) { + if (image.images || !image) { + return image; + } + + imageRef = CGImageCreateCopy([image CGImage]); + if (!imageRef) { + return nil; + } + } + + size_t width = CGImageGetWidth(imageRef); + size_t height = CGImageGetHeight(imageRef); + size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef); + + if (width * height > 1024 * 1024 || bitsPerComponent > 8) { + CGImageRelease(imageRef); + + return image; + } + + size_t bytesPerRow = 0; // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace); + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); + + if (colorSpaceModel == kCGColorSpaceModelRGB) { + uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask); +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wassign-enum" + if (alpha == kCGImageAlphaNone) { + bitmapInfo &= ~kCGBitmapAlphaInfoMask; + bitmapInfo |= kCGImageAlphaNoneSkipFirst; + } else if (!(alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast)) { + bitmapInfo &= ~kCGBitmapAlphaInfoMask; + bitmapInfo |= kCGImageAlphaPremultipliedFirst; + } +#pragma clang diagnostic pop + } + + CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo); + + CGColorSpaceRelease(colorSpace); + + if (!context) { + CGImageRelease(imageRef); + + return image; + } + + CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef); + CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context); + + CGContextRelease(context); + + UIImage *inflatedImage = [[UIImage alloc] initWithCGImage:inflatedImageRef scale:scale orientation:image.imageOrientation]; + + CGImageRelease(inflatedImageRef); + CGImageRelease(imageRef); + + return inflatedImage; +} +#endif + + +@implementation AFImageResponseSerializer + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.acceptableContentTypes = [[NSSet alloc] initWithObjects:@"image/tiff", @"image/jpeg", @"image/gif", @"image/png", @"image/ico", @"image/x-icon", @"image/bmp", @"image/x-bmp", @"image/x-xbitmap", @"image/x-win-bitmap", nil]; + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + self.imageScale = [[UIScreen mainScreen] scale]; + self.automaticallyInflatesResponseImage = YES; +#endif + + return self; +} + +#pragma mark - AFURLResponseSerializer + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + if (![self validateResponse:(NSHTTPURLResponse *)response data:data error:error]) { + if (!error || AFErrorOrUnderlyingErrorHasCodeInDomain(*error, NSURLErrorCannotDecodeContentData, AFURLResponseSerializationErrorDomain)) { + return nil; + } + } + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + if (self.automaticallyInflatesResponseImage) { + return AFInflatedImageFromResponseWithDataAtScale((NSHTTPURLResponse *)response, data, self.imageScale); + } else { + return AFImageWithDataAtScale(data, self.imageScale); + } +#elif defined(__MAC_OS_X_VERSION_MIN_REQUIRED) + // Ensure that the image is set to it's correct pixel width and height + NSBitmapImageRep *bitimage = [[NSBitmapImageRep alloc] initWithData:data]; + NSImage *image = [[NSImage alloc] initWithSize:NSMakeSize([bitimage pixelsWide], [bitimage pixelsHigh])]; + [image addRepresentation:bitimage]; + + return image; +#endif + + return nil; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + NSNumber *imageScale = [decoder decodeObjectOfClass:[NSNumber class] forKey:NSStringFromSelector(@selector(imageScale))]; +#if CGFLOAT_IS_DOUBLE + self.imageScale = [imageScale doubleValue]; +#else + self.imageScale = [imageScale floatValue]; +#endif + + self.automaticallyInflatesResponseImage = [decoder decodeBoolForKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; +#endif + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + [coder encodeObject:@(self.imageScale) forKey:NSStringFromSelector(@selector(imageScale))]; + [coder encodeBool:self.automaticallyInflatesResponseImage forKey:NSStringFromSelector(@selector(automaticallyInflatesResponseImage))]; +#endif +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFImageResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + serializer.imageScale = self.imageScale; + serializer.automaticallyInflatesResponseImage = self.automaticallyInflatesResponseImage; +#endif + + return serializer; +} + +@end + +#pragma mark - + +@interface AFCompoundResponseSerializer () +@property (readwrite, nonatomic, copy) NSArray *responseSerializers; +@end + +@implementation AFCompoundResponseSerializer + ++ (instancetype)compoundSerializerWithResponseSerializers:(NSArray *)responseSerializers { + AFCompoundResponseSerializer *serializer = [[self alloc] init]; + serializer.responseSerializers = responseSerializers; + + return serializer; +} + +#pragma mark - AFURLResponseSerialization + +- (id)responseObjectForResponse:(NSURLResponse *)response + data:(NSData *)data + error:(NSError *__autoreleasing *)error +{ + for (id serializer in self.responseSerializers) { + if (![serializer isKindOfClass:[AFHTTPResponseSerializer class]]) { + continue; + } + + NSError *serializerError = nil; + id responseObject = [serializer responseObjectForResponse:response data:data error:&serializerError]; + if (responseObject) { + if (error) { + *error = AFErrorWithUnderlyingError(serializerError, *error); + } + + return responseObject; + } + } + + return [super responseObjectForResponse:response data:data error:error]; +} + +#pragma mark - NSSecureCoding + +- (id)initWithCoder:(NSCoder *)decoder { + self = [super initWithCoder:decoder]; + if (!self) { + return nil; + } + + self.responseSerializers = [decoder decodeObjectOfClass:[NSArray class] forKey:NSStringFromSelector(@selector(responseSerializers))]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [super encodeWithCoder:coder]; + + [coder encodeObject:self.responseSerializers forKey:NSStringFromSelector(@selector(responseSerializers))]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + AFCompoundResponseSerializer *serializer = [[[self class] allocWithZone:zone] init]; + serializer.responseSerializers = self.responseSerializers; + + return serializer; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h new file mode 100644 index 0000000..966c3e8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.h @@ -0,0 +1,531 @@ +// AFURLSessionManager.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import "AFURLResponseSerialization.h" +#import "AFURLRequestSerialization.h" +#import "AFSecurityPolicy.h" +#import "AFNetworkReachabilityManager.h" + +/** + `AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. + + ## Subclassing Notes + + This is the base class for `AFHTTPSessionManager`, which adds functionality specific to making HTTP requests. If you are looking to extend `AFURLSessionManager` specifically for HTTP, consider subclassing `AFHTTPSessionManager` instead. + + ## NSURLSession & NSURLSessionTask Delegate Methods + + `AFURLSessionManager` implements the following delegate methods: + + ### `NSURLSessionDelegate` + + - `URLSession:didBecomeInvalidWithError:` + - `URLSession:didReceiveChallenge:completionHandler:` + - `URLSessionDidFinishEventsForBackgroundURLSession:` + + ### `NSURLSessionTaskDelegate` + + - `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:` + - `URLSession:task:didReceiveChallenge:completionHandler:` + - `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:` + - `URLSession:task:didCompleteWithError:` + + ### `NSURLSessionDataDelegate` + + - `URLSession:dataTask:didReceiveResponse:completionHandler:` + - `URLSession:dataTask:didBecomeDownloadTask:` + - `URLSession:dataTask:didReceiveData:` + - `URLSession:dataTask:willCacheResponse:completionHandler:` + + ### `NSURLSessionDownloadDelegate` + + - `URLSession:downloadTask:didFinishDownloadingToURL:` + - `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:` + - `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:` + + If any of these methods are overridden in a subclass, they _must_ call the `super` implementation first. + + ## Network Reachability Monitoring + + Network reachability status and change monitoring is available through the `reachabilityManager` property. Applications may choose to monitor network reachability conditions in order to prevent or suspend any outbound requests. See `AFNetworkReachabilityManager` for more details. + + ## NSCoding Caveats + + - Encoded managers do not include any block properties. Be sure to set delegate callback blocks when using `-initWithCoder:` or `NSKeyedUnarchiver`. + + ## NSCopying Caveats + + - `-copy` and `-copyWithZone:` return a new manager with a new `NSURLSession` created from the configuration of the original. + - Operation copies do not include any delegate callback blocks, as they often strongly captures a reference to `self`, which would otherwise have the unintuitive side-effect of pointing to the _original_ session manager when copied. + + @warning Managers for background sessions must be owned for the duration of their use. This can be accomplished by creating an application-wide or shared singleton instance. + */ + +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) + +@interface AFURLSessionManager : NSObject + +/** + The managed session. + */ +@property (readonly, nonatomic, strong) NSURLSession *session; + +/** + The operation queue on which delegate callbacks are run. + */ +@property (readonly, nonatomic, strong) NSOperationQueue *operationQueue; + +/** + Responses sent from the server in data tasks created with `dataTaskWithRequest:success:failure:` and run using the `GET` / `POST` / et al. convenience methods are automatically validated and serialized by the response serializer. By default, this property is set to an instance of `AFJSONResponseSerializer`. + + @warning `responseSerializer` must not be `nil`. + */ +@property (nonatomic, strong) id responseSerializer; + +///------------------------------- +/// @name Managing Security Policy +///------------------------------- + +/** + The security policy used by created request operations to evaluate server trust for secure connections. `AFURLSessionManager` uses the `defaultPolicy` unless otherwise specified. + */ +@property (nonatomic, strong) AFSecurityPolicy *securityPolicy; + +///-------------------------------------- +/// @name Monitoring Network Reachability +///-------------------------------------- + +/** + The network reachability manager. `AFURLSessionManager` uses the `sharedManager` by default. + */ +@property (readwrite, nonatomic, strong) AFNetworkReachabilityManager *reachabilityManager; + +///---------------------------- +/// @name Getting Session Tasks +///---------------------------- + +/** + The data, upload, and download tasks currently run by the managed session. + */ +@property (readonly, nonatomic, strong) NSArray *tasks; + +/** + The data tasks currently run by the managed session. + */ +@property (readonly, nonatomic, strong) NSArray *dataTasks; + +/** + The upload tasks currently run by the managed session. + */ +@property (readonly, nonatomic, strong) NSArray *uploadTasks; + +/** + The download tasks currently run by the managed session. + */ +@property (readonly, nonatomic, strong) NSArray *downloadTasks; + +///------------------------------- +/// @name Managing Callback Queues +///------------------------------- + +/** + The dispatch queue for `completionBlock`. If `NULL` (default), the main queue is used. + */ +@property (nonatomic, strong) dispatch_queue_t completionQueue; + +/** + The dispatch group for `completionBlock`. If `NULL` (default), a private dispatch group is used. + */ +@property (nonatomic, strong) dispatch_group_t completionGroup; + +///--------------------------------- +/// @name Working Around System Bugs +///--------------------------------- + +/** + Whether to attempt to retry creation of upload tasks for background sessions when initial call returns `nil`. `NO` by default. + + @bug As of iOS 7.0, there is a bug where upload tasks created for background tasks are sometimes `nil`. As a workaround, if this property is `YES`, AFNetworking will follow Apple's recommendation to try creating the task again. + + @see https://github.com/AFNetworking/AFNetworking/issues/1675 + */ +@property (nonatomic, assign) BOOL attemptsToRecreateUploadTasksForBackgroundSessions; + +///--------------------- +/// @name Initialization +///--------------------- + +/** + Creates and returns a manager for a session created with the specified configuration. This is the designated initializer. + + @param configuration The configuration used to create the managed session. + + @return A manager for a newly-created session. + */ +- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration NS_DESIGNATED_INITIALIZER; + +/** + Invalidates the managed session, optionally canceling pending tasks. + + @param cancelPendingTasks Whether or not to cancel pending tasks. + */ +- (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks; + +///------------------------- +/// @name Running Data Tasks +///------------------------- + +/** + Creates an `NSURLSessionDataTask` with the specified request. + + @param request The HTTP request for the request. + @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. + */ +- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; + +///--------------------------- +/// @name Running Upload Tasks +///--------------------------- + +/** + Creates an `NSURLSessionUploadTask` with the specified request for a local file. + + @param request The HTTP request for the request. + @param fileURL A URL to the local file to be uploaded. + @param progress A progress object monitoring the current upload progress. + @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. + + @see `attemptsToRecreateUploadTasksForBackgroundSessions` + */ +- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request + fromFile:(NSURL *)fileURL + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; + +/** + Creates an `NSURLSessionUploadTask` with the specified request for an HTTP body. + + @param request The HTTP request for the request. + @param bodyData A data object containing the HTTP body to be uploaded. + @param progress A progress object monitoring the current upload progress. + @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. + */ +- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request + fromData:(NSData *)bodyData + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; + +/** + Creates an `NSURLSessionUploadTask` with the specified streaming request. + + @param request The HTTP request for the request. + @param progress A progress object monitoring the current upload progress. + @param completionHandler A block object to be executed when the task finishes. This block has no return value and takes three arguments: the server response, the response object created by that serializer, and the error that occurred, if any. + */ +- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler; + +///----------------------------- +/// @name Running Download Tasks +///----------------------------- + +/** + Creates an `NSURLSessionDownloadTask` with the specified request. + + @param request The HTTP request for the request. + @param progress A progress object monitoring the current download progress. + @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. + @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. + + @warning If using a background `NSURLSessionConfiguration` on iOS, these blocks will be lost when the app is terminated. Background sessions may prefer to use `-setDownloadTaskDidFinishDownloadingBlock:` to specify the URL for saving the downloaded file, rather than the destination block of this method. + */ +- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request + progress:(NSProgress * __autoreleasing *)progress + destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler; + +/** + Creates an `NSURLSessionDownloadTask` with the specified resume data. + + @param resumeData The data used to resume downloading. + @param progress A progress object monitoring the current download progress. + @param destination A block object to be executed in order to determine the destination of the downloaded file. This block takes two arguments, the target path & the server response, and returns the desired file URL of the resulting download. The temporary file used during the download will be automatically deleted after being moved to the returned URL. + @param completionHandler A block to be executed when a task finishes. This block has no return value and takes three arguments: the server response, the path of the downloaded file, and the error describing the network or parsing error that occurred, if any. + */ +- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData + progress:(NSProgress * __autoreleasing *)progress + destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler; + +///--------------------------------- +/// @name Getting Progress for Tasks +///--------------------------------- + +/** + Returns the upload progress of the specified task. + + @param uploadTask The session upload task. Must not be `nil`. + + @return An `NSProgress` object reporting the upload progress of a task, or `nil` if the progress is unavailable. + */ +- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask; + +/** + Returns the download progress of the specified task. + + @param downloadTask The session download task. Must not be `nil`. + + @return An `NSProgress` object reporting the download progress of a task, or `nil` if the progress is unavailable. + */ +- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask; + +///----------------------------------------- +/// @name Setting Session Delegate Callbacks +///----------------------------------------- + +/** + Sets a block to be executed when the managed session becomes invalid, as handled by the `NSURLSessionDelegate` method `URLSession:didBecomeInvalidWithError:`. + + @param block A block object to be executed when the managed session becomes invalid. The block has no return value, and takes two arguments: the session, and the error related to the cause of invalidation. + */ +- (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block; + +/** + Sets a block to be executed when a connection level authentication challenge has occurred, as handled by the `NSURLSessionDelegate` method `URLSession:didReceiveChallenge:completionHandler:`. + + @param block A block object to be executed when a connection level authentication challenge has occurred. The block returns the disposition of the authentication challenge, and takes three arguments: the session, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. + */ +- (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block; + +///-------------------------------------- +/// @name Setting Task Delegate Callbacks +///-------------------------------------- + +/** + Sets a block to be executed when a task requires a new request body stream to send to the remote server, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:needNewBodyStream:`. + + @param block A block object to be executed when a task requires a new request body stream. + */ +- (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block; + +/** + Sets a block to be executed when an HTTP request is attempting to perform a redirection to a different URL, as handled by the `NSURLSessionTaskDelegate` method `URLSession:willPerformHTTPRedirection:newRequest:completionHandler:`. + + @param block A block object to be executed when an HTTP request is attempting to perform a redirection to a different URL. The block returns the request to be made for the redirection, and takes four arguments: the session, the task, the redirection response, and the request corresponding to the redirection response. + */ +- (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block; + +/** + Sets a block to be executed when a session task has received a request specific authentication challenge, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didReceiveChallenge:completionHandler:`. + + @param block A block object to be executed when a session task has received a request specific authentication challenge. The block returns the disposition of the authentication challenge, and takes four arguments: the session, the task, the authentication challenge, and a pointer to the credential that should be used to resolve the challenge. + */ +- (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block; + +/** + Sets a block to be executed periodically to track upload progress, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didSendBodyData:totalBytesSent:totalBytesExpectedToSend:`. + + @param block A block object to be called when an undetermined number of bytes have been uploaded to the server. This block has no return value and takes five arguments: the session, the task, the number of bytes written since the last time the upload progress block was called, the total bytes written, and the total bytes expected to be written during the request, as initially determined by the length of the HTTP body. This block may be called multiple times, and will execute on the main thread. + */ +- (void)setTaskDidSendBodyDataBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block; + +/** + Sets a block to be executed as the last message related to a specific task, as handled by the `NSURLSessionTaskDelegate` method `URLSession:task:didCompleteWithError:`. + + @param block A block object to be executed when a session task is completed. The block has no return value, and takes three arguments: the session, the task, and any error that occurred in the process of executing the task. + */ +- (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block; + +///------------------------------------------- +/// @name Setting Data Task Delegate Callbacks +///------------------------------------------- + +/** + Sets a block to be executed when a data task has received a response, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveResponse:completionHandler:`. + + @param block A block object to be executed when a data task has received a response. The block returns the disposition of the session response, and takes three arguments: the session, the data task, and the received response. + */ +- (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block; + +/** + Sets a block to be executed when a data task has become a download task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didBecomeDownloadTask:`. + + @param block A block object to be executed when a data task has become a download task. The block has no return value, and takes three arguments: the session, the data task, and the download task it has become. + */ +- (void)setDataTaskDidBecomeDownloadTaskBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block; + +/** + Sets a block to be executed when a data task receives data, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:didReceiveData:`. + + @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the session, the data task, and the data received. This block may be called multiple times, and will execute on the session manager operation queue. + */ +- (void)setDataTaskDidReceiveDataBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block; + +/** + Sets a block to be executed to determine the caching behavior of a data task, as handled by the `NSURLSessionDataDelegate` method `URLSession:dataTask:willCacheResponse:completionHandler:`. + + @param block A block object to be executed to determine the caching behavior of a data task. The block returns the response to cache, and takes three arguments: the session, the data task, and the proposed cached URL response. + */ +- (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block; + +/** + Sets a block to be executed once all messages enqueued for a session have been delivered, as handled by the `NSURLSessionDataDelegate` method `URLSessionDidFinishEventsForBackgroundURLSession:`. + + @param block A block object to be executed once all messages enqueued for a session have been delivered. The block has no return value and takes a single argument: the session. + */ +- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block; + +///----------------------------------------------- +/// @name Setting Download Task Delegate Callbacks +///----------------------------------------------- + +/** + Sets a block to be executed when a download task has completed a download, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didFinishDownloadingToURL:`. + + @param block A block object to be executed when a download task has completed. The block returns the URL the download should be moved to, and takes three arguments: the session, the download task, and the temporary location of the downloaded file. If the file manager encounters an error while attempting to move the temporary file to the destination, an `AFURLSessionDownloadTaskDidFailToMoveFileNotification` will be posted, with the download task as its object, and the user info of the error. + */ +- (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block; + +/** + Sets a block to be executed periodically to track download progress, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didWriteData:totalBytesWritten:totalBytesWritten:totalBytesExpectedToWrite:`. + + @param block A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes five arguments: the session, the download task, the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the session manager operation queue. + */ +- (void)setDownloadTaskDidWriteDataBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block; + +/** + Sets a block to be executed when a download task has been resumed, as handled by the `NSURLSessionDownloadDelegate` method `URLSession:downloadTask:didResumeAtOffset:expectedTotalBytes:`. + + @param block A block object to be executed when a download task has been resumed. The block has no return value and takes four arguments: the session, the download task, the file offset of the resumed download, and the total number of bytes expected to be downloaded. + */ +- (void)setDownloadTaskDidResumeBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block; + +@end + +#endif + +///-------------------- +/// @name Notifications +///-------------------- + +/** + Posted when a task begins executing. + + @deprecated Use `AFNetworkingTaskDidResumeNotification` instead. + */ +extern NSString * const AFNetworkingTaskDidStartNotification DEPRECATED_ATTRIBUTE; + +/** + Posted when a task resumes. + */ +extern NSString * const AFNetworkingTaskDidResumeNotification; + +/** + Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. + + @deprecated Use `AFNetworkingTaskDidCompleteNotification` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishNotification DEPRECATED_ATTRIBUTE; + +/** + Posted when a task finishes executing. Includes a userInfo dictionary with additional information about the task. + */ +extern NSString * const AFNetworkingTaskDidCompleteNotification; + +/** + Posted when a task suspends its execution. + */ +extern NSString * const AFNetworkingTaskDidSuspendNotification; + +/** + Posted when a session is invalidated. + */ +extern NSString * const AFURLSessionDidInvalidateNotification; + +/** + Posted when a session download task encountered an error when moving the temporary download file to a specified destination. + */ +extern NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification; + +/** + The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task. + + @deprecated Use `AFNetworkingTaskDidCompleteResponseDataKey` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishResponseDataKey DEPRECATED_ATTRIBUTE; + +/** + The raw response data of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if response data exists for the task. + */ +extern NSString * const AFNetworkingTaskDidCompleteResponseDataKey; + +/** + The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized. + + @deprecated Use `AFNetworkingTaskDidCompleteSerializedResponseKey` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishSerializedResponseKey DEPRECATED_ATTRIBUTE; + +/** + The serialized response object of the task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the response was serialized. + */ +extern NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey; + +/** + The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer. + + @deprecated Use `AFNetworkingTaskDidCompleteResponseSerializerKey` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishResponseSerializerKey DEPRECATED_ATTRIBUTE; + +/** + The response serializer used to serialize the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if the task has an associated response serializer. + */ +extern NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey; + +/** + The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk. + + @deprecated Use `AFNetworkingTaskDidCompleteAssetPathKey` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishAssetPathKey DEPRECATED_ATTRIBUTE; + +/** + The file path associated with the download task. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an the response data has been stored directly to disk. + */ +extern NSString * const AFNetworkingTaskDidCompleteAssetPathKey; + +/** + Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists. + + @deprecated Use `AFNetworkingTaskDidCompleteErrorKey` instead. + */ +extern NSString * const AFNetworkingTaskDidFinishErrorKey DEPRECATED_ATTRIBUTE; + +/** + Any error associated with the task, or the serialization of the response. Included in the userInfo dictionary of the `AFNetworkingTaskDidFinishNotification` if an error exists. + */ +extern NSString * const AFNetworkingTaskDidCompleteErrorKey; diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m new file mode 100644 index 0000000..a6ebbee --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/AFNetworking/AFURLSessionManager.m @@ -0,0 +1,1094 @@ +// AFURLSessionManager.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFURLSessionManager.h" +#import + +#if (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000) || (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && __MAC_OS_X_VERSION_MAX_ALLOWED >= 1090) + +static dispatch_queue_t url_session_manager_creation_queue() { + static dispatch_queue_t af_url_session_manager_creation_queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_url_session_manager_creation_queue = dispatch_queue_create("com.alamofire.networking.session.manager.creation", DISPATCH_QUEUE_SERIAL); + }); + + return af_url_session_manager_creation_queue; +} + +static dispatch_queue_t url_session_manager_processing_queue() { + static dispatch_queue_t af_url_session_manager_processing_queue; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_url_session_manager_processing_queue = dispatch_queue_create("com.alamofire.networking.session.manager.processing", DISPATCH_QUEUE_CONCURRENT); + }); + + return af_url_session_manager_processing_queue; +} + +static dispatch_group_t url_session_manager_completion_group() { + static dispatch_group_t af_url_session_manager_completion_group; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_url_session_manager_completion_group = dispatch_group_create(); + }); + + return af_url_session_manager_completion_group; +} + +NSString * const AFNetworkingTaskDidResumeNotification = @"com.alamofire.networking.task.resume"; +NSString * const AFNetworkingTaskDidCompleteNotification = @"com.alamofire.networking.task.complete"; +NSString * const AFNetworkingTaskDidSuspendNotification = @"com.alamofire.networking.task.suspend"; +NSString * const AFURLSessionDidInvalidateNotification = @"com.alamofire.networking.session.invalidate"; +NSString * const AFURLSessionDownloadTaskDidFailToMoveFileNotification = @"com.alamofire.networking.session.download.file-manager-error"; + +NSString * const AFNetworkingTaskDidStartNotification = @"com.alamofire.networking.task.resume"; // Deprecated +NSString * const AFNetworkingTaskDidFinishNotification = @"com.alamofire.networking.task.complete"; // Deprecated + +NSString * const AFNetworkingTaskDidCompleteSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; +NSString * const AFNetworkingTaskDidCompleteResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; +NSString * const AFNetworkingTaskDidCompleteResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; +NSString * const AFNetworkingTaskDidCompleteErrorKey = @"com.alamofire.networking.task.complete.error"; +NSString * const AFNetworkingTaskDidCompleteAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; + +NSString * const AFNetworkingTaskDidFinishSerializedResponseKey = @"com.alamofire.networking.task.complete.serializedresponse"; // Deprecated +NSString * const AFNetworkingTaskDidFinishResponseSerializerKey = @"com.alamofire.networking.task.complete.responseserializer"; // Deprecated +NSString * const AFNetworkingTaskDidFinishResponseDataKey = @"com.alamofire.networking.complete.finish.responsedata"; // Deprecated +NSString * const AFNetworkingTaskDidFinishErrorKey = @"com.alamofire.networking.task.complete.error"; // Deprecated +NSString * const AFNetworkingTaskDidFinishAssetPathKey = @"com.alamofire.networking.task.complete.assetpath"; // Deprecated + +static NSString * const AFURLSessionManagerLockName = @"com.alamofire.networking.session.manager.lock"; + +static NSUInteger const AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask = 3; + +static void * AFTaskStateChangedContext = &AFTaskStateChangedContext; + +typedef void (^AFURLSessionDidBecomeInvalidBlock)(NSURLSession *session, NSError *error); +typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); + +typedef NSURLRequest * (^AFURLSessionTaskWillPerformHTTPRedirectionBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request); +typedef NSURLSessionAuthChallengeDisposition (^AFURLSessionTaskDidReceiveAuthenticationChallengeBlock)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential); +typedef void (^AFURLSessionDidFinishEventsForBackgroundURLSessionBlock)(NSURLSession *session); + +typedef NSInputStream * (^AFURLSessionTaskNeedNewBodyStreamBlock)(NSURLSession *session, NSURLSessionTask *task); +typedef void (^AFURLSessionTaskDidSendBodyDataBlock)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend); +typedef void (^AFURLSessionTaskDidCompleteBlock)(NSURLSession *session, NSURLSessionTask *task, NSError *error); + +typedef NSURLSessionResponseDisposition (^AFURLSessionDataTaskDidReceiveResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response); +typedef void (^AFURLSessionDataTaskDidBecomeDownloadTaskBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask); +typedef void (^AFURLSessionDataTaskDidReceiveDataBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data); +typedef NSCachedURLResponse * (^AFURLSessionDataTaskWillCacheResponseBlock)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse); + +typedef NSURL * (^AFURLSessionDownloadTaskDidFinishDownloadingBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location); +typedef void (^AFURLSessionDownloadTaskDidWriteDataBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite); +typedef void (^AFURLSessionDownloadTaskDidResumeBlock)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes); + +typedef void (^AFURLSessionTaskCompletionHandler)(NSURLResponse *response, id responseObject, NSError *error); + +#pragma mark - + +@interface AFURLSessionManagerTaskDelegate : NSObject +@property (nonatomic, weak) AFURLSessionManager *manager; +@property (nonatomic, strong) NSMutableData *mutableData; +@property (nonatomic, strong) NSProgress *progress; +@property (nonatomic, copy) NSURL *downloadFileURL; +@property (nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; +@property (nonatomic, copy) AFURLSessionTaskCompletionHandler completionHandler; +@end + +@implementation AFURLSessionManagerTaskDelegate + +- (instancetype)init { + self = [super init]; + if (!self) { + return nil; + } + + self.mutableData = [NSMutableData data]; + + self.progress = [NSProgress progressWithTotalUnitCount:0]; + + return self; +} + +#pragma mark - NSURLSessionTaskDelegate + +- (void)URLSession:(__unused NSURLSession *)session + task:(__unused NSURLSessionTask *)task + didSendBodyData:(__unused int64_t)bytesSent + totalBytesSent:(int64_t)totalBytesSent +totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend +{ + self.progress.totalUnitCount = totalBytesExpectedToSend; + self.progress.completedUnitCount = totalBytesSent; +} + +- (void)URLSession:(__unused NSURLSession *)session + task:(NSURLSessionTask *)task +didCompleteWithError:(NSError *)error +{ +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + __strong AFURLSessionManager *manager = self.manager; + + __block id responseObject = nil; + + __block NSMutableDictionary *userInfo = [NSMutableDictionary dictionary]; + userInfo[AFNetworkingTaskDidCompleteResponseSerializerKey] = manager.responseSerializer; + + if (self.downloadFileURL) { + userInfo[AFNetworkingTaskDidCompleteAssetPathKey] = self.downloadFileURL; + } else if (self.mutableData) { + userInfo[AFNetworkingTaskDidCompleteResponseDataKey] = [NSData dataWithData:self.mutableData]; + } + + if (error) { + userInfo[AFNetworkingTaskDidCompleteErrorKey] = error; + + dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ + if (self.completionHandler) { + self.completionHandler(task.response, responseObject, error); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; + }); + }); + } else { + dispatch_async(url_session_manager_processing_queue(), ^{ + NSError *serializationError = nil; + responseObject = [manager.responseSerializer responseObjectForResponse:task.response data:[NSData dataWithData:self.mutableData] error:&serializationError]; + + if (self.downloadFileURL) { + responseObject = self.downloadFileURL; + } + + if (responseObject) { + userInfo[AFNetworkingTaskDidCompleteSerializedResponseKey] = responseObject; + } + + if (serializationError) { + userInfo[AFNetworkingTaskDidCompleteErrorKey] = serializationError; + } + + dispatch_group_async(manager.completionGroup ?: url_session_manager_completion_group(), manager.completionQueue ?: dispatch_get_main_queue(), ^{ + if (self.completionHandler) { + self.completionHandler(task.response, responseObject, serializationError); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidCompleteNotification object:task userInfo:userInfo]; + }); + }); + }); + } +#pragma clang diagnostic pop +} + +#pragma mark - NSURLSessionDataTaskDelegate + +- (void)URLSession:(__unused NSURLSession *)session + dataTask:(__unused NSURLSessionDataTask *)dataTask + didReceiveData:(NSData *)data +{ + [self.mutableData appendData:data]; +} + +#pragma mark - NSURLSessionDownloadTaskDelegate + +- (void)URLSession:(NSURLSession *)session + downloadTask:(NSURLSessionDownloadTask *)downloadTask +didFinishDownloadingToURL:(NSURL *)location +{ + NSError *fileManagerError = nil; + self.downloadFileURL = nil; + + if (self.downloadTaskDidFinishDownloading) { + self.downloadFileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); + if (self.downloadFileURL) { + [[NSFileManager defaultManager] moveItemAtURL:location toURL:self.downloadFileURL error:&fileManagerError]; + + if (fileManagerError) { + [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:fileManagerError.userInfo]; + } + } + } +} + +- (void)URLSession:(__unused NSURLSession *)session + downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask + didWriteData:(__unused int64_t)bytesWritten + totalBytesWritten:(int64_t)totalBytesWritten +totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite +{ + self.progress.totalUnitCount = totalBytesExpectedToWrite; + self.progress.completedUnitCount = totalBytesWritten; +} + +- (void)URLSession:(__unused NSURLSession *)session + downloadTask:(__unused NSURLSessionDownloadTask *)downloadTask + didResumeAtOffset:(int64_t)fileOffset +expectedTotalBytes:(int64_t)expectedTotalBytes { + self.progress.totalUnitCount = expectedTotalBytes; + self.progress.completedUnitCount = fileOffset; +} + +@end + +#pragma mark - + +/* + A workaround for issues related to key-value observing the `state` of an `NSURLSessionTask`. + + See https://github.com/AFNetworking/AFNetworking/issues/1477 + */ + +static inline void af_swizzleSelector(Class class, SEL originalSelector, SEL swizzledSelector) { + Method originalMethod = class_getInstanceMethod(class, originalSelector); + Method swizzledMethod = class_getInstanceMethod(class, swizzledSelector); + if (class_addMethod(class, originalSelector, method_getImplementation(swizzledMethod), method_getTypeEncoding(swizzledMethod))) { + class_replaceMethod(class, swizzledSelector, method_getImplementation(originalMethod), method_getTypeEncoding(originalMethod)); + } else { + method_exchangeImplementations(originalMethod, swizzledMethod); + } +} + +static NSString * const AFNSURLSessionTaskDidResumeNotification = @"com.alamofire.networking.nsurlsessiontask.resume"; +static NSString * const AFNSURLSessionTaskDidSuspendNotification = @"com.alamofire.networking.nsurlsessiontask.suspend"; + +@interface NSURLSessionTask (_AFStateObserving) +@end + +@implementation NSURLSessionTask (_AFStateObserving) + ++ (void)load { + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + af_swizzleSelector([self class], @selector(resume), @selector(af_resume)); + af_swizzleSelector([self class], @selector(suspend), @selector(af_suspend)); + }); +} + +#pragma mark - + +- (void)af_resume { + NSURLSessionTaskState state = self.state; + [self af_resume]; + + if (state != NSURLSessionTaskStateRunning) { + [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidResumeNotification object:self]; + } +} + +- (void)af_suspend { + NSURLSessionTaskState state = self.state; + [self af_suspend]; + + if (state != NSURLSessionTaskStateSuspended) { + [[NSNotificationCenter defaultCenter] postNotificationName:AFNSURLSessionTaskDidSuspendNotification object:self]; + } +} + +@end + +#pragma mark - + +@interface AFURLSessionManager () +@property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration; +@property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue; +@property (readwrite, nonatomic, strong) NSURLSession *session; +@property (readwrite, nonatomic, strong) NSMutableDictionary *mutableTaskDelegatesKeyedByTaskIdentifier; +@property (readonly, nonatomic, copy) NSString *taskDescriptionForSessionTasks; +@property (readwrite, nonatomic, strong) NSLock *lock; +@property (readwrite, nonatomic, copy) AFURLSessionDidBecomeInvalidBlock sessionDidBecomeInvalid; +@property (readwrite, nonatomic, copy) AFURLSessionDidReceiveAuthenticationChallengeBlock sessionDidReceiveAuthenticationChallenge; +@property (readwrite, nonatomic, copy) AFURLSessionDidFinishEventsForBackgroundURLSessionBlock didFinishEventsForBackgroundURLSession; +@property (readwrite, nonatomic, copy) AFURLSessionTaskWillPerformHTTPRedirectionBlock taskWillPerformHTTPRedirection; +@property (readwrite, nonatomic, copy) AFURLSessionTaskDidReceiveAuthenticationChallengeBlock taskDidReceiveAuthenticationChallenge; +@property (readwrite, nonatomic, copy) AFURLSessionTaskNeedNewBodyStreamBlock taskNeedNewBodyStream; +@property (readwrite, nonatomic, copy) AFURLSessionTaskDidSendBodyDataBlock taskDidSendBodyData; +@property (readwrite, nonatomic, copy) AFURLSessionTaskDidCompleteBlock taskDidComplete; +@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveResponseBlock dataTaskDidReceiveResponse; +@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidBecomeDownloadTaskBlock dataTaskDidBecomeDownloadTask; +@property (readwrite, nonatomic, copy) AFURLSessionDataTaskDidReceiveDataBlock dataTaskDidReceiveData; +@property (readwrite, nonatomic, copy) AFURLSessionDataTaskWillCacheResponseBlock dataTaskWillCacheResponse; +@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidFinishDownloadingBlock downloadTaskDidFinishDownloading; +@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidWriteDataBlock downloadTaskDidWriteData; +@property (readwrite, nonatomic, copy) AFURLSessionDownloadTaskDidResumeBlock downloadTaskDidResume; +@end + +@implementation AFURLSessionManager + +- (instancetype)init { + return [self initWithSessionConfiguration:nil]; +} + +- (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)configuration { + self = [super init]; + if (!self) { + return nil; + } + + if (!configuration) { + configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; + } + + self.sessionConfiguration = configuration; + + self.operationQueue = [[NSOperationQueue alloc] init]; + self.operationQueue.maxConcurrentOperationCount = 1; + + self.session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue]; + + self.responseSerializer = [AFJSONResponseSerializer serializer]; + + self.securityPolicy = [AFSecurityPolicy defaultPolicy]; + + self.reachabilityManager = [AFNetworkReachabilityManager sharedManager]; + + self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init]; + + self.lock = [[NSLock alloc] init]; + self.lock.name = AFURLSessionManagerLockName; + + [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { + for (NSURLSessionDataTask *task in dataTasks) { + [self addDelegateForDataTask:task completionHandler:nil]; + } + + for (NSURLSessionUploadTask *uploadTask in uploadTasks) { + [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil]; + } + + for (NSURLSessionDownloadTask *downloadTask in downloadTasks) { + [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil]; + } + }]; + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidResume:) name:AFNSURLSessionTaskDidResumeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(taskDidSuspend:) name:AFNSURLSessionTaskDidSuspendNotification object:nil]; + + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +#pragma mark - + +- (NSString *)taskDescriptionForSessionTasks { + return [NSString stringWithFormat:@"%p", self]; +} + +- (void)taskDidResume:(NSNotification *)notification { + NSURLSessionTask *task = notification.object; + if ([task isKindOfClass:[NSURLSessionTask class]]) { + if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidResumeNotification object:task]; + }); + } + } +} + +- (void)taskDidSuspend:(NSNotification *)notification { + NSURLSessionTask *task = notification.object; + if ([task isKindOfClass:[NSURLSessionTask class]]) { + if ([task.taskDescription isEqualToString:self.taskDescriptionForSessionTasks]) { + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:AFNetworkingTaskDidSuspendNotification object:task]; + }); + } + } +} + +#pragma mark - + +- (AFURLSessionManagerTaskDelegate *)delegateForTask:(NSURLSessionTask *)task { + NSParameterAssert(task); + + AFURLSessionManagerTaskDelegate *delegate = nil; + [self.lock lock]; + delegate = self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)]; + [self.lock unlock]; + + return delegate; +} + +- (void)setDelegate:(AFURLSessionManagerTaskDelegate *)delegate + forTask:(NSURLSessionTask *)task +{ + NSParameterAssert(task); + NSParameterAssert(delegate); + + [self.lock lock]; + self.mutableTaskDelegatesKeyedByTaskIdentifier[@(task.taskIdentifier)] = delegate; + [self.lock unlock]; +} + +- (void)addDelegateForDataTask:(NSURLSessionDataTask *)dataTask + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; + delegate.manager = self; + delegate.completionHandler = completionHandler; + + dataTask.taskDescription = self.taskDescriptionForSessionTasks; + [self setDelegate:delegate forTask:dataTask]; +} + +- (void)addDelegateForUploadTask:(NSURLSessionUploadTask *)uploadTask + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; + delegate.manager = self; + delegate.completionHandler = completionHandler; + + int64_t totalUnitCount = uploadTask.countOfBytesExpectedToSend; + if(totalUnitCount == NSURLSessionTransferSizeUnknown) { + NSString *contentLength = [uploadTask.originalRequest valueForHTTPHeaderField:@"Content-Length"]; + if(contentLength) { + totalUnitCount = (int64_t)[contentLength longLongValue]; + } + } + + if (delegate.progress) { + delegate.progress.totalUnitCount = totalUnitCount; + } else { + delegate.progress = [NSProgress progressWithTotalUnitCount:totalUnitCount]; + } + + delegate.progress.pausingHandler = ^{ + [uploadTask suspend]; + }; + delegate.progress.cancellationHandler = ^{ + [uploadTask cancel]; + }; + + if (progress) { + *progress = delegate.progress; + } + + uploadTask.taskDescription = self.taskDescriptionForSessionTasks; + + [self setDelegate:delegate forTask:uploadTask]; +} + +- (void)addDelegateForDownloadTask:(NSURLSessionDownloadTask *)downloadTask + progress:(NSProgress * __autoreleasing *)progress + destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler +{ + AFURLSessionManagerTaskDelegate *delegate = [[AFURLSessionManagerTaskDelegate alloc] init]; + delegate.manager = self; + delegate.completionHandler = completionHandler; + + if (destination) { + delegate.downloadTaskDidFinishDownloading = ^NSURL * (NSURLSession * __unused session, NSURLSessionDownloadTask *task, NSURL *location) { + return destination(location, task.response); + }; + } + + if (progress) { + *progress = delegate.progress; + } + + downloadTask.taskDescription = self.taskDescriptionForSessionTasks; + + [self setDelegate:delegate forTask:downloadTask]; +} + +- (void)removeDelegateForTask:(NSURLSessionTask *)task { + NSParameterAssert(task); + + [self.lock lock]; + [self.mutableTaskDelegatesKeyedByTaskIdentifier removeObjectForKey:@(task.taskIdentifier)]; + [self.lock unlock]; +} + +- (void)removeAllDelegates { + [self.lock lock]; + [self.mutableTaskDelegatesKeyedByTaskIdentifier removeAllObjects]; + [self.lock unlock]; +} + +#pragma mark - + +- (NSArray *)tasksForKeyPath:(NSString *)keyPath { + __block NSArray *tasks = nil; + dispatch_semaphore_t semaphore = dispatch_semaphore_create(0); + [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(dataTasks))]) { + tasks = dataTasks; + } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(uploadTasks))]) { + tasks = uploadTasks; + } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(downloadTasks))]) { + tasks = downloadTasks; + } else if ([keyPath isEqualToString:NSStringFromSelector(@selector(tasks))]) { + tasks = [@[dataTasks, uploadTasks, downloadTasks] valueForKeyPath:@"@unionOfArrays.self"]; + } + + dispatch_semaphore_signal(semaphore); + }]; + + dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER); + + return tasks; +} + +- (NSArray *)tasks { + return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; +} + +- (NSArray *)dataTasks { + return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; +} + +- (NSArray *)uploadTasks { + return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; +} + +- (NSArray *)downloadTasks { + return [self tasksForKeyPath:NSStringFromSelector(_cmd)]; +} + +#pragma mark - + +- (void)invalidateSessionCancelingTasks:(BOOL)cancelPendingTasks { + dispatch_async(dispatch_get_main_queue(), ^{ + if (cancelPendingTasks) { + [self.session invalidateAndCancel]; + } else { + [self.session finishTasksAndInvalidate]; + } + }); +} + +#pragma mark - + +- (void)setResponseSerializer:(id )responseSerializer { + NSParameterAssert(responseSerializer); + + _responseSerializer = responseSerializer; +} + +#pragma mark - + +- (NSURLSessionDataTask *)dataTaskWithRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + __block NSURLSessionDataTask *dataTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + dataTask = [self.session dataTaskWithRequest:request]; + }); + + [self addDelegateForDataTask:dataTask completionHandler:completionHandler]; + + return dataTask; +} + +#pragma mark - + +- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request + fromFile:(NSURL *)fileURL + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + __block NSURLSessionUploadTask *uploadTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; + }); + + if (!uploadTask && self.attemptsToRecreateUploadTasksForBackgroundSessions && self.session.configuration.identifier) { + for (NSUInteger attempts = 0; !uploadTask && attempts < AFMaximumNumberOfAttemptsToRecreateBackgroundSessionUploadTask; attempts++) { + uploadTask = [self.session uploadTaskWithRequest:request fromFile:fileURL]; + } + } + + [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; + + return uploadTask; +} + +- (NSURLSessionUploadTask *)uploadTaskWithRequest:(NSURLRequest *)request + fromData:(NSData *)bodyData + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + __block NSURLSessionUploadTask *uploadTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + uploadTask = [self.session uploadTaskWithRequest:request fromData:bodyData]; + }); + + [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; + + return uploadTask; +} + +- (NSURLSessionUploadTask *)uploadTaskWithStreamedRequest:(NSURLRequest *)request + progress:(NSProgress * __autoreleasing *)progress + completionHandler:(void (^)(NSURLResponse *response, id responseObject, NSError *error))completionHandler +{ + __block NSURLSessionUploadTask *uploadTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + uploadTask = [self.session uploadTaskWithStreamedRequest:request]; + }); + + [self addDelegateForUploadTask:uploadTask progress:progress completionHandler:completionHandler]; + + return uploadTask; +} + +#pragma mark - + +- (NSURLSessionDownloadTask *)downloadTaskWithRequest:(NSURLRequest *)request + progress:(NSProgress * __autoreleasing *)progress + destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler +{ + __block NSURLSessionDownloadTask *downloadTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + downloadTask = [self.session downloadTaskWithRequest:request]; + }); + + [self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler]; + + return downloadTask; +} + +- (NSURLSessionDownloadTask *)downloadTaskWithResumeData:(NSData *)resumeData + progress:(NSProgress * __autoreleasing *)progress + destination:(NSURL * (^)(NSURL *targetPath, NSURLResponse *response))destination + completionHandler:(void (^)(NSURLResponse *response, NSURL *filePath, NSError *error))completionHandler +{ + __block NSURLSessionDownloadTask *downloadTask = nil; + dispatch_sync(url_session_manager_creation_queue(), ^{ + downloadTask = [self.session downloadTaskWithResumeData:resumeData]; + }); + + [self addDelegateForDownloadTask:downloadTask progress:progress destination:destination completionHandler:completionHandler]; + + return downloadTask; +} + +#pragma mark - + +- (NSProgress *)uploadProgressForTask:(NSURLSessionUploadTask *)uploadTask { + return [[self delegateForTask:uploadTask] progress]; +} + +- (NSProgress *)downloadProgressForTask:(NSURLSessionDownloadTask *)downloadTask { + return [[self delegateForTask:downloadTask] progress]; +} + +#pragma mark - + +- (void)setSessionDidBecomeInvalidBlock:(void (^)(NSURLSession *session, NSError *error))block { + self.sessionDidBecomeInvalid = block; +} + +- (void)setSessionDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { + self.sessionDidReceiveAuthenticationChallenge = block; +} + +- (void)setDidFinishEventsForBackgroundURLSessionBlock:(void (^)(NSURLSession *session))block { + self.didFinishEventsForBackgroundURLSession = block; +} + +#pragma mark - + +- (void)setTaskNeedNewBodyStreamBlock:(NSInputStream * (^)(NSURLSession *session, NSURLSessionTask *task))block { + self.taskNeedNewBodyStream = block; +} + +- (void)setTaskWillPerformHTTPRedirectionBlock:(NSURLRequest * (^)(NSURLSession *session, NSURLSessionTask *task, NSURLResponse *response, NSURLRequest *request))block { + self.taskWillPerformHTTPRedirection = block; +} + +- (void)setTaskDidReceiveAuthenticationChallengeBlock:(NSURLSessionAuthChallengeDisposition (^)(NSURLSession *session, NSURLSessionTask *task, NSURLAuthenticationChallenge *challenge, NSURLCredential * __autoreleasing *credential))block { + self.taskDidReceiveAuthenticationChallenge = block; +} + +- (void)setTaskDidSendBodyDataBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, int64_t bytesSent, int64_t totalBytesSent, int64_t totalBytesExpectedToSend))block { + self.taskDidSendBodyData = block; +} + +- (void)setTaskDidCompleteBlock:(void (^)(NSURLSession *session, NSURLSessionTask *task, NSError *error))block { + self.taskDidComplete = block; +} + +#pragma mark - + +- (void)setDataTaskDidReceiveResponseBlock:(NSURLSessionResponseDisposition (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLResponse *response))block { + self.dataTaskDidReceiveResponse = block; +} + +- (void)setDataTaskDidBecomeDownloadTaskBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSURLSessionDownloadTask *downloadTask))block { + self.dataTaskDidBecomeDownloadTask = block; +} + +- (void)setDataTaskDidReceiveDataBlock:(void (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSData *data))block { + self.dataTaskDidReceiveData = block; +} + +- (void)setDataTaskWillCacheResponseBlock:(NSCachedURLResponse * (^)(NSURLSession *session, NSURLSessionDataTask *dataTask, NSCachedURLResponse *proposedResponse))block { + self.dataTaskWillCacheResponse = block; +} + +#pragma mark - + +- (void)setDownloadTaskDidFinishDownloadingBlock:(NSURL * (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, NSURL *location))block { + self.downloadTaskDidFinishDownloading = block; +} + +- (void)setDownloadTaskDidWriteDataBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t bytesWritten, int64_t totalBytesWritten, int64_t totalBytesExpectedToWrite))block { + self.downloadTaskDidWriteData = block; +} + +- (void)setDownloadTaskDidResumeBlock:(void (^)(NSURLSession *session, NSURLSessionDownloadTask *downloadTask, int64_t fileOffset, int64_t expectedTotalBytes))block { + self.downloadTaskDidResume = block; +} + +#pragma mark - NSObject + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@: %p, session: %@, operationQueue: %@>", NSStringFromClass([self class]), self, self.session, self.operationQueue]; +} + +- (BOOL)respondsToSelector:(SEL)selector { + if (selector == @selector(URLSession:task:willPerformHTTPRedirection:newRequest:completionHandler:)) { + return self.taskWillPerformHTTPRedirection != nil; + } else if (selector == @selector(URLSession:dataTask:didReceiveResponse:completionHandler:)) { + return self.dataTaskDidReceiveResponse != nil; + } else if (selector == @selector(URLSession:dataTask:willCacheResponse:completionHandler:)) { + return self.dataTaskWillCacheResponse != nil; + } else if (selector == @selector(URLSessionDidFinishEventsForBackgroundURLSession:)) { + return self.didFinishEventsForBackgroundURLSession != nil; + } + + return [[self class] instancesRespondToSelector:selector]; +} + +#pragma mark - NSURLSessionDelegate + +- (void)URLSession:(NSURLSession *)session +didBecomeInvalidWithError:(NSError *)error +{ + if (self.sessionDidBecomeInvalid) { + self.sessionDidBecomeInvalid(session, error); + } + + [self removeAllDelegates]; + [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDidInvalidateNotification object:session]; +} + +- (void)URLSession:(NSURLSession *)session +didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge + completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler +{ + NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; + __block NSURLCredential *credential = nil; + + if (self.sessionDidReceiveAuthenticationChallenge) { + disposition = self.sessionDidReceiveAuthenticationChallenge(session, challenge, &credential); + } else { + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { + credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + if (credential) { + disposition = NSURLSessionAuthChallengeUseCredential; + } else { + disposition = NSURLSessionAuthChallengePerformDefaultHandling; + } + } else { + disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; + } + } else { + disposition = NSURLSessionAuthChallengePerformDefaultHandling; + } + } + + if (completionHandler) { + completionHandler(disposition, credential); + } +} + +#pragma mark - NSURLSessionTaskDelegate + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task +willPerformHTTPRedirection:(NSHTTPURLResponse *)response + newRequest:(NSURLRequest *)request + completionHandler:(void (^)(NSURLRequest *))completionHandler +{ + NSURLRequest *redirectRequest = request; + + if (self.taskWillPerformHTTPRedirection) { + redirectRequest = self.taskWillPerformHTTPRedirection(session, task, response, request); + } + + if (completionHandler) { + completionHandler(redirectRequest); + } +} + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task +didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge + completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler +{ + NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; + __block NSURLCredential *credential = nil; + + if (self.taskDidReceiveAuthenticationChallenge) { + disposition = self.taskDidReceiveAuthenticationChallenge(session, task, challenge, &credential); + } else { + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + if ([self.securityPolicy evaluateServerTrust:challenge.protectionSpace.serverTrust forDomain:challenge.protectionSpace.host]) { + disposition = NSURLSessionAuthChallengeUseCredential; + credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + } else { + disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; + } + } else { + disposition = NSURLSessionAuthChallengePerformDefaultHandling; + } + } + + if (completionHandler) { + completionHandler(disposition, credential); + } +} + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task + needNewBodyStream:(void (^)(NSInputStream *bodyStream))completionHandler +{ + NSInputStream *inputStream = nil; + + if (self.taskNeedNewBodyStream) { + inputStream = self.taskNeedNewBodyStream(session, task); + } else if (task.originalRequest.HTTPBodyStream && [task.originalRequest.HTTPBodyStream conformsToProtocol:@protocol(NSCopying)]) { + inputStream = [task.originalRequest.HTTPBodyStream copy]; + } + + if (completionHandler) { + completionHandler(inputStream); + } +} + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task + didSendBodyData:(int64_t)bytesSent + totalBytesSent:(int64_t)totalBytesSent +totalBytesExpectedToSend:(int64_t)totalBytesExpectedToSend +{ + + int64_t totalUnitCount = totalBytesExpectedToSend; + if(totalUnitCount == NSURLSessionTransferSizeUnknown) { + NSString *contentLength = [task.originalRequest valueForHTTPHeaderField:@"Content-Length"]; + if(contentLength) { + totalUnitCount = (int64_t) [contentLength longLongValue]; + } + } + + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; + [delegate URLSession:session task:task didSendBodyData:bytesSent totalBytesSent:totalBytesSent totalBytesExpectedToSend:totalUnitCount]; + + if (self.taskDidSendBodyData) { + self.taskDidSendBodyData(session, task, bytesSent, totalBytesSent, totalUnitCount); + } +} + +- (void)URLSession:(NSURLSession *)session + task:(NSURLSessionTask *)task +didCompleteWithError:(NSError *)error +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:task]; + + // delegate may be nil when completing a task in the background + if (delegate) { + [delegate URLSession:session task:task didCompleteWithError:error]; + + [self removeDelegateForTask:task]; + } + + if (self.taskDidComplete) { + self.taskDidComplete(session, task, error); + } + +} + +#pragma mark - NSURLSessionDataDelegate + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask +didReceiveResponse:(NSURLResponse *)response + completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler +{ + NSURLSessionResponseDisposition disposition = NSURLSessionResponseAllow; + + if (self.dataTaskDidReceiveResponse) { + disposition = self.dataTaskDidReceiveResponse(session, dataTask, response); + } + + if (completionHandler) { + completionHandler(disposition); + } +} + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask +didBecomeDownloadTask:(NSURLSessionDownloadTask *)downloadTask +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; + if (delegate) { + [self removeDelegateForTask:dataTask]; + [self setDelegate:delegate forTask:downloadTask]; + } + + if (self.dataTaskDidBecomeDownloadTask) { + self.dataTaskDidBecomeDownloadTask(session, dataTask, downloadTask); + } +} + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + didReceiveData:(NSData *)data +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:dataTask]; + [delegate URLSession:session dataTask:dataTask didReceiveData:data]; + + if (self.dataTaskDidReceiveData) { + self.dataTaskDidReceiveData(session, dataTask, data); + } +} + +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask + willCacheResponse:(NSCachedURLResponse *)proposedResponse + completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler +{ + NSCachedURLResponse *cachedResponse = proposedResponse; + + if (self.dataTaskWillCacheResponse) { + cachedResponse = self.dataTaskWillCacheResponse(session, dataTask, proposedResponse); + } + + if (completionHandler) { + completionHandler(cachedResponse); + } +} + +- (void)URLSessionDidFinishEventsForBackgroundURLSession:(NSURLSession *)session { + if (self.didFinishEventsForBackgroundURLSession) { + dispatch_async(dispatch_get_main_queue(), ^{ + self.didFinishEventsForBackgroundURLSession(session); + }); + } +} + +#pragma mark - NSURLSessionDownloadDelegate + +- (void)URLSession:(NSURLSession *)session + downloadTask:(NSURLSessionDownloadTask *)downloadTask +didFinishDownloadingToURL:(NSURL *)location +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; + if (self.downloadTaskDidFinishDownloading) { + NSURL *fileURL = self.downloadTaskDidFinishDownloading(session, downloadTask, location); + if (fileURL) { + delegate.downloadFileURL = fileURL; + NSError *error = nil; + [[NSFileManager defaultManager] moveItemAtURL:location toURL:fileURL error:&error]; + if (error) { + [[NSNotificationCenter defaultCenter] postNotificationName:AFURLSessionDownloadTaskDidFailToMoveFileNotification object:downloadTask userInfo:error.userInfo]; + } + + return; + } + } + + if (delegate) { + [delegate URLSession:session downloadTask:downloadTask didFinishDownloadingToURL:location]; + } +} + +- (void)URLSession:(NSURLSession *)session + downloadTask:(NSURLSessionDownloadTask *)downloadTask + didWriteData:(int64_t)bytesWritten + totalBytesWritten:(int64_t)totalBytesWritten +totalBytesExpectedToWrite:(int64_t)totalBytesExpectedToWrite +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; + [delegate URLSession:session downloadTask:downloadTask didWriteData:bytesWritten totalBytesWritten:totalBytesWritten totalBytesExpectedToWrite:totalBytesExpectedToWrite]; + + if (self.downloadTaskDidWriteData) { + self.downloadTaskDidWriteData(session, downloadTask, bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } +} + +- (void)URLSession:(NSURLSession *)session + downloadTask:(NSURLSessionDownloadTask *)downloadTask + didResumeAtOffset:(int64_t)fileOffset +expectedTotalBytes:(int64_t)expectedTotalBytes +{ + AFURLSessionManagerTaskDelegate *delegate = [self delegateForTask:downloadTask]; + [delegate URLSession:session downloadTask:downloadTask didResumeAtOffset:fileOffset expectedTotalBytes:expectedTotalBytes]; + + if (self.downloadTaskDidResume) { + self.downloadTaskDidResume(session, downloadTask, fileOffset, expectedTotalBytes); + } +} + +#pragma mark - NSSecureCoding + ++ (BOOL)supportsSecureCoding { + return YES; +} + +- (id)initWithCoder:(NSCoder *)decoder { + NSURLSessionConfiguration *configuration = [decoder decodeObjectOfClass:[NSURLSessionConfiguration class] forKey:@"sessionConfiguration"]; + + self = [self initWithSessionConfiguration:configuration]; + if (!self) { + return nil; + } + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + [coder encodeObject:self.session.configuration forKey:@"sessionConfiguration"]; +} + +#pragma mark - NSCopying + +- (id)copyWithZone:(NSZone *)zone { + return [[[self class] allocWithZone:zone] initWithSessionConfiguration:self.session.configuration]; +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/LICENSE b/iOSStudy/iOSStudy/Pods/AFNetworking/LICENSE new file mode 100644 index 0000000..22508e7 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/README.md b/iOSStudy/iOSStudy/Pods/AFNetworking/README.md new file mode 100644 index 0000000..74104f0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/README.md @@ -0,0 +1,387 @@ +

+ AFNetworking +

+ +[![Build Status](https://travis-ci.org/AFNetworking/AFNetworking.svg)](https://travis-ci.org/AFNetworking/AFNetworking) + +AFNetworking is a delightful networking library for iOS and Mac OS X. It's built on top of the [Foundation URL Loading System](http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/URLLoadingSystem/URLLoadingSystem.html), extending the powerful high-level networking abstractions built into Cocoa. It has a modular architecture with well-designed, feature-rich APIs that are a joy to use. + +Perhaps the most important feature of all, however, is the amazing community of developers who use and contribute to AFNetworking every day. AFNetworking powers some of the most popular and critically-acclaimed apps on the iPhone, iPad, and Mac. + +Choose AFNetworking for your next project, or migrate over your existing projects—you'll be happy you did! + +## How To Get Started + +- [Download AFNetworking](https://github.com/AFNetworking/AFNetworking/archive/master.zip) and try out the included Mac and iPhone example apps +- Read the ["Getting Started" guide](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking), [FAQ](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-FAQ), or [other articles on the Wiki](https://github.com/AFNetworking/AFNetworking/wiki) +- Check out the [documentation](http://cocoadocs.org/docsets/AFNetworking/) for a comprehensive look at all of the APIs available in AFNetworking +- Read the [AFNetworking 2.0 Migration Guide](https://github.com/AFNetworking/AFNetworking/wiki/AFNetworking-2.0-Migration-Guide) for an overview of the architectural changes from 1.0. + +## Communication + +- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). (Tag 'afnetworking') +- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/afnetworking). +- If you **found a bug**, _and can provide steps to reliably reproduce it_, open an issue. +- If you **have a feature request**, open an issue. +- If you **want to contribute**, submit a pull request. + +### Installation with CocoaPods + +[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like AFNetworking in your projects. See the ["Getting Started" guide for more information](https://github.com/AFNetworking/AFNetworking/wiki/Getting-Started-with-AFNetworking). + +#### Podfile + +```ruby +platform :ios, '7.0' +pod "AFNetworking", "~> 2.0" +``` + +## Requirements + +| AFNetworking Version | Minimum iOS Target | Minimum OS X Target | Notes | +|:--------------------:|:---------------------------:|:----------------------------:|:-------------------------------------------------------------------------:| +| 2.x | iOS 6 | OS X 10.8 | Xcode 5 is required. `NSURLSession` subspec requires iOS 7 or OS X 10.9. | +| [1.x](https://github.com/AFNetworking/AFNetworking/tree/1.x) | iOS 5 | Mac OS X 10.7 | | +| [0.10.x](https://github.com/AFNetworking/AFNetworking/tree/0.10.x) | iOS 4 | Mac OS X 10.6 | | + +(OS X projects must support [64-bit with modern Cocoa runtime](https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjCRuntimeGuide/Articles/ocrtVersionsPlatforms.html)). + +> Programming in Swift? Try [Alamofire](https://github.com/Alamofire/Alamofire) for a more conventional set of APIs. + +## Architecture + +### NSURLConnection + +- `AFURLConnectionOperation` +- `AFHTTPRequestOperation` +- `AFHTTPRequestOperationManager` + +### NSURLSession _(iOS 7 / Mac OS X 10.9)_ + +- `AFURLSessionManager` +- `AFHTTPSessionManager` + +### Serialization + +* `` + - `AFHTTPRequestSerializer` + - `AFJSONRequestSerializer` + - `AFPropertyListRequestSerializer` +* `` + - `AFHTTPResponseSerializer` + - `AFJSONResponseSerializer` + - `AFXMLParserResponseSerializer` + - `AFXMLDocumentResponseSerializer` _(Mac OS X)_ + - `AFPropertyListResponseSerializer` + - `AFImageResponseSerializer` + - `AFCompoundResponseSerializer` + +### Additional Functionality + +- `AFSecurityPolicy` +- `AFNetworkReachabilityManager` + +## Usage + +### HTTP Request Operation Manager + +`AFHTTPRequestOperationManager` encapsulates the common patterns of communicating with a web application over HTTP, including request creation, response serialization, network reachability monitoring, and security, as well as request operation management. + +#### `GET` Request + +```objective-c +AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; +[manager GET:@"http://example.com/resources.json" parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"JSON: %@", responseObject); +} failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); +}]; +``` + +#### `POST` URL-Form-Encoded Request + +```objective-c +AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; +NSDictionary *parameters = @{@"foo": @"bar"}; +[manager POST:@"http://example.com/resources.json" parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"JSON: %@", responseObject); +} failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); +}]; +``` + +#### `POST` Multi-Part Request + +```objective-c +AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; +NSDictionary *parameters = @{@"foo": @"bar"}; +NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; +[manager POST:@"http://example.com/resources.json" parameters:parameters constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileURL:filePath name:@"image" error:nil]; +} success:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"Success: %@", responseObject); +} failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); +}]; +``` + +--- + +### AFURLSessionManager + +`AFURLSessionManager` creates and manages an `NSURLSession` object based on a specified `NSURLSessionConfiguration` object, which conforms to ``, ``, ``, and ``. + +#### Creating a Download Task + +```objective-c +NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; +AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; + +NSURL *URL = [NSURL URLWithString:@"http://example.com/download.zip"]; +NSURLRequest *request = [NSURLRequest requestWithURL:URL]; + +NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:nil destination:^NSURL *(NSURL *targetPath, NSURLResponse *response) { + NSURL *documentsDirectoryURL = [[NSFileManager defaultManager] URLForDirectory:NSDocumentDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil]; + return [documentsDirectoryURL URLByAppendingPathComponent:[response suggestedFilename]]; +} completionHandler:^(NSURLResponse *response, NSURL *filePath, NSError *error) { + NSLog(@"File downloaded to: %@", filePath); +}]; +[downloadTask resume]; +``` + +#### Creating an Upload Task + +```objective-c +NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; +AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; + +NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; +NSURLRequest *request = [NSURLRequest requestWithURL:URL]; + +NSURL *filePath = [NSURL fileURLWithPath:@"file://path/to/image.png"]; +NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithRequest:request fromFile:filePath progress:nil completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + if (error) { + NSLog(@"Error: %@", error); + } else { + NSLog(@"Success: %@ %@", response, responseObject); + } +}]; +[uploadTask resume]; +``` + +#### Creating an Upload Task for a Multi-Part Request, with Progress + +```objective-c +NSMutableURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileURL:[NSURL fileURLWithPath:@"file://path/to/image.jpg"] name:@"file" fileName:@"filename.jpg" mimeType:@"image/jpeg" error:nil]; + } error:nil]; + +AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]]; +NSProgress *progress = nil; + +NSURLSessionUploadTask *uploadTask = [manager uploadTaskWithStreamedRequest:request progress:&progress completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + if (error) { + NSLog(@"Error: %@", error); + } else { + NSLog(@"%@ %@", response, responseObject); + } +}]; + +[uploadTask resume]; +``` + +#### Creating a Data Task + +```objective-c +NSURLSessionConfiguration *configuration = [NSURLSessionConfiguration defaultSessionConfiguration]; +AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:configuration]; + +NSURL *URL = [NSURL URLWithString:@"http://example.com/upload"]; +NSURLRequest *request = [NSURLRequest requestWithURL:URL]; + +NSURLSessionDataTask *dataTask = [manager dataTaskWithRequest:request completionHandler:^(NSURLResponse *response, id responseObject, NSError *error) { + if (error) { + NSLog(@"Error: %@", error); + } else { + NSLog(@"%@ %@", response, responseObject); + } +}]; +[dataTask resume]; +``` + +--- + +### Request Serialization + +Request serializers create requests from URL strings, encoding parameters as either a query string or HTTP body. + +```objective-c +NSString *URLString = @"http://example.com"; +NSDictionary *parameters = @{@"foo": @"bar", @"baz": @[@1, @2, @3]}; +``` + +#### Query String Parameter Encoding + +```objective-c +[[AFHTTPRequestSerializer serializer] requestWithMethod:@"GET" URLString:URLString parameters:parameters error:nil]; +``` + + GET http://example.com?foo=bar&baz[]=1&baz[]=2&baz[]=3 + +#### URL Form Parameter Encoding + +```objective-c +[[AFHTTPRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters]; +``` + + POST http://example.com/ + Content-Type: application/x-www-form-urlencoded + + foo=bar&baz[]=1&baz[]=2&baz[]=3 + +#### JSON Parameter Encoding + +```objective-c +[[AFJSONRequestSerializer serializer] requestWithMethod:@"POST" URLString:URLString parameters:parameters]; +``` + + POST http://example.com/ + Content-Type: application/json + + {"foo": "bar", "baz": [1,2,3]} + +--- + +### Network Reachability Manager + +`AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. + +**Network reachability is a diagnostic tool that can be used to understand why a request might have failed. It should not be used to determine whether or not to make a request.** + +#### Shared Network Reachability + +```objective-c +[[AFNetworkReachabilityManager sharedManager] setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + NSLog(@"Reachability: %@", AFStringFromNetworkReachabilityStatus(status)); +}]; +``` + +#### HTTP Manager Reachability + +```objective-c +NSURL *baseURL = [NSURL URLWithString:@"http://example.com/"]; +AFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc] initWithBaseURL:baseURL]; + +NSOperationQueue *operationQueue = manager.operationQueue; +[manager.reachabilityManager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) { + switch (status) { + case AFNetworkReachabilityStatusReachableViaWWAN: + case AFNetworkReachabilityStatusReachableViaWiFi: + [operationQueue setSuspended:NO]; + break; + case AFNetworkReachabilityStatusNotReachable: + default: + [operationQueue setSuspended:YES]; + break; + } +}]; + +[manager.reachabilityManager startMonitoring]; +``` + +--- + +### Security Policy + +`AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. + +Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. + +#### Allowing Invalid SSL Certificates + +```objective-c +AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; +manager.securityPolicy.allowInvalidCertificates = YES; // not recommended for production +``` + +--- + +### AFHTTPRequestOperation + +`AFHTTPRequestOperation` is a subclass of `AFURLConnectionOperation` for requests using the HTTP or HTTPS protocols. It encapsulates the concept of acceptable status codes and content types, which determine the success or failure of a request. + +Although `AFHTTPRequestOperationManager` is usually the best way to go about making requests, `AFHTTPRequestOperation` can be used by itself. + +#### `GET` with `AFHTTPRequestOperation` + +```objective-c +NSURL *URL = [NSURL URLWithString:@"http://example.com/resources/123.json"]; +NSURLRequest *request = [NSURLRequest requestWithURL:URL]; +AFHTTPRequestOperation *op = [[AFHTTPRequestOperation alloc] initWithRequest:request]; +op.responseSerializer = [AFJSONResponseSerializer serializer]; +[op setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + NSLog(@"JSON: %@", responseObject); +} failure:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); +}]; +[[NSOperationQueue mainQueue] addOperation:op]; +``` + +#### Batch of Operations + +```objective-c +NSMutableArray *mutableOperations = [NSMutableArray array]; +for (NSURL *fileURL in filesToUpload) { + NSURLRequest *request = [[AFHTTPRequestSerializer serializer] multipartFormRequestWithMethod:@"POST" URLString:@"http://example.com/upload" parameters:nil constructingBodyWithBlock:^(id formData) { + [formData appendPartWithFileURL:fileURL name:@"images[]" error:nil]; + }]; + + AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; + + [mutableOperations addObject:operation]; +} + +NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:@[...] progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) { + NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations); +} completionBlock:^(NSArray *operations) { + NSLog(@"All operations in batch complete"); +}]; +[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO]; +``` + +## Unit Tests + +AFNetworking includes a suite of unit tests within the Tests subdirectory. In order to run the unit tests, you must install the testing dependencies via [CocoaPods](http://cocoapods.org/): + + $ cd Tests + $ pod install + +Once testing dependencies are installed, you can execute the test suite via the 'iOS Tests' and 'OS X Tests' schemes within Xcode. + +### Running Tests from the Command Line + +Tests can also be run from the command line or within a continuous integration environment. The [`xcpretty`](https://github.com/mneorr/xcpretty) utility needs to be installed before running the tests from the command line: + + $ gem install xcpretty + +Once `xcpretty` is installed, you can execute the suite via `rake test`. + +## Credits + +AFNetworking was originally created by [Scott Raymond](https://github.com/sco/) and [Mattt Thompson](https://github.com/mattt/) in the development of [Gowalla for iPhone](http://en.wikipedia.org/wiki/Gowalla). + +AFNetworking's logo was designed by [Alan Defibaugh](http://www.alandefibaugh.com/). + +And most of all, thanks to AFNetworking's [growing list of contributors](https://github.com/AFNetworking/AFNetworking/contributors). + +## Contact + +Follow AFNetworking on Twitter ([@AFNetworking](https://twitter.com/AFNetworking)) + +### Maintainers + +- [Mattt Thompson](http://github.com/mattt) ([@mattt](https://twitter.com/mattt)) + +## License + +AFNetworking is available under the MIT license. See the LICENSE file for more info. diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h new file mode 100644 index 0000000..afebad3 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h @@ -0,0 +1,76 @@ +// AFNetworkActivityIndicatorManager.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +/** + `AFNetworkActivityIndicatorManager` manages the state of the network activity indicator in the status bar. When enabled, it will listen for notifications indicating that a network request operation has started or finished, and start or stop animating the indicator accordingly. The number of active requests is incremented and decremented much like a stack or a semaphore, and the activity indicator will animate so long as that number is greater than zero. + + You should enable the shared instance of `AFNetworkActivityIndicatorManager` when your application finishes launching. In `AppDelegate application:didFinishLaunchingWithOptions:` you can do so with the following code: + + [[AFNetworkActivityIndicatorManager sharedManager] setEnabled:YES]; + + By setting `enabled` to `YES` for `sharedManager`, the network activity indicator will show and hide automatically as requests start and finish. You should not ever need to call `incrementActivityCount` or `decrementActivityCount` yourself. + + See the Apple Human Interface Guidelines section about the Network Activity Indicator for more information: + http://developer.apple.com/library/iOS/#documentation/UserExperience/Conceptual/MobileHIG/UIElementGuidelines/UIElementGuidelines.html#//apple_ref/doc/uid/TP40006556-CH13-SW44 + */ +@interface AFNetworkActivityIndicatorManager : NSObject + +/** + A Boolean value indicating whether the manager is enabled. + + If YES, the manager will change status bar network activity indicator according to network operation notifications it receives. The default value is NO. + */ +@property (nonatomic, assign, getter = isEnabled) BOOL enabled; + +/** + A Boolean value indicating whether the network activity indicator is currently displayed in the status bar. + */ +@property (readonly, nonatomic, assign) BOOL isNetworkActivityIndicatorVisible; + +/** + Returns the shared network activity indicator manager object for the system. + + @return The systemwide network activity indicator manager. + */ ++ (instancetype)sharedManager; + +/** + Increments the number of active network requests. If this number was zero before incrementing, this will start animating the status bar network activity indicator. + */ +- (void)incrementActivityCount; + +/** + Decrements the number of active network requests. If this number becomes zero after decrementing, this will stop animating the status bar network activity indicator. + */ +- (void)decrementActivityCount; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m new file mode 100644 index 0000000..5c6d4fa --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m @@ -0,0 +1,171 @@ +// AFNetworkActivityIndicatorManager.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "AFNetworkActivityIndicatorManager.h" + +#if defined(__IPHONE_OS_VERSION_MAX_ALLOWED) + +#import "AFHTTPRequestOperation.h" + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 +#import "AFURLSessionManager.h" +#endif + +static NSTimeInterval const kAFNetworkActivityIndicatorInvisibilityDelay = 0.17; + +static NSURLRequest * AFNetworkRequestFromNotification(NSNotification *notification) { + if ([[notification object] isKindOfClass:[AFURLConnectionOperation class]]) { + return [(AFURLConnectionOperation *)[notification object] request]; + } + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + if ([[notification object] respondsToSelector:@selector(originalRequest)]) { + return [(NSURLSessionTask *)[notification object] originalRequest]; + } +#endif + + return nil; +} + +@interface AFNetworkActivityIndicatorManager () +@property (readwrite, nonatomic, assign) NSInteger activityCount; +@property (readwrite, nonatomic, strong) NSTimer *activityIndicatorVisibilityTimer; +@property (readonly, nonatomic, getter = isNetworkActivityIndicatorVisible) BOOL networkActivityIndicatorVisible; + +- (void)updateNetworkActivityIndicatorVisibility; +- (void)updateNetworkActivityIndicatorVisibilityDelayed; +@end + +@implementation AFNetworkActivityIndicatorManager +@dynamic networkActivityIndicatorVisible; + ++ (instancetype)sharedManager { + static AFNetworkActivityIndicatorManager *_sharedManager = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + _sharedManager = [[self alloc] init]; + }); + + return _sharedManager; +} + ++ (NSSet *)keyPathsForValuesAffectingIsNetworkActivityIndicatorVisible { + return [NSSet setWithObject:@"activityCount"]; +} + +- (id)init { + self = [super init]; + if (!self) { + return nil; + } + + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingOperationDidStartNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingOperationDidFinishNotification object:nil]; + +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 70000 + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidStart:) name:AFNetworkingTaskDidResumeNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidSuspendNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(networkRequestDidFinish:) name:AFNetworkingTaskDidCompleteNotification object:nil]; +#endif + + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + + [_activityIndicatorVisibilityTimer invalidate]; +} + +- (void)updateNetworkActivityIndicatorVisibilityDelayed { + if (self.enabled) { + // Delay hiding of activity indicator for a short interval, to avoid flickering + if (![self isNetworkActivityIndicatorVisible]) { + [self.activityIndicatorVisibilityTimer invalidate]; + self.activityIndicatorVisibilityTimer = [NSTimer timerWithTimeInterval:kAFNetworkActivityIndicatorInvisibilityDelay target:self selector:@selector(updateNetworkActivityIndicatorVisibility) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.activityIndicatorVisibilityTimer forMode:NSRunLoopCommonModes]; + } else { + [self performSelectorOnMainThread:@selector(updateNetworkActivityIndicatorVisibility) withObject:nil waitUntilDone:NO modes:@[NSRunLoopCommonModes]]; + } + } +} + +- (BOOL)isNetworkActivityIndicatorVisible { + return self.activityCount > 0; +} + +- (void)updateNetworkActivityIndicatorVisibility { + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:[self isNetworkActivityIndicatorVisible]]; +} + +- (void)setActivityCount:(NSInteger)activityCount { + @synchronized(self) { + _activityCount = activityCount; + } + + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateNetworkActivityIndicatorVisibilityDelayed]; + }); +} + +- (void)incrementActivityCount { + [self willChangeValueForKey:@"activityCount"]; + @synchronized(self) { + _activityCount++; + } + [self didChangeValueForKey:@"activityCount"]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateNetworkActivityIndicatorVisibilityDelayed]; + }); +} + +- (void)decrementActivityCount { + [self willChangeValueForKey:@"activityCount"]; + @synchronized(self) { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + _activityCount = MAX(_activityCount - 1, 0); +#pragma clang diagnostic pop + } + [self didChangeValueForKey:@"activityCount"]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self updateNetworkActivityIndicatorVisibilityDelayed]; + }); +} + +- (void)networkRequestDidStart:(NSNotification *)notification { + if ([AFNetworkRequestFromNotification(notification) URL]) { + [self incrementActivityCount]; + } +} + +- (void)networkRequestDidFinish:(NSNotification *)notification { + if ([AFNetworkRequestFromNotification(notification) URL]) { + [self decrementActivityCount]; + } +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h new file mode 100644 index 0000000..cbefccd --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h @@ -0,0 +1,64 @@ +// UIActivityIndicatorView+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@class AFURLConnectionOperation; + +/** + This category adds methods to the UIKit framework's `UIActivityIndicatorView` class. The methods in this category provide support for automatically starting and stopping animation depending on the loading state of a request operation or session task. + */ +@interface UIActivityIndicatorView (AFNetworking) + +///---------------------------------- +/// @name Animating for Session Tasks +///---------------------------------- + +/** + Binds the animating state to the state of the specified task. + + @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task; +#endif + +///--------------------------------------- +/// @name Animating for Request Operations +///--------------------------------------- + +/** + Binds the animating state to the execution state of the specified operation. + + @param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled. + */ +- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m new file mode 100644 index 0000000..c981314 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m @@ -0,0 +1,97 @@ +// UIActivityIndicatorView+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIActivityIndicatorView+AFNetworking.h" + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFHTTPRequestOperation.h" + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +#import "AFURLSessionManager.h" +#endif + +@implementation UIActivityIndicatorView (AFNetworking) + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setAnimatingWithStateOfTask:(NSURLSessionTask *)task { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; + + if (task) { + if (task.state != NSURLSessionTaskStateCompleted) { + if (task.state == NSURLSessionTaskStateRunning) { + [self startAnimating]; + } else { + [self stopAnimating]; + } + + [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingTaskDidResumeNotification object:task]; + [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidCompleteNotification object:task]; + [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingTaskDidSuspendNotification object:task]; + } + } +} +#endif + +#pragma mark - + +- (void)setAnimatingWithStateOfOperation:(AFURLConnectionOperation *)operation { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil]; + + if (operation) { + if (![operation isFinished]) { + if ([operation isExecuting]) { + [self startAnimating]; + } else { + [self stopAnimating]; + } + + [notificationCenter addObserver:self selector:@selector(af_startAnimating) name:AFNetworkingOperationDidStartNotification object:operation]; + [notificationCenter addObserver:self selector:@selector(af_stopAnimating) name:AFNetworkingOperationDidFinishNotification object:operation]; + } + } +} + +#pragma mark - + +- (void)af_startAnimating { + dispatch_async(dispatch_get_main_queue(), ^{ + [self startAnimating]; + }); +} + +- (void)af_stopAnimating { + dispatch_async(dispatch_get_main_queue(), ^{ + [self stopAnimating]; + }); +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h new file mode 100644 index 0000000..3cc1694 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h @@ -0,0 +1,96 @@ +// UIAlertView+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@class AFURLConnectionOperation; + +/** + This category adds methods to the UIKit framework's `UIAlertView` class. The methods in this category provide support for automatically showing an alert if a session task or request operation finishes with an error. Alert title and message are filled from the corresponding `localizedDescription` & `localizedRecoverySuggestion` or `localizedFailureReason` of the error. + */ +@interface UIAlertView (AFNetworking) + +///------------------------------------- +/// @name Showing Alert for Session Task +///------------------------------------- + +/** + Shows an alert view with the error of the specified session task, if any. + + @param task The session task. + @param delegate The alert view delegate. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 ++ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task + delegate:(id)delegate; +#endif + +/** + Shows an alert view with the error of the specified session task, if any, with a custom cancel button title and other button titles. + + @param task The session task. + @param delegate The alert view delegate. + @param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title. + @param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 ++ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task + delegate:(id)delegate + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; +#endif + +///------------------------------------------ +/// @name Showing Alert for Request Operation +///------------------------------------------ + +/** + Shows an alert view with the error of the specified request operation, if any. + + @param operation The request operation. + @param delegate The alert view delegate. + */ ++ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation + delegate:(id)delegate; + +/** + Shows an alert view with the error of the specified request operation, if any, with a custom cancel button title and other button titles. + + @param operation The request operation. + @param delegate The alert view delegate. + @param cancelButtonTitle The title of the cancel button or nil if there is no cancel button. Using this argument is equivalent to setting the cancel button index to the value returned by invoking addButtonWithTitle: specifying this title. + @param otherButtonTitles The title of another button. Using this argument is equivalent to invoking addButtonWithTitle: with this title to add more buttons. Too many buttons can cause the alert view to scroll. For guidelines on the best ways to use an alert in an app, see "Temporary Views". Titles of additional buttons to add to the receiver, terminated with `nil`. + */ ++ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation + delegate:(id)delegate + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m new file mode 100644 index 0000000..bb4eabc --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.m @@ -0,0 +1,129 @@ +// UIAlertView+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIAlertView+AFNetworking.h" + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFURLConnectionOperation.h" + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +#import "AFURLSessionManager.h" +#endif + +static void AFGetAlertViewTitleAndMessageFromError(NSError *error, NSString * __autoreleasing *title, NSString * __autoreleasing *message) { + if (error.localizedDescription && (error.localizedRecoverySuggestion || error.localizedFailureReason)) { + *title = error.localizedDescription; + + if (error.localizedRecoverySuggestion) { + *message = error.localizedRecoverySuggestion; + } else { + *message = error.localizedFailureReason; + } + } else if (error.localizedDescription) { + *title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description"); + *message = error.localizedDescription; + } else { + *title = NSLocalizedStringFromTable(@"Error", @"AFNetworking", @"Fallback Error Description"); + *message = [NSString stringWithFormat:NSLocalizedStringFromTable(@"%@ Error: %ld", @"AFNetworking", @"Fallback Error Failure Reason Format"), error.domain, (long)error.code]; + } +} + +@implementation UIAlertView (AFNetworking) + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 ++ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task + delegate:(id)delegate +{ + [self showAlertViewForTaskWithErrorOnCompletion:task delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil]; +} + ++ (void)showAlertViewForTaskWithErrorOnCompletion:(NSURLSessionTask *)task + delegate:(id)delegate + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION +{ + va_list otherTitleList; + va_start(otherTitleList, otherButtonTitles); + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; + for(NSString *otherTitle = otherButtonTitles; otherTitle != nil; otherTitle = va_arg(otherTitleList, NSString *)){ + [alertView addButtonWithTitle:otherTitle]; + } + va_end(otherTitleList); + __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingTaskDidCompleteNotification object:task queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { + + NSError *error = notification.userInfo[AFNetworkingTaskDidCompleteErrorKey]; + if (error) { + NSString *title, *message; + AFGetAlertViewTitleAndMessageFromError(error, &title, &message); + + [alertView setTitle:title]; + [alertView setMessage:message]; + [alertView show]; + } + + [[NSNotificationCenter defaultCenter] removeObserver:observer name:AFNetworkingTaskDidCompleteNotification object:notification.object]; + }]; +} +#endif + +#pragma mark - + ++ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation + delegate:(id)delegate +{ + [self showAlertViewForRequestOperationWithErrorOnCompletion:operation delegate:delegate cancelButtonTitle:NSLocalizedStringFromTable(@"Dismiss", @"AFNetworking", @"UIAlertView Cancel Button Title") otherButtonTitles:nil, nil]; +} + ++ (void)showAlertViewForRequestOperationWithErrorOnCompletion:(AFURLConnectionOperation *)operation + delegate:(id)delegate + cancelButtonTitle:(NSString *)cancelButtonTitle + otherButtonTitles:(NSString *)otherButtonTitles, ... NS_REQUIRES_NIL_TERMINATION +{ + va_list otherTitleList; + va_start(otherTitleList, otherButtonTitles); + UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:nil message:nil delegate:delegate cancelButtonTitle:cancelButtonTitle otherButtonTitles:nil, nil]; + for(NSString *otherTitle = otherButtonTitles; otherTitle != nil; otherTitle = va_arg(otherTitleList, NSString *)){ + [alertView addButtonWithTitle:otherTitle]; + } + va_end(otherTitleList); + __block id observer = [[NSNotificationCenter defaultCenter] addObserverForName:AFNetworkingOperationDidFinishNotification object:operation queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *notification) { + + if (notification.object && [notification.object isKindOfClass:[AFURLConnectionOperation class]]) { + NSError *error = [(AFURLConnectionOperation *)notification.object error]; + if (error) { + NSString *title, *message; + AFGetAlertViewTitleAndMessageFromError(error, &title, &message); + + [alertView setTitle:title]; + [alertView setMessage:message]; + [alertView show]; + } + } + + [[NSNotificationCenter defaultCenter] removeObserver:observer name:AFNetworkingOperationDidFinishNotification object:notification.object]; + }]; +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h new file mode 100644 index 0000000..af8ff82 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h @@ -0,0 +1,181 @@ +// UIButton+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@protocol AFURLResponseSerialization, AFImageCache; + +/** + This category adds methods to the UIKit framework's `UIButton` class. The methods in this category provide support for loading remote images and background images asynchronously from a URL. + + @warning Compound values for control `state` (such as `UIControlStateHighlighted | UIControlStateDisabled`) are unsupported. + */ +@interface UIButton (AFNetworking) + +///---------------------------- +/// @name Accessing Image Cache +///---------------------------- + +/** + The image cache used to improve image loadiing performance on scroll views. By default, `UIButton` will use the `sharedImageCache` of `UIImageView`. + */ ++ (id )sharedImageCache; + +/** + Set the cache used for image loading. + + @param imageCache The image cache. + */ ++ (void)setSharedImageCache:(id )imageCache; + +///------------------------------------ +/// @name Accessing Response Serializer +///------------------------------------ + +/** + The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`. + + @discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer + */ +@property (nonatomic, strong) id imageResponseSerializer; + +///-------------------- +/// @name Setting Image +///-------------------- + +/** + Asynchronously downloads an image from the specified URL, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + @param state The control state. + @param url The URL used for the image request. + */ +- (void)setImageForState:(UIControlState)state + withURL:(NSURL *)url; + +/** + Asynchronously downloads an image from the specified URL, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + @param state The control state. + @param url The URL used for the image request. + @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes. + */ +- (void)setImageForState:(UIControlState)state + withURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage; + +/** + Asynchronously downloads an image from the specified URL request, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + If a success block is specified, it is the responsibility of the block to set the image of the button before returning. If no success block is specified, the default behavior of setting the image with `setImage:forState:` is applied. + + @param state The control state. + @param urlRequest The URL request used for the image request. + @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the button will not change its image until the image request finishes. + @param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes two arguments: the server response and the image. If the image was returned from cache, the request and response parameters will be `nil`. + @param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes a single argument: the error that occurred. + */ +- (void)setImageForState:(UIControlState)state + withURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSError *error))failure; + + +///------------------------------- +/// @name Setting Background Image +///------------------------------- + +/** + Asynchronously downloads an image from the specified URL, and sets it as the background image for the specified state once the request is finished. Any previous background image request for the receiver will be cancelled. + + If the background image is cached locally, the background image is set immediately, otherwise the specified placeholder background image will be set immediately, and then the remote background image will be set once the request is finished. + + @param state The control state. + @param url The URL used for the background image request. + */ +- (void)setBackgroundImageForState:(UIControlState)state + withURL:(NSURL *)url; + +/** + Asynchronously downloads an image from the specified URL, and sets it as the background image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + @param state The control state. + @param url The URL used for the background image request. + @param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes. + */ +- (void)setBackgroundImageForState:(UIControlState)state + withURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage; + +/** + Asynchronously downloads an image from the specified URL request, and sets it as the image for the specified state once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + If a success block is specified, it is the responsibility of the block to set the image of the button before returning. If no success block is specified, the default behavior of setting the image with `setBackgroundImage:forState:` is applied. + + @param state The control state. + @param urlRequest The URL request used for the image request. + @param placeholderImage The background image to be set initially, until the background image request finishes. If `nil`, the button will not change its background image until the background image request finishes. + */ +- (void)setBackgroundImageForState:(UIControlState)state + withURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSError *error))failure; + + +///------------------------------ +/// @name Canceling Image Loading +///------------------------------ + +/** + Cancels any executing image operation for the specified control state of the receiver, if one exists. + + @param state The control state. + */ +- (void)cancelImageRequestOperationForState:(UIControlState)state; + +/** + Cancels any executing background image operation for the specified control state of the receiver, if one exists. + + @param state The control state. + */ +- (void)cancelBackgroundImageRequestOperationForState:(UIControlState)state; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m new file mode 100644 index 0000000..d7a0a1b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.m @@ -0,0 +1,294 @@ +// UIButton+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIButton+AFNetworking.h" + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFURLResponseSerialization.h" +#import "AFHTTPRequestOperation.h" + +#import "UIImageView+AFNetworking.h" + +@interface UIButton (_AFNetworking) +@end + +@implementation UIButton (_AFNetworking) + ++ (NSOperationQueue *)af_sharedImageRequestOperationQueue { + static NSOperationQueue *_af_sharedImageRequestOperationQueue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_sharedImageRequestOperationQueue = [[NSOperationQueue alloc] init]; + _af_sharedImageRequestOperationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; + }); + + return _af_sharedImageRequestOperationQueue; +} + +#pragma mark - + +static char AFImageRequestOperationNormal; +static char AFImageRequestOperationHighlighted; +static char AFImageRequestOperationSelected; +static char AFImageRequestOperationDisabled; + +static const char * af_imageRequestOperationKeyForState(UIControlState state) { + switch (state) { + case UIControlStateHighlighted: + return &AFImageRequestOperationHighlighted; + case UIControlStateSelected: + return &AFImageRequestOperationSelected; + case UIControlStateDisabled: + return &AFImageRequestOperationDisabled; + case UIControlStateNormal: + default: + return &AFImageRequestOperationNormal; + } +} + +- (AFHTTPRequestOperation *)af_imageRequestOperationForState:(UIControlState)state { + return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, af_imageRequestOperationKeyForState(state)); +} + +- (void)af_setImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation + forState:(UIControlState)state +{ + objc_setAssociatedObject(self, af_imageRequestOperationKeyForState(state), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +static char AFBackgroundImageRequestOperationNormal; +static char AFBackgroundImageRequestOperationHighlighted; +static char AFBackgroundImageRequestOperationSelected; +static char AFBackgroundImageRequestOperationDisabled; + +static const char * af_backgroundImageRequestOperationKeyForState(UIControlState state) { + switch (state) { + case UIControlStateHighlighted: + return &AFBackgroundImageRequestOperationHighlighted; + case UIControlStateSelected: + return &AFBackgroundImageRequestOperationSelected; + case UIControlStateDisabled: + return &AFBackgroundImageRequestOperationDisabled; + case UIControlStateNormal: + default: + return &AFBackgroundImageRequestOperationNormal; + } +} + +- (AFHTTPRequestOperation *)af_backgroundImageRequestOperationForState:(UIControlState)state { + return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, af_backgroundImageRequestOperationKeyForState(state)); +} + +- (void)af_setBackgroundImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation + forState:(UIControlState)state +{ + objc_setAssociatedObject(self, af_backgroundImageRequestOperationKeyForState(state), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +#pragma mark - + +@implementation UIButton (AFNetworking) + ++ (id )sharedImageCache { +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(sharedImageCache)) ?: [UIImageView sharedImageCache]; +#pragma clang diagnostic pop +} + ++ (void)setSharedImageCache:(id )imageCache { + objc_setAssociatedObject(self, @selector(sharedImageCache), imageCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +- (id )imageResponseSerializer { + static id _af_defaultImageResponseSerializer = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_defaultImageResponseSerializer = [AFImageResponseSerializer serializer]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(imageResponseSerializer)) ?: _af_defaultImageResponseSerializer; +#pragma clang diagnostic pop +} + +- (void)setImageResponseSerializer:(id )serializer { + objc_setAssociatedObject(self, @selector(imageResponseSerializer), serializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +- (void)setImageForState:(UIControlState)state + withURL:(NSURL *)url +{ + [self setImageForState:state withURL:url placeholderImage:nil]; +} + +- (void)setImageForState:(UIControlState)state + withURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage +{ + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; + + [self setImageForState:state withURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; +} + +- (void)setImageForState:(UIControlState)state + withURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSError *error))failure +{ + [self cancelImageRequestOperationForState:state]; + + UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest]; + if (cachedImage) { + if (success) { + success(nil, nil, cachedImage); + } else { + [self setImage:cachedImage forState:state]; + } + + [self af_setImageRequestOperation:nil forState:state]; + } else { + if (placeholderImage) { + [self setImage:placeholderImage forState:state]; + } + + __weak __typeof(self)weakSelf = self; + AFHTTPRequestOperation *imageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; + imageRequestOperation.responseSerializer = self.imageResponseSerializer; + [imageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + if ([[urlRequest URL] isEqual:[operation.request URL]]) { + if (success) { + success(operation.request, operation.response, responseObject); + } else if (responseObject) { + [strongSelf setImage:responseObject forState:state]; + } + } + [[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest]; + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + if ([[urlRequest URL] isEqual:[operation.request URL]]) { + if (failure) { + failure(error); + } + } + }]; + + [self af_setImageRequestOperation:imageRequestOperation forState:state]; + [[[self class] af_sharedImageRequestOperationQueue] addOperation:imageRequestOperation]; + } +} + +#pragma mark - + +- (void)setBackgroundImageForState:(UIControlState)state + withURL:(NSURL *)url +{ + [self setBackgroundImageForState:state withURL:url placeholderImage:nil]; +} + +- (void)setBackgroundImageForState:(UIControlState)state + withURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage +{ + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; + + [self setBackgroundImageForState:state withURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; +} + +- (void)setBackgroundImageForState:(UIControlState)state + withURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSError *error))failure +{ + [self cancelBackgroundImageRequestOperationForState:state]; + + UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest]; + if (cachedImage) { + if (success) { + success(nil, nil, cachedImage); + } else { + [self setBackgroundImage:cachedImage forState:state]; + } + + [self af_setBackgroundImageRequestOperation:nil forState:state]; + } else { + if (placeholderImage) { + [self setBackgroundImage:placeholderImage forState:state]; + } + + __weak __typeof(self)weakSelf = self; + AFHTTPRequestOperation *backgroundImageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; + backgroundImageRequestOperation.responseSerializer = self.imageResponseSerializer; + [backgroundImageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + if ([[urlRequest URL] isEqual:[operation.request URL]]) { + if (success) { + success(operation.request, operation.response, responseObject); + } else if (responseObject) { + [strongSelf setBackgroundImage:responseObject forState:state]; + } + } + [[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest]; + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + if ([[urlRequest URL] isEqual:[operation.request URL]]) { + if (failure) { + failure(error); + } + } + }]; + + [self af_setBackgroundImageRequestOperation:backgroundImageRequestOperation forState:state]; + [[[self class] af_sharedImageRequestOperationQueue] addOperation:backgroundImageRequestOperation]; + } +} + +#pragma mark - + +- (void)cancelImageRequestOperationForState:(UIControlState)state { + [[self af_imageRequestOperationForState:state] cancel]; + [self af_setImageRequestOperation:nil forState:state]; +} + +- (void)cancelBackgroundImageRequestOperationForState:(UIControlState)state { + [[self af_backgroundImageRequestOperationForState:state] cancel]; + [self af_setBackgroundImageRequestOperation:nil forState:state]; +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h new file mode 100644 index 0000000..5838b56 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h @@ -0,0 +1,143 @@ +// UIImageView+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@protocol AFURLResponseSerialization, AFImageCache; + +/** + This category adds methods to the UIKit framework's `UIImageView` class. The methods in this category provide support for loading remote images asynchronously from a URL. + */ +@interface UIImageView (AFNetworking) + +///---------------------------- +/// @name Accessing Image Cache +///---------------------------- + +/** + The image cache used to improve image loadiing performance on scroll views. By default, this is an `NSCache` subclass conforming to the `AFImageCache` protocol, which listens for notification warnings and evicts objects accordingly. +*/ ++ (id )sharedImageCache; + +/** + Set the cache used for image loading. + + @param imageCache The image cache. + */ ++ (void)setSharedImageCache:(id )imageCache; + +///------------------------------------ +/// @name Accessing Response Serializer +///------------------------------------ + +/** + The response serializer used to create an image representation from the server response and response data. By default, this is an instance of `AFImageResponseSerializer`. + + @discussion Subclasses of `AFImageResponseSerializer` could be used to perform post-processing, such as color correction, face detection, or other effects. See https://github.com/AFNetworking/AFCoreImageSerializer + */ +@property (nonatomic, strong) id imageResponseSerializer; + +///-------------------- +/// @name Setting Image +///-------------------- + +/** + Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` + + @param url The URL used for the image request. + */ +- (void)setImageWithURL:(NSURL *)url; + +/** + Asynchronously downloads an image from the specified URL, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + By default, URL requests have a `Accept` header field value of "image / *", a cache policy of `NSURLCacheStorageAllowed` and a timeout interval of 30 seconds, and are set not handle cookies. To configure URL requests differently, use `setImageWithURLRequest:placeholderImage:success:failure:` + + @param url The URL used for the image request. + @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. + */ +- (void)setImageWithURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage; + +/** + Asynchronously downloads an image from the specified URL request, and sets it once the request is finished. Any previous image request for the receiver will be cancelled. + + If the image is cached locally, the image is set immediately, otherwise the specified placeholder image will be set immediately, and then the remote image will be set once the request is finished. + + If a success block is specified, it is the responsibility of the block to set the image of the image view before returning. If no success block is specified, the default behavior of setting the image with `self.image = image` is applied. + + @param urlRequest The URL request used for the image request. + @param placeholderImage The image to be set initially, until the image request finishes. If `nil`, the image view will not change its image until the image request finishes. + @param success A block to be executed when the image request operation finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the image created from the response data of request. If the image was returned from cache, the request and response parameters will be `nil`. + @param failure A block object to be executed when the image request operation finishes unsuccessfully, or that finishes successfully. This block has no return value and takes three arguments: the request sent from the client, the response received from the server, and the error object describing the network or parsing error that occurred. + */ +- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure; + +/** + Cancels any executing image operation for the receiver, if one exists. + */ +- (void)cancelImageRequestOperation; + +@end + +#pragma mark - + +/** + The `AFImageCache` protocol is adopted by an object used to cache images loaded by the AFNetworking category on `UIImageView`. + */ +@protocol AFImageCache + +/** + Returns a cached image for the specififed request, if available. + + @param request The image request. + + @return The cached image. + */ +- (UIImage *)cachedImageForRequest:(NSURLRequest *)request; + +/** + Caches a particular image for the specified request. + + @param image The image to cache. + @param request The request to be used as a cache key. + */ +- (void)cacheImage:(UIImage *)image + forRequest:(NSURLRequest *)request; +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m new file mode 100644 index 0000000..04b6b0c --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.m @@ -0,0 +1,216 @@ +// UIImageView+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIImageView+AFNetworking.h" + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFHTTPRequestOperation.h" + +@interface AFImageCache : NSCache +@end + +#pragma mark - + +@interface UIImageView (_AFNetworking) +@property (readwrite, nonatomic, strong, setter = af_setImageRequestOperation:) AFHTTPRequestOperation *af_imageRequestOperation; +@end + +@implementation UIImageView (_AFNetworking) + ++ (NSOperationQueue *)af_sharedImageRequestOperationQueue { + static NSOperationQueue *_af_sharedImageRequestOperationQueue = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_sharedImageRequestOperationQueue = [[NSOperationQueue alloc] init]; + _af_sharedImageRequestOperationQueue.maxConcurrentOperationCount = NSOperationQueueDefaultMaxConcurrentOperationCount; + }); + + return _af_sharedImageRequestOperationQueue; +} + +- (AFHTTPRequestOperation *)af_imageRequestOperation { + return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(af_imageRequestOperation)); +} + +- (void)af_setImageRequestOperation:(AFHTTPRequestOperation *)imageRequestOperation { + objc_setAssociatedObject(self, @selector(af_imageRequestOperation), imageRequestOperation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +#pragma mark - + +@implementation UIImageView (AFNetworking) +@dynamic imageResponseSerializer; + ++ (id )sharedImageCache { + static AFImageCache *_af_defaultImageCache = nil; + static dispatch_once_t oncePredicate; + dispatch_once(&oncePredicate, ^{ + _af_defaultImageCache = [[AFImageCache alloc] init]; + + [[NSNotificationCenter defaultCenter] addObserverForName:UIApplicationDidReceiveMemoryWarningNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification * __unused notification) { + [_af_defaultImageCache removeAllObjects]; + }]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(sharedImageCache)) ?: _af_defaultImageCache; +#pragma clang diagnostic pop +} + ++ (void)setSharedImageCache:(id )imageCache { + objc_setAssociatedObject(self, @selector(sharedImageCache), imageCache, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +- (id )imageResponseSerializer { + static id _af_defaultImageResponseSerializer = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_defaultImageResponseSerializer = [AFImageResponseSerializer serializer]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(imageResponseSerializer)) ?: _af_defaultImageResponseSerializer; +#pragma clang diagnostic pop +} + +- (void)setImageResponseSerializer:(id )serializer { + objc_setAssociatedObject(self, @selector(imageResponseSerializer), serializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +- (void)setImageWithURL:(NSURL *)url { + [self setImageWithURL:url placeholderImage:nil]; +} + +- (void)setImageWithURL:(NSURL *)url + placeholderImage:(UIImage *)placeholderImage +{ + NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; + [request addValue:@"image/*" forHTTPHeaderField:@"Accept"]; + + [self setImageWithURLRequest:request placeholderImage:placeholderImage success:nil failure:nil]; +} + +- (void)setImageWithURLRequest:(NSURLRequest *)urlRequest + placeholderImage:(UIImage *)placeholderImage + success:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, UIImage *image))success + failure:(void (^)(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error))failure +{ + [self cancelImageRequestOperation]; + + UIImage *cachedImage = [[[self class] sharedImageCache] cachedImageForRequest:urlRequest]; + if (cachedImage) { + if (success) { + success(nil, nil, cachedImage); + } else { + self.image = cachedImage; + } + + self.af_imageRequestOperation = nil; + } else { + if (placeholderImage) { + self.image = placeholderImage; + } + + __weak __typeof(self)weakSelf = self; + self.af_imageRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:urlRequest]; + self.af_imageRequestOperation.responseSerializer = self.imageResponseSerializer; + [self.af_imageRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + if ([[urlRequest URL] isEqual:[strongSelf.af_imageRequestOperation.request URL]]) { + if (success) { + success(urlRequest, operation.response, responseObject); + } else if (responseObject) { + strongSelf.image = responseObject; + } + + if (operation == strongSelf.af_imageRequestOperation){ + strongSelf.af_imageRequestOperation = nil; + } + } + + [[[strongSelf class] sharedImageCache] cacheImage:responseObject forRequest:urlRequest]; + } failure:^(AFHTTPRequestOperation *operation, NSError *error) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + if ([[urlRequest URL] isEqual:[strongSelf.af_imageRequestOperation.request URL]]) { + if (failure) { + failure(urlRequest, operation.response, error); + } + + if (operation == strongSelf.af_imageRequestOperation){ + strongSelf.af_imageRequestOperation = nil; + } + } + }]; + + [[[self class] af_sharedImageRequestOperationQueue] addOperation:self.af_imageRequestOperation]; + } +} + +- (void)cancelImageRequestOperation { + [self.af_imageRequestOperation cancel]; + self.af_imageRequestOperation = nil; +} + +@end + +#pragma mark - + +static inline NSString * AFImageCacheKeyFromURLRequest(NSURLRequest *request) { + return [[request URL] absoluteString]; +} + +@implementation AFImageCache + +- (UIImage *)cachedImageForRequest:(NSURLRequest *)request { + switch ([request cachePolicy]) { + case NSURLRequestReloadIgnoringCacheData: + case NSURLRequestReloadIgnoringLocalAndRemoteCacheData: + return nil; + default: + break; + } + + return [self objectForKey:AFImageCacheKeyFromURLRequest(request)]; +} + +- (void)cacheImage:(UIImage *)image + forRequest:(NSURLRequest *)request +{ + if (image && request) { + [self setObject:image forKey:AFImageCacheKeyFromURLRequest(request)]; + } +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h new file mode 100644 index 0000000..94082f6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h @@ -0,0 +1,38 @@ +// UIKit+AFNetworking.h +// +// Copyright (c) 2013 AFNetworking (http://afnetworking.com/) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#ifndef _UIKIT_AFNETWORKING_ + #define _UIKIT_AFNETWORKING_ + + #import "AFNetworkActivityIndicatorManager.h" + + #import "UIActivityIndicatorView+AFNetworking.h" + #import "UIAlertView+AFNetworking.h" + #import "UIButton+AFNetworking.h" + #import "UIImageView+AFNetworking.h" + #import "UIKit+AFNetworking.h" + #import "UIProgressView+AFNetworking.h" + #import "UIRefreshControl+AFNetworking.h" + #import "UIWebView+AFNetworking.h" +#endif /* _UIKIT_AFNETWORKING_ */ diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h new file mode 100644 index 0000000..06f3808 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h @@ -0,0 +1,88 @@ +// UIProgressView+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@class AFURLConnectionOperation; + +/** + This category adds methods to the UIKit framework's `UIProgressView` class. The methods in this category provide support for binding the progress to the upload and download progress of a session task or request operation. + */ +@interface UIProgressView (AFNetworking) + +///------------------------------------ +/// @name Setting Session Task Progress +///------------------------------------ + +/** + Binds the progress to the upload progress of the specified session task. + + @param task The session task. + @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task + animated:(BOOL)animated; +#endif + +/** + Binds the progress to the download progress of the specified session task. + + @param task The session task. + @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task + animated:(BOOL)animated; +#endif + +///------------------------------------ +/// @name Setting Session Task Progress +///------------------------------------ + +/** + Binds the progress to the upload progress of the specified request operation. + + @param operation The request operation. + @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. + */ +- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation + animated:(BOOL)animated; + +/** + Binds the progress to the download progress of the specified request operation. + + @param operation The request operation. + @param animated `YES` if the change should be animated, `NO` if the change should happen immediately. + */ +- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation + animated:(BOOL)animated; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m new file mode 100644 index 0000000..dfe4151 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.m @@ -0,0 +1,183 @@ +// UIProgressView+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIProgressView+AFNetworking.h" + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFURLConnectionOperation.h" + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +#import "AFURLSessionManager.h" +#endif + +static void * AFTaskCountOfBytesSentContext = &AFTaskCountOfBytesSentContext; +static void * AFTaskCountOfBytesReceivedContext = &AFTaskCountOfBytesReceivedContext; + +@interface AFURLConnectionOperation (_UIProgressView) +@property (readwrite, nonatomic, copy) void (^uploadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected); +@property (readwrite, nonatomic, assign, setter = af_setUploadProgressAnimated:) BOOL af_uploadProgressAnimated; + +@property (readwrite, nonatomic, copy) void (^downloadProgress)(NSUInteger bytes, long long totalBytes, long long totalBytesExpected); +@property (readwrite, nonatomic, assign, setter = af_setDownloadProgressAnimated:) BOOL af_downloadProgressAnimated; +@end + +@implementation AFURLConnectionOperation (_UIProgressView) +@dynamic uploadProgress; // Implemented in AFURLConnectionOperation +@dynamic af_uploadProgressAnimated; + +@dynamic downloadProgress; // Implemented in AFURLConnectionOperation +@dynamic af_downloadProgressAnimated; +@end + +#pragma mark - + +@implementation UIProgressView (AFNetworking) + +- (BOOL)af_uploadProgressAnimated { + return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_uploadProgressAnimated)) boolValue]; +} + +- (void)af_setUploadProgressAnimated:(BOOL)animated { + objc_setAssociatedObject(self, @selector(af_uploadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (BOOL)af_downloadProgressAnimated { + return [(NSNumber *)objc_getAssociatedObject(self, @selector(af_downloadProgressAnimated)) boolValue]; +} + +- (void)af_setDownloadProgressAnimated:(BOOL)animated { + objc_setAssociatedObject(self, @selector(af_downloadProgressAnimated), @(animated), OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setProgressWithUploadProgressOfTask:(NSURLSessionUploadTask *)task + animated:(BOOL)animated +{ + [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; + [task addObserver:self forKeyPath:@"countOfBytesSent" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesSentContext]; + + [self af_setUploadProgressAnimated:animated]; +} + +- (void)setProgressWithDownloadProgressOfTask:(NSURLSessionDownloadTask *)task + animated:(BOOL)animated +{ + [task addObserver:self forKeyPath:@"state" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; + [task addObserver:self forKeyPath:@"countOfBytesReceived" options:(NSKeyValueObservingOptions)0 context:AFTaskCountOfBytesReceivedContext]; + + [self af_setDownloadProgressAnimated:animated]; +} +#endif + +#pragma mark - + +- (void)setProgressWithUploadProgressOfOperation:(AFURLConnectionOperation *)operation + animated:(BOOL)animated +{ + __weak __typeof(self)weakSelf = self; + void (^original)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) = [operation.uploadProgress copy]; + [operation setUploadProgressBlock:^(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite) { + if (original) { + original(bytesWritten, totalBytesWritten, totalBytesExpectedToWrite); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + if (totalBytesExpectedToWrite > 0) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + [strongSelf setProgress:(totalBytesWritten / (totalBytesExpectedToWrite * 1.0f)) animated:animated]; + } + }); + }]; +} + +- (void)setProgressWithDownloadProgressOfOperation:(AFURLConnectionOperation *)operation + animated:(BOOL)animated +{ + __weak __typeof(self)weakSelf = self; + void (^original)(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) = [operation.downloadProgress copy]; + [operation setDownloadProgressBlock:^(NSUInteger bytesRead, long long totalBytesRead, long long totalBytesExpectedToRead) { + if (original) { + original(bytesRead, totalBytesRead, totalBytesExpectedToRead); + } + + dispatch_async(dispatch_get_main_queue(), ^{ + if (totalBytesExpectedToRead > 0) { + __strong __typeof(weakSelf)strongSelf = weakSelf; + [strongSelf setProgress:(totalBytesRead / (totalBytesExpectedToRead * 1.0f)) animated:animated]; + } + }); + }]; +} + +#pragma mark - NSKeyValueObserving + +- (void)observeValueForKeyPath:(NSString *)keyPath + ofObject:(id)object + change:(__unused NSDictionary *)change + context:(void *)context +{ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 + if (context == AFTaskCountOfBytesSentContext || context == AFTaskCountOfBytesReceivedContext) { + if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesSent))]) { + if ([object countOfBytesExpectedToSend] > 0) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self setProgress:[object countOfBytesSent] / ([object countOfBytesExpectedToSend] * 1.0f) animated:self.af_uploadProgressAnimated]; + }); + } + } + + if ([keyPath isEqualToString:NSStringFromSelector(@selector(countOfBytesReceived))]) { + if ([object countOfBytesExpectedToReceive] > 0) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self setProgress:[object countOfBytesReceived] / ([object countOfBytesExpectedToReceive] * 1.0f) animated:self.af_downloadProgressAnimated]; + }); + } + } + + if ([keyPath isEqualToString:NSStringFromSelector(@selector(state))]) { + if ([(NSURLSessionTask *)object state] == NSURLSessionTaskStateCompleted) { + @try { + [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(state))]; + + if (context == AFTaskCountOfBytesSentContext) { + [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesSent))]; + } + + if (context == AFTaskCountOfBytesReceivedContext) { + [object removeObserver:self forKeyPath:NSStringFromSelector(@selector(countOfBytesReceived))]; + } + } + @catch (NSException * __unused exception) {} + } + } + } +#endif +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h new file mode 100644 index 0000000..18c12ea --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h @@ -0,0 +1,64 @@ +// UIRefreshControl+AFNetworking.m +// +// Copyright (c) 2014 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@class AFURLConnectionOperation; + +/** + This category adds methods to the UIKit framework's `UIRefreshControl` class. The methods in this category provide support for automatically begining and ending refreshing depending on the loading state of a request operation or session task. + */ +@interface UIRefreshControl (AFNetworking) + +///----------------------------------- +/// @name Refreshing for Session Tasks +///----------------------------------- + +/** + Binds the refreshing state to the state of the specified task. + + @param task The task. If `nil`, automatic updating from any previously specified operation will be disabled. + */ +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task; +#endif + +///---------------------------------------- +/// @name Refreshing for Request Operations +///---------------------------------------- + +/** + Binds the refreshing state to the execution state of the specified operation. + + @param operation The operation. If `nil`, automatic updating from any previously specified operation will be disabled. + */ +- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m new file mode 100644 index 0000000..e266451 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.m @@ -0,0 +1,93 @@ +// UIRefreshControl+AFNetworking.m +// +// Copyright (c) 2014 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIRefreshControl+AFNetworking.h" + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFHTTPRequestOperation.h" + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +#import "AFURLSessionManager.h" +#endif + +@implementation UIRefreshControl (AFNetworking) + +#if __IPHONE_OS_VERSION_MIN_REQUIRED >= 70000 +- (void)setRefreshingWithStateOfTask:(NSURLSessionTask *)task { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter removeObserver:self name:AFNetworkingTaskDidResumeNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingTaskDidSuspendNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingTaskDidCompleteNotification object:nil]; + + if (task) { + if (task.state == NSURLSessionTaskStateRunning) { + [self beginRefreshing]; + + [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingTaskDidResumeNotification object:task]; + [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidCompleteNotification object:task]; + [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingTaskDidSuspendNotification object:task]; + } else { + [self endRefreshing]; + } + } +} +#endif + +- (void)setRefreshingWithStateOfOperation:(AFURLConnectionOperation *)operation { + NSNotificationCenter *notificationCenter = [NSNotificationCenter defaultCenter]; + + [notificationCenter removeObserver:self name:AFNetworkingOperationDidStartNotification object:nil]; + [notificationCenter removeObserver:self name:AFNetworkingOperationDidFinishNotification object:nil]; + + if (operation) { + if (![operation isFinished]) { + if ([operation isExecuting]) { + [self beginRefreshing]; + } else { + [self endRefreshing]; + } + + [notificationCenter addObserver:self selector:@selector(af_beginRefreshing) name:AFNetworkingOperationDidStartNotification object:operation]; + [notificationCenter addObserver:self selector:@selector(af_endRefreshing) name:AFNetworkingOperationDidFinishNotification object:operation]; + } + } +} + +#pragma mark - + +- (void)af_beginRefreshing { + dispatch_async(dispatch_get_main_queue(), ^{ + [self beginRefreshing]; + }); +} + +- (void)af_endRefreshing { + dispatch_async(dispatch_get_main_queue(), ^{ + [self endRefreshing]; + }); +} + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h new file mode 100644 index 0000000..159a51a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h @@ -0,0 +1,83 @@ +// UIWebView+AFNetworking.h +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import + +@class AFHTTPRequestSerializer, AFHTTPResponseSerializer; +@protocol AFURLRequestSerialization, AFURLResponseSerialization; + +/** + This category adds methods to the UIKit framework's `UIWebView` class. The methods in this category provide increased control over the request cycle, including progress monitoring and success / failure handling. + + @discussion When using these category methods, make sure to assign `delegate` for the web view, which implements `–webView:shouldStartLoadWithRequest:navigationType:` appropriately. This allows for tapped links to be loaded through AFNetworking, and can ensure that `canGoBack` & `canGoForward` update their values correctly. + */ +@interface UIWebView (AFNetworking) + +/** + The request serializer used to serialize requests made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPRequestSerializer`. + */ +@property (nonatomic, strong) AFHTTPRequestSerializer * requestSerializer; + +/** + The response serializer used to serialize responses made with the `-loadRequest:...` category methods. By default, this is an instance of `AFHTTPResponseSerializer`. + */ +@property (nonatomic, strong) AFHTTPResponseSerializer * responseSerializer; + +/** + Asynchronously loads the specified request. + + @param request A URL request identifying the location of the content to load. This must not be `nil`. + @param progress A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. + @param success A block object to be executed when the request finishes loading successfully. This block returns the HTML string to be loaded by the web view, and takes two arguments: the response, and the response string. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. + */ +- (void)loadRequest:(NSURLRequest *)request + progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress + success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success + failure:(void (^)(NSError *error))failure; + +/** + Asynchronously loads the data associated with a particular request with a specified MIME type and text encoding. + + @param request A URL request identifying the location of the content to load. This must not be `nil`. + @param MIMEType The MIME type of the content. Defaults to the content type of the response if not specified. + @param textEncodingName The IANA encoding name, as in `utf-8` or `utf-16`. Defaults to the response text encoding if not specified. + @param progress A block object to be called when an undetermined number of bytes have been downloaded from the server. This block has no return value and takes three arguments: the number of bytes read since the last time the download progress block was called, the total bytes read, and the total bytes expected to be read during the request, as initially determined by the expected content size of the `NSHTTPURLResponse` object. This block may be called multiple times, and will execute on the main thread. + @param success A block object to be executed when the request finishes loading successfully. This block returns the data to be loaded by the web view and takes two arguments: the response, and the downloaded data. + @param failure A block object to be executed when the request operation finishes unsuccessfully, or that finishes successfully, but encountered an error while parsing the response data. This block has no return value and takes a single argument: the error that occurred. + */ +- (void)loadRequest:(NSURLRequest *)request + MIMEType:(NSString *)MIMEType + textEncodingName:(NSString *)textEncodingName + progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress + success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success + failure:(void (^)(NSError *error))failure; + +@end + +#endif diff --git a/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m new file mode 100644 index 0000000..4ff13e4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.m @@ -0,0 +1,151 @@ +// UIWebView+AFNetworking.m +// +// Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com) +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +#import "UIWebView+AFNetworking.h" + +#import + +#if defined(__IPHONE_OS_VERSION_MIN_REQUIRED) + +#import "AFHTTPRequestOperation.h" +#import "AFURLResponseSerialization.h" +#import "AFURLRequestSerialization.h" + +@interface UIWebView (_AFNetworking) +@property (readwrite, nonatomic, strong, setter = af_setHTTPRequestOperation:) AFHTTPRequestOperation *af_HTTPRequestOperation; +@end + +@implementation UIWebView (_AFNetworking) + +- (AFHTTPRequestOperation *)af_HTTPRequestOperation { + return (AFHTTPRequestOperation *)objc_getAssociatedObject(self, @selector(af_HTTPRequestOperation)); +} + +- (void)af_setHTTPRequestOperation:(AFHTTPRequestOperation *)operation { + objc_setAssociatedObject(self, @selector(af_HTTPRequestOperation), operation, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +@end + +#pragma mark - + +@implementation UIWebView (AFNetworking) + +- (AFHTTPRequestSerializer *)requestSerializer { + static AFHTTPRequestSerializer *_af_defaultRequestSerializer = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_defaultRequestSerializer = [AFHTTPRequestSerializer serializer]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(requestSerializer)) ?: _af_defaultRequestSerializer; +#pragma clang diagnostic pop +} + +- (void)setRequestSerializer:(AFHTTPRequestSerializer *)requestSerializer { + objc_setAssociatedObject(self, @selector(requestSerializer), requestSerializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (AFHTTPResponseSerializer *)responseSerializer { + static AFHTTPResponseSerializer *_af_defaultResponseSerializer = nil; + static dispatch_once_t onceToken; + dispatch_once(&onceToken, ^{ + _af_defaultResponseSerializer = [AFHTTPResponseSerializer serializer]; + }); + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + return objc_getAssociatedObject(self, @selector(responseSerializer)) ?: _af_defaultResponseSerializer; +#pragma clang diagnostic pop +} + +- (void)setResponseSerializer:(AFHTTPResponseSerializer *)responseSerializer { + objc_setAssociatedObject(self, @selector(responseSerializer), responseSerializer, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +#pragma mark - + +- (void)loadRequest:(NSURLRequest *)request + progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress + success:(NSString * (^)(NSHTTPURLResponse *response, NSString *HTML))success + failure:(void (^)(NSError *error))failure +{ + [self loadRequest:request MIMEType:nil textEncodingName:nil progress:progress success:^NSData *(NSHTTPURLResponse *response, NSData *data) { + NSStringEncoding stringEncoding = NSUTF8StringEncoding; + if (response.textEncodingName) { + CFStringEncoding encoding = CFStringConvertIANACharSetNameToEncoding((CFStringRef)response.textEncodingName); + if (encoding != kCFStringEncodingInvalidId) { + stringEncoding = CFStringConvertEncodingToNSStringEncoding(encoding); + } + } + + NSString *string = [[NSString alloc] initWithData:data encoding:stringEncoding]; + if (success) { + string = success(response, string); + } + + return [string dataUsingEncoding:stringEncoding]; + } failure:failure]; +} + +- (void)loadRequest:(NSURLRequest *)request + MIMEType:(NSString *)MIMEType + textEncodingName:(NSString *)textEncodingName + progress:(void (^)(NSUInteger bytesWritten, long long totalBytesWritten, long long totalBytesExpectedToWrite))progress + success:(NSData * (^)(NSHTTPURLResponse *response, NSData *data))success + failure:(void (^)(NSError *error))failure +{ + NSParameterAssert(request); + + if (self.af_HTTPRequestOperation) { + [self.af_HTTPRequestOperation cancel]; + } + + request = [self.requestSerializer requestBySerializingRequest:request withParameters:nil error:nil]; + + self.af_HTTPRequestOperation = [[AFHTTPRequestOperation alloc] initWithRequest:request]; + self.af_HTTPRequestOperation.responseSerializer = self.responseSerializer; + + __weak __typeof(self)weakSelf = self; + [self.af_HTTPRequestOperation setDownloadProgressBlock:progress]; + [self.af_HTTPRequestOperation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id __unused responseObject) { + NSData *data = success ? success(operation.response, operation.responseData) : operation.responseData; + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wgnu" + __strong __typeof(weakSelf) strongSelf = weakSelf; + [strongSelf loadData:data MIMEType:(MIMEType ?: [operation.response MIMEType]) textEncodingName:(textEncodingName ?: [operation.response textEncodingName]) baseURL:[operation.response URL]]; +#pragma clang diagnostic pop + } failure:^(AFHTTPRequestOperation * __unused operation, NSError *error) { + if (failure) { + failure(error); + } + }]; + + [self.af_HTTPRequestOperation start]; +} + +@end + +#endif diff --git a/iOSStudy/Pods/FMDB/LICENSE.txt b/iOSStudy/iOSStudy/Pods/FMDB/LICENSE.txt similarity index 100% rename from iOSStudy/Pods/FMDB/LICENSE.txt rename to iOSStudy/iOSStudy/Pods/FMDB/LICENSE.txt diff --git a/iOSStudy/Pods/FMDB/README.markdown b/iOSStudy/iOSStudy/Pods/FMDB/README.markdown similarity index 100% rename from iOSStudy/Pods/FMDB/README.markdown rename to iOSStudy/iOSStudy/Pods/FMDB/README.markdown diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDB.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDB.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDB.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDB.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.m b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.m similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.m rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabase.m diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseAdditions.m diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.m b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.m similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.m rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabasePool.m diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.m b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.m similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.m rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMDatabaseQueue.m diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.h b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.h similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.h rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.h diff --git a/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.m b/iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.m similarity index 100% rename from iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.m rename to iOSStudy/iOSStudy/Pods/FMDB/src/fmdb/FMResultSet.m diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperation.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperation.h new file mode 120000 index 0000000..ac762c8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperation.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFHTTPRequestOperation.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperationManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperationManager.h new file mode 120000 index 0000000..9dcc623 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPRequestOperationManager.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFHTTPRequestOperationManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPSessionManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPSessionManager.h new file mode 120000 index 0000000..56feb9f --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFHTTPSessionManager.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFHTTPSessionManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkActivityIndicatorManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkActivityIndicatorManager.h new file mode 120000 index 0000000..67519d9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkActivityIndicatorManager.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkReachabilityManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkReachabilityManager.h new file mode 120000 index 0000000..68fc774 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworkReachabilityManager.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFNetworkReachabilityManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworking.h new file mode 120000 index 0000000..a5a38da --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFSecurityPolicy.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFSecurityPolicy.h new file mode 120000 index 0000000..fd1322d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFSecurityPolicy.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFSecurityPolicy.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLConnectionOperation.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLConnectionOperation.h new file mode 120000 index 0000000..d9b35fb --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLConnectionOperation.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFURLConnectionOperation.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLRequestSerialization.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLRequestSerialization.h new file mode 120000 index 0000000..ca8209b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLRequestSerialization.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFURLRequestSerialization.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLResponseSerialization.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLResponseSerialization.h new file mode 120000 index 0000000..e36a765 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLResponseSerialization.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFURLResponseSerialization.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLSessionManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLSessionManager.h new file mode 120000 index 0000000..835101d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/AFURLSessionManager.h @@ -0,0 +1 @@ +../../../AFNetworking/AFNetworking/AFURLSessionManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIActivityIndicatorView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIActivityIndicatorView+AFNetworking.h new file mode 120000 index 0000000..c534ebf --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIActivityIndicatorView+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIAlertView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIAlertView+AFNetworking.h new file mode 120000 index 0000000..f992813 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIAlertView+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIAlertView+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIButton+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIButton+AFNetworking.h new file mode 120000 index 0000000..8f2e221 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIButton+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIButton+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIImageView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIImageView+AFNetworking.h new file mode 120000 index 0000000..a95d673 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIImageView+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIImageView+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIKit+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIKit+AFNetworking.h new file mode 120000 index 0000000..95017cc --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIKit+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIKit+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIProgressView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIProgressView+AFNetworking.h new file mode 120000 index 0000000..730b167 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIProgressView+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIProgressView+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIRefreshControl+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIRefreshControl+AFNetworking.h new file mode 120000 index 0000000..8efd826 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIRefreshControl+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIRefreshControl+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIWebView+AFNetworking.h b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIWebView+AFNetworking.h new file mode 120000 index 0000000..c8df6ef --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/AFNetworking/UIWebView+AFNetworking.h @@ -0,0 +1 @@ +../../../AFNetworking/UIKit+AFNetworking/UIWebView+AFNetworking.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMDB.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDB.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMDB.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDB.h diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMDatabase.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabase.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMDatabase.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabase.h diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseAdditions.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseAdditions.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseAdditions.h diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMDatabasePool.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabasePool.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMDatabasePool.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabasePool.h diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseQueue.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseQueue.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseQueue.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMDatabaseQueue.h diff --git a/iOSStudy/Pods/Headers/Public/FMDB/FMResultSet.h b/iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMResultSet.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/FMDB/FMResultSet.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/FMDB/FMResultSet.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefresh.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefresh.h new file mode 120000 index 0000000..f6ae748 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefresh.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshBaseView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshBaseView.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshBaseView.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshBaseView.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshConst.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshConst.h new file mode 120000 index 0000000..933687e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshConst.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooterView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooterView.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooterView.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshFooterView.h diff --git a/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeaderView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeaderView.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeaderView.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/MJRefreshHeaderView.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJExtension.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJExtension.h new file mode 120000 index 0000000..be6e18a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJExtension.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJRefresh.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJRefresh.h new file mode 120000 index 0000000..968b9e9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIScrollView+MJRefresh.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIView+MJExtension.h b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIView+MJExtension.h new file mode 120000 index 0000000..75464ee --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/MJRefresh/UIView+MJExtension.h @@ -0,0 +1 @@ +../../../MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/EXTKeyPathCoding.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTKeyPathCoding.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/Mantle/EXTKeyPathCoding.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTKeyPathCoding.h diff --git a/iOSStudy/Pods/Headers/Public/Mantle/EXTRuntimeExtensions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTRuntimeExtensions.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/Mantle/EXTRuntimeExtensions.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTRuntimeExtensions.h diff --git a/iOSStudy/Pods/Headers/Public/Mantle/EXTScope.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTScope.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/Mantle/EXTScope.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/EXTScope.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLJSONAdapter.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLJSONAdapter.h new file mode 120000 index 0000000..8ff5c15 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLJSONAdapter.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLJSONAdapter.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/MTLManagedObjectAdapter.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLManagedObjectAdapter.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/Mantle/MTLManagedObjectAdapter.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLManagedObjectAdapter.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel+NSCoding.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel+NSCoding.h new file mode 120000 index 0000000..549748e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel+NSCoding.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLModel+NSCoding.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel.h new file mode 120000 index 0000000..c1dd5c0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLModel.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLModel.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLReflection.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLReflection.h new file mode 120000 index 0000000..e0fa0b2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLReflection.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLReflection.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLValueTransformer.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLValueTransformer.h new file mode 120000 index 0000000..c999e46 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/MTLValueTransformer.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/MTLValueTransformer.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/Mantle.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/Mantle.h new file mode 120000 index 0000000..b3a3b59 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/Mantle.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/Mantle.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSArray+MTLManipulationAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSArray+MTLManipulationAdditions.h new file mode 120000 index 0000000..72a74e5 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSArray+MTLManipulationAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSArray+MTLManipulationAdditions.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLManipulationAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLManipulationAdditions.h new file mode 120000 index 0000000..d27d0f6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSDictionary+MTLManipulationAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSError+MTLModelException.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSError+MTLModelException.h new file mode 120000 index 0000000..71a67b0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSError+MTLModelException.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSError+MTLModelException.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSObject+MTLComparisonAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSObject+MTLComparisonAdditions.h new file mode 120000 index 0000000..a2c2ca1 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSObject+MTLComparisonAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSObject+MTLComparisonAdditions.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLInversionAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLInversionAdditions.h new file mode 120000 index 0000000..86e393a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLInversionAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h new file mode 120000 index 0000000..c308137 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h @@ -0,0 +1 @@ +../../../Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h \ No newline at end of file diff --git a/iOSStudy/Pods/Headers/Public/Mantle/metamacros.h b/iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/metamacros.h similarity index 100% rename from iOSStudy/Pods/Headers/Public/Mantle/metamacros.h rename to iOSStudy/iOSStudy/Pods/Headers/Public/Mantle/metamacros.h diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/NSData+ImageContentType.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/NSData+ImageContentType.h new file mode 120000 index 0000000..8457498 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/NSData+ImageContentType.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/NSData+ImageContentType.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDImageCache.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDImageCache.h new file mode 120000 index 0000000..0040b06 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDImageCache.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDImageCache.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageCompat.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageCompat.h new file mode 120000 index 0000000..6ca2478 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageCompat.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageCompat.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDecoder.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDecoder.h new file mode 120000 index 0000000..a2f3a68 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDecoder.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageDecoder.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloader.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloader.h new file mode 120000 index 0000000..303b03b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloader.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageDownloader.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloaderOperation.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloaderOperation.h new file mode 120000 index 0000000..99441c4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageDownloaderOperation.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageManager.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageManager.h new file mode 120000 index 0000000..1b81848 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageManager.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageManager.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageOperation.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageOperation.h new file mode 120000 index 0000000..20e5b89 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImageOperation.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImageOperation.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImagePrefetcher.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImagePrefetcher.h new file mode 120000 index 0000000..50585c6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/SDWebImagePrefetcher.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/SDWebImagePrefetcher.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIButton+WebCache.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIButton+WebCache.h new file mode 120000 index 0000000..19d2d8e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIButton+WebCache.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIButton+WebCache.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+GIF.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+GIF.h new file mode 120000 index 0000000..14d5aad --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+GIF.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIImage+GIF.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+MultiFormat.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+MultiFormat.h new file mode 120000 index 0000000..1fb9650 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImage+MultiFormat.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIImage+MultiFormat.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+HighlightedWebCache.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+HighlightedWebCache.h new file mode 120000 index 0000000..fd4dea4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+HighlightedWebCache.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+WebCache.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+WebCache.h new file mode 120000 index 0000000..0c53a47 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIImageView+WebCache.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIImageView+WebCache.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIView+WebCacheOperation.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIView+WebCacheOperation.h new file mode 120000 index 0000000..f9890c4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SDWebImage/UIView+WebCacheOperation.h @@ -0,0 +1 @@ +../../../SDWebImage/SDWebImage/UIView+WebCacheOperation.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVIndefiniteAnimatedView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVIndefiniteAnimatedView.h new file mode 120000 index 0000000..55a38a2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVIndefiniteAnimatedView.h @@ -0,0 +1 @@ +../../../SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVProgressHUD.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVProgressHUD.h new file mode 120000 index 0000000..608a8aa --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVProgressHUD/SVProgressHUD.h @@ -0,0 +1 @@ +../../../SVProgressHUD/SVProgressHUD/SVProgressHUD.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVModalWebViewController.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVModalWebViewController.h new file mode 120000 index 0000000..5178191 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVModalWebViewController.h @@ -0,0 +1 @@ +../../../SVWebViewController/SVWebViewController/SVModalWebViewController.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewController.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewController.h new file mode 120000 index 0000000..5f44ce2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewController.h @@ -0,0 +1 @@ +../../../SVWebViewController/SVWebViewController/SVWebViewController.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivity.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivity.h new file mode 120000 index 0000000..0224985 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivity.h @@ -0,0 +1 @@ +../../../SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivityChrome.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivityChrome.h new file mode 120000 index 0000000..50166ae --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivityChrome.h @@ -0,0 +1 @@ +../../../SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivitySafari.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivitySafari.h new file mode 120000 index 0000000..a01e248 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SVWebViewController/SVWebViewControllerActivitySafari.h @@ -0,0 +1 @@ +../../../SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/NSMutableArray+SWUtilityButtons.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/NSMutableArray+SWUtilityButtons.h new file mode 120000 index 0000000..c64bfc9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/NSMutableArray+SWUtilityButtons.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWCellScrollView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWCellScrollView.h new file mode 120000 index 0000000..c6e86c6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWCellScrollView.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWLongPressGestureRecognizer.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWLongPressGestureRecognizer.h new file mode 120000 index 0000000..1f3a0ad --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWLongPressGestureRecognizer.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWTableViewCell.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWTableViewCell.h new file mode 120000 index 0000000..d3256e4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWTableViewCell.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonTapGestureRecognizer.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonTapGestureRecognizer.h new file mode 120000 index 0000000..53a975d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonTapGestureRecognizer.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonView.h b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonView.h new file mode 120000 index 0000000..66c02f1 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Headers/Public/SWTableViewCell/SWUtilityButtonView.h @@ -0,0 +1 @@ +../../../SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.h \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/LICENSE b/iOSStudy/iOSStudy/Pods/MJRefresh/LICENSE new file mode 100644 index 0000000..7f7ecfd --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/LICENSE @@ -0,0 +1,19 @@ +Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle/arrow@2x.png b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle/arrow@2x.png new file mode 100755 index 0000000..a016473 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle/arrow@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h new file mode 100755 index 0000000..caebbd9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h @@ -0,0 +1,32 @@ +/** + * 代码地址: https://github.com/CoderMJLee/MJRefresh + * 代码地址: http://code4app.com/ios/%E5%BF%AB%E9%80%9F%E9%9B%86%E6%88%90%E4%B8%8B%E6%8B%89%E4%B8%8A%E6%8B%89%E5%88%B7%E6%96%B0/52326ce26803fabc46000000 + * 友情提示: 遇到一些小问题, 最好及时下载最新的代码试试 + */ + +#import "UIScrollView+MJRefresh.h" + +/** + MJ友情提示: + 1. 添加头部控件的方法 + [self.tableView addHeaderWithTarget:self action:@selector(headerRereshing)]; + 或者 + [self.tableView addHeaderWithCallback:^{ }]; + + 2. 添加尾部控件的方法 + [self.tableView addFooterWithTarget:self action:@selector(footerRereshing)]; + 或者 + [self.tableView addFooterWithCallback:^{ }]; + + 3. 可以在MJRefreshConst.h和MJRefreshConst.m文件中自定义显示的文字内容和文字颜色 + + 4. 本框架兼容iOS6\iOS7,iPhone\iPad横竖屏 + + 5.自动进入刷新状态 + 1> [self.tableView headerBeginRefreshing]; + 2> [self.tableView footerBeginRefreshing]; + + 6.结束刷新 + 1> [self.tableView headerEndRefreshing]; + 2> [self.tableView footerEndRefreshing]; +*/ \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h new file mode 100755 index 0000000..ae71f2a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h @@ -0,0 +1,41 @@ +// +// MJRefreshConst.h +// MJRefresh +// +// Created by mj on 14-1-3. +// Copyright (c) 2014年 itcast. All rights reserved. +// +#import + +#ifdef DEBUG +#define MJLog(...) NSLog(__VA_ARGS__) +#else +#define MJLog(...) +#endif + +// objc_msgSend +#define msgSend(...) ((void (*)(void *, SEL, UIView *))objc_msgSend)(__VA_ARGS__) +#define msgTarget(target) (__bridge void *)(target) + +#define MJColor(r, g, b) [UIColor colorWithRed:(r)/255.0 green:(g)/255.0 blue:(b)/255.0 alpha:1.0] +// 文字颜色 +#define MJRefreshLabelTextColor MJColor(150, 150, 150) + +// 图片路径 +#define MJRefreshSrcName(file) [@"MJRefresh.bundle" stringByAppendingPathComponent:file] + +UIKIT_EXTERN const CGFloat MJRefreshViewHeight; +UIKIT_EXTERN const CGFloat MJRefreshFastAnimationDuration; +UIKIT_EXTERN const CGFloat MJRefreshSlowAnimationDuration; + +UIKIT_EXTERN NSString *const MJRefreshFooterPullToRefresh; +UIKIT_EXTERN NSString *const MJRefreshFooterReleaseToRefresh; +UIKIT_EXTERN NSString *const MJRefreshFooterRefreshing; + +UIKIT_EXTERN NSString *const MJRefreshHeaderPullToRefresh; +UIKIT_EXTERN NSString *const MJRefreshHeaderReleaseToRefresh; +UIKIT_EXTERN NSString *const MJRefreshHeaderRefreshing; +UIKIT_EXTERN NSString *const MJRefreshHeaderTimeKey; + +UIKIT_EXTERN NSString *const MJRefreshContentOffset; +extern NSString *const MJRefreshContentSize; \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m new file mode 100755 index 0000000..8280e44 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m @@ -0,0 +1,25 @@ +// +// MJRefreshConst.m +// MJRefresh +// +// Created by mj on 14-1-3. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import + +const CGFloat MJRefreshViewHeight = 64.0; +const CGFloat MJRefreshFastAnimationDuration = 0.25; +const CGFloat MJRefreshSlowAnimationDuration = 0.4; + +NSString *const MJRefreshFooterPullToRefresh = @"上拉可以加载更多数据"; +NSString *const MJRefreshFooterReleaseToRefresh = @"松开立即加载更多数据"; +NSString *const MJRefreshFooterRefreshing = @"正在帮你加载数据..."; + +NSString *const MJRefreshHeaderPullToRefresh = @"下拉可以刷新"; +NSString *const MJRefreshHeaderReleaseToRefresh = @"松开立即刷新"; +NSString *const MJRefreshHeaderRefreshing = @"正在帮你刷新..."; +NSString *const MJRefreshHeaderTimeKey = @"MJRefreshHeaderView"; + +NSString *const MJRefreshContentOffset = @"contentOffset"; +NSString *const MJRefreshContentSize = @"contentSize"; \ No newline at end of file diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h diff --git a/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m similarity index 100% rename from iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m rename to iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h new file mode 100644 index 0000000..96f5283 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h @@ -0,0 +1,22 @@ +// +// UIScrollView+Extension.h +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import + +@interface UIScrollView (MJExtension) +@property (assign, nonatomic) CGFloat mj_contentInsetTop; +@property (assign, nonatomic) CGFloat mj_contentInsetBottom; +@property (assign, nonatomic) CGFloat mj_contentInsetLeft; +@property (assign, nonatomic) CGFloat mj_contentInsetRight; + +@property (assign, nonatomic) CGFloat mj_contentOffsetX; +@property (assign, nonatomic) CGFloat mj_contentOffsetY; + +@property (assign, nonatomic) CGFloat mj_contentSizeWidth; +@property (assign, nonatomic) CGFloat mj_contentSizeHeight; +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m new file mode 100644 index 0000000..0a5fe07 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m @@ -0,0 +1,107 @@ +// +// UIScrollView+Extension.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import "UIScrollView+MJExtension.h" + +@implementation UIScrollView (MJExtension) +- (void)setMj_contentInsetTop:(CGFloat)mj_contentInsetTop +{ + UIEdgeInsets inset = self.contentInset; + inset.top = mj_contentInsetTop; + self.contentInset = inset; +} + +- (CGFloat)mj_contentInsetTop +{ + return self.contentInset.top; +} + +- (void)setMj_contentInsetBottom:(CGFloat)mj_contentInsetBottom +{ + UIEdgeInsets inset = self.contentInset; + inset.bottom = mj_contentInsetBottom; + self.contentInset = inset; +} + +- (CGFloat)mj_contentInsetBottom +{ + return self.contentInset.bottom; +} + +- (void)setMj_contentInsetLeft:(CGFloat)mj_contentInsetLeft +{ + UIEdgeInsets inset = self.contentInset; + inset.left = mj_contentInsetLeft; + self.contentInset = inset; +} + +- (CGFloat)mj_contentInsetLeft +{ + return self.contentInset.left; +} + +- (void)setMj_contentInsetRight:(CGFloat)mj_contentInsetRight +{ + UIEdgeInsets inset = self.contentInset; + inset.right = mj_contentInsetRight; + self.contentInset = inset; +} + +- (CGFloat)mj_contentInsetRight +{ + return self.contentInset.right; +} + +- (void)setMj_contentOffsetX:(CGFloat)mj_contentOffsetX +{ + CGPoint offset = self.contentOffset; + offset.x = mj_contentOffsetX; + self.contentOffset = offset; +} + +- (CGFloat)mj_contentOffsetX +{ + return self.contentOffset.x; +} + +- (void)setMj_contentOffsetY:(CGFloat)mj_contentOffsetY +{ + CGPoint offset = self.contentOffset; + offset.y = mj_contentOffsetY; + self.contentOffset = offset; +} + +- (CGFloat)mj_contentOffsetY +{ + return self.contentOffset.y; +} + +- (void)setMj_contentSizeWidth:(CGFloat)mj_contentSizeWidth +{ + CGSize size = self.contentSize; + size.width = mj_contentSizeWidth; + self.contentSize = size; +} + +- (CGFloat)mj_contentSizeWidth +{ + return self.contentSize.width; +} + +- (void)setMj_contentSizeHeight:(CGFloat)mj_contentSizeHeight +{ + CGSize size = self.contentSize; + size.height = mj_contentSizeHeight; + self.contentSize = size; +} + +- (CGFloat)mj_contentSizeHeight +{ + return self.contentSize.height; +} +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h new file mode 100644 index 0000000..e5ae65b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h @@ -0,0 +1,124 @@ +// +// UIScrollView+MJRefresh.h +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import + +@interface UIScrollView (MJRefresh) +#pragma mark - 下拉刷新 +/** + * 添加一个下拉刷新头部控件 + * + * @param callback 回调 + */ +- (void)addHeaderWithCallback:(void (^)())callback; + +/** + * 添加一个下拉刷新头部控件 + * + * @param callback 回调 + * @param dateKey 刷新时间保存的key值 + */ +- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey; + +/** + * 添加一个下拉刷新头部控件 + * + * @param target 目标 + * @param action 回调方法 + */ +- (void)addHeaderWithTarget:(id)target action:(SEL)action; + +/** + * 添加一个下拉刷新头部控件 + * + * @param target 目标 + * @param action 回调方法 + * @param dateKey 刷新时间保存的key值 + */ +- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey; + +/** + * 移除下拉刷新头部控件 + */ +- (void)removeHeader; + +/** + * 主动让下拉刷新头部控件进入刷新状态 + */ +- (void)headerBeginRefreshing; + +/** + * 让下拉刷新头部控件停止刷新状态 + */ +- (void)headerEndRefreshing; + +/** + * 下拉刷新头部控件的可见性 + */ +@property (nonatomic, assign, getter = isHeaderHidden) BOOL headerHidden; + +/** + * 是否正在下拉刷新 + */ +@property (nonatomic, assign, readonly, getter = isHeaderRefreshing) BOOL headerRefreshing; + +#pragma mark - 上拉刷新 +/** + * 添加一个上拉刷新尾部控件 + * + * @param callback 回调 + */ +- (void)addFooterWithCallback:(void (^)())callback; + +/** + * 添加一个上拉刷新尾部控件 + * + * @param target 目标 + * @param action 回调方法 + */ +- (void)addFooterWithTarget:(id)target action:(SEL)action; + +/** + * 移除上拉刷新尾部控件 + */ +- (void)removeFooter; + +/** + * 主动让上拉刷新尾部控件进入刷新状态 + */ +- (void)footerBeginRefreshing; + +/** + * 让上拉刷新尾部控件停止刷新状态 + */ +- (void)footerEndRefreshing; + +/** + * 上拉刷新头部控件的可见性 + */ +@property (nonatomic, assign, getter = isFooterHidden) BOOL footerHidden; + +/** + * 是否正在上拉刷新 + */ +@property (nonatomic, assign, readonly, getter = isFooterRefreshing) BOOL footerRefreshing; + +/** + * 设置尾部控件的文字 + */ +@property (copy, nonatomic) NSString *footerPullToRefreshText; // 默认:@"上拉可以加载更多数据" +@property (copy, nonatomic) NSString *footerReleaseToRefreshText; // 默认:@"松开立即加载更多数据" +@property (copy, nonatomic) NSString *footerRefreshingText; // 默认:@"MJ哥正在帮你加载数据..." + +/** + * 设置头部控件的文字 + */ +@property (copy, nonatomic) NSString *headerPullToRefreshText; // 默认:@"下拉可以刷新" +@property (copy, nonatomic) NSString *headerReleaseToRefreshText; // 默认:@"松开立即刷新" +@property (copy, nonatomic) NSString *headerRefreshingText; // 默认:@"MJ哥正在帮你刷新..." +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m new file mode 100644 index 0000000..74a72b8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m @@ -0,0 +1,292 @@ +// +// UIScrollView+MJRefresh.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import "UIScrollView+MJRefresh.h" +#import "MJRefreshHeaderView.h" +#import "MJRefreshFooterView.h" +#import + +@interface UIScrollView() +@property (weak, nonatomic) MJRefreshHeaderView *header; +@property (weak, nonatomic) MJRefreshFooterView *footer; +@end + + +@implementation UIScrollView (MJRefresh) + +#pragma mark - 运行时相关 +static char MJRefreshHeaderViewKey; +static char MJRefreshFooterViewKey; + +- (void)setHeader:(MJRefreshHeaderView *)header { + [self willChangeValueForKey:@"MJRefreshHeaderViewKey"]; + objc_setAssociatedObject(self, &MJRefreshHeaderViewKey, + header, + OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"MJRefreshHeaderViewKey"]; +} + +- (MJRefreshHeaderView *)header { + return objc_getAssociatedObject(self, &MJRefreshHeaderViewKey); +} + +- (void)setFooter:(MJRefreshFooterView *)footer { + [self willChangeValueForKey:@"MJRefreshFooterViewKey"]; + objc_setAssociatedObject(self, &MJRefreshFooterViewKey, + footer, + OBJC_ASSOCIATION_ASSIGN); + [self didChangeValueForKey:@"MJRefreshFooterViewKey"]; +} + +- (MJRefreshFooterView *)footer { + return objc_getAssociatedObject(self, &MJRefreshFooterViewKey); +} + +#pragma mark - 下拉刷新 +/** + * 添加一个下拉刷新头部控件 + * + * @param callback 回调 + */ +- (void)addHeaderWithCallback:(void (^)())callback +{ + [self addHeaderWithCallback:callback dateKey:nil]; +} + +- (void)addHeaderWithCallback:(void (^)())callback dateKey:(NSString*)dateKey +{ + // 1.创建新的header + if (!self.header) { + MJRefreshHeaderView *header = [MJRefreshHeaderView header]; + [self addSubview:header]; + self.header = header; + } + + // 2.设置block回调 + self.header.beginRefreshingCallback = callback; + + // 3.设置存储刷新时间的key + self.header.dateKey = dateKey; +} + +/** + * 添加一个下拉刷新头部控件 + * + * @param target 目标 + * @param action 回调方法 + */ +- (void)addHeaderWithTarget:(id)target action:(SEL)action +{ + [self addHeaderWithTarget:target action:action dateKey:nil]; +} + +- (void)addHeaderWithTarget:(id)target action:(SEL)action dateKey:(NSString*)dateKey +{ + // 1.创建新的header + if (!self.header) { + MJRefreshHeaderView *header = [MJRefreshHeaderView header]; + [self addSubview:header]; + self.header = header; + } + + // 2.设置目标和回调方法 + self.header.beginRefreshingTaget = target; + self.header.beginRefreshingAction = action; + + // 3.设置存储刷新时间的key + self.header.dateKey = dateKey; +} + +/** + * 移除下拉刷新头部控件 + */ +- (void)removeHeader +{ + [self.header removeFromSuperview]; + self.header = nil; +} + +/** + * 主动让下拉刷新头部控件进入刷新状态 + */ +- (void)headerBeginRefreshing +{ + [self.header beginRefreshing]; +} + +/** + * 让下拉刷新头部控件停止刷新状态 + */ +- (void)headerEndRefreshing +{ + [self.header endRefreshing]; +} + +/** + * 下拉刷新头部控件的可见性 + */ +- (void)setHeaderHidden:(BOOL)hidden +{ + self.header.hidden = hidden; +} + +- (BOOL)isHeaderHidden +{ + return self.header.isHidden; +} + +- (BOOL)isHeaderRefreshing +{ + return self.header.isRefreshing; +} + +#pragma mark - 上拉刷新 +/** + * 添加一个上拉刷新尾部控件 + * + * @param callback 回调 + */ +- (void)addFooterWithCallback:(void (^)())callback +{ + // 1.创建新的footer + if (!self.footer) { + MJRefreshFooterView *footer = [MJRefreshFooterView footer]; + [self addSubview:footer]; + self.footer = footer; + } + + // 2.设置block回调 + self.footer.beginRefreshingCallback = callback; +} + +/** + * 添加一个上拉刷新尾部控件 + * + * @param target 目标 + * @param action 回调方法 + */ +- (void)addFooterWithTarget:(id)target action:(SEL)action +{ + // 1.创建新的footer + if (!self.footer) { + MJRefreshFooterView *footer = [MJRefreshFooterView footer]; + [self addSubview:footer]; + self.footer = footer; + } + + // 2.设置目标和回调方法 + self.footer.beginRefreshingTaget = target; + self.footer.beginRefreshingAction = action; +} + +/** + * 移除上拉刷新尾部控件 + */ +- (void)removeFooter +{ + [self.footer removeFromSuperview]; + self.footer = nil; +} + +/** + * 主动让上拉刷新尾部控件进入刷新状态 + */ +- (void)footerBeginRefreshing +{ + [self.footer beginRefreshing]; +} + +/** + * 让上拉刷新尾部控件停止刷新状态 + */ +- (void)footerEndRefreshing +{ + [self.footer endRefreshing]; +} + +/** + * 下拉刷新头部控件的可见性 + */ +- (void)setFooterHidden:(BOOL)hidden +{ + self.footer.hidden = hidden; +} + +- (BOOL)isFooterHidden +{ + return self.footer.isHidden; +} + +- (BOOL)isFooterRefreshing +{ + return self.footer.isRefreshing; +} + +/** + * 文字 + */ +- (void)setFooterPullToRefreshText:(NSString *)footerPullToRefreshText +{ + self.footer.pullToRefreshText = footerPullToRefreshText; +} + +- (NSString *)footerPullToRefreshText +{ + return self.footer.pullToRefreshText; +} + +- (void)setFooterReleaseToRefreshText:(NSString *)footerReleaseToRefreshText +{ + self.footer.releaseToRefreshText = footerReleaseToRefreshText; +} + +- (NSString *)footerReleaseToRefreshText +{ + return self.footer.releaseToRefreshText; +} + +- (void)setFooterRefreshingText:(NSString *)footerRefreshingText +{ + self.footer.refreshingText = footerRefreshingText; +} + +- (NSString *)footerRefreshingText +{ + return self.footer.refreshingText; +} + +- (void)setHeaderPullToRefreshText:(NSString *)headerPullToRefreshText +{ + self.header.pullToRefreshText = headerPullToRefreshText; +} + +- (NSString *)headerPullToRefreshText +{ + return self.header.pullToRefreshText; +} + +- (void)setHeaderReleaseToRefreshText:(NSString *)headerReleaseToRefreshText +{ + self.header.releaseToRefreshText = headerReleaseToRefreshText; +} + +- (NSString *)headerReleaseToRefreshText +{ + return self.header.releaseToRefreshText; +} + +- (void)setHeaderRefreshingText:(NSString *)headerRefreshingText +{ + self.header.refreshingText = headerRefreshingText; +} + +- (NSString *)headerRefreshingText +{ + return self.header.refreshingText; +} +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h new file mode 100644 index 0000000..8033456 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h @@ -0,0 +1,18 @@ +// +// UIView+Extension.h +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import + +@interface UIView (MJExtension) +@property (assign, nonatomic) CGFloat mj_x; +@property (assign, nonatomic) CGFloat mj_y; +@property (assign, nonatomic) CGFloat mj_width; +@property (assign, nonatomic) CGFloat mj_height; +@property (assign, nonatomic) CGSize mj_size; +@property (assign, nonatomic) CGPoint mj_origin; +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m new file mode 100644 index 0000000..a4f8194 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m @@ -0,0 +1,83 @@ +// +// UIView+Extension.m +// MJRefreshExample +// +// Created by MJ Lee on 14-5-28. +// Copyright (c) 2014年 itcast. All rights reserved. +// + +#import "UIView+MJExtension.h" + +@implementation UIView (MJExtension) +- (void)setMj_x:(CGFloat)mj_x +{ + CGRect frame = self.frame; + frame.origin.x = mj_x; + self.frame = frame; +} + +- (CGFloat)mj_x +{ + return self.frame.origin.x; +} + +- (void)setMj_y:(CGFloat)mj_y +{ + CGRect frame = self.frame; + frame.origin.y = mj_y; + self.frame = frame; +} + +- (CGFloat)mj_y +{ + return self.frame.origin.y; +} + +- (void)setMj_width:(CGFloat)mj_width +{ + CGRect frame = self.frame; + frame.size.width = mj_width; + self.frame = frame; +} + +- (CGFloat)mj_width +{ + return self.frame.size.width; +} + +- (void)setMj_height:(CGFloat)mj_height +{ + CGRect frame = self.frame; + frame.size.height = mj_height; + self.frame = frame; +} + +- (CGFloat)mj_height +{ + return self.frame.size.height; +} + +- (void)setMj_size:(CGSize)mj_size +{ + CGRect frame = self.frame; + frame.size = mj_size; + self.frame = frame; +} + +- (CGSize)mj_size +{ + return self.frame.size; +} + +- (void)setMj_origin:(CGPoint)mj_origin +{ + CGRect frame = self.frame; + frame.origin = mj_origin; + self.frame = frame; +} + +- (CGPoint)mj_origin +{ + return self.frame.origin; +} +@end diff --git a/iOSStudy/iOSStudy/Pods/MJRefresh/README.md b/iOSStudy/iOSStudy/Pods/MJRefresh/README.md new file mode 100644 index 0000000..a2e50fa --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/MJRefresh/README.md @@ -0,0 +1,43 @@ +## MJRefresh +The easiest way to use pull-to-refresh + +![(52326ce26803fabc46000000_18)](http://code4app.qiniudn.com/photo/52326ce26803fabc46000000_18.gif) + +### 添加头部控件 +```objc +[self.tableView addHeaderWithTarget:self action:@selector(headerRereshing)]; +``` +或者 +```objc +[self.tableView addHeaderWithCallback:^{ }]; +``` + +### 添加尾部控件 +```objc +[self.tableView addFooterWithTarget:self action:@selector(footerRereshing)]; +``` +或者 +```objc +[self.tableView addFooterWithCallback:^{ }]; +``` + +### 自动进入刷新状态 +```objc +[self.tableView headerBeginRefreshing]; +[self.tableView footerBeginRefreshing]; +``` + +### 结束刷新 +```objc +[self.tableView headerEndRefreshing]; +[self.tableView footerEndRefreshing]; +``` + +### 可以在MJRefreshConst.h和MJRefreshConst.m文件中自定义显示的文字内容和文字颜色 + +### 本框架兼容的系统>=iOS6.0,iPhone\iPad横竖屏 + +## 期待 +* 如果在使用过程中遇到BUG,希望你能Issues我,谢谢 +* 如果在使用过程中发现功能不够用,希望你能Issues我,我非常想为这个框架增加更多好用的功能,谢谢 +* 如果你想为MJRefresh输出代码,请拼命Pull Requests我 \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Manifest.lock b/iOSStudy/iOSStudy/Pods/Manifest.lock new file mode 100644 index 0000000..ee61b81 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Manifest.lock @@ -0,0 +1,59 @@ +PODS: + - AFNetworking (2.5.1): + - AFNetworking/NSURLConnection (= 2.5.1) + - AFNetworking/NSURLSession (= 2.5.1) + - AFNetworking/Reachability (= 2.5.1) + - AFNetworking/Security (= 2.5.1) + - AFNetworking/Serialization (= 2.5.1) + - AFNetworking/UIKit (= 2.5.1) + - AFNetworking/NSURLConnection (2.5.1): + - AFNetworking/Reachability + - AFNetworking/Security + - AFNetworking/Serialization + - AFNetworking/NSURLSession (2.5.1): + - AFNetworking/Reachability + - AFNetworking/Security + - AFNetworking/Serialization + - AFNetworking/Reachability (2.5.1) + - AFNetworking/Security (2.5.1) + - AFNetworking/Serialization (2.5.1) + - AFNetworking/UIKit (2.5.1): + - AFNetworking/NSURLConnection + - AFNetworking/NSURLSession + - FMDB (2.5): + - FMDB/standard (= 2.5) + - FMDB/common (2.5) + - FMDB/standard (2.5): + - FMDB/common + - Mantle (1.5.4): + - Mantle/extobjc (= 1.5.4) + - Mantle/extobjc (1.5.4) + - MJRefresh (0.0.1) + - SDWebImage (3.7.1): + - SDWebImage/Core (= 3.7.1) + - SDWebImage/Core (3.7.1) + - SVProgressHUD (1.1.2) + - SVWebViewController (1.0) + - SWTableViewCell (0.3.7) + +DEPENDENCIES: + - AFNetworking (~> 2.0) + - FMDB + - Mantle + - MJRefresh + - SDWebImage + - SVProgressHUD + - SVWebViewController + - SWTableViewCell (~> 0.3.7) + +SPEC CHECKSUMS: + AFNetworking: 8bee59492a6ff15d69130efa4d0dc67e0094a52a + FMDB: 0efa188cf0dd1ce82c27a478cd5f5fa245308677 + Mantle: d5fbaf30fbc58031223af13812c060e15934a1fe + MJRefresh: 02638d90855109026754562b7507e5c5eabfcc65 + SDWebImage: 116e88633b5b416ea0ca4b334a4ac59cf72dd38d + SVProgressHUD: da7a49e789af645d9279ffbca62318945a832438 + SVWebViewController: fbf917baa92744c54cfb89a52a4c056e409973a4 + SWTableViewCell: 25de71898e3fcd11cf75707ef90245acf990ec03 + +COCOAPODS: 0.35.0 diff --git a/iOSStudy/iOSStudy/Pods/Mantle/LICENSE.md b/iOSStudy/iOSStudy/Pods/Mantle/LICENSE.md new file mode 100644 index 0000000..0c46720 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/LICENSE.md @@ -0,0 +1,21 @@ +**Copyright (c) 2012 - 2014, GitHub, Inc.** +**All rights reserved.** + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +**This project uses portions of code from the Proton framework.** +**Proton is copyright (c) 2012, Bitswift, Inc.** +**All rights reserved.** + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h new file mode 100644 index 0000000..368c5ab --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.h @@ -0,0 +1,172 @@ +// +// MTLJSONAdapter.h +// Mantle +// +// Created by Justin Spahr-Summers on 2013-02-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +@class MTLModel; + +// A MTLModel object that supports being parsed from and serialized to JSON. +@protocol MTLJSONSerializing +@required + +// Specifies how to map property keys to different key paths in JSON. +// +// Subclasses overriding this method should combine their values with those of +// `super`. +// +// Any property keys not present in the dictionary are assumed to match the JSON +// key that should be used. Any keys associated with NSNull will not participate +// in JSON serialization. +// +// Returns a dictionary mapping property keys to JSON key paths (as strings) or +// NSNull values. ++ (NSDictionary *)JSONKeyPathsByPropertyKey; + +@optional + +// Specifies how to convert a JSON value to the given property key. If +// reversible, the transformer will also be used to convert the property value +// back to JSON. +// +// If the receiver implements a `+JSONTransformer` method, MTLJSONAdapter +// will use the result of that method instead. +// +// Returns a value transformer, or nil if no transformation should be performed. ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key; + +// Overridden to parse the receiver as a different class, based on information +// in the provided dictionary. +// +// This is mostly useful for class clusters, where the abstract base class would +// be passed into -[MTLJSONAdapter initWithJSONDictionary:modelClass:], but +// a subclass should be instantiated instead. +// +// JSONDictionary - The JSON dictionary that will be parsed. +// +// Returns the class that should be parsed (which may be the receiver), or nil +// to abort parsing (e.g., if the data is invalid). ++ (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary; + +@end + +// The domain for errors originating from MTLJSONAdapter. +extern NSString * const MTLJSONAdapterErrorDomain; + +// +classForParsingJSONDictionary: returned nil for the given dictionary. +extern const NSInteger MTLJSONAdapterErrorNoClassFound; + +// The provided JSONDictionary is not valid. +extern const NSInteger MTLJSONAdapterErrorInvalidJSONDictionary; + +// The model's implementation of +JSONKeyPathsByPropertyKey included a key which +// does not actually exist in +propertyKeys. +extern const NSInteger MTLJSONAdapterErrorInvalidJSONMapping; + +// Converts a MTLModel object to and from a JSON dictionary. +@interface MTLJSONAdapter : NSObject + +// The model object that the receiver was initialized with, or that the receiver +// parsed from a JSON dictionary. +@property (nonatomic, strong, readonly) MTLModel *model; + +// Attempts to parse a JSON dictionary into a model object. +// +// modelClass - The MTLModel subclass to attempt to parse from the JSON. +// This class must conform to . This +// argument must not be nil. +// JSONDictionary - A dictionary representing JSON data. This should match the +// format returned by NSJSONSerialization. If this argument is +// nil, the method returns nil. +// error - If not NULL, this may be set to an error that occurs during +// parsing or initializing an instance of `modelClass`. +// +// Returns an instance of `modelClass` upon success, or nil if a parsing error +// occurred. ++ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error; + +// Attempts to parse an array of JSON dictionary objects into a model objects +// of a specific class. +// +// modelClass - The MTLModel subclass to attempt to parse from the JSON. This +// class must conform to . This argument must +// not be nil. +// JSONArray - A array of dictionaries representing JSON data. This should +// match the format returned by NSJSONSerialization. If this +// argument is nil, the method returns nil. +// error - If not NULL, this may be set to an error that occurs during +// parsing or initializing an any of the instances of +// `modelClass`. +// +// Returns an array of `modelClass` instances upon success, or nil if a parsing +// error occurred. ++ (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error; + +// Converts a model into a JSON representation. +// +// model - The model to use for JSON serialization. This argument must not be +// nil. +// +// Returns a JSON dictionary, or nil if a serialization error occurred. ++ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model; + +// Converts a array of models into a JSON representation. +// +// models - The array of models to use for JSON serialization. This argument +// must not be nil. +// +// Returns a JSON array, or nil if a serialization error occurred for any +// model. ++ (NSArray *)JSONArrayFromModels:(NSArray *)models; + +// Initializes the receiver by attempting to parse a JSON dictionary into +// a model object. +// +// JSONDictionary - A dictionary representing JSON data. This should match the +// format returned by NSJSONSerialization. If this argument is +// nil, the method returns nil and an error with code +// MTLJSONAdapterErrorInvalidJSONDictionary. +// modelClass - The MTLModel subclass to attempt to parse from the JSON. +// This class must conform to . This +// argument must not be nil. +// error - If not NULL, this may be set to an error that occurs during +// parsing or initializing an instance of `modelClass`. +// +// Returns an initialized adapter upon success, or nil if a parsing error +// occurred. +- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error; + +// Initializes the receiver with an existing model. +// +// model - The model to use for JSON serialization. This argument must not be +// nil. +- (id)initWithModel:(MTLModel *)model; + +// Serializes the receiver's `model` into JSON. +// +// Returns a JSON dictionary, or nil if a serialization error occurred. +- (NSDictionary *)JSONDictionary; + +// Looks up the JSON key path in the model's +propertyKeys. +// +// Subclasses may override this method to customize the adapter's seralizing +// behavior. You should not call this method directly. +// +// key - The property key to retrieve the corresponding JSON key path for. This +// argument must not be nil. +// +// Returns a key path to use, or nil to omit the property from JSON. +- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key; + +@end + +@interface MTLJSONAdapter (Deprecated) + ++ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary __attribute__((deprecated("Replaced by +modelOfClass:fromJSONDictionary:error:"))); +- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass __attribute__((deprecated("Replaced by -initWithJSONDictionary:modelClass:error:"))); + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m new file mode 100644 index 0000000..9872921 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLJSONAdapter.m @@ -0,0 +1,325 @@ +// +// MTLJSONAdapter.m +// Mantle +// +// Created by Justin Spahr-Summers on 2013-02-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLJSONAdapter.h" +#import "MTLModel.h" +#import "MTLReflection.h" + +NSString * const MTLJSONAdapterErrorDomain = @"MTLJSONAdapterErrorDomain"; +const NSInteger MTLJSONAdapterErrorNoClassFound = 2; +const NSInteger MTLJSONAdapterErrorInvalidJSONDictionary = 3; +const NSInteger MTLJSONAdapterErrorInvalidJSONMapping = 4; + +// An exception was thrown and caught. +const NSInteger MTLJSONAdapterErrorExceptionThrown = 1; + +// Associated with the NSException that was caught. +static NSString * const MTLJSONAdapterThrownExceptionErrorKey = @"MTLJSONAdapterThrownException"; + +@interface MTLJSONAdapter () + +// The MTLModel subclass being parsed, or the class of `model` if parsing has +// completed. +@property (nonatomic, strong, readonly) Class modelClass; + +// A cached copy of the return value of +JSONKeyPathsByPropertyKey. +@property (nonatomic, copy, readonly) NSDictionary *JSONKeyPathsByPropertyKey; + +// Looks up the NSValueTransformer that should be used for the given key. +// +// key - The property key to transform from or to. This argument must not be nil. +// +// Returns a transformer to use, or nil to not transform the property. +- (NSValueTransformer *)JSONTransformerForKey:(NSString *)key; + +@end + +@implementation MTLJSONAdapter + +#pragma mark Convenience methods + ++ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary error:(NSError **)error { + MTLJSONAdapter *adapter = [[self alloc] initWithJSONDictionary:JSONDictionary modelClass:modelClass error:error]; + return adapter.model; +} + ++ (NSArray *)modelsOfClass:(Class)modelClass fromJSONArray:(NSArray *)JSONArray error:(NSError **)error { + if (JSONArray == nil || ![JSONArray isKindOfClass:NSArray.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Missing JSON array", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%@ could not be created because an invalid JSON array was provided: %@", @""), NSStringFromClass(modelClass), JSONArray.class], + }; + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + } + return nil; + } + + NSMutableArray *models = [NSMutableArray arrayWithCapacity:JSONArray.count]; + for (NSDictionary *JSONDictionary in JSONArray){ + MTLModel *model = [self modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:error]; + + if (model == nil) return nil; + + [models addObject:model]; + } + + return models; +} + ++ (NSDictionary *)JSONDictionaryFromModel:(MTLModel *)model { + MTLJSONAdapter *adapter = [[self alloc] initWithModel:model]; + return adapter.JSONDictionary; +} + ++ (NSArray *)JSONArrayFromModels:(NSArray *)models { + NSParameterAssert(models != nil); + NSParameterAssert([models isKindOfClass:NSArray.class]); + + NSMutableArray *JSONArray = [NSMutableArray arrayWithCapacity:models.count]; + for (MTLModel *model in models) { + NSDictionary *JSONDictionary = [self JSONDictionaryFromModel:model]; + if (JSONDictionary == nil) return nil; + + [JSONArray addObject:JSONDictionary]; + } + + return JSONArray; +} + +#pragma mark Lifecycle + +- (id)init { + NSAssert(NO, @"%@ must be initialized with a JSON dictionary or model object", self.class); + return nil; +} + +- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass error:(NSError **)error { + NSParameterAssert(modelClass != nil); + NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]); + NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); + + if (JSONDictionary == nil || ![JSONDictionary isKindOfClass:NSDictionary.class]) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Missing JSON dictionary", @""), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%@ could not be created because an invalid JSON dictionary was provided: %@", @""), NSStringFromClass(modelClass), JSONDictionary.class], + }; + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + } + return nil; + } + + if ([modelClass respondsToSelector:@selector(classForParsingJSONDictionary:)]) { + modelClass = [modelClass classForParsingJSONDictionary:JSONDictionary]; + if (modelClass == nil) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Could not parse JSON", @""), + NSLocalizedFailureReasonErrorKey: NSLocalizedString(@"No model class could be found to parse the JSON dictionary.", @"") + }; + + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorNoClassFound userInfo:userInfo]; + } + + return nil; + } + + NSAssert([modelClass isSubclassOfClass:MTLModel.class], @"Class %@ returned from +classForParsingJSONDictionary: is not a subclass of MTLModel", modelClass); + NSAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)], @"Class %@ returned from +classForParsingJSONDictionary: does not conform to ", modelClass); + } + + self = [super init]; + if (self == nil) return nil; + + _modelClass = modelClass; + _JSONKeyPathsByPropertyKey = [[modelClass JSONKeyPathsByPropertyKey] copy]; + + NSMutableDictionary *dictionaryValue = [[NSMutableDictionary alloc] initWithCapacity:JSONDictionary.count]; + + NSSet *propertyKeys = [self.modelClass propertyKeys]; + + for (NSString *mappedPropertyKey in self.JSONKeyPathsByPropertyKey) { + if (![propertyKeys containsObject:mappedPropertyKey]) { + NSAssert(NO, @"%@ is not a property of %@.", mappedPropertyKey, modelClass); + return nil; + } + + id value = self.JSONKeyPathsByPropertyKey[mappedPropertyKey]; + + if (![value isKindOfClass:NSString.class] && value != NSNull.null) { + NSAssert(NO, @"%@ must either map to a JSON key path or NSNull, got: %@.",mappedPropertyKey, value); + return nil; + } + } + + for (NSString *propertyKey in propertyKeys) { + NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey]; + if (JSONKeyPath == nil) continue; + + id value; + @try { + value = [JSONDictionary valueForKeyPath:JSONKeyPath]; + } @catch (NSException *ex) { + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: NSLocalizedString(@"Invalid JSON dictionary", nil), + NSLocalizedFailureReasonErrorKey: [NSString stringWithFormat:NSLocalizedString(@"%1$@ could not be parsed because an invalid JSON dictionary was provided for key path \"%2$@\"", nil), modelClass, JSONKeyPath], + MTLJSONAdapterThrownExceptionErrorKey: ex + }; + + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorInvalidJSONDictionary userInfo:userInfo]; + } + + return nil; + } + + if (value == nil) continue; + + @try { + NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey]; + if (transformer != nil) { + // Map NSNull -> nil for the transformer, and then back for the + // dictionary we're going to insert into. + if ([value isEqual:NSNull.null]) value = nil; + value = [transformer transformedValue:value] ?: NSNull.null; + } + + dictionaryValue[propertyKey] = value; + } @catch (NSException *ex) { + NSLog(@"*** Caught exception %@ parsing JSON key path \"%@\" from: %@", ex, JSONKeyPath, JSONDictionary); + + // Fail fast in Debug builds. + #if DEBUG + @throw ex; + #else + if (error != NULL) { + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: ex.description, + NSLocalizedFailureReasonErrorKey: ex.reason, + MTLJSONAdapterThrownExceptionErrorKey: ex + }; + + *error = [NSError errorWithDomain:MTLJSONAdapterErrorDomain code:MTLJSONAdapterErrorExceptionThrown userInfo:userInfo]; + } + + return nil; + #endif + } + } + + _model = [self.modelClass modelWithDictionary:dictionaryValue error:error]; + if (_model == nil) return nil; + + return self; +} + +- (id)initWithModel:(MTLModel *)model { + NSParameterAssert(model != nil); + + self = [super init]; + if (self == nil) return nil; + + _model = model; + _modelClass = model.class; + _JSONKeyPathsByPropertyKey = [[model.class JSONKeyPathsByPropertyKey] copy]; + + return self; +} + +#pragma mark Serialization + +- (NSDictionary *)JSONDictionary { + NSDictionary *dictionaryValue = self.model.dictionaryValue; + NSMutableDictionary *JSONDictionary = [[NSMutableDictionary alloc] initWithCapacity:dictionaryValue.count]; + + [dictionaryValue enumerateKeysAndObjectsUsingBlock:^(NSString *propertyKey, id value, BOOL *stop) { + NSString *JSONKeyPath = [self JSONKeyPathForPropertyKey:propertyKey]; + if (JSONKeyPath == nil) return; + + NSValueTransformer *transformer = [self JSONTransformerForKey:propertyKey]; + if ([transformer.class allowsReverseTransformation]) { + // Map NSNull -> nil for the transformer, and then back for the + // dictionaryValue we're going to insert into. + if ([value isEqual:NSNull.null]) value = nil; + value = [transformer reverseTransformedValue:value] ?: NSNull.null; + } + + NSArray *keyPathComponents = [JSONKeyPath componentsSeparatedByString:@"."]; + + // Set up dictionaries at each step of the key path. + id obj = JSONDictionary; + for (NSString *component in keyPathComponents) { + if ([obj valueForKey:component] == nil) { + // Insert an empty mutable dictionary at this spot so that we + // can set the whole key path afterward. + [obj setValue:[NSMutableDictionary dictionary] forKey:component]; + } + + obj = [obj valueForKey:component]; + } + + [JSONDictionary setValue:value forKeyPath:JSONKeyPath]; + }]; + + return JSONDictionary; +} + +- (NSValueTransformer *)JSONTransformerForKey:(NSString *)key { + NSParameterAssert(key != nil); + + SEL selector = MTLSelectorWithKeyPattern(key, "JSONTransformer"); + if ([self.modelClass respondsToSelector:selector]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self.modelClass methodSignatureForSelector:selector]]; + invocation.target = self.modelClass; + invocation.selector = selector; + [invocation invoke]; + + __unsafe_unretained id result = nil; + [invocation getReturnValue:&result]; + return result; + } + + if ([self.modelClass respondsToSelector:@selector(JSONTransformerForKey:)]) { + return [self.modelClass JSONTransformerForKey:key]; + } + + return nil; +} + +- (NSString *)JSONKeyPathForPropertyKey:(NSString *)key { + NSParameterAssert(key != nil); + + id JSONKeyPath = self.JSONKeyPathsByPropertyKey[key]; + if ([JSONKeyPath isEqual:NSNull.null]) return nil; + + if (JSONKeyPath == nil) { + return key; + } else { + return JSONKeyPath; + } +} + +@end + +@implementation MTLJSONAdapter (Deprecated) + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-implementations" + ++ (id)modelOfClass:(Class)modelClass fromJSONDictionary:(NSDictionary *)JSONDictionary { + return [self modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:NULL]; +} + +- (id)initWithJSONDictionary:(NSDictionary *)JSONDictionary modelClass:(Class)modelClass { + return [self initWithJSONDictionary:JSONDictionary modelClass:modelClass error:NULL]; +} + +#pragma clang diagnostic pop + +@end diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.h similarity index 100% rename from iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.h rename to iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.h diff --git a/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.m similarity index 100% rename from iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.m rename to iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLManagedObjectAdapter.m diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h new file mode 100644 index 0000000..94b8f7b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.h @@ -0,0 +1,128 @@ +// +// MTLModel+NSCoding.h +// Mantle +// +// Created by Justin Spahr-Summers on 2013-02-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLModel.h" + +// Defines how a MTLModel property key should be encoded into an archive. +// +// MTLModelEncodingBehaviorExcluded - The property should never be encoded. +// MTLModelEncodingBehaviorUnconditional - The property should always be +// encoded. +// MTLModelEncodingBehaviorConditional - The object should be encoded only +// if unconditionally encoded elsewhere. +// This should only be used for object +// properties. +typedef enum : NSUInteger { + MTLModelEncodingBehaviorExcluded = 0, + MTLModelEncodingBehaviorUnconditional, + MTLModelEncodingBehaviorConditional, +} MTLModelEncodingBehavior; + +// Implements default archiving and unarchiving behaviors for MTLModel. +@interface MTLModel (NSCoding) + +// Initializes the receiver from an archive. +// +// This will decode the original +modelVersion of the archived object, then +// invoke -decodeValueForKey:withCoder:modelVersion: for each of the receiver's +// +propertyKeys. +// +// Returns an initialized model object, or nil if a decoding error occurred. +- (id)initWithCoder:(NSCoder *)coder; + +// Archives the receiver using the given coder. +// +// This will encode the receiver's +modelVersion, then the receiver's properties +// according to the behaviors specified in +encodingBehaviorsByPropertyKey. +- (void)encodeWithCoder:(NSCoder *)coder; + +// Determines how the +propertyKeys of the class are encoded into an archive. +// The values of this dictionary should be boxed MTLModelEncodingBehavior +// values. +// +// Any keys not present in the dictionary will be excluded from the archive. +// +// Subclasses overriding this method should combine their values with those of +// `super`. +// +// Returns a dictionary mapping the receiver's +propertyKeys to default encoding +// behaviors. If a property is an object with `weak` semantics, the default +// behavior is MTLModelEncodingBehaviorConditional; otherwise, the default is +// MTLModelEncodingBehaviorUnconditional. ++ (NSDictionary *)encodingBehaviorsByPropertyKey; + +// Determines the classes that are allowed to be decoded for each of the +// receiver's properties when using . The values of this +// dictionary should be NSArrays of Class objects. +// +// If any encodable keys (as determined by +encodingBehaviorsByPropertyKey) are +// not present in the dictionary, an exception will be thrown during secure +// encoding or decoding. +// +// Subclasses overriding this method should combine their values with those of +// `super`. +// +// Returns a dictionary mapping the receiver's encodable keys (as determined by +// +encodingBehaviorsByPropertyKey) to default allowed classes, based on the +// type that each property is declared as. If type of an encodable property +// cannot be determined (e.g., it is declared as `id`), it will be omitted from +// the dictionary, and subclasses must provide a valid value to prevent an +// exception being thrown during encoding/decoding. ++ (NSDictionary *)allowedSecureCodingClassesByPropertyKey; + +// Decodes the value of the given property key from an archive. +// +// By default, this method looks for a `-decodeWithCoder:modelVersion:` +// method on the receiver, and invokes it if found. +// +// If the custom method is not implemented and `coder` does not require secure +// coding, `-[NSCoder decodeObjectForKey:]` will be invoked with the given +// `key`. +// +// If the custom method is not implemented and `coder` requires secure coding, +// `-[NSCoder decodeObjectOfClasses:forKey:]` will be invoked with the +// information from +allowedSecureCodingClassesByPropertyKey and the given `key`. The +// receiver must conform to for this to work correctly. +// +// key - The property key to decode the value for. This argument cannot +// be nil. +// coder - The NSCoder representing the archive being decoded. This +// argument cannot be nil. +// modelVersion - The version of the original model object that was encoded. +// +// Returns the decoded and boxed value, or nil if the key was not present. +- (id)decodeValueForKey:(NSString *)key withCoder:(NSCoder *)coder modelVersion:(NSUInteger)modelVersion; + +// The version of this MTLModel subclass. +// +// This version number is saved in archives so that later model changes can be +// made backwards-compatible with old versions. +// +// Subclasses should override this method to return a higher version number +// whenever a breaking change is made to the model. +// +// Returns 0. ++ (NSUInteger)modelVersion; + +@end + +// This method must be overridden to support archives created by older versions +// of Mantle (before the `MTLModel+NSCoding` interface existed). +@interface MTLModel (OldArchiveSupport) + +// Converts an archived external representation to a dictionary suitable for +// passing to -initWithDictionary:. +// +// externalRepresentation - The decoded external representation of the receiver. +// fromVersion - The model version at the time the external +// representation was encoded. +// +// Returns nil by default, indicating that conversion failed. ++ (NSDictionary *)dictionaryValueFromArchivedExternalRepresentation:(NSDictionary *)externalRepresentation version:(NSUInteger)fromVersion; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m new file mode 100644 index 0000000..852f5ae --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel+NSCoding.m @@ -0,0 +1,267 @@ +// +// MTLModel+NSCoding.m +// Mantle +// +// Created by Justin Spahr-Summers on 2013-02-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLModel+NSCoding.h" +#import "EXTRuntimeExtensions.h" +#import "EXTScope.h" +#import "MTLReflection.h" +#import + +// Used in archives to store the modelVersion of the archived instance. +static NSString * const MTLModelVersionKey = @"MTLModelVersion"; + +// Used to cache the reflection performed in +allowedSecureCodingClassesByPropertyKey. +static void *MTLModelCachedAllowedClassesKey = &MTLModelCachedAllowedClassesKey; + +// Returns whether the given NSCoder requires secure coding. +static BOOL coderRequiresSecureCoding(NSCoder *coder) { + SEL requiresSecureCodingSelector = @selector(requiresSecureCoding); + + // Only invoke the method if it's implemented (i.e., only on OS X 10.8+ and + // iOS 6+). + if (![coder respondsToSelector:requiresSecureCodingSelector]) return NO; + + BOOL (*requiresSecureCodingIMP)(NSCoder *, SEL) = (__typeof__(requiresSecureCodingIMP))[coder methodForSelector:requiresSecureCodingSelector]; + if (requiresSecureCodingIMP == NULL) return NO; + + return requiresSecureCodingIMP(coder, requiresSecureCodingSelector); +} + +// Returns all of the given class' encodable property keys (those that will not +// be excluded from archives). +static NSSet *encodablePropertyKeysForClass(Class modelClass) { + return [[modelClass encodingBehaviorsByPropertyKey] keysOfEntriesPassingTest:^ BOOL (NSString *propertyKey, NSNumber *behavior, BOOL *stop) { + return behavior.unsignedIntegerValue != MTLModelEncodingBehaviorExcluded; + }]; +} + +// Verifies that all of the specified class' encodable property keys are present +// in +allowedSecureCodingClassesByPropertyKey, and throws an exception if not. +static void verifyAllowedClassesByPropertyKey(Class modelClass) { + NSDictionary *allowedClasses = [modelClass allowedSecureCodingClassesByPropertyKey]; + + NSMutableSet *specifiedPropertyKeys = [[NSMutableSet alloc] initWithArray:allowedClasses.allKeys]; + [specifiedPropertyKeys minusSet:encodablePropertyKeysForClass(modelClass)]; + + if (specifiedPropertyKeys.count > 0) { + [NSException raise:NSInvalidArgumentException format:@"Cannot encode %@ securely, because keys are missing from +allowedSecureCodingClassesByPropertyKey: %@", modelClass, specifiedPropertyKeys]; + } +} + +@implementation MTLModel (NSCoding) + +#pragma mark Versioning + ++ (NSUInteger)modelVersion { + return 0; +} + +#pragma mark Encoding Behaviors + ++ (NSDictionary *)encodingBehaviorsByPropertyKey { + NSSet *propertyKeys = self.propertyKeys; + NSMutableDictionary *behaviors = [[NSMutableDictionary alloc] initWithCapacity:propertyKeys.count]; + + for (NSString *key in propertyKeys) { + objc_property_t property = class_getProperty(self, key.UTF8String); + NSAssert(property != NULL, @"Could not find property \"%@\" on %@", key, self); + + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); + @onExit { + free(attributes); + }; + + MTLModelEncodingBehavior behavior = (attributes->weak ? MTLModelEncodingBehaviorConditional : MTLModelEncodingBehaviorUnconditional); + behaviors[key] = @(behavior); + } + + return behaviors; +} + ++ (NSDictionary *)allowedSecureCodingClassesByPropertyKey { + NSDictionary *cachedClasses = objc_getAssociatedObject(self, MTLModelCachedAllowedClassesKey); + if (cachedClasses != nil) return cachedClasses; + + // Get all property keys that could potentially be encoded. + NSSet *propertyKeys = [self.encodingBehaviorsByPropertyKey keysOfEntriesPassingTest:^ BOOL (NSString *propertyKey, NSNumber *behavior, BOOL *stop) { + return behavior.unsignedIntegerValue != MTLModelEncodingBehaviorExcluded; + }]; + + NSMutableDictionary *allowedClasses = [[NSMutableDictionary alloc] initWithCapacity:propertyKeys.count]; + + for (NSString *key in propertyKeys) { + objc_property_t property = class_getProperty(self, key.UTF8String); + NSAssert(property != NULL, @"Could not find property \"%@\" on %@", key, self); + + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); + @onExit { + free(attributes); + }; + + // If the property is not of object or class type, assume that it's + // a primitive which would be boxed into an NSValue. + if (attributes->type[0] != '@' && attributes->type[0] != '#') { + allowedClasses[key] = @[ NSValue.class ]; + continue; + } + + // Omit this property from the dictionary if its class isn't known. + if (attributes->objectClass != nil) { + allowedClasses[key] = @[ attributes->objectClass ]; + } + } + + // It doesn't really matter if we replace another thread's work, since we do + // it atomically and the result should be the same. + objc_setAssociatedObject(self, MTLModelCachedAllowedClassesKey, allowedClasses, OBJC_ASSOCIATION_COPY); + + return allowedClasses; +} + +- (id)decodeValueForKey:(NSString *)key withCoder:(NSCoder *)coder modelVersion:(NSUInteger)modelVersion { + NSParameterAssert(key != nil); + NSParameterAssert(coder != nil); + + SEL selector = MTLSelectorWithCapitalizedKeyPattern("decode", key, "WithCoder:modelVersion:"); + if ([self respondsToSelector:selector]) { + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; + invocation.target = self; + invocation.selector = selector; + [invocation setArgument:&coder atIndex:2]; + [invocation setArgument:&modelVersion atIndex:3]; + [invocation invoke]; + + __unsafe_unretained id result = nil; + [invocation getReturnValue:&result]; + return result; + } + + @try { + if (coderRequiresSecureCoding(coder)) { + NSArray *allowedClasses = self.class.allowedSecureCodingClassesByPropertyKey[key]; + NSAssert(allowedClasses != nil, @"No allowed classes specified for securely decoding key \"%@\" on %@", key, self.class); + + return [coder decodeObjectOfClasses:[NSSet setWithArray:allowedClasses] forKey:key]; + } else { + return [coder decodeObjectForKey:key]; + } + } @catch (NSException *ex) { + NSLog(@"*** Caught exception decoding value for key \"%@\" on class %@: %@", key, self.class, ex); + @throw ex; + } +} + +#pragma mark NSCoding + +- (instancetype)initWithCoder:(NSCoder *)coder { + BOOL requiresSecureCoding = coderRequiresSecureCoding(coder); + NSNumber *version = nil; + if (requiresSecureCoding) { + version = [coder decodeObjectOfClass:NSNumber.class forKey:MTLModelVersionKey]; + } else { + version = [coder decodeObjectForKey:MTLModelVersionKey]; + } + + if (version == nil) { + NSLog(@"Warning: decoding an archive of %@ without a version, assuming 0", self.class); + } else if (version.unsignedIntegerValue > self.class.modelVersion) { + // Don't try to decode newer versions. + return nil; + } + + if (requiresSecureCoding) { + verifyAllowedClassesByPropertyKey(self.class); + } else { + // Handle the old archive format. + NSDictionary *externalRepresentation = [coder decodeObjectForKey:@"externalRepresentation"]; + if (externalRepresentation != nil) { + NSAssert([self.class methodForSelector:@selector(dictionaryValueFromArchivedExternalRepresentation:version:)] != [MTLModel methodForSelector:@selector(dictionaryValueFromArchivedExternalRepresentation:version:)], @"Decoded an old archive of %@ that contains an externalRepresentation, but +dictionaryValueFromArchivedExternalRepresentation:version: is not overridden to handle it", self.class); + + NSDictionary *dictionaryValue = [self.class dictionaryValueFromArchivedExternalRepresentation:externalRepresentation version:version.unsignedIntegerValue]; + if (dictionaryValue == nil) return nil; + + NSError *error = nil; + self = [self initWithDictionary:dictionaryValue error:&error]; + if (self == nil) NSLog(@"*** Could not decode old %@ archive: %@", self.class, error); + + return self; + } + } + + NSSet *propertyKeys = self.class.propertyKeys; + NSMutableDictionary *dictionaryValue = [[NSMutableDictionary alloc] initWithCapacity:propertyKeys.count]; + + for (NSString *key in propertyKeys) { + id value = [self decodeValueForKey:key withCoder:coder modelVersion:version.unsignedIntegerValue]; + if (value == nil) continue; + + dictionaryValue[key] = value; + } + + NSError *error = nil; + self = [self initWithDictionary:dictionaryValue error:&error]; + if (self == nil) NSLog(@"*** Could not unarchive %@: %@", self.class, error); + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + if (coderRequiresSecureCoding(coder)) verifyAllowedClassesByPropertyKey(self.class); + + [coder encodeObject:@(self.class.modelVersion) forKey:MTLModelVersionKey]; + + NSDictionary *encodingBehaviors = self.class.encodingBehaviorsByPropertyKey; + [self.dictionaryValue enumerateKeysAndObjectsUsingBlock:^(NSString *key, id value, BOOL *stop) { + @try { + // Skip nil values. + if ([value isEqual:NSNull.null]) return; + + switch ([encodingBehaviors[key] unsignedIntegerValue]) { + // This will also match a nil behavior. + case MTLModelEncodingBehaviorExcluded: + break; + + case MTLModelEncodingBehaviorUnconditional: + [coder encodeObject:value forKey:key]; + break; + + case MTLModelEncodingBehaviorConditional: + [coder encodeConditionalObject:value forKey:key]; + break; + + default: + NSAssert(NO, @"Unrecognized encoding behavior %@ on class %@ for key \"%@\"", self.class, encodingBehaviors[key], key); + } + } @catch (NSException *ex) { + NSLog(@"*** Caught exception encoding value for key \"%@\" on class %@: %@", key, self.class, ex); + @throw ex; + } + }]; +} + +#pragma mark NSSecureCoding + ++ (BOOL)supportsSecureCoding { + // Disable secure coding support by default, so subclasses are forced to + // opt-in by conforming to the protocol and overriding this method. + // + // We only implement this method because XPC complains if a subclass tries + // to implement it but does not override -initWithCoder:. See + // https://github.com/github/Mantle/issues/74. + return NO; +} + +@end + +@implementation MTLModel (OldArchiveSupport) + ++ (NSDictionary *)dictionaryValueFromArchivedExternalRepresentation:(NSDictionary *)externalRepresentation version:(NSUInteger)fromVersion { + return nil; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.h new file mode 100644 index 0000000..65da40d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.h @@ -0,0 +1,125 @@ +// +// MTLModel.h +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-11. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +// An abstract base class for model objects, using reflection to provide +// sensible default behaviors. +// +// The default implementations of , -hash, and -isEqual: make use of +// the +propertyKeys method. +@interface MTLModel : NSObject + +// Returns a new instance of the receiver initialized using +// -initWithDictionary:error:. ++ (instancetype)modelWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error; + +// Initializes the receiver with default values. +// +// This is the designated initializer for this class. +- (instancetype)init; + +// Initializes the receiver using key-value coding, setting the keys and values +// in the given dictionary. +// +// Subclass implementations may override this method, calling the super +// implementation, in order to perform further processing and initialization +// after deserialization. +// +// dictionaryValue - Property keys and values to set on the receiver. Any NSNull +// values will be converted to nil before being used. KVC +// validation methods will automatically be invoked for all of +// the properties given. If nil, this method is equivalent to +// -init. +// error - If not NULL, this may be set to any error that occurs +// (like a KVC validation error). +// +// Returns an initialized model object, or nil if validation failed. +- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error; + +// Returns the keys for all @property declarations, except for `readonly` +// properties without ivars, or properties on MTLModel itself. ++ (NSSet *)propertyKeys; + +// A dictionary representing the properties of the receiver. +// +// The default implementation combines the values corresponding to all +// +propertyKeys into a dictionary, with any nil values represented by NSNull. +// +// This property must never be nil. +@property (nonatomic, copy, readonly) NSDictionary *dictionaryValue; + +// Merges the value of the given key on the receiver with the value of the same +// key from the given model object, giving precedence to the other model object. +// +// By default, this method looks for a `-mergeFromModel:` method on the +// receiver, and invokes it if found. If not found, and `model` is not nil, the +// value for the given key is taken from `model`. +- (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model; + +// Merges the values of the given model object into the receiver, using +// -mergeValueForKey:fromModel: for each key in +propertyKeys. +// +// `model` must be an instance of the receiver's class or a subclass thereof. +- (void)mergeValuesForKeysFromModel:(MTLModel *)model; + +// Compares the receiver with another object for equality. +// +// The default implementation is equivalent to comparing both models' +// -dictionaryValue. +// +// Note that this may lead to infinite loops if the receiver holds a circular +// reference to another MTLModel and both use the default behavior. +// It is recommended to override -isEqual: in this scenario. +- (BOOL)isEqual:(id)object; + +// A string that describes the contents of the receiver. +// +// The default implementation is based on the receiver's class and its +// -dictionaryValue. +// +// Note that this may lead to infinite loops if the receiver holds a circular +// reference to another MTLModel and both use the default behavior. +// It is recommended to override -description in this scenario. +- (NSString *)description; + +@end + +// Implements validation logic for MTLModel. +@interface MTLModel (Validation) + +// Validates the model. +// +// The default implementation simply invokes -validateValue:forKey:error: with +// all +propertyKeys and their current value. If -validateValue:forKey:error: +// returns a new value, the property is set to that new value. +// +// error - If not NULL, this may be set to any error that occurs during +// validation +// +// Returns YES if the model is valid, or NO if the validation failed. +- (BOOL)validate:(NSError **)error; + +@end + +@interface MTLModel (Unavailable) + ++ (instancetype)modelWithDictionary:(NSDictionary *)dictionaryValue __attribute__((deprecated("Replaced by +modelWithDictionary:error:"))); +- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue __attribute__((deprecated("Replaced by -initWithDictionary:error:"))); + ++ (instancetype)modelWithExternalRepresentation:(NSDictionary *)externalRepresentation __attribute__((deprecated("Replaced by -[MTLJSONAdapter initWithJSONDictionary:modelClass:]"))); +- (instancetype)initWithExternalRepresentation:(NSDictionary *)externalRepresentation __attribute__((deprecated("Replaced by -[MTLJSONAdapter initWithJSONDictionary:modelClass:]"))); + +@property (nonatomic, copy, readonly) NSDictionary *externalRepresentation __attribute__((deprecated("Replaced by MTLJSONAdapter.JSONDictionary"))); + ++ (NSDictionary *)externalRepresentationKeyPathsByPropertyKey __attribute__((deprecated("Replaced by +JSONKeyPathsByPropertyKey in "))); ++ (NSValueTransformer *)transformerForKey:(NSString *)key __attribute__((deprecated("Replaced by +JSONTransformerForKey: in "))); + ++ (NSDictionary *)migrateExternalRepresentation:(NSDictionary *)externalRepresentation fromVersion:(NSUInteger)fromVersion __attribute__((deprecated("Replaced by -decodeValueForKey:withCoder:modelVersion:"))); + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.m new file mode 100644 index 0000000..2ef60fe --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLModel.m @@ -0,0 +1,245 @@ +// +// MTLModel.m +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-11. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import "NSError+MTLModelException.h" +#import "MTLModel.h" +#import "EXTRuntimeExtensions.h" +#import "EXTScope.h" +#import "MTLReflection.h" +#import + +// This coupling is needed for backwards compatibility in MTLModel's deprecated +// methods. +#import "MTLJSONAdapter.h" +#import "MTLModel+NSCoding.h" + +// Used to cache the reflection performed in +propertyKeys. +static void *MTLModelCachedPropertyKeysKey = &MTLModelCachedPropertyKeysKey; + +// Validates a value for an object and sets it if necessary. +// +// obj - The object for which the value is being validated. This value +// must not be nil. +// key - The name of one of `obj`s properties. This value must not be +// nil. +// value - The new value for the property identified by `key`. +// forceUpdate - If set to `YES`, the value is being updated even if validating +// it did not change it. +// error - If not NULL, this may be set to any error that occurs during +// validation +// +// Returns YES if `value` could be validated and set, or NO if an error +// occurred. +static BOOL MTLValidateAndSetValue(id obj, NSString *key, id value, BOOL forceUpdate, NSError **error) { + // Mark this as being autoreleased, because validateValue may return + // a new object to be stored in this variable (and we don't want ARC to + // double-free or leak the old or new values). + __autoreleasing id validatedValue = value; + + @try { + if (![obj validateValue:&validatedValue forKey:key error:error]) return NO; + + if (forceUpdate || value != validatedValue) { + [obj setValue:validatedValue forKey:key]; + } + + return YES; + } @catch (NSException *ex) { + NSLog(@"*** Caught exception setting key \"%@\" : %@", key, ex); + + // Fail fast in Debug builds. + #if DEBUG + @throw ex; + #else + if (error != NULL) { + *error = [NSError mtl_modelErrorWithException:ex]; + } + + return NO; + #endif + } +} + +@interface MTLModel () + +// Enumerates all properties of the receiver's class hierarchy, starting at the +// receiver, and continuing up until (but not including) MTLModel. +// +// The given block will be invoked multiple times for any properties declared on +// multiple classes in the hierarchy. ++ (void)enumeratePropertiesUsingBlock:(void (^)(objc_property_t property, BOOL *stop))block; + +@end + +@implementation MTLModel + +#pragma mark Lifecycle + ++ (instancetype)modelWithDictionary:(NSDictionary *)dictionary error:(NSError **)error { + return [[self alloc] initWithDictionary:dictionary error:error]; +} + +- (instancetype)init { + // Nothing special by default, but we have a declaration in the header. + return [super init]; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionary error:(NSError **)error { + self = [self init]; + if (self == nil) return nil; + + for (NSString *key in dictionary) { + // Mark this as being autoreleased, because validateValue may return + // a new object to be stored in this variable (and we don't want ARC to + // double-free or leak the old or new values). + __autoreleasing id value = [dictionary objectForKey:key]; + + if ([value isEqual:NSNull.null]) value = nil; + + BOOL success = MTLValidateAndSetValue(self, key, value, YES, error); + if (!success) return nil; + } + + return self; +} + +#pragma mark Reflection + ++ (void)enumeratePropertiesUsingBlock:(void (^)(objc_property_t property, BOOL *stop))block { + Class cls = self; + BOOL stop = NO; + + while (!stop && ![cls isEqual:MTLModel.class]) { + unsigned count = 0; + objc_property_t *properties = class_copyPropertyList(cls, &count); + + cls = cls.superclass; + if (properties == NULL) continue; + + @onExit { + free(properties); + }; + + for (unsigned i = 0; i < count; i++) { + block(properties[i], &stop); + if (stop) break; + } + } +} + ++ (NSSet *)propertyKeys { + NSSet *cachedKeys = objc_getAssociatedObject(self, MTLModelCachedPropertyKeysKey); + if (cachedKeys != nil) return cachedKeys; + + NSMutableSet *keys = [NSMutableSet set]; + + [self enumeratePropertiesUsingBlock:^(objc_property_t property, BOOL *stop) { + mtl_propertyAttributes *attributes = mtl_copyPropertyAttributes(property); + @onExit { + free(attributes); + }; + + if (attributes->readonly && attributes->ivar == NULL) return; + + NSString *key = @(property_getName(property)); + [keys addObject:key]; + }]; + + // It doesn't really matter if we replace another thread's work, since we do + // it atomically and the result should be the same. + objc_setAssociatedObject(self, MTLModelCachedPropertyKeysKey, keys, OBJC_ASSOCIATION_COPY); + + return keys; +} + +- (NSDictionary *)dictionaryValue { + return [self dictionaryWithValuesForKeys:self.class.propertyKeys.allObjects]; +} + +#pragma mark Merging + +- (void)mergeValueForKey:(NSString *)key fromModel:(MTLModel *)model { + NSParameterAssert(key != nil); + + SEL selector = MTLSelectorWithCapitalizedKeyPattern("merge", key, "FromModel:"); + if (![self respondsToSelector:selector]) { + if (model != nil) { + [self setValue:[model valueForKey:key] forKey:key]; + } + + return; + } + + NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:selector]]; + invocation.target = self; + invocation.selector = selector; + + [invocation setArgument:&model atIndex:2]; + [invocation invoke]; +} + +- (void)mergeValuesForKeysFromModel:(MTLModel *)model { + NSSet *propertyKeys = model.class.propertyKeys; + for (NSString *key in self.class.propertyKeys) { + if (![propertyKeys containsObject:key]) continue; + + [self mergeValueForKey:key fromModel:model]; + } +} + +#pragma mark Validation + +- (BOOL)validate:(NSError **)error { + for (NSString *key in self.class.propertyKeys) { + id value = [self valueForKey:key]; + + BOOL success = MTLValidateAndSetValue(self, key, value, NO, error); + if (!success) return NO; + } + + return YES; +} + +#pragma mark NSCopying + +- (instancetype)copyWithZone:(NSZone *)zone { + return [[self.class allocWithZone:zone] initWithDictionary:self.dictionaryValue error:NULL]; +} + +#pragma mark NSObject + +- (NSString *)description { + return [NSString stringWithFormat:@"<%@: %p> %@", self.class, self, self.dictionaryValue]; +} + +- (NSUInteger)hash { + NSUInteger value = 0; + + for (NSString *key in self.class.propertyKeys) { + value ^= [[self valueForKey:key] hash]; + } + + return value; +} + +- (BOOL)isEqual:(MTLModel *)model { + if (self == model) return YES; + if (![model isMemberOfClass:self.class]) return NO; + + for (NSString *key in self.class.propertyKeys) { + id selfValue = [self valueForKey:key]; + id modelValue = [model valueForKey:key]; + + BOOL valuesEqual = ((selfValue == nil && modelValue == nil) || [selfValue isEqual:modelValue]); + if (!valuesEqual) return NO; + } + + return YES; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h new file mode 100644 index 0000000..f4c100e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.h @@ -0,0 +1,31 @@ +// +// MTLReflection.h +// Mantle +// +// Created by Justin Spahr-Summers on 2013-03-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +// Creates a selector from a key and a constant string. +// +// key - The key to insert into the generated selector. This key should be in +// its natural case. +// suffix - A string to append to the key as part of the selector. +// +// Returns a selector, or NULL if the input strings cannot form a valid +// selector. +SEL MTLSelectorWithKeyPattern(NSString *key, const char *suffix) __attribute__((pure, nonnull(1, 2))); + +// Creates a selector from a key and a constant prefix and suffix. +// +// prefix - A string to prepend to the key as part of the selector. +// key - The key to insert into the generated selector. This key should be in +// its natural case, and will have its first letter capitalized when +// inserted. +// suffix - A string to append to the key as part of the selector. +// +// Returns a selector, or NULL if the input strings cannot form a valid +// selector. +SEL MTLSelectorWithCapitalizedKeyPattern(const char *prefix, NSString *key, const char *suffix) __attribute__((pure, nonnull(1, 2, 3))); diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.m new file mode 100644 index 0000000..923e9e2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLReflection.m @@ -0,0 +1,50 @@ +// +// MTLReflection.m +// Mantle +// +// Created by Justin Spahr-Summers on 2013-03-12. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLReflection.h" +#import + +SEL MTLSelectorWithKeyPattern(NSString *key, const char *suffix) { + NSUInteger keyLength = [key maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + NSUInteger suffixLength = strlen(suffix); + + char selector[keyLength + suffixLength + 1]; + + BOOL success = [key getBytes:selector maxLength:keyLength usedLength:&keyLength encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0, key.length) remainingRange:NULL]; + if (!success) return NULL; + + memcpy(selector + keyLength, suffix, suffixLength); + selector[keyLength + suffixLength] = '\0'; + + return sel_registerName(selector); +} + +SEL MTLSelectorWithCapitalizedKeyPattern(const char *prefix, NSString *key, const char *suffix) { + NSUInteger prefixLength = strlen(prefix); + NSUInteger suffixLength = strlen(suffix); + + NSString *initial = [key substringToIndex:1].uppercaseString; + NSUInteger initialLength = [initial maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + NSString *rest = [key substringFromIndex:1]; + NSUInteger restLength = [rest maximumLengthOfBytesUsingEncoding:NSUTF8StringEncoding]; + + char selector[prefixLength + initialLength + restLength + suffixLength + 1]; + memcpy(selector, prefix, prefixLength); + + BOOL success = [initial getBytes:selector + prefixLength maxLength:initialLength usedLength:&initialLength encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0, initial.length) remainingRange:NULL]; + if (!success) return NULL; + + success = [rest getBytes:selector + prefixLength + initialLength maxLength:restLength usedLength:&restLength encoding:NSUTF8StringEncoding options:0 range:NSMakeRange(0, rest.length) remainingRange:NULL]; + if (!success) return NULL; + + memcpy(selector + prefixLength + initialLength + restLength, suffix, suffixLength); + selector[prefixLength + initialLength + restLength + suffixLength] = '\0'; + + return sel_registerName(selector); +} diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h new file mode 100644 index 0000000..231b59f --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.h @@ -0,0 +1,29 @@ +// +// MTLValueTransformer.h +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-11. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +typedef id (^MTLValueTransformerBlock)(id); + +// +// A value transformer supporting block-based transformation. +// +@interface MTLValueTransformer : NSValueTransformer + +// Returns a transformer which transforms values using the given block. Reverse +// transformations will not be allowed. ++ (instancetype)transformerWithBlock:(MTLValueTransformerBlock)transformationBlock; + +// Returns a transformer which transforms values using the given block, for +// forward or reverse transformations. ++ (instancetype)reversibleTransformerWithBlock:(MTLValueTransformerBlock)transformationBlock; + +// Returns a transformer which transforms values using the given blocks. ++ (instancetype)reversibleTransformerWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m new file mode 100644 index 0000000..5400d45 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/MTLValueTransformer.m @@ -0,0 +1,88 @@ +// +// MTLValueTransformer.m +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-11. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import "MTLValueTransformer.h" + +// +// Any MTLValueTransformer supporting reverse transformation. Necessary because +// +allowsReverseTransformation is a class method. +// +@interface MTLReversibleValueTransformer : MTLValueTransformer +@end + +@interface MTLValueTransformer () + +@property (nonatomic, copy, readonly) MTLValueTransformerBlock forwardBlock; +@property (nonatomic, copy, readonly) MTLValueTransformerBlock reverseBlock; + +@end + +@implementation MTLValueTransformer + +#pragma mark Lifecycle + ++ (instancetype)transformerWithBlock:(MTLValueTransformerBlock)transformationBlock { + return [[self alloc] initWithForwardBlock:transformationBlock reverseBlock:nil]; +} + ++ (instancetype)reversibleTransformerWithBlock:(MTLValueTransformerBlock)transformationBlock { + return [self reversibleTransformerWithForwardBlock:transformationBlock reverseBlock:transformationBlock]; +} + ++ (instancetype)reversibleTransformerWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock { + return [[MTLReversibleValueTransformer alloc] initWithForwardBlock:forwardBlock reverseBlock:reverseBlock]; +} + +- (id)initWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock { + NSParameterAssert(forwardBlock != nil); + + self = [super init]; + if (self == nil) return nil; + + _forwardBlock = [forwardBlock copy]; + _reverseBlock = [reverseBlock copy]; + + return self; +} + +#pragma mark NSValueTransformer + ++ (BOOL)allowsReverseTransformation { + return NO; +} + ++ (Class)transformedValueClass { + return [NSObject class]; +} + +- (id)transformedValue:(id)value { + return self.forwardBlock(value); +} + +@end + +@implementation MTLReversibleValueTransformer + +#pragma mark Lifecycle + +- (id)initWithForwardBlock:(MTLValueTransformerBlock)forwardBlock reverseBlock:(MTLValueTransformerBlock)reverseBlock { + NSParameterAssert(reverseBlock != nil); + return [super initWithForwardBlock:forwardBlock reverseBlock:reverseBlock]; +} + +#pragma mark NSValueTransformer + ++ (BOOL)allowsReverseTransformation { + return YES; +} + +- (id)reverseTransformedValue:(id)value { + return self.reverseBlock(value); +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/Mantle.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/Mantle.h new file mode 100644 index 0000000..ebd74e7 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/Mantle.h @@ -0,0 +1,26 @@ +// +// Mantle.h +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-04. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +//! Project version number for Mantle. +FOUNDATION_EXPORT double MantleVersionNumber; + +//! Project version string for Mantle. +FOUNDATION_EXPORT const unsigned char MantleVersionString[]; + +#import +#import +#import +#import +#import +#import +#import +#import +#import +#import diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h new file mode 100644 index 0000000..fd7347c --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.h @@ -0,0 +1,28 @@ +// +// NSArray+MTLManipulationAdditions.h +// Mantle +// +// Created by Josh Abernathy on 9/19/12. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +@interface NSArray (MTLManipulationAdditions) + +// The first object in the array or nil if the array is empty. +// Forwards to `firstObject` which has been first declared in iOS7, but works with iOS4/10.6. +@property (nonatomic, readonly, strong) id mtl_firstObject; + +// Returns a new array without all instances of the given object. +- (NSArray *)mtl_arrayByRemovingObject:(id)object; + +// Returns a new array without the first object. If the array is empty, it +// returns the empty array. +- (NSArray *)mtl_arrayByRemovingFirstObject; + +// Returns a new array without the last object. If the array is empty, it +// returns the empty array. +- (NSArray *)mtl_arrayByRemovingLastObject; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.m new file mode 100644 index 0000000..e6932c9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSArray+MTLManipulationAdditions.m @@ -0,0 +1,42 @@ +// +// NSArray+MTLManipulationAdditions.m +// Mantle +// +// Created by Josh Abernathy on 9/19/12. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import "NSArray+MTLManipulationAdditions.h" + +@interface NSArray (MTLDeclarations) + +// This declaration is needed so Mantle can be compiled with SDK 6 / 10.8. +- (id)firstObject; + +@end + +@implementation NSArray (MTLManipulationAdditions) + +- (id)mtl_firstObject { + return self.firstObject; +} + +- (instancetype)mtl_arrayByRemovingObject:(id)object { + NSMutableArray *result = [self mutableCopy]; + [result removeObject:object]; + return result; +} + +- (instancetype)mtl_arrayByRemovingFirstObject { + if (self.count == 0) return self; + + return [self subarrayWithRange:NSMakeRange(1, self.count - 1)]; +} + +- (instancetype)mtl_arrayByRemovingLastObject { + if (self.count == 0) return self; + + return [self subarrayWithRange:NSMakeRange(0, self.count - 1)]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h new file mode 100644 index 0000000..83254d3 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.h @@ -0,0 +1,25 @@ +// +// NSDictionary+MTLManipulationAdditions.h +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-24. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +@interface NSDictionary (MTLManipulationAdditions) + +// Merges the keys and values from the given dictionary into the receiver. If +// both the receiver and `dictionary` have a given key, the value from +// `dictionary` is used. +// +// Returns a new dictionary containing the entries of the receiver combined with +// those of `dictionary`. +- (NSDictionary *)mtl_dictionaryByAddingEntriesFromDictionary:(NSDictionary *)dictionary; + +// Creates a new dictionary with all the entries for the given keys removed from +// the receiver. +- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m new file mode 100644 index 0000000..0ed5746 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSDictionary+MTLManipulationAdditions.m @@ -0,0 +1,25 @@ +// +// NSDictionary+MTLManipulationAdditions.m +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-24. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import "NSDictionary+MTLManipulationAdditions.h" + +@implementation NSDictionary (MTLManipulationAdditions) + +- (NSDictionary *)mtl_dictionaryByAddingEntriesFromDictionary:(NSDictionary *)dictionary { + NSMutableDictionary *result = [self mutableCopy]; + [result addEntriesFromDictionary:dictionary]; + return result; +} + +- (NSDictionary *)mtl_dictionaryByRemovingEntriesWithKeys:(NSSet *)keys { + NSMutableDictionary *result = [self mutableCopy]; + [result removeObjectsForKeys:keys.allObjects]; + return result; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h new file mode 100644 index 0000000..f7c1e9e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.h @@ -0,0 +1,23 @@ +// +// NSError+MTLModelException.h +// Mantle +// +// Created by Robert Böhnke on 7/6/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +@interface NSError (MTLModelException) + +// Creates a new error for an exception that occured during updating an +// MTLModel. +// +// exception - The exception that was thrown while updating the model. +// This argument must not be nil. +// +// Returns an error that takes its localized description and failure reason +// from the exception. ++ (instancetype)mtl_modelErrorWithException:(NSException *)exception; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.m new file mode 100644 index 0000000..8b71e06 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSError+MTLModelException.m @@ -0,0 +1,36 @@ +// +// NSError+MTLModelException.m +// Mantle +// +// Created by Robert Böhnke on 7/6/13. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "MTLModel.h" + +#import "NSError+MTLModelException.h" + +// The domain for errors originating from MTLModel. +static NSString * const MTLModelErrorDomain = @"MTLModelErrorDomain"; + +// An exception was thrown and caught. +static const NSInteger MTLModelErrorExceptionThrown = 1; + +// Associated with the NSException that was caught. +static NSString * const MTLModelThrownExceptionErrorKey = @"MTLModelThrownException"; + +@implementation NSError (MTLModelException) + ++ (instancetype)mtl_modelErrorWithException:(NSException *)exception { + NSParameterAssert(exception != nil); + + NSDictionary *userInfo = @{ + NSLocalizedDescriptionKey: exception.description, + NSLocalizedFailureReasonErrorKey: exception.reason, + MTLModelThrownExceptionErrorKey: exception + }; + + return [NSError errorWithDomain:MTLModelErrorDomain code:MTLModelErrorExceptionThrown userInfo:userInfo]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h new file mode 100644 index 0000000..4f7c03e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.h @@ -0,0 +1,15 @@ +// +// NSObject+MTLComparisonAdditions.h +// Mantle +// +// Created by Josh Vera on 10/26/12. +// Copyright (c) 2012 GitHub. All rights reserved. +// +// Portions copyright (c) 2011 Bitswift. All rights reserved. +// See the LICENSE file for more information. +// + +#import + +// Returns whether both objects are identical or equal via -isEqual: +BOOL MTLEqualObjects(id obj1, id obj2); diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.m new file mode 100644 index 0000000..3b77b35 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSObject+MTLComparisonAdditions.m @@ -0,0 +1,16 @@ +// +// NSObject+MTLComparisonAdditions.m +// Mantle +// +// Created by Josh Vera on 10/26/12. +// Copyright (c) 2012 GitHub. All rights reserved. +// +// Portions copyright (c) 2011 Bitswift. All rights reserved. +// See the LICENSE file for more information. +// + +#import "NSObject+MTLComparisonAdditions.h" + +BOOL MTLEqualObjects(id obj1, id obj2) { + return (obj1 == obj2 || [obj1 isEqual:obj2]); +} diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h new file mode 100644 index 0000000..eefceec --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.h @@ -0,0 +1,21 @@ +// +// NSValueTransformer+MTLInversionAdditions.h +// Mantle +// +// Created by Justin Spahr-Summers on 2013-05-18. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import + +@interface NSValueTransformer (MTLInversionAdditions) + +// Flips the direction of the receiver's transformation, such that +// -transformedValue: will become -reverseTransformedValue:, and vice-versa. +// +// The receiver must allow reverse transformation. +// +// Returns an inverted transformer. +- (NSValueTransformer *)mtl_invertedTransformer; + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m new file mode 100644 index 0000000..71fe4b0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLInversionAdditions.m @@ -0,0 +1,24 @@ +// +// NSValueTransformer+MTLInversionAdditions.m +// Mantle +// +// Created by Justin Spahr-Summers on 2013-05-18. +// Copyright (c) 2013 GitHub. All rights reserved. +// + +#import "NSValueTransformer+MTLInversionAdditions.h" +#import "MTLValueTransformer.h" + +@implementation NSValueTransformer (MTLInversionAdditions) + +- (NSValueTransformer *)mtl_invertedTransformer { + NSParameterAssert(self.class.allowsReverseTransformation); + + return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(id value) { + return [self reverseTransformedValue:value]; + } reverseBlock:^(id value) { + return [self transformedValue:value]; + }]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h new file mode 100644 index 0000000..78a6b19 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h @@ -0,0 +1,84 @@ +// +// NSValueTransformer+MTLPredefinedTransformerAdditions.h +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-27. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import + +// The name for a value transformer that converts strings into URLs and back. +extern NSString * const MTLURLValueTransformerName; + +// Ensure an NSNumber is backed by __NSCFBoolean/CFBooleanRef +// +// NSJSONSerialization, and likely other serialization libraries, ordinarily +// serialize NSNumbers as numbers, and thus booleans would be serialized as +// 0/1. The exception is when the NSNumber is backed by __NSCFBoolean, which, +// though very much an implementation detail, is detected and serialized as a +// proper boolean. +extern NSString * const MTLBooleanValueTransformerName; + +@interface NSValueTransformer (MTLPredefinedTransformerAdditions) + +// Creates a reversible transformer to convert a JSON dictionary into a MTLModel +// object, and vice-versa. +// +// modelClass - The MTLModel subclass to attempt to parse from the JSON. This +// class must conform to . This argument must +// not be nil. +// +// Returns a reversible transformer which uses MTLJSONAdapter for transforming +// values back and forth. ++ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass; + +// Creates a reversible transformer to convert an array of JSON dictionaries +// into an array of MTLModel objects, and vice-versa. +// +// modelClass - The MTLModel subclass to attempt to parse from each JSON +// dictionary. This class must conform to . +// This argument must not be nil. +// +// Returns a reversible transformer which uses MTLJSONAdapter for transforming +// array elements back and forth. ++ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass; + +// A reversible value transformer to transform between the keys and objects of a +// dictionary. +// +// dictionary - The dictionary whose keys and values should be +// transformed between. This argument must not be nil. +// defaultValue - The result to fall back to, in case no key matching the +// input value was found during a forward transformation. +// reverseDefaultValue - The result to fall back to, in case no value matching +// the input value was found during a reverse +// transformation. +// +// Can for example be used for transforming between enum values and their string +// representation. +// +// NSValueTransformer *valueTransformer = [NSValueTransformer mtl_valueMappingTransformerWithDictionary:@{ +// @"foo": @(EnumDataTypeFoo), +// @"bar": @(EnumDataTypeBar), +// } defaultValue: @(EnumDataTypeUndefined) reverseDefaultValue: @"undefined"]; +// +// Returns a transformer that will map from keys to values in dictionary +// for forward transformation, and from values to keys for reverse +// transformations. If no matching key or value can be found, the respective +// default value is returned. ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue; + +// Returns a value transformer created by calling +// `+mtl_valueMappingTransformerWithDictionary:defaultValue:reverseDefaultValue:` +// with a default value of `nil` and a reverse default value of `nil`. ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary; + +@end + +@interface NSValueTransformer (UnavailableMTLPredefinedTransformerAdditions) + ++ (NSValueTransformer *)mtl_externalRepresentationTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +mtl_JSONDictionaryTransformerWithModelClass:"))); ++ (NSValueTransformer *)mtl_externalRepresentationArrayTransformerWithModelClass:(Class)modelClass __attribute__((deprecated("Replaced by +mtl_JSONArrayTransformerWithModelClass:"))); + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m new file mode 100644 index 0000000..10622a0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m @@ -0,0 +1,141 @@ +// +// NSValueTransformer+MTLPredefinedTransformerAdditions.m +// Mantle +// +// Created by Justin Spahr-Summers on 2012-09-27. +// Copyright (c) 2012 GitHub. All rights reserved. +// + +#import "NSValueTransformer+MTLPredefinedTransformerAdditions.h" +#import "MTLJSONAdapter.h" +#import "MTLModel.h" +#import "MTLValueTransformer.h" + +NSString * const MTLURLValueTransformerName = @"MTLURLValueTransformerName"; +NSString * const MTLBooleanValueTransformerName = @"MTLBooleanValueTransformerName"; + +@implementation NSValueTransformer (MTLPredefinedTransformerAdditions) + +#pragma mark Category Loading + ++ (void)load { + @autoreleasepool { + MTLValueTransformer *URLValueTransformer = [MTLValueTransformer + reversibleTransformerWithForwardBlock:^ id (NSString *str) { + if (![str isKindOfClass:NSString.class]) return nil; + return [NSURL URLWithString:str]; + } + reverseBlock:^ id (NSURL *URL) { + if (![URL isKindOfClass:NSURL.class]) return nil; + return URL.absoluteString; + }]; + + [NSValueTransformer setValueTransformer:URLValueTransformer forName:MTLURLValueTransformerName]; + + MTLValueTransformer *booleanValueTransformer = [MTLValueTransformer + reversibleTransformerWithBlock:^ id (NSNumber *boolean) { + if (![boolean isKindOfClass:NSNumber.class]) return nil; + return (NSNumber *)(boolean.boolValue ? kCFBooleanTrue : kCFBooleanFalse); + }]; + + [NSValueTransformer setValueTransformer:booleanValueTransformer forName:MTLBooleanValueTransformerName]; + } +} + +#pragma mark Customizable Transformers + ++ (NSValueTransformer *)mtl_JSONDictionaryTransformerWithModelClass:(Class)modelClass { + NSParameterAssert([modelClass isSubclassOfClass:MTLModel.class]); + NSParameterAssert([modelClass conformsToProtocol:@protocol(MTLJSONSerializing)]); + + return [MTLValueTransformer + reversibleTransformerWithForwardBlock:^ id (id JSONDictionary) { + if (JSONDictionary == nil) return nil; + + NSAssert([JSONDictionary isKindOfClass:NSDictionary.class], @"Expected a dictionary, got: %@", JSONDictionary); + + return [MTLJSONAdapter modelOfClass:modelClass fromJSONDictionary:JSONDictionary error:NULL]; + } + reverseBlock:^ id (id model) { + if (model == nil) return nil; + + NSAssert([model isKindOfClass:MTLModel.class], @"Expected a MTLModel object, got %@", model); + NSAssert([model conformsToProtocol:@protocol(MTLJSONSerializing)], @"Expected a model object conforming to , got %@", model); + + return [MTLJSONAdapter JSONDictionaryFromModel:model]; + }]; +} + ++ (NSValueTransformer *)mtl_JSONArrayTransformerWithModelClass:(Class)modelClass { + NSValueTransformer *dictionaryTransformer = [self mtl_JSONDictionaryTransformerWithModelClass:modelClass]; + + return [MTLValueTransformer + reversibleTransformerWithForwardBlock:^ id (NSArray *dictionaries) { + if (dictionaries == nil) return nil; + + NSAssert([dictionaries isKindOfClass:NSArray.class], @"Expected an array of dictionaries, got: %@", dictionaries); + + NSMutableArray *models = [NSMutableArray arrayWithCapacity:dictionaries.count]; + for (id JSONDictionary in dictionaries) { + if (JSONDictionary == NSNull.null) { + [models addObject:NSNull.null]; + continue; + } + + NSAssert([JSONDictionary isKindOfClass:NSDictionary.class], @"Expected a dictionary or an NSNull, got: %@", JSONDictionary); + + id model = [dictionaryTransformer transformedValue:JSONDictionary]; + if (model == nil) continue; + + [models addObject:model]; + } + + return models; + } + reverseBlock:^ id (NSArray *models) { + if (models == nil) return nil; + + NSAssert([models isKindOfClass:NSArray.class], @"Expected an array of MTLModels, got: %@", models); + + NSMutableArray *dictionaries = [NSMutableArray arrayWithCapacity:models.count]; + for (id model in models) { + if (model == NSNull.null) { + [dictionaries addObject:NSNull.null]; + continue; + } + + NSAssert([model isKindOfClass:MTLModel.class], @"Expected an MTLModel or an NSNull, got: %@", model); + + NSDictionary *dict = [dictionaryTransformer reverseTransformedValue:model]; + if (dict == nil) continue; + + [dictionaries addObject:dict]; + } + + return dictionaries; + }]; +} + ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary { + return [self mtl_valueMappingTransformerWithDictionary:dictionary defaultValue:nil reverseDefaultValue:nil]; +} + ++ (NSValueTransformer *)mtl_valueMappingTransformerWithDictionary:(NSDictionary *)dictionary defaultValue:(id)defaultValue reverseDefaultValue:(id)reverseDefaultValue { + NSParameterAssert(dictionary != nil); + NSParameterAssert(dictionary.count == [[NSSet setWithArray:dictionary.allValues] count]); + + return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(id key) { + return dictionary[key ?: NSNull.null] ?: defaultValue; + } reverseBlock:^(id object) { + __block id result = nil; + [dictionary enumerateKeysAndObjectsUsingBlock:^(id key, id anObject, BOOL *stop) { + if ([object isEqual:anObject]) { + result = key; + *stop = YES; + } + }]; + return result ?: reverseDefaultValue; + }]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTKeyPathCoding.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTKeyPathCoding.h new file mode 100644 index 0000000..f34dc4a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTKeyPathCoding.h @@ -0,0 +1,68 @@ +// +// EXTKeyPathCoding.h +// extobjc +// +// Created by Justin Spahr-Summers on 19.06.12. +// Copyright (C) 2012 Justin Spahr-Summers. +// Released under the MIT license. +// + +#import +#import "metamacros.h" + +/** + * \@keypath allows compile-time verification of key paths. Given a real object + * receiver and key path: + * + * @code + +NSString *UTF8StringPath = @keypath(str.lowercaseString.UTF8String); +// => @"lowercaseString.UTF8String" + +NSString *versionPath = @keypath(NSObject, version); +// => @"version" + +NSString *lowercaseStringPath = @keypath(NSString.new, lowercaseString); +// => @"lowercaseString" + + * @endcode + * + * ... the macro returns an \c NSString containing all but the first path + * component or argument (e.g., @"lowercaseString.UTF8String", @"version"). + * + * In addition to simply creating a key path, this macro ensures that the key + * path is valid at compile-time (causing a syntax error if not), and supports + * refactoring, such that changing the name of the property will also update any + * uses of \@keypath. + */ +#define keypath(...) \ + metamacro_if_eq(1, metamacro_argcount(__VA_ARGS__))(keypath1(__VA_ARGS__))(keypath2(__VA_ARGS__)) + +#define keypath1(PATH) \ + (((void)(NO && ((void)PATH, NO)), strchr(# PATH, '.') + 1)) + +#define keypath2(OBJ, PATH) \ + (((void)(NO && ((void)OBJ.PATH, NO)), # PATH)) + +/** + * \@collectionKeypath allows compile-time verification of key paths across collections NSArray/NSSet etc. Given a real object + * receiver, collection object receiver and related keypaths: + * + * @code + + NSString *employessFirstNamePath = @collectionKeypath(department.employees, Employee.new, firstName) + // => @"employees.firstName" + + NSString *employessFirstNamePath = @collectionKeypath(Department.new, employees, Employee.new, firstName) + // => @"employees.firstName" + + * @endcode + * + */ +#define collectionKeypath(...) \ + metamacro_if_eq(3, metamacro_argcount(__VA_ARGS__))(collectionKeypath3(__VA_ARGS__))(collectionKeypath4(__VA_ARGS__)) + +#define collectionKeypath3(PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) + +#define collectionKeypath4(OBJ, PATH, COLLECTION_OBJECT, COLLECTION_PATH) ([[NSString stringWithFormat:@"%s.%s",keypath(OBJ, PATH), keypath(COLLECTION_OBJECT, COLLECTION_PATH)] UTF8String]) + diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.h new file mode 100644 index 0000000..191d749 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.h @@ -0,0 +1,113 @@ +// +// EXTRuntimeExtensions.h +// extobjc +// +// Created by Justin Spahr-Summers on 2011-03-05. +// Copyright (C) 2012 Justin Spahr-Summers. +// Released under the MIT license. +// + +#import + +/** + * Describes the memory management policy of a property. + */ +typedef enum { + /** + * The value is assigned. + */ + mtl_propertyMemoryManagementPolicyAssign = 0, + + /** + * The value is retained. + */ + mtl_propertyMemoryManagementPolicyRetain, + + /** + * The value is copied. + */ + mtl_propertyMemoryManagementPolicyCopy +} mtl_propertyMemoryManagementPolicy; + +/** + * Describes the attributes and type information of a property. + */ +typedef struct { + /** + * Whether this property was declared with the \c readonly attribute. + */ + BOOL readonly; + + /** + * Whether this property was declared with the \c nonatomic attribute. + */ + BOOL nonatomic; + + /** + * Whether the property is a weak reference. + */ + BOOL weak; + + /** + * Whether the property is eligible for garbage collection. + */ + BOOL canBeCollected; + + /** + * Whether this property is defined with \c \@dynamic. + */ + BOOL dynamic; + + /** + * The memory management policy for this property. This will always be + * #mtl_propertyMemoryManagementPolicyAssign if #readonly is \c YES. + */ + mtl_propertyMemoryManagementPolicy memoryManagementPolicy; + + /** + * The selector for the getter of this property. This will reflect any + * custom \c getter= attribute provided in the property declaration, or the + * inferred getter name otherwise. + */ + SEL getter; + + /** + * The selector for the setter of this property. This will reflect any + * custom \c setter= attribute provided in the property declaration, or the + * inferred setter name otherwise. + * + * @note If #readonly is \c YES, this value will represent what the setter + * \e would be, if the property were writable. + */ + SEL setter; + + /** + * The backing instance variable for this property, or \c NULL if \c + * \c @synthesize was not used, and therefore no instance variable exists. This + * would also be the case if the property is implemented dynamically. + */ + const char *ivar; + + /** + * If this property is defined as being an instance of a specific class, + * this will be the class object representing it. + * + * This will be \c nil if the property was defined as type \c id, if the + * property is not of an object type, or if the class could not be found at + * runtime. + */ + Class objectClass; + + /** + * The type encoding for the value of this property. This is the type as it + * would be returned by the \c \@encode() directive. + */ + char type[]; +} mtl_propertyAttributes; + +/** + * Returns a pointer to a structure containing information about \a property. + * You must \c free() the returned pointer. Returns \c NULL if there is an error + * obtaining information from \a property. + */ +mtl_propertyAttributes *mtl_copyPropertyAttributes (objc_property_t property); diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.m new file mode 100644 index 0000000..6a034b0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTRuntimeExtensions.m @@ -0,0 +1,211 @@ +// +// EXTRuntimeExtensions.m +// extobjc +// +// Created by Justin Spahr-Summers on 2011-03-05. +// Copyright (C) 2012 Justin Spahr-Summers. +// Released under the MIT license. +// + +#import "EXTRuntimeExtensions.h" + +#import + +mtl_propertyAttributes *mtl_copyPropertyAttributes (objc_property_t property) { + const char * const attrString = property_getAttributes(property); + if (!attrString) { + fprintf(stderr, "ERROR: Could not get attribute string from property %s\n", property_getName(property)); + return NULL; + } + + if (attrString[0] != 'T') { + fprintf(stderr, "ERROR: Expected attribute string \"%s\" for property %s to start with 'T'\n", attrString, property_getName(property)); + return NULL; + } + + const char *typeString = attrString + 1; + const char *next = NSGetSizeAndAlignment(typeString, NULL, NULL); + if (!next) { + fprintf(stderr, "ERROR: Could not read past type in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + return NULL; + } + + size_t typeLength = next - typeString; + if (!typeLength) { + fprintf(stderr, "ERROR: Invalid type in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + return NULL; + } + + // allocate enough space for the structure and the type string (plus a NUL) + mtl_propertyAttributes *attributes = calloc(1, sizeof(mtl_propertyAttributes) + typeLength + 1); + if (!attributes) { + fprintf(stderr, "ERROR: Could not allocate mtl_propertyAttributes structure for attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + return NULL; + } + + // copy the type string + strncpy(attributes->type, typeString, typeLength); + attributes->type[typeLength] = '\0'; + + // if this is an object type, and immediately followed by a quoted string... + if (typeString[0] == *(@encode(id)) && typeString[1] == '"') { + // we should be able to extract a class name + const char *className = typeString + 2; + next = strchr(className, '"'); + + if (!next) { + fprintf(stderr, "ERROR: Could not read class name in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + return NULL; + } + + if (className != next) { + size_t classNameLength = next - className; + char trimmedName[classNameLength + 1]; + + strncpy(trimmedName, className, classNameLength); + trimmedName[classNameLength] = '\0'; + + // attempt to look up the class in the runtime + attributes->objectClass = objc_getClass(trimmedName); + } + } + + if (*next != '\0') { + // skip past any junk before the first flag + next = strchr(next, ','); + } + + while (next && *next == ',') { + char flag = next[1]; + next += 2; + + switch (flag) { + case '\0': + break; + + case 'R': + attributes->readonly = YES; + break; + + case 'C': + attributes->memoryManagementPolicy = mtl_propertyMemoryManagementPolicyCopy; + break; + + case '&': + attributes->memoryManagementPolicy = mtl_propertyMemoryManagementPolicyRetain; + break; + + case 'N': + attributes->nonatomic = YES; + break; + + case 'G': + case 'S': + { + const char *nextFlag = strchr(next, ','); + SEL name = NULL; + + if (!nextFlag) { + // assume that the rest of the string is the selector + const char *selectorString = next; + next = ""; + + name = sel_registerName(selectorString); + } else { + size_t selectorLength = nextFlag - next; + if (!selectorLength) { + fprintf(stderr, "ERROR: Found zero length selector name in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + goto errorOut; + } + + char selectorString[selectorLength + 1]; + + strncpy(selectorString, next, selectorLength); + selectorString[selectorLength] = '\0'; + + name = sel_registerName(selectorString); + next = nextFlag; + } + + if (flag == 'G') + attributes->getter = name; + else + attributes->setter = name; + } + + break; + + case 'D': + attributes->dynamic = YES; + attributes->ivar = NULL; + break; + + case 'V': + // assume that the rest of the string (if present) is the ivar name + if (*next == '\0') { + // if there's nothing there, let's assume this is dynamic + attributes->ivar = NULL; + } else { + attributes->ivar = next; + next = ""; + } + + break; + + case 'W': + attributes->weak = YES; + break; + + case 'P': + attributes->canBeCollected = YES; + break; + + case 't': + fprintf(stderr, "ERROR: Old-style type encoding is unsupported in attribute string \"%s\" for property %s\n", attrString, property_getName(property)); + + // skip over this type encoding + while (*next != ',' && *next != '\0') + ++next; + + break; + + default: + fprintf(stderr, "ERROR: Unrecognized attribute string flag '%c' in attribute string \"%s\" for property %s\n", flag, attrString, property_getName(property)); + } + } + + if (next && *next != '\0') { + fprintf(stderr, "Warning: Unparsed data \"%s\" in attribute string \"%s\" for property %s\n", next, attrString, property_getName(property)); + } + + if (!attributes->getter) { + // use the property name as the getter by default + attributes->getter = sel_registerName(property_getName(property)); + } + + if (!attributes->setter) { + const char *propertyName = property_getName(property); + size_t propertyNameLength = strlen(propertyName); + + // we want to transform the name to setProperty: style + size_t setterLength = propertyNameLength + 4; + + char setterName[setterLength + 1]; + strncpy(setterName, "set", 3); + strncpy(setterName + 3, propertyName, propertyNameLength); + + // capitalize property name for the setter + setterName[3] = (char)toupper(setterName[3]); + + setterName[setterLength - 1] = ':'; + setterName[setterLength] = '\0'; + + attributes->setter = sel_registerName(setterName); + } + + return attributes; + +errorOut: + free(attributes); + return NULL; +} diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.h new file mode 100644 index 0000000..7548b81 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.h @@ -0,0 +1,99 @@ +// +// EXTScope.h +// extobjc +// +// Created by Justin Spahr-Summers on 2011-05-04. +// Copyright (C) 2012 Justin Spahr-Summers. +// Released under the MIT license. +// + +#import "metamacros.h" + +/** + * \@onExit defines some code to be executed when the current scope exits. The + * code must be enclosed in braces and terminated with a semicolon, and will be + * executed regardless of how the scope is exited, including from exceptions, + * \c goto, \c return, \c break, and \c continue. + * + * Provided code will go into a block to be executed later. Keep this in mind as + * it pertains to memory management, restrictions on assignment, etc. Because + * the code is used within a block, \c return is a legal (though perhaps + * confusing) way to exit the cleanup block early. + * + * Multiple \@onExit statements in the same scope are executed in reverse + * lexical order. This helps when pairing resource acquisition with \@onExit + * statements, as it guarantees teardown in the opposite order of acquisition. + * + * @note This statement cannot be used within scopes defined without braces + * (like a one line \c if). In practice, this is not an issue, since \@onExit is + * a useless construct in such a case anyways. + */ +#define onExit \ + try {} @finally {} \ + __strong mtl_cleanupBlock_t metamacro_concat(mtl_exitBlock_, __LINE__) __attribute__((cleanup(mtl_executeCleanupBlock), unused)) = ^ + +/** + * Creates \c __weak shadow variables for each of the variables provided as + * arguments, which can later be made strong again with #strongify. + * + * This is typically used to weakly reference variables in a block, but then + * ensure that the variables stay alive during the actual execution of the block + * (if they were live upon entry). + * + * See #strongify for an example of usage. + */ +#define weakify(...) \ + try {} @finally {} \ + metamacro_foreach_cxt(mtl_weakify_,, __weak, __VA_ARGS__) + +/** + * Like #weakify, but uses \c __unsafe_unretained instead, for targets or + * classes that do not support weak references. + */ +#define unsafeify(...) \ + try {} @finally {} \ + metamacro_foreach_cxt(mtl_weakify_,, __unsafe_unretained, __VA_ARGS__) + +/** + * Strongly references each of the variables provided as arguments, which must + * have previously been passed to #weakify. + * + * The strong references created will shadow the original variable names, such + * that the original names can be used without issue (and a significantly + * reduced risk of retain cycles) in the current scope. + * + * @code + + id foo = [[NSObject alloc] init]; + id bar = [[NSObject alloc] init]; + + @weakify(foo, bar); + + // this block will not keep 'foo' or 'bar' alive + BOOL (^matchesFooOrBar)(id) = ^ BOOL (id obj){ + // but now, upon entry, 'foo' and 'bar' will stay alive until the block has + // finished executing + @strongify(foo, bar); + + return [foo isEqual:obj] || [bar isEqual:obj]; + }; + + * @endcode + */ +#define strongify(...) \ + try {} @finally {} \ + _Pragma("clang diagnostic push") \ + _Pragma("clang diagnostic ignored \"-Wshadow\"") \ + metamacro_foreach(mtl_strongify_,, __VA_ARGS__) \ + _Pragma("clang diagnostic pop") + +/*** implementation details follow ***/ +typedef void (^mtl_cleanupBlock_t)(); + +void mtl_executeCleanupBlock (__strong mtl_cleanupBlock_t *block); + +#define mtl_weakify_(INDEX, CONTEXT, VAR) \ + CONTEXT __typeof__(VAR) metamacro_concat(VAR, _weak_) = (VAR); + +#define mtl_strongify_(INDEX, VAR) \ + __strong __typeof__(VAR) VAR = metamacro_concat(VAR, _weak_); diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.m b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.m new file mode 100644 index 0000000..b34c1c6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/EXTScope.m @@ -0,0 +1,15 @@ +// +// EXTScope.m +// extobjc +// +// Created by Justin Spahr-Summers on 2011-05-04. +// Copyright (C) 2012 Justin Spahr-Summers. +// Released under the MIT license. +// + +#import "EXTScope.h" + +void mtl_executeCleanupBlock (__strong mtl_cleanupBlock_t *block) { + (*block)(); +} + diff --git a/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/metamacros.h b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/metamacros.h new file mode 100644 index 0000000..77a77b5 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/Mantle/extobjc/metamacros.h @@ -0,0 +1,666 @@ +/** + * Macros for metaprogramming + * ExtendedC + * + * Copyright (C) 2012 Justin Spahr-Summers + * Released under the MIT license + */ + +#ifndef EXTC_METAMACROS_H +#define EXTC_METAMACROS_H + +/** + * Executes one or more expressions (which may have a void type, such as a call + * to a function that returns no value) and always returns true. + */ +#define metamacro_exprify(...) \ + ((__VA_ARGS__), true) + +/** + * Returns a string representation of VALUE after full macro expansion. + */ +#define metamacro_stringify(VALUE) \ + metamacro_stringify_(VALUE) + +/** + * Returns A and B concatenated after full macro expansion. + */ +#define metamacro_concat(A, B) \ + metamacro_concat_(A, B) + +/** + * Returns the Nth variadic argument (starting from zero). At least + * N + 1 variadic arguments must be given. N must be between zero and twenty, + * inclusive. + */ +#define metamacro_at(N, ...) \ + metamacro_concat(metamacro_at, N)(__VA_ARGS__) + +/** + * Returns the number of arguments (up to twenty) provided to the macro. At + * least one argument must be provided. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_argcount(...) \ + metamacro_at(20, __VA_ARGS__, 20, 19, 18, 17, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1) + +/** + * Identical to #metamacro_foreach_cxt, except that no CONTEXT argument is + * given. Only the index and current argument will thus be passed to MACRO. + */ +#define metamacro_foreach(MACRO, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_iter, SEP, MACRO, __VA_ARGS__) + +/** + * For each consecutive variadic argument (up to twenty), MACRO is passed the + * zero-based index of the current argument, CONTEXT, and then the argument + * itself. The results of adjoining invocations of MACRO are then separated by + * SEP. + * + * Inspired by P99: http://p99.gforge.inria.fr + */ +#define metamacro_foreach_cxt(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * Identical to #metamacro_foreach_cxt. This can be used when the former would + * fail due to recursive macro expansion. + */ +#define metamacro_foreach_cxt_recursive(MACRO, SEP, CONTEXT, ...) \ + metamacro_concat(metamacro_foreach_cxt_recursive, metamacro_argcount(__VA_ARGS__))(MACRO, SEP, CONTEXT, __VA_ARGS__) + +/** + * In consecutive order, appends each variadic argument (up to twenty) onto + * BASE. The resulting concatenations are then separated by SEP. + * + * This is primarily useful to manipulate a list of macro invocations into instead + * invoking a different, possibly related macro. + */ +#define metamacro_foreach_concat(BASE, SEP, ...) \ + metamacro_foreach_cxt(metamacro_foreach_concat_iter, SEP, BASE, __VA_ARGS__) + +/** + * Iterates COUNT times, each time invoking MACRO with the current index + * (starting at zero) and CONTEXT. The results of adjoining invocations of MACRO + * are then separated by SEP. + * + * COUNT must be an integer between zero and twenty, inclusive. + */ +#define metamacro_for_cxt(COUNT, MACRO, SEP, CONTEXT) \ + metamacro_concat(metamacro_for_cxt, COUNT)(MACRO, SEP, CONTEXT) + +/** + * Returns the first argument given. At least one argument must be provided. + * + * This is useful when implementing a variadic macro, where you may have only + * one variadic argument, but no way to retrieve it (for example, because \c ... + * always needs to match at least one argument). + * + * @code + +#define varmacro(...) \ + metamacro_head(__VA_ARGS__) + + * @endcode + */ +#define metamacro_head(...) \ + metamacro_head_(__VA_ARGS__, 0) + +/** + * Returns every argument except the first. At least two arguments must be + * provided. + */ +#define metamacro_tail(...) \ + metamacro_tail_(__VA_ARGS__) + +/** + * Returns the first N (up to twenty) variadic arguments as a new argument list. + * At least N variadic arguments must be provided. + */ +#define metamacro_take(N, ...) \ + metamacro_concat(metamacro_take, N)(__VA_ARGS__) + +/** + * Removes the first N (up to twenty) variadic arguments from the given argument + * list. At least N variadic arguments must be provided. + */ +#define metamacro_drop(N, ...) \ + metamacro_concat(metamacro_drop, N)(__VA_ARGS__) + +/** + * Decrements VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_dec(VAL) \ + metamacro_at(VAL, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19) + +/** + * Increments VAL, which must be a number between zero and twenty, inclusive. + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_inc(VAL) \ + metamacro_at(VAL, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21) + +/** + * If A is equal to B, the next argument list is expanded; otherwise, the + * argument list after that is expanded. A and B must be numbers between zero + * and twenty, inclusive. Additionally, B must be greater than or equal to A. + * + * @code + +// expands to true +metamacro_if_eq(0, 0)(true)(false) + +// expands to false +metamacro_if_eq(0, 1)(true)(false) + + * @endcode + * + * This is primarily useful when dealing with indexes and counts in + * metaprogramming. + */ +#define metamacro_if_eq(A, B) \ + metamacro_concat(metamacro_if_eq, A)(B) + +/** + * Identical to #metamacro_if_eq. This can be used when the former would fail + * due to recursive macro expansion. + */ +#define metamacro_if_eq_recursive(A, B) \ + metamacro_concat(metamacro_if_eq_recursive, A)(B) + +/** + * Returns 1 if N is an even number, or 0 otherwise. N must be between zero and + * twenty, inclusive. + * + * For the purposes of this test, zero is considered even. + */ +#define metamacro_is_even(N) \ + metamacro_at(N, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1) + +/** + * Returns the logical NOT of B, which must be the number zero or one. + */ +#define metamacro_not(B) \ + metamacro_at(B, 1, 0) + +// IMPLEMENTATION DETAILS FOLLOW! +// Do not write code that depends on anything below this line. +#define metamacro_stringify_(VALUE) # VALUE +#define metamacro_concat_(A, B) A ## B +#define metamacro_foreach_iter(INDEX, MACRO, ARG) MACRO(INDEX, ARG) +#define metamacro_head_(FIRST, ...) FIRST +#define metamacro_tail_(FIRST, ...) __VA_ARGS__ +#define metamacro_consume_(...) +#define metamacro_expand_(...) __VA_ARGS__ + +// implemented from scratch so that metamacro_concat() doesn't end up nesting +#define metamacro_foreach_concat_iter(INDEX, BASE, ARG) metamacro_foreach_concat_iter_(BASE, ARG) +#define metamacro_foreach_concat_iter_(BASE, ARG) BASE ## ARG + +// metamacro_at expansions +#define metamacro_at0(...) metamacro_head(__VA_ARGS__) +#define metamacro_at1(_0, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at2(_0, _1, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at3(_0, _1, _2, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at4(_0, _1, _2, _3, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at5(_0, _1, _2, _3, _4, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at6(_0, _1, _2, _3, _4, _5, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at7(_0, _1, _2, _3, _4, _5, _6, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at8(_0, _1, _2, _3, _4, _5, _6, _7, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at9(_0, _1, _2, _3, _4, _5, _6, _7, _8, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at10(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at11(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at12(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at13(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at14(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at15(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at16(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at17(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at18(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at19(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, ...) metamacro_head(__VA_ARGS__) +#define metamacro_at20(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19, ...) metamacro_head(__VA_ARGS__) + +// metamacro_foreach_cxt expansions +#define metamacro_foreach_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_foreach_cxt_recursive expansions +#define metamacro_foreach_cxt_recursive0(MACRO, SEP, CONTEXT) +#define metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) MACRO(0, CONTEXT, _0) + +#define metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + metamacro_foreach_cxt_recursive1(MACRO, SEP, CONTEXT, _0) \ + SEP \ + MACRO(1, CONTEXT, _1) + +#define metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + metamacro_foreach_cxt_recursive2(MACRO, SEP, CONTEXT, _0, _1) \ + SEP \ + MACRO(2, CONTEXT, _2) + +#define metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + metamacro_foreach_cxt_recursive3(MACRO, SEP, CONTEXT, _0, _1, _2) \ + SEP \ + MACRO(3, CONTEXT, _3) + +#define metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + metamacro_foreach_cxt_recursive4(MACRO, SEP, CONTEXT, _0, _1, _2, _3) \ + SEP \ + MACRO(4, CONTEXT, _4) + +#define metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + metamacro_foreach_cxt_recursive5(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4) \ + SEP \ + MACRO(5, CONTEXT, _5) + +#define metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + metamacro_foreach_cxt_recursive6(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5) \ + SEP \ + MACRO(6, CONTEXT, _6) + +#define metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + metamacro_foreach_cxt_recursive7(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6) \ + SEP \ + MACRO(7, CONTEXT, _7) + +#define metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + metamacro_foreach_cxt_recursive8(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7) \ + SEP \ + MACRO(8, CONTEXT, _8) + +#define metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + metamacro_foreach_cxt_recursive9(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8) \ + SEP \ + MACRO(9, CONTEXT, _9) + +#define metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + metamacro_foreach_cxt_recursive10(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9) \ + SEP \ + MACRO(10, CONTEXT, _10) + +#define metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + metamacro_foreach_cxt_recursive11(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10) \ + SEP \ + MACRO(11, CONTEXT, _11) + +#define metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + metamacro_foreach_cxt_recursive12(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11) \ + SEP \ + MACRO(12, CONTEXT, _12) + +#define metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + metamacro_foreach_cxt_recursive13(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12) \ + SEP \ + MACRO(13, CONTEXT, _13) + +#define metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + metamacro_foreach_cxt_recursive14(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13) \ + SEP \ + MACRO(14, CONTEXT, _14) + +#define metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + metamacro_foreach_cxt_recursive15(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14) \ + SEP \ + MACRO(15, CONTEXT, _15) + +#define metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + metamacro_foreach_cxt_recursive16(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15) \ + SEP \ + MACRO(16, CONTEXT, _16) + +#define metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + metamacro_foreach_cxt_recursive17(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16) \ + SEP \ + MACRO(17, CONTEXT, _17) + +#define metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + metamacro_foreach_cxt_recursive18(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17) \ + SEP \ + MACRO(18, CONTEXT, _18) + +#define metamacro_foreach_cxt_recursive20(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18, _19) \ + metamacro_foreach_cxt_recursive19(MACRO, SEP, CONTEXT, _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, _17, _18) \ + SEP \ + MACRO(19, CONTEXT, _19) + +// metamacro_for_cxt expansions +#define metamacro_for_cxt0(MACRO, SEP, CONTEXT) +#define metamacro_for_cxt1(MACRO, SEP, CONTEXT) MACRO(0, CONTEXT) + +#define metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt1(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(1, CONTEXT) + +#define metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt2(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(2, CONTEXT) + +#define metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt3(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(3, CONTEXT) + +#define metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt4(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(4, CONTEXT) + +#define metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt5(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(5, CONTEXT) + +#define metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt6(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(6, CONTEXT) + +#define metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt7(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(7, CONTEXT) + +#define metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt8(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(8, CONTEXT) + +#define metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt9(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(9, CONTEXT) + +#define metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt10(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(10, CONTEXT) + +#define metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt11(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(11, CONTEXT) + +#define metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt12(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(12, CONTEXT) + +#define metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt13(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(13, CONTEXT) + +#define metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt14(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(14, CONTEXT) + +#define metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt15(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(15, CONTEXT) + +#define metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt16(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(16, CONTEXT) + +#define metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt17(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(17, CONTEXT) + +#define metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt18(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(18, CONTEXT) + +#define metamacro_for_cxt20(MACRO, SEP, CONTEXT) \ + metamacro_for_cxt19(MACRO, SEP, CONTEXT) \ + SEP \ + MACRO(19, CONTEXT) + +// metamacro_if_eq expansions +#define metamacro_if_eq0(VALUE) \ + metamacro_concat(metamacro_if_eq0_, VALUE) + +#define metamacro_if_eq0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq0_1(...) metamacro_expand_ +#define metamacro_if_eq0_2(...) metamacro_expand_ +#define metamacro_if_eq0_3(...) metamacro_expand_ +#define metamacro_if_eq0_4(...) metamacro_expand_ +#define metamacro_if_eq0_5(...) metamacro_expand_ +#define metamacro_if_eq0_6(...) metamacro_expand_ +#define metamacro_if_eq0_7(...) metamacro_expand_ +#define metamacro_if_eq0_8(...) metamacro_expand_ +#define metamacro_if_eq0_9(...) metamacro_expand_ +#define metamacro_if_eq0_10(...) metamacro_expand_ +#define metamacro_if_eq0_11(...) metamacro_expand_ +#define metamacro_if_eq0_12(...) metamacro_expand_ +#define metamacro_if_eq0_13(...) metamacro_expand_ +#define metamacro_if_eq0_14(...) metamacro_expand_ +#define metamacro_if_eq0_15(...) metamacro_expand_ +#define metamacro_if_eq0_16(...) metamacro_expand_ +#define metamacro_if_eq0_17(...) metamacro_expand_ +#define metamacro_if_eq0_18(...) metamacro_expand_ +#define metamacro_if_eq0_19(...) metamacro_expand_ +#define metamacro_if_eq0_20(...) metamacro_expand_ + +#define metamacro_if_eq1(VALUE) metamacro_if_eq0(metamacro_dec(VALUE)) +#define metamacro_if_eq2(VALUE) metamacro_if_eq1(metamacro_dec(VALUE)) +#define metamacro_if_eq3(VALUE) metamacro_if_eq2(metamacro_dec(VALUE)) +#define metamacro_if_eq4(VALUE) metamacro_if_eq3(metamacro_dec(VALUE)) +#define metamacro_if_eq5(VALUE) metamacro_if_eq4(metamacro_dec(VALUE)) +#define metamacro_if_eq6(VALUE) metamacro_if_eq5(metamacro_dec(VALUE)) +#define metamacro_if_eq7(VALUE) metamacro_if_eq6(metamacro_dec(VALUE)) +#define metamacro_if_eq8(VALUE) metamacro_if_eq7(metamacro_dec(VALUE)) +#define metamacro_if_eq9(VALUE) metamacro_if_eq8(metamacro_dec(VALUE)) +#define metamacro_if_eq10(VALUE) metamacro_if_eq9(metamacro_dec(VALUE)) +#define metamacro_if_eq11(VALUE) metamacro_if_eq10(metamacro_dec(VALUE)) +#define metamacro_if_eq12(VALUE) metamacro_if_eq11(metamacro_dec(VALUE)) +#define metamacro_if_eq13(VALUE) metamacro_if_eq12(metamacro_dec(VALUE)) +#define metamacro_if_eq14(VALUE) metamacro_if_eq13(metamacro_dec(VALUE)) +#define metamacro_if_eq15(VALUE) metamacro_if_eq14(metamacro_dec(VALUE)) +#define metamacro_if_eq16(VALUE) metamacro_if_eq15(metamacro_dec(VALUE)) +#define metamacro_if_eq17(VALUE) metamacro_if_eq16(metamacro_dec(VALUE)) +#define metamacro_if_eq18(VALUE) metamacro_if_eq17(metamacro_dec(VALUE)) +#define metamacro_if_eq19(VALUE) metamacro_if_eq18(metamacro_dec(VALUE)) +#define metamacro_if_eq20(VALUE) metamacro_if_eq19(metamacro_dec(VALUE)) + +// metamacro_if_eq_recursive expansions +#define metamacro_if_eq_recursive0(VALUE) \ + metamacro_concat(metamacro_if_eq_recursive0_, VALUE) + +#define metamacro_if_eq_recursive0_0(...) __VA_ARGS__ metamacro_consume_ +#define metamacro_if_eq_recursive0_1(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_2(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_3(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_4(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_5(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_6(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_7(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_8(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_9(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_10(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_11(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_12(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_13(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_14(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_15(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_16(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_17(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_18(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_19(...) metamacro_expand_ +#define metamacro_if_eq_recursive0_20(...) metamacro_expand_ + +#define metamacro_if_eq_recursive1(VALUE) metamacro_if_eq_recursive0(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive2(VALUE) metamacro_if_eq_recursive1(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive3(VALUE) metamacro_if_eq_recursive2(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive4(VALUE) metamacro_if_eq_recursive3(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive5(VALUE) metamacro_if_eq_recursive4(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive6(VALUE) metamacro_if_eq_recursive5(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive7(VALUE) metamacro_if_eq_recursive6(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive8(VALUE) metamacro_if_eq_recursive7(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive9(VALUE) metamacro_if_eq_recursive8(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive10(VALUE) metamacro_if_eq_recursive9(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive11(VALUE) metamacro_if_eq_recursive10(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive12(VALUE) metamacro_if_eq_recursive11(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive13(VALUE) metamacro_if_eq_recursive12(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive14(VALUE) metamacro_if_eq_recursive13(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive15(VALUE) metamacro_if_eq_recursive14(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive16(VALUE) metamacro_if_eq_recursive15(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive17(VALUE) metamacro_if_eq_recursive16(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive18(VALUE) metamacro_if_eq_recursive17(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive19(VALUE) metamacro_if_eq_recursive18(metamacro_dec(VALUE)) +#define metamacro_if_eq_recursive20(VALUE) metamacro_if_eq_recursive19(metamacro_dec(VALUE)) + +// metamacro_take expansions +#define metamacro_take0(...) +#define metamacro_take1(...) metamacro_head(__VA_ARGS__) +#define metamacro_take2(...) metamacro_head(__VA_ARGS__), metamacro_take1(metamacro_tail(__VA_ARGS__)) +#define metamacro_take3(...) metamacro_head(__VA_ARGS__), metamacro_take2(metamacro_tail(__VA_ARGS__)) +#define metamacro_take4(...) metamacro_head(__VA_ARGS__), metamacro_take3(metamacro_tail(__VA_ARGS__)) +#define metamacro_take5(...) metamacro_head(__VA_ARGS__), metamacro_take4(metamacro_tail(__VA_ARGS__)) +#define metamacro_take6(...) metamacro_head(__VA_ARGS__), metamacro_take5(metamacro_tail(__VA_ARGS__)) +#define metamacro_take7(...) metamacro_head(__VA_ARGS__), metamacro_take6(metamacro_tail(__VA_ARGS__)) +#define metamacro_take8(...) metamacro_head(__VA_ARGS__), metamacro_take7(metamacro_tail(__VA_ARGS__)) +#define metamacro_take9(...) metamacro_head(__VA_ARGS__), metamacro_take8(metamacro_tail(__VA_ARGS__)) +#define metamacro_take10(...) metamacro_head(__VA_ARGS__), metamacro_take9(metamacro_tail(__VA_ARGS__)) +#define metamacro_take11(...) metamacro_head(__VA_ARGS__), metamacro_take10(metamacro_tail(__VA_ARGS__)) +#define metamacro_take12(...) metamacro_head(__VA_ARGS__), metamacro_take11(metamacro_tail(__VA_ARGS__)) +#define metamacro_take13(...) metamacro_head(__VA_ARGS__), metamacro_take12(metamacro_tail(__VA_ARGS__)) +#define metamacro_take14(...) metamacro_head(__VA_ARGS__), metamacro_take13(metamacro_tail(__VA_ARGS__)) +#define metamacro_take15(...) metamacro_head(__VA_ARGS__), metamacro_take14(metamacro_tail(__VA_ARGS__)) +#define metamacro_take16(...) metamacro_head(__VA_ARGS__), metamacro_take15(metamacro_tail(__VA_ARGS__)) +#define metamacro_take17(...) metamacro_head(__VA_ARGS__), metamacro_take16(metamacro_tail(__VA_ARGS__)) +#define metamacro_take18(...) metamacro_head(__VA_ARGS__), metamacro_take17(metamacro_tail(__VA_ARGS__)) +#define metamacro_take19(...) metamacro_head(__VA_ARGS__), metamacro_take18(metamacro_tail(__VA_ARGS__)) +#define metamacro_take20(...) metamacro_head(__VA_ARGS__), metamacro_take19(metamacro_tail(__VA_ARGS__)) + +// metamacro_drop expansions +#define metamacro_drop0(...) __VA_ARGS__ +#define metamacro_drop1(...) metamacro_tail(__VA_ARGS__) +#define metamacro_drop2(...) metamacro_drop1(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop3(...) metamacro_drop2(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop4(...) metamacro_drop3(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop5(...) metamacro_drop4(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop6(...) metamacro_drop5(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop7(...) metamacro_drop6(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop8(...) metamacro_drop7(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop9(...) metamacro_drop8(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop10(...) metamacro_drop9(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop11(...) metamacro_drop10(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop12(...) metamacro_drop11(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop13(...) metamacro_drop12(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop14(...) metamacro_drop13(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop15(...) metamacro_drop14(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop16(...) metamacro_drop15(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop17(...) metamacro_drop16(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop18(...) metamacro_drop17(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop19(...) metamacro_drop18(metamacro_tail(__VA_ARGS__)) +#define metamacro_drop20(...) metamacro_drop19(metamacro_tail(__VA_ARGS__)) + +#endif diff --git a/iOSStudy/iOSStudy/Pods/Mantle/README.md b/iOSStudy/iOSStudy/Pods/Mantle/README.md new file mode 100644 index 0000000..b3bee10 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Mantle/README.md @@ -0,0 +1,507 @@ +# Mantle + +Mantle makes it easy to write a simple model layer for your Cocoa or Cocoa Touch +application. + +## The Typical Model Object + +What's wrong with the way model objects are usually written in Objective-C? + +Let's use the [GitHub API](http://developer.github.com) for demonstration. How +would one typically represent a [GitHub +issue](http://developer.github.com/v3/issues/#get-a-single-issue) in +Objective-C? + +```objc +typedef enum : NSUInteger { + GHIssueStateOpen, + GHIssueStateClosed +} GHIssueState; + +@interface GHIssue : NSObject + +@property (nonatomic, copy, readonly) NSURL *URL; +@property (nonatomic, copy, readonly) NSURL *HTMLURL; +@property (nonatomic, copy, readonly) NSNumber *number; +@property (nonatomic, assign, readonly) GHIssueState state; +@property (nonatomic, copy, readonly) NSString *reporterLogin; +@property (nonatomic, copy, readonly) NSDate *updatedAt; +@property (nonatomic, strong, readonly) GHUser *assignee; +@property (nonatomic, copy, readonly) NSDate *retrievedAt; + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *body; + +- (id)initWithDictionary:(NSDictionary *)dictionary; + +@end +``` + +```objc +@implementation GHIssue + ++ (NSDateFormatter *)dateFormatter { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; + return dateFormatter; +} + +- (id)initWithDictionary:(NSDictionary *)dictionary { + self = [self init]; + if (self == nil) return nil; + + _URL = [NSURL URLWithString:dictionary[@"url"]]; + _HTMLURL = [NSURL URLWithString:dictionary[@"html_url"]]; + _number = dictionary[@"number"]; + + if ([dictionary[@"state"] isEqualToString:@"open"]) { + _state = GHIssueStateOpen; + } else if ([dictionary[@"state"] isEqualToString:@"closed"]) { + _state = GHIssueStateClosed; + } + + _title = [dictionary[@"title"] copy]; + _retrievedAt = [NSDate date]; + _body = [dictionary[@"body"] copy]; + _reporterLogin = [dictionary[@"user"][@"login"] copy]; + _assignee = [[GHUser alloc] initWithDictionary:dictionary[@"assignee"]]; + + _updatedAt = [self.class.dateFormatter dateFromString:dictionary[@"updated_at"]]; + + return self; +} + +- (id)initWithCoder:(NSCoder *)coder { + self = [self init]; + if (self == nil) return nil; + + _URL = [coder decodeObjectForKey:@"URL"]; + _HTMLURL = [coder decodeObjectForKey:@"HTMLURL"]; + _number = [coder decodeObjectForKey:@"number"]; + _state = [coder decodeUnsignedIntegerForKey:@"state"]; + _title = [coder decodeObjectForKey:@"title"]; + _retrievedAt = [NSDate date]; + _body = [coder decodeObjectForKey:@"body"]; + _reporterLogin = [coder decodeObjectForKey:@"reporterLogin"]; + _assignee = [coder decodeObjectForKey:@"assignee"]; + _updatedAt = [coder decodeObjectForKey:@"updatedAt"]; + + return self; +} + +- (void)encodeWithCoder:(NSCoder *)coder { + if (self.URL != nil) [coder encodeObject:self.URL forKey:@"URL"]; + if (self.HTMLURL != nil) [coder encodeObject:self.HTMLURL forKey:@"HTMLURL"]; + if (self.number != nil) [coder encodeObject:self.number forKey:@"number"]; + if (self.title != nil) [coder encodeObject:self.title forKey:@"title"]; + if (self.body != nil) [coder encodeObject:self.body forKey:@"body"]; + if (self.reporterLogin != nil) [coder encodeObject:self.reporterLogin forKey:@"reporterLogin"]; + if (self.assignee != nil) [coder encodeObject:self.assignee forKey:@"assignee"]; + if (self.updatedAt != nil) [coder encodeObject:self.updatedAt forKey:@"updatedAt"]; + + [coder encodeUnsignedInteger:self.state forKey:@"state"]; +} + +- (id)copyWithZone:(NSZone *)zone { + GHIssue *issue = [[self.class allocWithZone:zone] init]; + issue->_URL = self.URL; + issue->_HTMLURL = self.HTMLURL; + issue->_number = self.number; + issue->_state = self.state; + issue->_reporterLogin = self.reporterLogin; + issue->_assignee = self.assignee; + issue->_updatedAt = self.updatedAt; + + issue.title = self.title; + issue->_retrievedAt = [NSDate date]; + issue.body = self.body; + + return issue; +} + +- (NSUInteger)hash { + return self.number.hash; +} + +- (BOOL)isEqual:(GHIssue *)issue { + if (![issue isKindOfClass:GHIssue.class]) return NO; + + return [self.number isEqual:issue.number] && [self.title isEqual:issue.title] && [self.body isEqual:issue.body]; +} + +@end +``` + +Whew, that's a lot of boilerplate for something so simple! And, even then, there +are some problems that this example doesn't address: + + * There's no way to update a `GHIssue` with new data from the server. + * There's no way to turn a `GHIssue` _back_ into JSON. + * `GHIssueState` shouldn't be encoded as-is. If the enum changes in the future, + existing archives might break. + * If the interface of `GHIssue` changes down the road, existing archives might + break. + +## Why Not Use Core Data? + +Core Data solves certain problems very well. If you need to execute complex +queries across your data, handle a huge object graph with lots of relationships, +or support undo and redo, Core Data is an excellent fit. + +It does, however, come with a couple of pain points: + + * **There's still a lot of boilerplate.** Managed objects reduce some of the + boilerplate seen above, but Core Data has plenty of its own. Correctly + setting up a Core Data stack (with a persistent store and persistent store + coordinator) and executing fetches can take many lines of code. + * **It's hard to get right.** Even experienced developers can make mistakes + when using Core Data, and the framework is not forgiving. + +If you're just trying to access some JSON objects, Core Data can be a lot of +work for little gain. + +Nonetheless, if you're using or want to use Core Data in your app already, +Mantle can still be a convenient translation layer between the API and your +managed model objects. + +## MTLModel + +Enter +**[MTLModel](https://github.com/github/Mantle/blob/master/Mantle/MTLModel.h)**. +This is what `GHIssue` looks like inheriting from `MTLModel`: + +```objc +typedef enum : NSUInteger { + GHIssueStateOpen, + GHIssueStateClosed +} GHIssueState; + +@interface GHIssue : MTLModel + +@property (nonatomic, copy, readonly) NSURL *URL; +@property (nonatomic, copy, readonly) NSURL *HTMLURL; +@property (nonatomic, copy, readonly) NSNumber *number; +@property (nonatomic, assign, readonly) GHIssueState state; +@property (nonatomic, copy, readonly) NSString *reporterLogin; +@property (nonatomic, strong, readonly) GHUser *assignee; +@property (nonatomic, copy, readonly) NSDate *updatedAt; + +@property (nonatomic, copy) NSString *title; +@property (nonatomic, copy) NSString *body; + +@property (nonatomic, copy, readonly) NSDate *retrievedAt; + +@end +``` + +```objc +@implementation GHIssue + ++ (NSDateFormatter *)dateFormatter { + NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init]; + dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US_POSIX"]; + dateFormatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'Z'"; + return dateFormatter; +} + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{ + @"URL": @"url", + @"HTMLURL": @"html_url", + @"reporterLogin": @"user.login", + @"assignee": @"assignee", + @"updatedAt": @"updated_at" + }; +} + ++ (NSValueTransformer *)URLJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; +} + ++ (NSValueTransformer *)HTMLURLJSONTransformer { + return [NSValueTransformer valueTransformerForName:MTLURLValueTransformerName]; +} + ++ (NSValueTransformer *)stateJSONTransformer { + return [NSValueTransformer mtl_valueMappingTransformerWithDictionary:@{ + @"open": @(GHIssueStateOpen), + @"closed": @(GHIssueStateClosed) + }]; +} + ++ (NSValueTransformer *)assigneeJSONTransformer { + return [NSValueTransformer mtl_JSONDictionaryTransformerWithModelClass:GHUser.class]; +} + ++ (NSValueTransformer *)updatedAtJSONTransformer { + return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) { + return [self.dateFormatter dateFromString:str]; + } reverseBlock:^(NSDate *date) { + return [self.dateFormatter stringFromDate:date]; + }]; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error { + self = [super initWithDictionary:dictionaryValue error:error]; + if (self == nil) return nil; + + // Store a value that needs to be determined locally upon initialization. + _retrievedAt = [NSDate date]; + + return self; +} + +@end +``` + +Notably absent from this version are implementations of ``, +``, `-isEqual:`, and `-hash`. By inspecting the `@property` +declarations you have in your subclass, `MTLModel` can provide default +implementations for all these methods. + +The problems with the original example all happen to be fixed as well: + +> There's no way to update a `GHIssue` with new data from the server. + +`MTLModel` has an extensible `-mergeValuesForKeysFromModel:` method, which makes +it easy to specify how new model data should be integrated. + +> There's no way to turn a `GHIssue` _back_ into JSON. + +This is where reversible transformers really come in handy. `+[MTLJSONAdapter +JSONDictionaryFromModel:]` can transform any model object conforming to +`` back into a JSON dictionary. `+[MTLJSONAdapter +JSONArrayForModels:]` is the same but turns an array of model objects into an JSON array of dictionaries. + +> If the interface of `GHIssue` changes down the road, existing archives might break. + +`MTLModel` automatically saves the version of the model object that was used for +archival. When unarchiving, `-decodeValueForKey:withCoder:modelVersion:` will +be invoked if overridden, giving you a convenient hook to upgrade old data. + +## MTLJSONSerializing + +In order to serialize your model objects from or into JSON, you need to +implement `` in your `MTLModel` subclass. This allows you to +use `MTLJSONAdapter` to convert your model objects from JSON and back: + +```objc +NSError *error = nil; +XYUser *user = [MTLJSONAdapter modelOfClass:XYUser.class fromJSONDictionary:JSONDictionary error:&error]; +``` + +```objc +NSDictionary *JSONDictionary = [MTLJSONAdapter JSONDictionaryFromModel:user]; +``` + +### `+JSONKeyPathsByPropertyKey` + +The dictionary returned by this method specifies how your model object's +properties map to the keys in the JSON representation. Properties that map to +`NSNull` will not be present in the JSON representation, for example: + +```objc + +@interface XYUser : MTLModel + +@property (readonly, nonatomic, copy) NSString *name; +@property (readonly, nonatomic, strong) NSDate *createdAt; + +@property (readonly, nonatomic, assign, getter = isMeUser) BOOL meUser; +@property (readonly, nonatomic, strong) XYHelper *helper; + +@end + +@implementation XYUser + ++ (NSDictionary *)JSONKeyPathsByPropertyKey { + return @{ + @"createdAt": @"created_at", + @"meUser": NSNull.null + }; +} + +- (instancetype)initWithDictionary:(NSDictionary *)dictionaryValue error:(NSError **)error { + self = [super initWithDictionary:dictionaryValue error:error]; + if (self == nil) return nil; + + _helper = [XYHelper helperWithName:self.name createdAt:self.createdAt]; + + return self; +} + +@end +``` + +In this example, the `XYUser` class declares four properties that Mantle +handles in different ways: + +- `name` is implicitly mapped to a key of the same name in the JSON + representation. +- `createdAt` is converted to its snake case equivalent. +- `meUser` is not serialized into JSON. +- `helper` is initialized exactly once after JSON deserialization. + +Use `-[NSDictionary mtl_dictionaryByAddingEntriesFromDictionary:]` if your +model's superclass also implements `MTLJSONSerializing` to merge their mappings. + +When deserializing JSON using +`+[MTLJSONAdapter modelOfClass:fromJSONDictionary:error:]`, JSON keys that don't +correspond to a property name or have an explicit mapping are ignored: + +```objc +NSDictionary *JSONDictionary = @{ + @"name": @"john", + @"created_at": @"2013/07/02 16:40:00 +0000", + @"plan": @"lite" +}; + +XYUser *user = [MTLJSONAdapter modelOfClass:XYUser.class fromJSONDictionary:JSONDictionary error:&error]; +``` + +Here, the `plan` would be ignored since it neither matches a property name of +`XYUser` nor is it otherwise mapped in `+JSONKeyPathsByPropertyKey`. + +### `+JSONTransformerForKey:` + +Implement this optional method to convert a property from a different type when +deserializing from JSON. + +``` ++ (NSValueTransformer *)JSONTransformerForKey:(NSString *)key { + if ([key isEqualToString:@"createdAt"]) { + return [NSValueTransformer valueTransformerForName:XYDateValueTransformerName]; + } + + return nil; +} +``` + +For added convenience, if you implement `+JSONTransformer`, +`MTLJSONAdapter` will use the result of that method instead. For example, dates +that are commonly represented as strings in JSON can be transformed to `NSDate`s +like so: + +```objc ++ (NSValueTransformer *)createdAtJSONTransformer { + return [MTLValueTransformer reversibleTransformerWithForwardBlock:^(NSString *str) { + return [self.dateFormatter dateFromString:str]; + } reverseBlock:^(NSDate *date) { + return [self.dateFormatter stringFromDate:date]; + }]; +} +``` + +If the transformer is reversible, it will also be used when serializing the +object into JSON. + +### `+classForParsingJSONDictionary:` + +If you are implementing a class cluster, implement this optional method to +determine which subclass of your base class should be used when deserializing an +object from JSON. + +```objc +@interface XYMessage : MTLModel + +@end + +@interface XYTextMessage: XYMessage + +@property (readonly, nonatomic, copy) NSString *body; + +@end + +@interface XYPictureMessage : XYMessage + +@property (readonly, nonatomic, strong) NSURL *imageURL; + +@end + +@implementation XYMessage + ++ (Class)classForParsingJSONDictionary:(NSDictionary *)JSONDictionary { + if (JSONDictionary[@"image_url"] != nil) { + return XYPictureMessage.class; + } + + if (JSONDictionary[@"body"] != nil) { + return XYTextMessage.class; + } + + NSAssert(NO, @"No matching class for the JSON dictionary '%@'.", JSONDictionary); + return self; +} + +@end +``` + +`MTLJSONAdapter` will then pick the class based on the JSON dictionary you pass +in: + +```objc +NSDictionary *textMessage = @{ + @"id": @1, + @"body": @"Hello World!" +}; + +NSDictionary *pictureMessage = @{ + @"id": @2, + @"image_url": @"http://example.com/lolcat.gif" +}; + +XYTextMessage *messageA = [MTLJSONAdapter modelOfClass:XYMessage.class fromJSONDictionary:textMessage error:NULL]; + +XYPictureMessage *messageB = [MTLJSONAdapter modelOfClass:XYMessage.class fromJSONDictionary:pictureMessage error:NULL]; +``` + +## Persistence + +Mantle doesn't automatically persist your objects for you. However, `MTLModel` +does conform to ``, so model objects can be archived to disk using +`NSKeyedArchiver`. + +If you need something more powerful, or want to avoid keeping your whole model +in memory at once, Core Data may be a better choice. + +## System Requirements + +Mantle supports OS X 10.7+ and iOS 5.0+. + +## Importing Mantle + +To add Mantle to your application: + + 1. Add the Mantle repository as a submodule of your application's repository. + 1. Run `script/bootstrap` from within the Mantle folder. + 1. Drag and drop `Mantle.xcodeproj` into your application's Xcode project or + workspace. + 1. On the "Build Phases" tab of your application target, add Mantle to the + "Link Binary With Libraries" phase. + * **On iOS**, add `libMantle.a`. + * **On OS X**, add `Mantle.framework`. Mantle must also be added to any + "Copy Frameworks" build phase. If you don't already have one, simply add a + "Copy Files" build phase and target the "Frameworks" destination. + 1. Add `"$(BUILD_ROOT)/../IntermediateBuildFilesPath/UninstalledProducts/include" $(inherited)` + to the "Header Search Paths" build setting (this is only + necessary for archive builds, but it has no negative effect otherwise). + 1. **For iOS targets**, add `-ObjC` to the "Other Linker Flags" build setting. + 1. **If you added Mantle to a project (not a workspace)**, you will also need + to add the appropriate Mantle target to the "Target Dependencies" of your + application. + +If you would prefer to use [CocoaPods](http://cocoapods.org), there are some +[Mantle podspecs](https://github.com/CocoaPods/Specs/tree/master/Specs/Mantle) that +have been generously contributed by third parties. + +If you’re instead developing Mantle on its own, use the `Mantle.xcworkspace` file. + +## License + +Mantle is released under the MIT license. See +[LICENSE.md](https://github.com/github/Mantle/blob/master/LICENSE.md). + +## More Info + +Have a question? Please [open an issue](https://github.com/Mantle/Mantle/issues/new)! diff --git a/iOSStudy/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj b/iOSStudy/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj new file mode 100644 index 0000000..d94c134 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Pods.xcodeproj/project.pbxproj @@ -0,0 +1,7325 @@ + + + + + archiveVersion + 1 + classes + + objectVersion + 46 + objects + + 00184188B977DFF23A1F85C5 + + buildConfigurations + + F6CDC7E60CF17930F7262034 + 72575C4414A386B75A1236C3 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 003A31C6AADD74836B88341F + + attributes + + LastUpgradeCheck + 0510 + + buildConfigurationList + EF1605A5BAD020789C0D6DCD + compatibilityVersion + Xcode 3.2 + developmentRegion + English + hasScannedForEncodings + 0 + isa + PBXProject + knownRegions + + en + + mainGroup + 29EBF6D132B45FA490AAE8C4 + productRefGroup + 7A9806F1FFB8C59E80CBFD08 + projectDirPath + + projectReferences + + projectRoot + + targets + + 41B60CD843C52B8457DCB0E0 + E0F50EA1905F2A7094812973 + F5AD41E8F4E3CBFFE9D0A6AD + D6558E03D7E8E7369D57D62A + EA053313AC9B201518E824AF + 7FFBF073B63F5E27B5D0072F + 6736EF81F571346B01E63AAB + 0D2F41CC755DC941A9D3282F + 0E44B521E203EC4F111815E4 + + + 00768924736E895D7D503478 + + buildConfigurations + + A25EAE9D801AB760A4747E4B + 8A72EC2E5ADEFD1185ACE525 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 015D98E4D31C2E29C4FB9DBA + + fileRef + B2DFB8ABE3C361564605FC09 + isa + PBXBuildFile + + 016D2ED5429A374F8D023442 + + fileRef + D405E1711A624A1719E082D2 + isa + PBXBuildFile + + 019033947122D26DFF88E20C + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerBack.png + path + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png + sourceTree + <group> + + 02E92DC83C62401C25C8913C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSError+MTLModelException.m + path + Mantle/NSError+MTLModelException.m + sourceTree + <group> + + 0371BF6A0BA2FCC5D93407F8 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SDWebImage.a + sourceTree + BUILT_PRODUCTS_DIR + + 0398B69338481EC817F6F6EB + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-FMDB.a + sourceTree + BUILT_PRODUCTS_DIR + + 03FA11483C1D0F3D8E20B008 + + fileRef + BDD54D59F9F168C7CDC3C286 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 04205120B87CE3914882E1E1 + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + 051EC94587D0A832E9D6DEBA + + isa + PBXTargetDependency + name + Pods-SVWebViewController + target + 0D2F41CC755DC941A9D3282F + targetProxy + CCD36D89B4623217A9BB4F11 + + 055CD4E1DAF33217D19B9141 + + fileRef + 52C22D274C762A81E9AEFD70 + isa + PBXBuildFile + + 057A36C64C16BAE9CBB65645 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivityChrome@2x.png + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png + sourceTree + <group> + + 060110539E4022EC7547DC8A + + children + + E1AD240F7028E1A092DCBEDC + 7B237DEB99E4A1EC780BD565 + + isa + PBXGroup + name + Security + sourceTree + <group> + + 06B18C667B34A3836288B3E6 + + buildActionMask + 2147483647 + files + + D003F4EA52D0953E6AF73AF6 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 06D77D3ADBE13269F32AE1CF + + buildActionMask + 2147483647 + files + + AB1DEC2C8FBB36DEECEF04E0 + 8CCB2EE71B1282861778906D + DD8F1007201AC5D9E168DE32 + ADC6D3BD671FB020D4E165E1 + 651297332C80103B10000DCA + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 071305CB59F3D8E013288619 + + children + + C50CBBB3320CBFC5FA8EA34D + 8A081DC2D78B0C22A3B1CDDE + 6D6492CFDFC03E3EEED90937 + 225B176F2E2BC5974E8C8001 + BB46AB577CB11E2DEC496B53 + 304E5532CC66B25020968ED2 + 90692384AE86654AF740CBA0 + A110D8DB17AB6647C7795EBD + 674480447F049BFA1C4EA514 + 4D56B1E3005FDE505FCEF6C6 + 98D565C31B4E1BA8DEC0CD71 + 778D223C43915891DECBE645 + D139BE864E7331A490A31F83 + 7A75EF39F7B6094E98E9D58F + 11E705D1FBE2231D8B3FA30B + 76D0502FC1D6208D9E893050 + BB9E6E4F4B05385705EB97C0 + + isa + PBXGroup + name + UIKit + sourceTree + <group> + + 0BC85B368F05F28D8AC1E014 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + EXTScope.h + path + Mantle/extobjc/EXTScope.h + sourceTree + <group> + + 0BD156919664C48A35EEDBFE + + fileRef + E7926F44F6DD7675C4CAB292 + isa + PBXBuildFile + + 0BD65AA041B8332119344140 + + fileRef + 0E03512149CABB1F580F757D + isa + PBXBuildFile + + 0C14F1A11A291CA30BCB976F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMDB.h + path + src/fmdb/FMDB.h + sourceTree + <group> + + 0D2F41CC755DC941A9D3282F + + buildConfigurationList + 00768924736E895D7D503478 + buildPhases + + FAFFA27183B7E1544DC2D54D + 9165E3916BCF3741753508DC + 06D77D3ADBE13269F32AE1CF + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-SVWebViewController + productName + Pods-SVWebViewController + productReference + 8BF1A56862208AAE73DA9531 + productType + com.apple.product-type.library.static + + 0DDB7686E187F3FC19D520AC + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-Mantle.a + sourceTree + BUILT_PRODUCTS_DIR + + 0E03512149CABB1F580F757D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIScrollView+MJExtension.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.h + sourceTree + <group> + + 0E0B9761485C54F60690139C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFHTTPRequestOperationManager.h + path + AFNetworking/AFHTTPRequestOperationManager.h + sourceTree + <group> + + 0E0C3DD3CC95A1B05DA0ED85 + + fileRef + BB9E6E4F4B05385705EB97C0 + isa + PBXBuildFile + + 0E44B521E203EC4F111815E4 + + buildConfigurationList + 7571161F8493E257141282E2 + buildPhases + + 9AAAE1957C330405FAFB9600 + 8F935F9ED6A55A5476D707C4 + BDD171D88E04245FF41CFF78 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-SWTableViewCell + productName + Pods-SWTableViewCell + productReference + 463D037C8D05265B93AA341F + productType + com.apple.product-type.library.static + + 0E941574580314BABC46EF00 + + buildActionMask + 2147483647 + files + + CC2EB1431A8BBB896B00A972 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 0F22D9A04C4D256875AD1033 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIButton+WebCache.h + path + SDWebImage/UIButton+WebCache.h + sourceTree + <group> + + 10BE1219154FDDC59F7E91E8 + + fileRef + AC1C5B4CE91F11AE998D64F6 + isa + PBXBuildFile + + 10D51B68691D31108009BE93 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFHTTPRequestOperation.m + path + AFNetworking/AFHTTPRequestOperation.m + sourceTree + <group> + + 11292E3DE8EF40F9DCBCD526 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-MJRefresh-Private.xcconfig + sourceTree + <group> + + 11E705D1FBE2231D8B3FA30B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIRefreshControl+AFNetworking.m + path + UIKit+AFNetworking/UIRefreshControl+AFNetworking.m + sourceTree + <group> + + 12371F77B302ED20D4ABE615 + + children + + EB111D63CDEEB43E08195847 + + isa + PBXGroup + name + Resources + sourceTree + <group> + + 12896047E29D3DF31213A494 + + fileRef + EDA79BFF36ED8CC66472C4B4 + isa + PBXBuildFile + + 13A1A364A5506D8A8B3CB81E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVModalWebViewController.m + path + SVWebViewController/SVModalWebViewController.m + sourceTree + <group> + + 142C5427A774A7FFD4A9FD58 + + fileRef + 225B176F2E2BC5974E8C8001 + isa + PBXBuildFile + + 14C6C2B33E3B9C9DB8064CE3 + + fileRef + 9F77207596AAC05C2F57FD7F + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 15C57B0A0D754AA9967330DF + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + SystemConfiguration.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/SystemConfiguration.framework + sourceTree + DEVELOPER_DIR + + 160D3E2EB45E710B513005B2 + + fileRef + 18779A7BA8AAD008F51F3F9D + isa + PBXBuildFile + + 16BE2A454A10A0FFBBFDD201 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-AFNetworking-dummy.m + sourceTree + <group> + + 1817BF46EC0C042C7D3CF340 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLJSONAdapter.m + path + Mantle/MTLJSONAdapter.m + sourceTree + <group> + + 183B217DE3DE00FBD76C9DE5 + + isa + PBXTargetDependency + name + Pods-SDWebImage + target + 7FFBF073B63F5E27B5D0072F + targetProxy + 1A50A961A1670095B4C092C4 + + 18779A7BA8AAD008F51F3F9D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMResultSet.h + path + src/fmdb/FMResultSet.h + sourceTree + <group> + + 187C3AFF7CA47A0B29C75D89 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefreshBaseView.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.h + sourceTree + <group> + + 1890A9018AFB550869401948 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImageDownloader.m + path + SDWebImage/SDWebImageDownloader.m + sourceTree + <group> + + 1A404CF9215FA5CE825E6AE2 + + fileRef + 0C14F1A11A291CA30BCB976F + isa + PBXBuildFile + + 1A50A961A1670095B4C092C4 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 7FFBF073B63F5E27B5D0072F + remoteInfo + Pods-SDWebImage + + 1AF9F27A2984FABBCD8BB35F + + fileRef + 6A38B085018671A0ABB83BE1 + isa + PBXBuildFile + + 1B0ECD78A6C7584001AA72BE + + fileRef + 3FE2CB4E3BF724BF9DADD804 + isa + PBXBuildFile + + 1BF5129F506CB75B0F1BC5FB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + wrapper.plug-in + name + SVWebViewController.bundle + path + SVWebViewController/SVWebViewController.bundle + sourceTree + <group> + + 1CD8DE0BC0E13E9F18B3F9A1 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + E0F50EA1905F2A7094812973 + remoteInfo + Pods-AFNetworking + + 1D5CA0F9B7FCF817B26A5DBE + + fileRef + 9449B700FD78B567CDCE349E + isa + PBXBuildFile + + 1D87621C8A8B06BD9D364D45 + + children + + 752BB0BB115A89E3F4860E7E + + isa + PBXGroup + name + Targets Support Files + sourceTree + <group> + + 1DBA1A3F18B0BCF7E976DA37 + + fileRef + D139BE864E7331A490A31F83 + isa + PBXBuildFile + + 1DFAEC12DD2639335AF49ACE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSArray+MTLManipulationAdditions.m + path + Mantle/NSArray+MTLManipulationAdditions.m + sourceTree + <group> + + 1F5410B3AD75104BB163C869 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-dummy.m + sourceTree + <group> + + 2046088381816FB1A6115AE8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFURLRequestSerialization.h + path + AFNetworking/AFURLRequestSerialization.h + sourceTree + <group> + + 2170FBC10D2E8E490ECD303D + + fileRef + DC50FB9ACAC3D68AE360BF5F + isa + PBXBuildFile + + 217FA4FB15D4EDE83A84233D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefreshConst.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.h + sourceTree + <group> + + 21E3949570212F296A98F3C3 + + fileRef + 1F5410B3AD75104BB163C869 + isa + PBXBuildFile + + 221E3FF2B9CDB1D4F3615F0D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.plist.xml + path + Pods-acknowledgements.plist + sourceTree + <group> + + 222F9FE85B6C3B610407F404 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + FMResultSet.m + path + src/fmdb/FMResultSet.m + sourceTree + <group> + + 225B176F2E2BC5974E8C8001 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIActivityIndicatorView+AFNetworking.m + path + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.m + sourceTree + <group> + + 2366FECF46A2354EC3AC77D5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSDictionary+MTLManipulationAdditions.h + path + Mantle/NSDictionary+MTLManipulationAdditions.h + sourceTree + <group> + + 2384225F66B601A470E03B2D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSMutableArray+SWUtilityButtons.h + path + SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h + sourceTree + <group> + + 23A7B732974BAA16EF4D4F5A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLModel+NSCoding.m + path + Mantle/MTLModel+NSCoding.m + sourceTree + <group> + + 24200E9BAE5616D614E3BA14 + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + YES + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + ONLY_ACTIVE_ARCH + YES + STRIP_INSTALLED_PRODUCT + NO + + isa + XCBuildConfiguration + name + Debug + + 245A7D5B09274802299A5413 + + fileRef + DC6959F6B0389433A846F09B + isa + PBXBuildFile + + 2480FD39925604EC68E2B1B1 + + children + + F7446765000306425A8653CB + 33DC1FE29B55A083427A2983 + 3AACA1031CB453DF0B0F1B62 + 9E99E930712393BD264CF051 + B2FE89B302D990CFC2393FFB + 4346B230A89B46E6BE901D9E + A3516881B3D6F981B73AC538 + 6C91BBFD0AEB7230111657C4 + + isa + PBXGroup + name + Pods + sourceTree + <group> + + 24ECE29E2A83329E77BC464B + + fileRef + 716C03D21AAED4A8DD5ED96E + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 24EDA1E60FA28D25D59006F1 + + fileRef + 6D0FE93D2F53E6F9BE778A43 + isa + PBXBuildFile + + 256F4A417937912F5BA0262B + + fileRef + 8DC0686ECBB745003C3651C3 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 2579348338E55E4DD3339342 + + children + + A9649B3D73F213DD8CAF3844 + E3C180F70C4829EC3E7C8741 + AD4009A3CA3371D1F8C780E5 + 7AF9843A5A131AAFDB93EA21 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-FMDB + sourceTree + <group> + + 25BC2970B45A7D905D5F19BB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIScrollView+MJRefresh.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.m + sourceTree + <group> + + 25CE073DBCD2584B257B39DA + + fileRef + D0C3135DA2BA3C019BAF2DCF + isa + PBXBuildFile + + 26D05A8A28DCD60C1CA8EC7E + + buildActionMask + 2147483647 + files + + 749D67B382740B441A6C9985 + 04205120B87CE3914882E1E1 + F5336FA18F2792224B01F5AD + DDCF5122548DF51242583A68 + F44EDFC44AEF1BC95DB7FA7D + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 273E8CC1B7A1DF52553B76D7 + + buildActionMask + 2147483647 + files + + A566AAD0BC4F7B6641A8C759 + FA2858642D021A2940D97851 + F3B157F0A7C5AE48DEF99006 + 9FA315080E627AB06418F4B4 + C2F2F561C27931B0CFA6A5AD + A0BC09B6CD44A3EC41327140 + 7C9788498CCBBD0718711B7D + 9F9C79DFE629562CA77CD2CA + 12896047E29D3DF31213A494 + 1D5CA0F9B7FCF817B26A5DBE + 6EE966C6726621AA9BA61694 + 142C5427A774A7FFD4A9FD58 + 47D9D21AF5FF6276C1230478 + BE940E795DD463ACED5B538C + 6DC5F2F2A80D898D1B9BA4E9 + 1DBA1A3F18B0BCF7E976DA37 + 79AE7927E2E34267BBB4EEFB + 0E0C3DD3CC95A1B05DA0ED85 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 27A001025D8F6246D8E0D8D3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFHTTPRequestOperation.h + path + AFNetworking/AFHTTPRequestOperation.h + sourceTree + <group> + + 27CC88179E549D8028BB3973 + + buildActionMask + 2147483647 + files + + 8C11E60C3F243002B20ABAF7 + A3E886CEC48C491886768370 + D6D6D28D37442BAAA468A18D + A3A92429628C08F12D3FC1CD + 24ECE29E2A83329E77BC464B + B5CE0321A8AEFC3F5FA0DF70 + 639C0E9A9E7ADF70C513571E + EDCDF1F1A409A8EF63058261 + 14C6C2B33E3B9C9DB8064CE3 + 895426A01E6E4514960D5307 + F38473E10FE10739CC22000B + 03FA11483C1D0F3D8E20B008 + 55A7772828B4EE4C2F35A0CD + 8D934380DB6CDDF6B1F43315 + 256F4A417937912F5BA0262B + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 282B0048A3E511971931B363 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFURLConnectionOperation.h + path + AFNetworking/AFURLConnectionOperation.h + sourceTree + <group> + + 283AD6CF440DCA9B38B0B53C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLModel.m + path + Mantle/MTLModel.m + sourceTree + <group> + + 290221507373808ABAA4054B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFHTTPSessionManager.m + path + AFNetworking/AFHTTPSessionManager.m + sourceTree + <group> + + 292F5F1319A89AE506A962C2 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + CoreGraphics.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/CoreGraphics.framework + sourceTree + DEVELOPER_DIR + + 29A714F97FEC7249C075FD1B + + fileRef + 98D565C31B4E1BA8DEC0CD71 + isa + PBXBuildFile + + 29C91E9A9A1FACD36088397D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SWTableViewCell-Private.xcconfig + sourceTree + <group> + + 29EBF6D132B45FA490AAE8C4 + + children + + EF04ADF8DBB1227D34EBBEEA + DD72EA41B8BD0DC998006611 + 2480FD39925604EC68E2B1B1 + 7A9806F1FFB8C59E80CBFD08 + 1D87621C8A8B06BD9D364D45 + + isa + PBXGroup + sourceTree + <group> + + 2A7803167CE7616DAD6D45D8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMDatabase.h + path + src/fmdb/FMDatabase.h + sourceTree + <group> + + 2C5859609EFA12DBF8041624 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + EA053313AC9B201518E824AF + remoteInfo + Pods-Mantle + + 2D3A6D4FA7D703DF6C8A7450 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFURLSessionManager.h + path + AFNetworking/AFURLSessionManager.h + sourceTree + <group> + + 2D77E6FB71644E503AB9ED42 + + fileRef + 23A7B732974BAA16EF4D4F5A + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 2E82A19ADA9D6FA582DFA1B8 + + fileRef + 5CDF5BD81D96D9F7921C8DC4 + isa + PBXBuildFile + + 2F252426DE161299AE05188D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + wrapper.plug-in + name + MJRefresh.bundle + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle + sourceTree + <group> + + 2FC003B95AA7F89F6830FF92 + + fileRef + 32C94CBBCF8C76526F8213DA + isa + PBXBuildFile + + 304E5532CC66B25020968ED2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIAlertView+AFNetworking.m + path + UIKit+AFNetworking/UIAlertView+AFNetworking.m + sourceTree + <group> + + 30531E76C05F3BC19F4D8D31 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerNext@2x.png + path + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png + sourceTree + <group> + + 30C3BD86CBED0DC2975AE9C1 + + fileRef + 282B0048A3E511971931B363 + isa + PBXBuildFile + + 31ED12F5CEA9A23F5663038A + + buildConfigurations + + 666B1AFF5E73BE290468F5EC + 8A8E2AEA05C87BF2E72C7FCA + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 322D65FFB3319CBE9B35DD56 + + children + + 575254127992AC3095637C85 + C8519CEEEF547AA9EE9D9271 + 928FEC03396D35D183A65963 + 8DCB4D41A489D80F71A9D029 + F19082954117D5EC4CBF111A + E32EAF52CDE8541AAA86F6A0 + B3C85AC9AFD3294AE7C56106 + 716C03D21AAED4A8DD5ED96E + 84E79296009B0C709F29B5C1 + 1890A9018AFB550869401948 + 60142F5566216743E153E6C3 + 9F59D37382C8481C4A3543E6 + 3C4B103B2DCE282C9C9EA571 + FD93687F5220E28F92C0D41E + E9A68AA93E6B24526C1517E5 + 69070D1F2DAD001B977D7FCD + 9F77207596AAC05C2F57FD7F + 0F22D9A04C4D256875AD1033 + 7A1CB4CAA83E0FC77E12607B + 43B8A0C73CAAAADDEBCE7C0C + 8E7746C93B5A382A8BFB31C8 + FD317A4CDFFEF6932C841E62 + BDD54D59F9F168C7CDC3C286 + 5CDF5BD81D96D9F7921C8DC4 + 9878234455241C9D71D7D974 + E96F46F8A984911D7538CA63 + BC949D87330F6EC5E34A3352 + 35DE48B4FA6E51BD7D1BA6FC + 8DC0686ECBB745003C3651C3 + + isa + PBXGroup + name + Core + sourceTree + <group> + + 32C94CBBCF8C76526F8213DA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MJRefreshBaseView.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshBaseView.m + sourceTree + <group> + + 3396072C759A0E898549D6E7 + + fileRef + 90E53DFD34C1281914AAC149 + isa + PBXBuildFile + + 33DC1FE29B55A083427A2983 + + children + + 2579348338E55E4DD3339342 + 3A04D5BA2926938475C2BC63 + + isa + PBXGroup + name + FMDB + path + FMDB + sourceTree + <group> + + 34257C1DD98D838891B765BC + + children + + 44E5FEBB52959F4FE292E75F + 29C91E9A9A1FACD36088397D + A2B106C048B78A5C6FBAA445 + 94AC0364478A39DA51322B7F + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SWTableViewCell + sourceTree + <group> + + 34A0A9B27EF8487D6B85D039 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFNetworkReachabilityManager.m + path + AFNetworking/AFNetworkReachabilityManager.m + sourceTree + <group> + + 35DE48B4FA6E51BD7D1BA6FC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIView+WebCacheOperation.h + path + SDWebImage/UIView+WebCacheOperation.h + sourceTree + <group> + + 379C4A4E6343D5622A38206E + + fileRef + 0F22D9A04C4D256875AD1033 + isa + PBXBuildFile + + 379D3CCD2FFBB2698E6A788E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + metamacros.h + path + Mantle/extobjc/metamacros.h + sourceTree + <group> + + 37B990D486EB877EA36E8C25 + + fileRef + 6352CB3951039CAB104F5D32 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 3886D77C2964260BA24AC311 + + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + CLANG_CXX_LANGUAGE_STANDARD + gnu++0x + CLANG_CXX_LIBRARY + libc++ + CLANG_ENABLE_MODULES + YES + CLANG_ENABLE_OBJC_ARC + YES + CLANG_WARN_BOOL_CONVERSION + YES + CLANG_WARN_CONSTANT_CONVERSION + YES + CLANG_WARN_DIRECT_OBJC_ISA_USAGE + YES + CLANG_WARN_EMPTY_BODY + YES + CLANG_WARN_ENUM_CONVERSION + YES + CLANG_WARN_INT_CONVERSION + YES + CLANG_WARN_OBJC_ROOT_CLASS + YES + COPY_PHASE_STRIP + NO + ENABLE_NS_ASSERTIONS + NO + GCC_C_LANGUAGE_STANDARD + gnu99 + GCC_PREPROCESSOR_DEFINITIONS + + RELEASE=1 + + GCC_WARN_64_TO_32_BIT_CONVERSION + YES + GCC_WARN_ABOUT_RETURN_TYPE + YES + GCC_WARN_UNDECLARED_SELECTOR + YES + GCC_WARN_UNINITIALIZED_AUTOS + YES + GCC_WARN_UNUSED_FUNCTION + YES + GCC_WARN_UNUSED_VARIABLE + YES + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + STRIP_INSTALLED_PRODUCT + NO + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 3A04D5BA2926938475C2BC63 + + children + + 0C14F1A11A291CA30BCB976F + 2A7803167CE7616DAD6D45D8 + 595FC29ACF0D8E7894A124BF + 9E3CADF4D34242891C1E4725 + 96B82497505EF98401B50E1D + C684423B9F0BCABE69332621 + 6352CB3951039CAB104F5D32 + DC332F6A26805C987939E79B + FFF0E1F586F1C9698F168012 + 18779A7BA8AAD008F51F3F9D + 222F9FE85B6C3B610407F404 + + isa + PBXGroup + name + common + sourceTree + <group> + + 3A2FD88F529A99A655D5C439 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVIndefiniteAnimatedView.m + path + SVProgressHUD/SVIndefiniteAnimatedView.m + sourceTree + <group> + + 3AACA1031CB453DF0B0F1B62 + + children + + 3D08731A2D8B7A9D2A860E1E + 187C3AFF7CA47A0B29C75D89 + 32C94CBBCF8C76526F8213DA + 217FA4FB15D4EDE83A84233D + A19B2B715041A76AD22B7BB7 + C5B29E7C81D4C77334248AA5 + 3ED88041ED6DCCA7AB130669 + DC6959F6B0389433A846F09B + D0C6BE4F0F08EEF1AD4759BF + 0E03512149CABB1F580F757D + DC50FB9ACAC3D68AE360BF5F + 8ED9213EE55680C24F1EB677 + 25BC2970B45A7D905D5F19BB + 635165301CE75B15CC16EE35 + D405E1711A624A1719E082D2 + 77D44783F9EE017394DF2D6A + 6A082816851C55476BD99C06 + + isa + PBXGroup + name + MJRefresh + path + MJRefresh + sourceTree + <group> + + 3C4B103B2DCE282C9C9EA571 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageManager.h + path + SDWebImage/SDWebImageManager.h + sourceTree + <group> + + 3C55B095805681785D374172 + + fileRef + D0C6BE4F0F08EEF1AD4759BF + isa + PBXBuildFile + + 3CF9B45DDE34993A3FD50533 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-MJRefresh.a + sourceTree + BUILT_PRODUCTS_DIR + + 3D08731A2D8B7A9D2A860E1E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefresh.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.h + sourceTree + <group> + + 3E47599B0E330499635F07EE + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods.a + sourceTree + BUILT_PRODUCTS_DIR + + 3E7E94589902454FD328B4FD + + fileRef + 76D0502FC1D6208D9E893050 + isa + PBXBuildFile + + 3ED88041ED6DCCA7AB130669 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MJRefreshFooterView.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.m + sourceTree + <group> + + 3F40BF383E1E1834C0191BD5 + + fileRef + 771F20504BB303BB62A88285 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 3FE2CB4E3BF724BF9DADD804 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-SVProgressHUD-dummy.m + sourceTree + <group> + + 404F813C33EA2B5B22382ED6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-AFNetworking.xcconfig + sourceTree + <group> + + 4128868F2EF04420A1F35E0D + + buildActionMask + 2147483647 + files + + 1B0ECD78A6C7584001AA72BE + 912AE7405EF879CF2313E84E + 055CD4E1DAF33217D19B9141 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 41B60CD843C52B8457DCB0E0 + + buildConfigurationList + BEC66FA7BE915660404F69F2 + buildPhases + + E6D38302A5F37DB5658C41BB + F3B7C44428DC09B4933F043E + + buildRules + + dependencies + + 57232EF4CF27F922F799FEB8 + AD73A79FDD2F245D4F40C14B + 75C7388F53F668992B97A813 + DCFD647287A6F3DEE53059EB + 183B217DE3DE00FBD76C9DE5 + AADD81544137DB9F341D6ED3 + 051EC94587D0A832E9D6DEBA + 74B2111F4657AE8313673C8E + + isa + PBXNativeTarget + name + Pods + productName + Pods + productReference + 3E47599B0E330499635F07EE + productType + com.apple.product-type.library.static + + 4346B230A89B46E6BE901D9E + + children + + 9FB2FE90C5104F065B94608B + 3A2FD88F529A99A655D5C439 + 47ED5B3E2E498FA972A1AC3B + 52C22D274C762A81E9AEFD70 + 12371F77B302ED20D4ABE615 + F85DB5D3718ADE63303C06E7 + + isa + PBXGroup + name + SVProgressHUD + path + SVProgressHUD + sourceTree + <group> + + 436DFB9BEE3EAF06EAB25B0A + + fileRef + 1DFAEC12DD2639335AF49ACE + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 43B8A0C73CAAAADDEBCE7C0C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImage+GIF.h + path + SDWebImage/UIImage+GIF.h + sourceTree + <group> + + 4404E8E40C694424BA0B2EA2 + + fileRef + 514D95EC1DE6E7F84DFD7077 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 447B33241D6E8376ACAC2270 + + fileRef + 2046088381816FB1A6115AE8 + isa + PBXBuildFile + + 44E5FEBB52959F4FE292E75F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SWTableViewCell.xcconfig + sourceTree + <group> + + 4510BD0D82B5FD8633E82F6C + + fileRef + 61E1D6F569824AE60EC953DC + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 4639EC1DFC9BDEE03FCECD28 + + fileRef + FD317A4CDFFEF6932C841E62 + isa + PBXBuildFile + + 463D037C8D05265B93AA341F + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SWTableViewCell.a + sourceTree + BUILT_PRODUCTS_DIR + + 46F1E537458316428EEE009F + + fileRef + C834791111C32E19511470D4 + isa + PBXBuildFile + + 475828FB9C2F29954582B1E4 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerNext.png + path + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png + sourceTree + <group> + + 47BC372C33FCDDB0603FF870 + + baseConfigurationReference + 11292E3DE8EF40F9DCBCD526 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 47C11AD21FEAD8A5CAA86FC0 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-AFNetworking.a + sourceTree + BUILT_PRODUCTS_DIR + + 47D9D21AF5FF6276C1230478 + + fileRef + 304E5532CC66B25020968ED2 + isa + PBXBuildFile + + 47ED5B3E2E498FA972A1AC3B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVProgressHUD.h + path + SVProgressHUD/SVProgressHUD.h + sourceTree + <group> + + 48558FEAC015CC0EFC37FD0A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVWebViewControllerActivity.m + path + SVWebViewController/UIActivities/SVWebViewControllerActivity.m + sourceTree + <group> + + 49C2583DD5BC008CD83F6071 + + fileRef + C50CBBB3320CBFC5FA8EA34D + isa + PBXBuildFile + + 4AC5FA018B13C92FA6D66B86 + + fileRef + 983F9AB5B982D654799AA2AC + isa + PBXBuildFile + + 4D56B1E3005FDE505FCEF6C6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImageView+AFNetworking.m + path + UIKit+AFNetworking/UIImageView+AFNetworking.m + sourceTree + <group> + + 514D95EC1DE6E7F84DFD7077 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + EXTRuntimeExtensions.m + path + Mantle/extobjc/EXTRuntimeExtensions.m + sourceTree + <group> + + 5161C757881F6F6873559967 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-SVProgressHUD-prefix.pch + sourceTree + <group> + + 52C22D274C762A81E9AEFD70 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVProgressHUD.m + path + SVProgressHUD/SVProgressHUD.m + sourceTree + <group> + + 52D9636A49CE4EAB4B056599 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivitySafari@2x.png + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png + sourceTree + <group> + + 531197FDF80BC84527CCAF02 + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + 532E5B4150ED4F50E11BF0C7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLModel+NSCoding.h + path + Mantle/MTLModel+NSCoding.h + sourceTree + <group> + + 53C5A15AD63D3476D0CF1531 + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + 5453F743BF1ED5091106B499 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLManagedObjectAdapter.h + path + Mantle/MTLManagedObjectAdapter.h + sourceTree + <group> + + 54AF66B17C0AEFF7AE1E5828 + + children + + 27A001025D8F6246D8E0D8D3 + 10D51B68691D31108009BE93 + 0E0B9761485C54F60690139C + 63B65631DCD63B55E53DCE03 + 282B0048A3E511971931B363 + BD7A57AABDA83E720552763E + + isa + PBXGroup + name + NSURLConnection + sourceTree + <group> + + 55A7772828B4EE4C2F35A0CD + + fileRef + 9878234455241C9D71D7D974 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 57232EF4CF27F922F799FEB8 + + isa + PBXTargetDependency + name + Pods-AFNetworking + target + E0F50EA1905F2A7094812973 + targetProxy + 1CD8DE0BC0E13E9F18B3F9A1 + + 5737FC94B9492B6E6C616163 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text + path + Pods-acknowledgements.markdown + sourceTree + <group> + + 573C8CC99C8641490B222C89 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLValueTransformer.m + path + Mantle/MTLValueTransformer.m + sourceTree + <group> + + 575254127992AC3095637C85 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSData+ImageContentType.h + path + SDWebImage/NSData+ImageContentType.h + sourceTree + <group> + + 57FA31C7342E4A8693201F60 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-MJRefresh-dummy.m + sourceTree + <group> + + 585F33F75FFBDB5A2D635BC5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-AFNetworking-Private.xcconfig + sourceTree + <group> + + 58D5E10B6F509A4D289AC17C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SWUtilityButtonView.h + path + SWTableViewCell/PodFiles/SWUtilityButtonView.h + sourceTree + <group> + + 595FC29ACF0D8E7894A124BF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + FMDatabase.m + path + src/fmdb/FMDatabase.m + sourceTree + <group> + + 59C305ABE1A25B9CB62E5D80 + + buildActionMask + 2147483647 + files + + 7B339A4AB2229806F0376DB7 + BE9EDA04D687D70B682E1E0C + 69F567464F319FC63F2636E9 + 49C2583DD5BC008CD83F6071 + F02AEA09DBE0E12AF360F35D + 89DFAC3443DB77191DF2822E + C3A33DB3AF5947A220C22474 + 30C3BD86CBED0DC2975AE9C1 + 447B33241D6E8376ACAC2270 + D88A7258E9903DD9091947B3 + DB5A704B96D04FBF9549DA3B + FB392C3A7B8813F8724C2732 + EB394718051F19102CEA333B + 7CD1296E64395F26B193A132 + 8F938B6A800B85ACF6903654 + 29A714F97FEC7249C075FD1B + 615507F606D311E239F28363 + F78D23F252315D98B9BE3FA6 + 3E7E94589902454FD328B4FD + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 59DD36BD9A4D804D5A701ED2 + + buildActionMask + 2147483647 + files + + 1A404CF9215FA5CE825E6AE2 + 7DA715BA2498F3CB799A4431 + C885E60E6C8BD0A926570AF5 + 892235EA9B366AF2D9486607 + E4F17FDA9A2004644DE362D1 + 160D3E2EB45E710B513005B2 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 5A89A95B50754A00C6F8883D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SVWebViewController.xcconfig + sourceTree + <group> + + 5C59B57AC630CD73AB5E2D1E + + fileRef + 35DE48B4FA6E51BD7D1BA6FC + isa + PBXBuildFile + + 5CDF5BD81D96D9F7921C8DC4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImageView+HighlightedWebCache.h + path + SDWebImage/UIImageView+HighlightedWebCache.h + sourceTree + <group> + + 5CEA9DDB4661A6FC3DC94DC6 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 6736EF81F571346B01E63AAB + remoteInfo + Pods-SVProgressHUD + + 5DF09EA3510F7C19B9A4DA3C + + fileRef + 187C3AFF7CA47A0B29C75D89 + isa + PBXBuildFile + + 60142F5566216743E153E6C3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageDownloaderOperation.h + path + SDWebImage/SDWebImageDownloaderOperation.h + sourceTree + <group> + + 613007691409B9A6751D3737 + + fileRef + AD4009A3CA3371D1F8C780E5 + isa + PBXBuildFile + + 615507F606D311E239F28363 + + fileRef + 778D223C43915891DECBE645 + isa + PBXBuildFile + + 61E1D6F569824AE60EC953DC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLManagedObjectAdapter.m + path + Mantle/MTLManagedObjectAdapter.m + sourceTree + <group> + + 62417097E44F7D3F8139F32F + + baseConfigurationReference + A1B208310F6C031CA9568682 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 62A6847E2C4950BA9C5A8A73 + + fileRef + 02E92DC83C62401C25C8913C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 633433250CA4F0951A356573 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + EXTKeyPathCoding.h + path + Mantle/extobjc/EXTKeyPathCoding.h + sourceTree + <group> + + 635165301CE75B15CC16EE35 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIView+MJExtension.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.h + sourceTree + <group> + + 6352CB3951039CAB104F5D32 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + FMDatabasePool.m + path + src/fmdb/FMDatabasePool.m + sourceTree + <group> + + 639C0E9A9E7ADF70C513571E + + fileRef + 9F59D37382C8481C4A3543E6 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 63B65631DCD63B55E53DCE03 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFHTTPRequestOperationManager.m + path + AFNetworking/AFHTTPRequestOperationManager.m + sourceTree + <group> + + 640D32B00E7CA013FAA9F891 + + fileRef + 2384225F66B601A470E03B2D + isa + PBXBuildFile + + 651297332C80103B10000DCA + + fileRef + BD9CA4ED0FDE48B5335FA601 + isa + PBXBuildFile + + 65D19C9FCE68CD267930EF33 + + fileRef + E9A68AA93E6B24526C1517E5 + isa + PBXBuildFile + + 662A98C63D4A25AEDD5B5EC8 + + fileRef + 69070D1F2DAD001B977D7FCD + isa + PBXBuildFile + + 662F6BC68D35264D3A2E14DF + + baseConfigurationReference + E0E9DDEE088E41C8CF4C003D + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 666B1AFF5E73BE290468F5EC + + baseConfigurationReference + B9F5BA86ACFC81B344D15D30 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 6736EF81F571346B01E63AAB + + buildConfigurationList + 00184188B977DFF23A1F85C5 + buildPhases + + 4128868F2EF04420A1F35E0D + 7371E4E66A36022278C4AA90 + 73926FAB26BEDB4523776F71 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-SVProgressHUD + productName + Pods-SVProgressHUD + productReference + C8409304ABBDB3DE6635DB18 + productType + com.apple.product-type.library.static + + 674480447F049BFA1C4EA514 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImageView+AFNetworking.h + path + UIKit+AFNetworking/UIImageView+AFNetworking.h + sourceTree + <group> + + 67528D3EFE5A643ED1F3CCAA + + fileRef + 0BC85B368F05F28D8AC1E014 + isa + PBXBuildFile + + 69070D1F2DAD001B977D7FCD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImagePrefetcher.h + path + SDWebImage/SDWebImagePrefetcher.h + sourceTree + <group> + + 6947C9D1C5EE33C1D2440E0C + + fileRef + F0DD19AA7C01867C1769DBE1 + isa + PBXBuildFile + + 69F567464F319FC63F2636E9 + + fileRef + D9CF805123DCF31BD815B4BB + isa + PBXBuildFile + + 6A082816851C55476BD99C06 + + children + + B3654B8D5A85FC44A7A6B1FE + 11292E3DE8EF40F9DCBCD526 + 57FA31C7342E4A8693201F60 + A7755A9FB17EA678C37DCD95 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-MJRefresh + sourceTree + <group> + + 6A38B085018671A0ABB83BE1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLReflection.h + path + Mantle/MTLReflection.h + sourceTree + <group> + + 6AE46452959456D9CAA2648A + + fileRef + 3ED88041ED6DCCA7AB130669 + isa + PBXBuildFile + + 6B6B026C7F8F1376C998B055 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-Mantle-prefix.pch + sourceTree + <group> + + 6C469821D18CEA22E80ACA5E + + fileRef + CE4B7722CAC9ED8DD0114663 + isa + PBXBuildFile + + 6C883654D7A0A3023FD1840D + + fileRef + E96F46F8A984911D7538CA63 + isa + PBXBuildFile + + 6C91BBFD0AEB7230111657C4 + + children + + 2384225F66B601A470E03B2D + BF9582E6D1D11AAE4C82790C + CE4B7722CAC9ED8DD0114663 + D2AE7F8D94E0B80BFA8F603A + A32AD2139187CB1F5F2B6247 + FC45931EABC40836F3C02FDB + B2DFB8ABE3C361564605FC09 + D8F1FDF888DD2382AECC30C3 + C56F74D0AAB1C57653DA7F7A + 983F9AB5B982D654799AA2AC + 58D5E10B6F509A4D289AC17C + F3E77A78BED9A830D2670005 + 34257C1DD98D838891B765BC + + isa + PBXGroup + name + SWTableViewCell + path + SWTableViewCell + sourceTree + <group> + + 6D0FE93D2F53E6F9BE778A43 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + EXTRuntimeExtensions.h + path + Mantle/extobjc/EXTRuntimeExtensions.h + sourceTree + <group> + + 6D3B22115589829E7FEAC2D2 + + fileRef + 7EABDBD965900014161BECCC + isa + PBXBuildFile + + 6D6492CFDFC03E3EEED90937 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIActivityIndicatorView+AFNetworking.h + path + UIKit+AFNetworking/UIActivityIndicatorView+AFNetworking.h + sourceTree + <group> + + 6DC5F2F2A80D898D1B9BA4E9 + + fileRef + 4D56B1E3005FDE505FCEF6C6 + isa + PBXBuildFile + + 6EE966C6726621AA9BA61694 + + fileRef + 16BE2A454A10A0FFBBFDD201 + isa + PBXBuildFile + + 70F7A8DB0E39B67802CA7A76 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVWebViewController.h + path + SVWebViewController/SVWebViewController.h + sourceTree + <group> + + 7119A73FBB159384BD4FC17E + + fileRef + D8F1FDF888DD2382AECC30C3 + isa + PBXBuildFile + + 716C03D21AAED4A8DD5ED96E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImageDecoder.m + path + SDWebImage/SDWebImageDecoder.m + sourceTree + <group> + + 720BC6CAA4ECD29F66CE897D + + fileRef + A32AD2139187CB1F5F2B6247 + isa + PBXBuildFile + + 72575C4414A386B75A1236C3 + + baseConfigurationReference + F20B4E0EAAA530D24685A4E2 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 726EFC473FE50E3788EFFEEF + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + 72C660C537791274ABD52CB9 + + fileRef + AD4719C2919B562DF3C80502 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 72D8C02503DA06347455FDD9 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + D6558E03D7E8E7369D57D62A + remoteInfo + Pods-MJRefresh + + 730266F29F62BC3EB931952F + + fileRef + C32A44B3BB593CF09E391F55 + isa + PBXBuildFile + + 7371E4E66A36022278C4AA90 + + buildActionMask + 2147483647 + files + + B81737201F183B1D172A4B4D + BFA9BA48E845CDA5D016018D + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 73866FD56D89AA5A3F622874 + + buildActionMask + 2147483647 + files + + 4404E8E40C694424BA0B2EA2 + 91ACDD3A1590BBCBEDEBA6E4 + 8AFBA1F303183188ABA0AD0D + 4510BD0D82B5FD8633E82F6C + 2D77E6FB71644E503AB9ED42 + 9B92478EA76FF9303AFAE57A + EAABEB6BACA94FCEFBA11DFD + FB6C8948A46CF245ECD20949 + 436DFB9BEE3EAF06EAB25B0A + 3F40BF383E1E1834C0191BD5 + 62A6847E2C4950BA9C5A8A73 + C3756A16C38B7B1455914F49 + FDAFE1F6255ECC888D7503AB + 72C660C537791274ABD52CB9 + DFFAC01197AE918D4C9DFD66 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 73926FAB26BEDB4523776F71 + + buildActionMask + 2147483647 + files + + CB6E38F58D69B7640B71B0D2 + 7EEF3E303A89EACE920C35DD + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 7398CA0C7FAD6B1A8E5B3A95 + + children + + 1BF5129F506CB75B0F1BC5FB + 80D1CC4C00005AC726EEF730 + E29DFA8F7F2E89354CECB6C3 + 057A36C64C16BAE9CBB65645 + 795E09B9C10CEEFC412F3BF1 + D2504912E25654781C939724 + 52D9636A49CE4EAB4B056599 + 019033947122D26DFF88E20C + 86C0AE129EAF30BD5988B84A + 475828FB9C2F29954582B1E4 + 30531E76C05F3BC19F4D8D31 + + isa + PBXGroup + name + Resources + sourceTree + <group> + + 749D67B382740B441A6C9985 + + fileRef + 292F5F1319A89AE506A962C2 + isa + PBXBuildFile + + 74B2111F4657AE8313673C8E + + isa + PBXTargetDependency + name + Pods-SWTableViewCell + target + 0E44B521E203EC4F111815E4 + targetProxy + A212E3E719279B15D99358D7 + + 74ED67273EBDF1D93351D598 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SVProgressHUD.xcconfig + sourceTree + <group> + + 752BB0BB115A89E3F4860E7E + + children + + 5737FC94B9492B6E6C616163 + 221E3FF2B9CDB1D4F3615F0D + 1F5410B3AD75104BB163C869 + C0ECB4C8D31A24B2C3CF9E1F + FC5FC75F692847F3591B34B3 + ECDFCA3A35CD6A95747B8E90 + E0E9DDEE088E41C8CF4C003D + + isa + PBXGroup + name + Pods + path + Target Support Files/Pods + sourceTree + <group> + + 7571161F8493E257141282E2 + + buildConfigurations + + 823C291B70653700AE069288 + 7DB2B870719E2167330488F5 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 75C7388F53F668992B97A813 + + isa + PBXTargetDependency + name + Pods-MJRefresh + target + D6558E03D7E8E7369D57D62A + targetProxy + 72D8C02503DA06347455FDD9 + + 76D0502FC1D6208D9E893050 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIWebView+AFNetworking.h + path + UIKit+AFNetworking/UIWebView+AFNetworking.h + sourceTree + <group> + + 76F2FB474F9C57ED0AB606BB + + children + + 2046088381816FB1A6115AE8 + D09A62E8A6854C6E80B36152 + 7E1CD1AAAE86E52A5E55A54C + EDA79BFF36ED8CC66472C4B4 + + isa + PBXGroup + name + Serialization + sourceTree + <group> + + 771F20504BB303BB62A88285 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSDictionary+MTLManipulationAdditions.m + path + Mantle/NSDictionary+MTLManipulationAdditions.m + sourceTree + <group> + + 778D223C43915891DECBE645 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIProgressView+AFNetworking.h + path + UIKit+AFNetworking/UIProgressView+AFNetworking.h + sourceTree + <group> + + 77B2205754BF87FD2229D9F2 + + fileRef + D2AE7F8D94E0B80BFA8F603A + isa + PBXBuildFile + + 77D44783F9EE017394DF2D6A + + children + + 2F252426DE161299AE05188D + + isa + PBXGroup + name + Resources + sourceTree + <group> + + 795E09B9C10CEEFC412F3BF1 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivitySafari-iPad.png + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png + sourceTree + <group> + + 79AE7927E2E34267BBB4EEFB + + fileRef + 11E705D1FBE2231D8B3FA30B + isa + PBXBuildFile + + 7A1CB4CAA83E0FC77E12607B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIButton+WebCache.m + path + SDWebImage/UIButton+WebCache.m + sourceTree + <group> + + 7A75EF39F7B6094E98E9D58F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIRefreshControl+AFNetworking.h + path + UIKit+AFNetworking/UIRefreshControl+AFNetworking.h + sourceTree + <group> + + 7A9806F1FFB8C59E80CBFD08 + + children + + 3E47599B0E330499635F07EE + 47C11AD21FEAD8A5CAA86FC0 + 0398B69338481EC817F6F6EB + 3CF9B45DDE34993A3FD50533 + 0DDB7686E187F3FC19D520AC + 0371BF6A0BA2FCC5D93407F8 + C8409304ABBDB3DE6635DB18 + 8BF1A56862208AAE73DA9531 + 463D037C8D05265B93AA341F + + isa + PBXGroup + name + Products + sourceTree + <group> + + 7AF9843A5A131AAFDB93EA21 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-FMDB-prefix.pch + sourceTree + <group> + + 7B237DEB99E4A1EC780BD565 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFSecurityPolicy.m + path + AFNetworking/AFSecurityPolicy.m + sourceTree + <group> + + 7B339A4AB2229806F0376DB7 + + fileRef + 27A001025D8F6246D8E0D8D3 + isa + PBXBuildFile + + 7C9788498CCBBD0718711B7D + + fileRef + BD7A57AABDA83E720552763E + isa + PBXBuildFile + + 7CD1296E64395F26B193A132 + + fileRef + 90692384AE86654AF740CBA0 + isa + PBXBuildFile + + 7D4286C5720F98FA2A3F8A35 + + fileRef + 8ED9213EE55680C24F1EB677 + isa + PBXBuildFile + + 7DA715BA2498F3CB799A4431 + + fileRef + 2A7803167CE7616DAD6D45D8 + isa + PBXBuildFile + + 7DB2B870719E2167330488F5 + + baseConfigurationReference + 29C91E9A9A1FACD36088397D + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 7E1CD1AAAE86E52A5E55A54C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFURLResponseSerialization.h + path + AFNetworking/AFURLResponseSerialization.h + sourceTree + <group> + + 7E41E08A91865687803B6C82 + + baseConfigurationReference + A1B208310F6C031CA9568682 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 7E4322D8FA302168CB5CFFB2 + + buildActionMask + 2147483647 + files + + 87A2F8DB244BEC5D78F28B8B + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 7E4DEC9F5579FF9E6012310D + + buildActionMask + 2147483647 + files + + 2FC003B95AA7F89F6830FF92 + ECFFA56C6B3F8AC988E09B43 + 6AE46452959456D9CAA2648A + 3C55B095805681785D374172 + D568513A73D383D812B92361 + 2170FBC10D2E8E490ECD303D + CCD59E2FDDA491F626635409 + 016D2ED5429A374F8D023442 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 7EABDBD965900014161BECCC + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + ImageIO.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/ImageIO.framework + sourceTree + DEVELOPER_DIR + + 7EEF3E303A89EACE920C35DD + + fileRef + 47ED5B3E2E498FA972A1AC3B + isa + PBXBuildFile + + 7F117C1078DB1AD4F3B4FE11 + + fileRef + 928FEC03396D35D183A65963 + isa + PBXBuildFile + + 7F71FB5470A79B51285AB34E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSObject+MTLComparisonAdditions.m + path + Mantle/NSObject+MTLComparisonAdditions.m + sourceTree + <group> + + 7FFBF073B63F5E27B5D0072F + + buildConfigurationList + 8EB04CFA656709317963A2B2 + buildPhases + + 27CC88179E549D8028BB3973 + B75F517882BF000A53EC59B3 + EBB725B945B1732ECF3A9006 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-SDWebImage + productName + Pods-SDWebImage + productReference + 0371BF6A0BA2FCC5D93407F8 + productType + com.apple.product-type.library.static + + 80D1CC4C00005AC726EEF730 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivityChrome-iPad.png + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png + sourceTree + <group> + + 816C64CDAD58A599C6C8138B + + children + + CAC00BB41401121BDC44E7E5 + B9F5BA86ACFC81B344D15D30 + A95D82B9D1D2BEFE3D2DAB00 + 6B6B026C7F8F1376C998B055 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-Mantle + sourceTree + <group> + + 823C291B70653700AE069288 + + baseConfigurationReference + 29C91E9A9A1FACD36088397D + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 82D7942CFFB4B5F9A8039B0E + + buildConfigurations + + FC51B49E4686DFD82E09DE0B + AF263AC92D39C068F246DF63 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 83C50DBF98466D8F993D6269 + + fileRef + 3D08731A2D8B7A9D2A860E1E + isa + PBXBuildFile + + 846C466F2240C4C93CD6C24C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVWebViewController.m + path + SVWebViewController/SVWebViewController.m + sourceTree + <group> + + 84E79296009B0C709F29B5C1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageDownloader.h + path + SDWebImage/SDWebImageDownloader.h + sourceTree + <group> + + 856BC697A0DE727D2365B4B7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSError+MTLModelException.h + path + Mantle/NSError+MTLModelException.h + sourceTree + <group> + + 86C0AE129EAF30BD5988B84A + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerBack@2x.png + path + SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png + sourceTree + <group> + + 86F73289E11C480C16D33BCB + + baseConfigurationReference + ECDFCA3A35CD6A95747B8E90 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + 87A2F8DB244BEC5D78F28B8B + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + 892235EA9B366AF2D9486607 + + fileRef + C684423B9F0BCABE69332621 + isa + PBXBuildFile + + 895426A01E6E4514960D5307 + + fileRef + 7A1CB4CAA83E0FC77E12607B + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 89DFAC3443DB77191DF2822E + + fileRef + 9AC054684C72878BFD1354BD + isa + PBXBuildFile + + 8A081DC2D78B0C22A3B1CDDE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFNetworkActivityIndicatorManager.m + path + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.m + sourceTree + <group> + + 8A72EC2E5ADEFD1185ACE525 + + baseConfigurationReference + E8D5D18DAA535CA6B08AA393 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 8A8E2AEA05C87BF2E72C7FCA + + baseConfigurationReference + B9F5BA86ACFC81B344D15D30 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + 8AFBA1F303183188ABA0AD0D + + fileRef + 1817BF46EC0C042C7D3CF340 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 8BF1A56862208AAE73DA9531 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SVWebViewController.a + sourceTree + BUILT_PRODUCTS_DIR + + 8C11E60C3F243002B20ABAF7 + + fileRef + C8519CEEEF547AA9EE9D9271 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 8CCB2EE71B1282861778906D + + fileRef + 70F7A8DB0E39B67802CA7A76 + isa + PBXBuildFile + + 8D934380DB6CDDF6B1F43315 + + fileRef + BC949D87330F6EC5E34A3352 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 8DC0686ECBB745003C3651C3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIView+WebCacheOperation.m + path + SDWebImage/UIView+WebCacheOperation.m + sourceTree + <group> + + 8DCB4D41A489D80F71A9D029 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDImageCache.m + path + SDWebImage/SDImageCache.m + sourceTree + <group> + + 8E7746C93B5A382A8BFB31C8 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImage+GIF.m + path + SDWebImage/UIImage+GIF.m + sourceTree + <group> + + 8EB04CFA656709317963A2B2 + + buildConfigurations + + 62417097E44F7D3F8139F32F + 7E41E08A91865687803B6C82 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + 8ED9213EE55680C24F1EB677 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIScrollView+MJRefresh.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJRefresh.h + sourceTree + <group> + + 8F935F9ED6A55A5476D707C4 + + buildActionMask + 2147483647 + files + + 726EFC473FE50E3788EFFEEF + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 8F938B6A800B85ACF6903654 + + fileRef + 674480447F049BFA1C4EA514 + isa + PBXBuildFile + + 90692384AE86654AF740CBA0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIButton+AFNetworking.h + path + UIKit+AFNetworking/UIButton+AFNetworking.h + sourceTree + <group> + + 90E53DFD34C1281914AAC149 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-SVWebViewController-dummy.m + sourceTree + <group> + + 912AE7405EF879CF2313E84E + + fileRef + 3A2FD88F529A99A655D5C439 + isa + PBXBuildFile + + 9165E3916BCF3741753508DC + + buildActionMask + 2147483647 + files + + 53C5A15AD63D3476D0CF1531 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 91ACDD3A1590BBCBEDEBA6E4 + + fileRef + E62260C013619653C0C58B3D + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 928FEC03396D35D183A65963 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDImageCache.h + path + SDWebImage/SDImageCache.h + sourceTree + <group> + + 92947A2B649AE65D923B7C2E + + fileRef + A2B106C048B78A5C6FBAA445 + isa + PBXBuildFile + + 92D1A0BBD0D2B1EA721B084C + + fileRef + 3C4B103B2DCE282C9C9EA571 + isa + PBXBuildFile + + 9449B700FD78B567CDCE349E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFURLSessionManager.m + path + AFNetworking/AFURLSessionManager.m + sourceTree + <group> + + 94AC0364478A39DA51322B7F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-SWTableViewCell-prefix.pch + sourceTree + <group> + + 94D197FD4192DB667B6E9A51 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFNetworkReachabilityManager.h + path + AFNetworking/AFNetworkReachabilityManager.h + sourceTree + <group> + + 968006EA8109A263FDFD3965 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-SDWebImage-dummy.m + sourceTree + <group> + + 96B82497505EF98401B50E1D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + FMDatabaseAdditions.m + path + src/fmdb/FMDatabaseAdditions.m + sourceTree + <group> + + 96E033AF44F3F21FB871FC01 + + fileRef + 48558FEAC015CC0EFC37FD0A + isa + PBXBuildFile + + 971BBE7FBC532FD0C3684E99 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + MobileCoreServices.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/MobileCoreServices.framework + sourceTree + DEVELOPER_DIR + + 97959B6C405A6219826BAFBE + + fileRef + 13A1A364A5506D8A8B3CB81E + isa + PBXBuildFile + + 983F9AB5B982D654799AA2AC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWUtilityButtonTapGestureRecognizer.m + path + SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m + sourceTree + <group> + + 9878234455241C9D71D7D974 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImageView+HighlightedWebCache.m + path + SDWebImage/UIImageView+HighlightedWebCache.m + sourceTree + <group> + + 98D565C31B4E1BA8DEC0CD71 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIKit+AFNetworking.h + path + UIKit+AFNetworking/UIKit+AFNetworking.h + sourceTree + <group> + + 9AAAE1957C330405FAFB9600 + + buildActionMask + 2147483647 + files + + C1DE7C20F35B97860D706B66 + 92947A2B649AE65D923B7C2E + 77B2205754BF87FD2229D9F2 + F49B17CD5DB7BF511AD95FE0 + 7119A73FBB159384BD4FC17E + 4AC5FA018B13C92FA6D66B86 + B58F93C474B2E8430B05D256 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 9AC054684C72878BFD1354BD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFNetworking.h + path + AFNetworking/AFNetworking.h + sourceTree + <group> + + 9B92478EA76FF9303AFAE57A + + fileRef + 283AD6CF440DCA9B38B0B53C + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + 9C079AF4CCEEC69481F2BF10 + + fileRef + CA15D003C21CFCA2294BE5DB + isa + PBXBuildFile + + 9E3CADF4D34242891C1E4725 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMDatabaseAdditions.h + path + src/fmdb/FMDatabaseAdditions.h + sourceTree + <group> + + 9E99E930712393BD264CF051 + + children + + A6D689B150BE62B7DB1AC767 + 1817BF46EC0C042C7D3CF340 + 5453F743BF1ED5091106B499 + 61E1D6F569824AE60EC953DC + C834791111C32E19511470D4 + 283AD6CF440DCA9B38B0B53C + 532E5B4150ED4F50E11BF0C7 + 23A7B732974BAA16EF4D4F5A + 6A38B085018671A0ABB83BE1 + A8C971E5B6D1D6B34B5C9A1B + E7926F44F6DD7675C4CAB292 + 573C8CC99C8641490B222C89 + AF131B236DD5AB2E742ADEF2 + F0DD19AA7C01867C1769DBE1 + 1DFAEC12DD2639335AF49ACE + 2366FECF46A2354EC3AC77D5 + 771F20504BB303BB62A88285 + 856BC697A0DE727D2365B4B7 + 02E92DC83C62401C25C8913C + BFCFD346B7D3A14BA3BA069B + 7F71FB5470A79B51285AB34E + AC1C5B4CE91F11AE998D64F6 + AADE27D38FBFB33465D0DA5F + D0C3135DA2BA3C019BAF2DCF + AD4719C2919B562DF3C80502 + 816C64CDAD58A599C6C8138B + C932222C6328C3C84A162E3B + + isa + PBXGroup + name + Mantle + path + Mantle + sourceTree + <group> + + 9E9A3CEB47FB55E4697B447A + + fileRef + 532E5B4150ED4F50E11BF0C7 + isa + PBXBuildFile + + 9EC42BD6CC05E3F9835DEB3C + + children + + EA98CE819CDC3A1C462DA862 + A1B208310F6C031CA9568682 + 968006EA8109A263FDFD3965 + AA553D7A3D3565A545F3AD41 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SDWebImage + sourceTree + <group> + + 9EDC843AF94153F5B29AD001 + + fileRef + 58D5E10B6F509A4D289AC17C + isa + PBXBuildFile + + 9EFF5CE823942564335B0542 + + fileRef + 60142F5566216743E153E6C3 + isa + PBXBuildFile + + 9F4821AF45F02268E44D0C1D + + fileRef + 84E79296009B0C709F29B5C1 + isa + PBXBuildFile + + 9F59D37382C8481C4A3543E6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImageDownloaderOperation.m + path + SDWebImage/SDWebImageDownloaderOperation.m + sourceTree + <group> + + 9F745963084D8E9E216392E2 + + buildActionMask + 2147483647 + files + + A361D7EB87257BFB39CD297F + 24EDA1E60FA28D25D59006F1 + 67528D3EFE5A643ED1F3CCAA + FC77BBB341E0605E8ED130FB + B668271A16D47AF44F9BBCDA + 9E9A3CEB47FB55E4697B447A + 46F1E537458316428EEE009F + 1AF9F27A2984FABBCD8BB35F + 0BD156919664C48A35EEDBFE + FED8EC57D00423F3832AA2A9 + 6947C9D1C5EE33C1D2440E0C + 9FF9F40002ADF22BEF8BE069 + ABDDECC9891EA588DA2A5FF8 + E45958CE3CBD11F1707F441C + 10BE1219154FDDC59F7E91E8 + 25CE073DBCD2584B257B39DA + D79E955756AA01C364E52FE8 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + 9F77207596AAC05C2F57FD7F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImagePrefetcher.m + path + SDWebImage/SDWebImagePrefetcher.m + sourceTree + <group> + + 9F9C79DFE629562CA77CD2CA + + fileRef + D09A62E8A6854C6E80B36152 + isa + PBXBuildFile + + 9FA315080E627AB06418F4B4 + + fileRef + 8A081DC2D78B0C22A3B1CDDE + isa + PBXBuildFile + + 9FB2FE90C5104F065B94608B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVIndefiniteAnimatedView.h + path + SVProgressHUD/SVIndefiniteAnimatedView.h + sourceTree + <group> + + 9FF9F40002ADF22BEF8BE069 + + fileRef + 2366FECF46A2354EC3AC77D5 + isa + PBXBuildFile + + A0BC09B6CD44A3EC41327140 + + fileRef + 7B237DEB99E4A1EC780BD565 + isa + PBXBuildFile + + A0EB66A861D7F9BE99167595 + + fileRef + 595FC29ACF0D8E7894A124BF + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + A110D8DB17AB6647C7795EBD + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIButton+AFNetworking.m + path + UIKit+AFNetworking/UIButton+AFNetworking.m + sourceTree + <group> + + A19B2B715041A76AD22B7BB7 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MJRefreshConst.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshConst.m + sourceTree + <group> + + A19CDB887CB102ECC06C0723 + + baseConfigurationReference + 11292E3DE8EF40F9DCBCD526 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + A1B208310F6C031CA9568682 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SDWebImage-Private.xcconfig + sourceTree + <group> + + A212E3E719279B15D99358D7 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 0E44B521E203EC4F111815E4 + remoteInfo + Pods-SWTableViewCell + + A25EAE9D801AB760A4747E4B + + baseConfigurationReference + E8D5D18DAA535CA6B08AA393 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + A2B106C048B78A5C6FBAA445 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-SWTableViewCell-dummy.m + sourceTree + <group> + + A2EBB8311F6F713C23AA9103 + + fileRef + F19082954117D5EC4CBF111A + isa + PBXBuildFile + + A32AD2139187CB1F5F2B6247 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SWLongPressGestureRecognizer.h + path + SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h + sourceTree + <group> + + A3516881B3D6F981B73AC538 + + children + + FA9D9250626EDCE049F74048 + 13A1A364A5506D8A8B3CB81E + 70F7A8DB0E39B67802CA7A76 + 846C466F2240C4C93CD6C24C + AC6F1AA84590ACFF61BAAD60 + 48558FEAC015CC0EFC37FD0A + D9813C4AEDC5894EE1B3451F + C32A44B3BB593CF09E391F55 + BD9CA4ED0FDE48B5335FA601 + CA15D003C21CFCA2294BE5DB + 7398CA0C7FAD6B1A8E5B3A95 + AE42B8105AFFE0B288D61B38 + + isa + PBXGroup + name + SVWebViewController + path + SVWebViewController + sourceTree + <group> + + A361D7EB87257BFB39CD297F + + fileRef + 633433250CA4F0951A356573 + isa + PBXBuildFile + + A3A92429628C08F12D3FC1CD + + fileRef + E32EAF52CDE8541AAA86F6A0 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + A3E886CEC48C491886768370 + + fileRef + 968006EA8109A263FDFD3965 + isa + PBXBuildFile + + A566AAD0BC4F7B6641A8C759 + + fileRef + 10D51B68691D31108009BE93 + isa + PBXBuildFile + + A6D689B150BE62B7DB1AC767 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLJSONAdapter.h + path + Mantle/MTLJSONAdapter.h + sourceTree + <group> + + A6EA95925C726D0A8F6D6DA1 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + F5AD41E8F4E3CBFFE9D0A6AD + remoteInfo + Pods-FMDB + + A735B515C1DCF4D2370CAF9A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-SVWebViewController-prefix.pch + sourceTree + <group> + + A7755A9FB17EA678C37DCD95 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-MJRefresh-prefix.pch + sourceTree + <group> + + A8C971E5B6D1D6B34B5C9A1B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MTLReflection.m + path + Mantle/MTLReflection.m + sourceTree + <group> + + A95D82B9D1D2BEFE3D2DAB00 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-Mantle-dummy.m + sourceTree + <group> + + A9649B3D73F213DD8CAF3844 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-FMDB.xcconfig + sourceTree + <group> + + A98547DB16A7BA47C179FA8D + + children + + 292F5F1319A89AE506A962C2 + F0D0B8FA1F237AF39207A58C + 7EABDBD965900014161BECCC + 971BBE7FBC532FD0C3684E99 + F5FB40E1554F5686F97998FA + D2F8B867A02B15A8D833E6E7 + 15C57B0A0D754AA9967330DF + + isa + PBXGroup + name + iOS + sourceTree + <group> + + AA553D7A3D3565A545F3AD41 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-SDWebImage-prefix.pch + sourceTree + <group> + + AADD81544137DB9F341D6ED3 + + isa + PBXTargetDependency + name + Pods-SVProgressHUD + target + 6736EF81F571346B01E63AAB + targetProxy + 5CEA9DDB4661A6FC3DC94DC6 + + AADE27D38FBFB33465D0DA5F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSValueTransformer+MTLInversionAdditions.m + path + Mantle/NSValueTransformer+MTLInversionAdditions.m + sourceTree + <group> + + AB1DEC2C8FBB36DEECEF04E0 + + fileRef + FA9D9250626EDCE049F74048 + isa + PBXBuildFile + + ABDDECC9891EA588DA2A5FF8 + + fileRef + 856BC697A0DE727D2365B4B7 + isa + PBXBuildFile + + AC1C5B4CE91F11AE998D64F6 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSValueTransformer+MTLInversionAdditions.h + path + Mantle/NSValueTransformer+MTLInversionAdditions.h + sourceTree + <group> + + AC6F1AA84590ACFF61BAAD60 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVWebViewControllerActivity.h + path + SVWebViewController/UIActivities/SVWebViewControllerActivity.h + sourceTree + <group> + + AD4009A3CA3371D1F8C780E5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + path + Pods-FMDB-dummy.m + sourceTree + <group> + + AD4719C2919B562DF3C80502 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSValueTransformer+MTLPredefinedTransformerAdditions.m + path + Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.m + sourceTree + <group> + + AD73A79FDD2F245D4F40C14B + + isa + PBXTargetDependency + name + Pods-FMDB + target + F5AD41E8F4E3CBFFE9D0A6AD + targetProxy + A6EA95925C726D0A8F6D6DA1 + + ADC6D3BD671FB020D4E165E1 + + fileRef + D9813C4AEDC5894EE1B3451F + isa + PBXBuildFile + + AE42B8105AFFE0B288D61B38 + + children + + 5A89A95B50754A00C6F8883D + E8D5D18DAA535CA6B08AA393 + 90E53DFD34C1281914AAC149 + A735B515C1DCF4D2370CAF9A + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SVWebViewController + sourceTree + <group> + + AF131B236DD5AB2E742ADEF2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + Mantle.h + path + Mantle/Mantle.h + sourceTree + <group> + + AF263AC92D39C068F246DF63 + + baseConfigurationReference + E3C180F70C4829EC3E7C8741 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + B0F31E9D675CDD8EF475F4A7 + + fileRef + 43B8A0C73CAAAADDEBCE7C0C + isa + PBXBuildFile + + B2DFB8ABE3C361564605FC09 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SWTableViewCell.h + path + SWTableViewCell/PodFiles/SWTableViewCell.h + sourceTree + <group> + + B2FE89B302D990CFC2393FFB + + children + + 322D65FFB3319CBE9B35DD56 + 9EC42BD6CC05E3F9835DEB3C + + isa + PBXGroup + name + SDWebImage + path + SDWebImage + sourceTree + <group> + + B3654B8D5A85FC44A7A6B1FE + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-MJRefresh.xcconfig + sourceTree + <group> + + B37092B574E47123FA62F48A + + baseConfigurationReference + 585F33F75FFBDB5A2D635BC5 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + YES + DSTROOT + /tmp/xcodeproj.dst + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_CFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_CPLUSPLUSFLAGS + + -DNS_BLOCK_ASSERTIONS=1 + $(inherited) + + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + VALIDATE_PRODUCT + YES + + isa + XCBuildConfiguration + name + Release + + B3C85AC9AFD3294AE7C56106 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageDecoder.h + path + SDWebImage/SDWebImageDecoder.h + sourceTree + <group> + + B49FB948DC12B27713617596 + + children + + D9CF805123DCF31BD815B4BB + 290221507373808ABAA4054B + 2D3A6D4FA7D703DF6C8A7450 + 9449B700FD78B567CDCE349E + + isa + PBXGroup + name + NSURLSession + sourceTree + <group> + + B58F93C474B2E8430B05D256 + + fileRef + F3E77A78BED9A830D2670005 + isa + PBXBuildFile + + B5CE0321A8AEFC3F5FA0DF70 + + fileRef + 1890A9018AFB550869401948 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + B668271A16D47AF44F9BBCDA + + fileRef + 5453F743BF1ED5091106B499 + isa + PBXBuildFile + + B75F517882BF000A53EC59B3 + + buildActionMask + 2147483647 + files + + DDA12FA0A07A90423DAC2DAF + 6D3B22115589829E7FEAC2D2 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B7B2983751AA2DB871BE4F87 + + buildActionMask + 2147483647 + files + + 83C50DBF98466D8F993D6269 + 5DF09EA3510F7C19B9A4DA3C + FE4113033936F46AED1AC492 + E047647F1042A54423864302 + 245A7D5B09274802299A5413 + 0BD65AA041B8332119344140 + 7D4286C5720F98FA2A3F8A35 + D059787EBF44D5A0BC02F87F + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + B81737201F183B1D172A4B4D + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + B9011D79C925C7A071C4D24A + + baseConfigurationReference + 585F33F75FFBDB5A2D635BC5 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + B9F5BA86ACFC81B344D15D30 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-Mantle-Private.xcconfig + sourceTree + <group> + + BB46AB577CB11E2DEC496B53 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIAlertView+AFNetworking.h + path + UIKit+AFNetworking/UIAlertView+AFNetworking.h + sourceTree + <group> + + BB9E6E4F4B05385705EB97C0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIWebView+AFNetworking.m + path + UIKit+AFNetworking/UIWebView+AFNetworking.m + sourceTree + <group> + + BC949D87330F6EC5E34A3352 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImageView+WebCache.m + path + SDWebImage/UIImageView+WebCache.m + sourceTree + <group> + + BD7A57AABDA83E720552763E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFURLConnectionOperation.m + path + AFNetworking/AFURLConnectionOperation.m + sourceTree + <group> + + BD9CA4ED0FDE48B5335FA601 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVWebViewControllerActivitySafari.h + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h + sourceTree + <group> + + BDD171D88E04245FF41CFF78 + + buildActionMask + 2147483647 + files + + 640D32B00E7CA013FAA9F891 + 6C469821D18CEA22E80ACA5E + 720BC6CAA4ECD29F66CE897D + 015D98E4D31C2E29C4FB9DBA + D0A9652EBFFEC41C2F239263 + 9EDC843AF94153F5B29AD001 + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + BDD54D59F9F168C7CDC3C286 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIImage+MultiFormat.m + path + SDWebImage/UIImage+MultiFormat.m + sourceTree + <group> + + BE940E795DD463ACED5B538C + + fileRef + A110D8DB17AB6647C7795EBD + isa + PBXBuildFile + + BE9EDA04D687D70B682E1E0C + + fileRef + 0E0B9761485C54F60690139C + isa + PBXBuildFile + + BEC66FA7BE915660404F69F2 + + buildConfigurations + + 86F73289E11C480C16D33BCB + 662F6BC68D35264D3A2E14DF + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + BF9582E6D1D11AAE4C82790C + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSMutableArray+SWUtilityButtons.m + path + SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m + sourceTree + <group> + + BFA9BA48E845CDA5D016018D + + fileRef + F5FB40E1554F5686F97998FA + isa + PBXBuildFile + + BFCFD346B7D3A14BA3BA069B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSObject+MTLComparisonAdditions.h + path + Mantle/NSObject+MTLComparisonAdditions.h + sourceTree + <group> + + C0ECB4C8D31A24B2C3CF9E1F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-environment.h + sourceTree + <group> + + C1DE7C20F35B97860D706B66 + + fileRef + BF9582E6D1D11AAE4C82790C + isa + PBXBuildFile + + C2F2F561C27931B0CFA6A5AD + + fileRef + 34A0A9B27EF8487D6B85D039 + isa + PBXBuildFile + + C32A44B3BB593CF09E391F55 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVWebViewControllerActivityChrome.m + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m + sourceTree + <group> + + C3756A16C38B7B1455914F49 + + fileRef + 7F71FB5470A79B51285AB34E + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + C3A33DB3AF5947A220C22474 + + fileRef + E1AD240F7028E1A092DCBEDC + isa + PBXBuildFile + + C50CBBB3320CBFC5FA8EA34D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFNetworkActivityIndicatorManager.h + path + UIKit+AFNetworking/AFNetworkActivityIndicatorManager.h + sourceTree + <group> + + C55BDF5794C4C27E7A69A131 + + fileRef + 575254127992AC3095637C85 + isa + PBXBuildFile + + C56F74D0AAB1C57653DA7F7A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SWUtilityButtonTapGestureRecognizer.h + path + SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h + sourceTree + <group> + + C5B29E7C81D4C77334248AA5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefreshFooterView.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshFooterView.h + sourceTree + <group> + + C684423B9F0BCABE69332621 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMDatabasePool.h + path + src/fmdb/FMDatabasePool.h + sourceTree + <group> + + C7236453AB69F2D92E70EC3B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + path + Pods-AFNetworking-prefix.pch + sourceTree + <group> + + C834791111C32E19511470D4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLModel.h + path + Mantle/MTLModel.h + sourceTree + <group> + + C8409304ABBDB3DE6635DB18 + + explicitFileType + archive.ar + includeInIndex + 0 + isa + PBXFileReference + path + libPods-SVProgressHUD.a + sourceTree + BUILT_PRODUCTS_DIR + + C8519CEEEF547AA9EE9D9271 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + NSData+ImageContentType.m + path + SDWebImage/NSData+ImageContentType.m + sourceTree + <group> + + C885E60E6C8BD0A926570AF5 + + fileRef + 9E3CADF4D34242891C1E4725 + isa + PBXBuildFile + + C932222C6328C3C84A162E3B + + children + + 633433250CA4F0951A356573 + 6D0FE93D2F53E6F9BE778A43 + 514D95EC1DE6E7F84DFD7077 + 0BC85B368F05F28D8AC1E014 + E62260C013619653C0C58B3D + 379D3CCD2FFBB2698E6A788E + + isa + PBXGroup + name + extobjc + sourceTree + <group> + + CA15D003C21CFCA2294BE5DB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SVWebViewControllerActivitySafari.m + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m + sourceTree + <group> + + CAC00BB41401121BDC44E7E5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-Mantle.xcconfig + sourceTree + <group> + + CB6E38F58D69B7640B71B0D2 + + fileRef + 9FB2FE90C5104F065B94608B + isa + PBXBuildFile + + CC2EB1431A8BBB896B00A972 + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + CCD36D89B4623217A9BB4F11 + + containerPortal + 003A31C6AADD74836B88341F + isa + PBXContainerItemProxy + proxyType + 1 + remoteGlobalIDString + 0D2F41CC755DC941A9D3282F + remoteInfo + Pods-SVWebViewController + + CCD59E2FDDA491F626635409 + + fileRef + 25BC2970B45A7D905D5F19BB + isa + PBXBuildFile + + CE4B7722CAC9ED8DD0114663 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SWCellScrollView.h + path + SWTableViewCell/PodFiles/SWCellScrollView.h + sourceTree + <group> + + D003F4EA52D0953E6AF73AF6 + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + D059787EBF44D5A0BC02F87F + + fileRef + 635165301CE75B15CC16EE35 + isa + PBXBuildFile + + D09A62E8A6854C6E80B36152 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFURLRequestSerialization.m + path + AFNetworking/AFURLRequestSerialization.m + sourceTree + <group> + + D0A9652EBFFEC41C2F239263 + + fileRef + C56F74D0AAB1C57653DA7F7A + isa + PBXBuildFile + + D0C3135DA2BA3C019BAF2DCF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSValueTransformer+MTLPredefinedTransformerAdditions.h + path + Mantle/NSValueTransformer+MTLPredefinedTransformerAdditions.h + sourceTree + <group> + + D0C6BE4F0F08EEF1AD4759BF + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + MJRefreshHeaderView.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.m + sourceTree + <group> + + D139BE864E7331A490A31F83 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIProgressView+AFNetworking.m + path + UIKit+AFNetworking/UIProgressView+AFNetworking.m + sourceTree + <group> + + D2504912E25654781C939724 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivitySafari-iPad@2x.png + path + SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad@2x.png + sourceTree + <group> + + D2AE7F8D94E0B80BFA8F603A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWCellScrollView.m + path + SWTableViewCell/PodFiles/SWCellScrollView.m + sourceTree + <group> + + D2F8B867A02B15A8D833E6E7 + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + Security.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Security.framework + sourceTree + DEVELOPER_DIR + + D405E1711A624A1719E082D2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIView+MJExtension.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIView+MJExtension.m + sourceTree + <group> + + D568513A73D383D812B92361 + + fileRef + 57FA31C7342E4A8693201F60 + isa + PBXBuildFile + + D6558E03D7E8E7369D57D62A + + buildConfigurationList + FB388FD7B6E8D0EC4EFA5D58 + buildPhases + + 7E4DEC9F5579FF9E6012310D + 7E4322D8FA302168CB5CFFB2 + B7B2983751AA2DB871BE4F87 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-MJRefresh + productName + Pods-MJRefresh + productReference + 3CF9B45DDE34993A3FD50533 + productType + com.apple.product-type.library.static + + D6D6D28D37442BAAA468A18D + + fileRef + 8DCB4D41A489D80F71A9D029 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + D76DB4316F4A2BBC29B6E2E7 + + fileRef + 222F9FE85B6C3B610407F404 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + D79E955756AA01C364E52FE8 + + fileRef + 379D3CCD2FFBB2698E6A788E + isa + PBXBuildFile + + D88A7258E9903DD9091947B3 + + fileRef + 7E1CD1AAAE86E52A5E55A54C + isa + PBXBuildFile + + D8F1FDF888DD2382AECC30C3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWTableViewCell.m + path + SWTableViewCell/PodFiles/SWTableViewCell.m + sourceTree + <group> + + D9813C4AEDC5894EE1B3451F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVWebViewControllerActivityChrome.h + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h + sourceTree + <group> + + D9CF805123DCF31BD815B4BB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFHTTPSessionManager.h + path + AFNetworking/AFHTTPSessionManager.h + sourceTree + <group> + + DB34CB5D53D03543A81CD43D + + buildConfigurations + + B9011D79C925C7A071C4D24A + B37092B574E47123FA62F48A + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + DB5A704B96D04FBF9549DA3B + + fileRef + 2D3A6D4FA7D703DF6C8A7450 + isa + PBXBuildFile + + DC332F6A26805C987939E79B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + FMDatabaseQueue.h + path + src/fmdb/FMDatabaseQueue.h + sourceTree + <group> + + DC50FB9ACAC3D68AE360BF5F + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + UIScrollView+MJExtension.m + path + MJRefreshExample/MJRefreshExample/MJRefresh/UIScrollView+MJExtension.m + sourceTree + <group> + + DC6959F6B0389433A846F09B + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MJRefreshHeaderView.h + path + MJRefreshExample/MJRefreshExample/MJRefresh/MJRefreshHeaderView.h + sourceTree + <group> + + DCFD647287A6F3DEE53059EB + + isa + PBXTargetDependency + name + Pods-Mantle + target + EA053313AC9B201518E824AF + targetProxy + 2C5859609EFA12DBF8041624 + + DD72EA41B8BD0DC998006611 + + children + + A98547DB16A7BA47C179FA8D + + isa + PBXGroup + name + Frameworks + sourceTree + <group> + + DD8F1007201AC5D9E168DE32 + + fileRef + AC6F1AA84590ACFF61BAAD60 + isa + PBXBuildFile + + DDA12FA0A07A90423DAC2DAF + + fileRef + F0D0B8FA1F237AF39207A58C + isa + PBXBuildFile + + DDCF5122548DF51242583A68 + + fileRef + D2F8B867A02B15A8D833E6E7 + isa + PBXBuildFile + + DE2CEF2D7F7D4D643900FCE5 + + fileRef + 846C466F2240C4C93CD6C24C + isa + PBXBuildFile + + DF3027E5A4AB1DC95FB5EA9D + + fileRef + B3C85AC9AFD3294AE7C56106 + isa + PBXBuildFile + + DFFAC01197AE918D4C9DFD66 + + fileRef + A95D82B9D1D2BEFE3D2DAB00 + isa + PBXBuildFile + + E047647F1042A54423864302 + + fileRef + C5B29E7C81D4C77334248AA5 + isa + PBXBuildFile + + E0E9DDEE088E41C8CF4C003D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods.release.xcconfig + sourceTree + <group> + + E0F50EA1905F2A7094812973 + + buildConfigurationList + DB34CB5D53D03543A81CD43D + buildPhases + + 273E8CC1B7A1DF52553B76D7 + 26D05A8A28DCD60C1CA8EC7E + 59C305ABE1A25B9CB62E5D80 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-AFNetworking + productName + Pods-AFNetworking + productReference + 47C11AD21FEAD8A5CAA86FC0 + productType + com.apple.product-type.library.static + + E11A8E6E65928AF83EDA8DEF + + children + + 404F813C33EA2B5B22382ED6 + 585F33F75FFBDB5A2D635BC5 + 16BE2A454A10A0FFBBFDD201 + C7236453AB69F2D92E70EC3B + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-AFNetworking + sourceTree + <group> + + E1AD240F7028E1A092DCBEDC + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + AFSecurityPolicy.h + path + AFNetworking/AFSecurityPolicy.h + sourceTree + <group> + + E29DFA8F7F2E89354CECB6C3 + + includeInIndex + 1 + isa + PBXFileReference + name + SVWebViewControllerActivityChrome-iPad@2x.png + path + SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png + sourceTree + <group> + + E2D8E0AC81FFF45B5643EB4C + + buildActionMask + 2147483647 + files + + A0EB66A861D7F9BE99167595 + F8219A50BB91E25BFDDAA0AD + 37B990D486EB877EA36E8C25 + F6E91A553C49F4862B78C4F1 + D76DB4316F4A2BBC29B6E2E7 + 613007691409B9A6751D3737 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + E32EAF52CDE8541AAA86F6A0 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImageCompat.m + path + SDWebImage/SDWebImageCompat.m + sourceTree + <group> + + E3C180F70C4829EC3E7C8741 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-FMDB-Private.xcconfig + sourceTree + <group> + + E45958CE3CBD11F1707F441C + + fileRef + BFCFD346B7D3A14BA3BA069B + isa + PBXBuildFile + + E4F17FDA9A2004644DE362D1 + + fileRef + DC332F6A26805C987939E79B + isa + PBXBuildFile + + E62260C013619653C0C58B3D + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + EXTScope.m + path + Mantle/extobjc/EXTScope.m + sourceTree + <group> + + E6D38302A5F37DB5658C41BB + + buildActionMask + 2147483647 + files + + 21E3949570212F296A98F3C3 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + E7926F44F6DD7675C4CAB292 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + MTLValueTransformer.h + path + Mantle/MTLValueTransformer.h + sourceTree + <group> + + E8D5D18DAA535CA6B08AA393 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SVWebViewController-Private.xcconfig + sourceTree + <group> + + E96F46F8A984911D7538CA63 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImageView+WebCache.h + path + SDWebImage/UIImageView+WebCache.h + sourceTree + <group> + + E9A68AA93E6B24526C1517E5 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageOperation.h + path + SDWebImage/SDWebImageOperation.h + sourceTree + <group> + + EA053313AC9B201518E824AF + + buildConfigurationList + 31ED12F5CEA9A23F5663038A + buildPhases + + 73866FD56D89AA5A3F622874 + 06B18C667B34A3836288B3E6 + 9F745963084D8E9E216392E2 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-Mantle + productName + Pods-Mantle + productReference + 0DDB7686E187F3FC19D520AC + productType + com.apple.product-type.library.static + + EA063A5FA969AA2475F21918 + + children + + 94D197FD4192DB667B6E9A51 + 34A0A9B27EF8487D6B85D039 + + isa + PBXGroup + name + Reachability + sourceTree + <group> + + EA98CE819CDC3A1C462DA862 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SDWebImage.xcconfig + sourceTree + <group> + + EAABEB6BACA94FCEFBA11DFD + + fileRef + A8C971E5B6D1D6B34B5C9A1B + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + EB111D63CDEEB43E08195847 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + wrapper.plug-in + name + SVProgressHUD.bundle + path + SVProgressHUD/SVProgressHUD.bundle + sourceTree + <group> + + EB394718051F19102CEA333B + + fileRef + BB46AB577CB11E2DEC496B53 + isa + PBXBuildFile + + EBB725B945B1732ECF3A9006 + + buildActionMask + 2147483647 + files + + C55BDF5794C4C27E7A69A131 + 7F117C1078DB1AD4F3B4FE11 + A2EBB8311F6F713C23AA9103 + DF3027E5A4AB1DC95FB5EA9D + 9F4821AF45F02268E44D0C1D + 9EFF5CE823942564335B0542 + 92D1A0BBD0D2B1EA721B084C + 65D19C9FCE68CD267930EF33 + 662A98C63D4A25AEDD5B5EC8 + 379C4A4E6343D5622A38206E + B0F31E9D675CDD8EF475F4A7 + 4639EC1DFC9BDEE03FCECD28 + 2E82A19ADA9D6FA582DFA1B8 + 6C883654D7A0A3023FD1840D + 5C59B57AC630CD73AB5E2D1E + + isa + PBXHeadersBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + ECDFCA3A35CD6A95747B8E90 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods.debug.xcconfig + sourceTree + <group> + + ECFFA56C6B3F8AC988E09B43 + + fileRef + A19B2B715041A76AD22B7BB7 + isa + PBXBuildFile + + EDA79BFF36ED8CC66472C4B4 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + AFURLResponseSerialization.m + path + AFNetworking/AFURLResponseSerialization.m + sourceTree + <group> + + EDCDF1F1A409A8EF63058261 + + fileRef + FD93687F5220E28F92C0D41E + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + EF04ADF8DBB1227D34EBBEEA + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text + name + Podfile + path + ../Podfile + sourceTree + SOURCE_ROOT + xcLanguageSpecificationIdentifier + xcode.lang.ruby + + EF1605A5BAD020789C0D6DCD + + buildConfigurations + + 24200E9BAE5616D614E3BA14 + 3886D77C2964260BA24AC311 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + F02AEA09DBE0E12AF360F35D + + fileRef + 94D197FD4192DB667B6E9A51 + isa + PBXBuildFile + + F0D0B8FA1F237AF39207A58C + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + Foundation.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/Foundation.framework + sourceTree + DEVELOPER_DIR + + F0DD19AA7C01867C1769DBE1 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + NSArray+MTLManipulationAdditions.h + path + Mantle/NSArray+MTLManipulationAdditions.h + sourceTree + <group> + + F19082954117D5EC4CBF111A + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SDWebImageCompat.h + path + SDWebImage/SDWebImageCompat.h + sourceTree + <group> + + F20B4E0EAAA530D24685A4E2 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.xcconfig + path + Pods-SVProgressHUD-Private.xcconfig + sourceTree + <group> + + F38473E10FE10739CC22000B + + fileRef + 8E7746C93B5A382A8BFB31C8 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + F3B157F0A7C5AE48DEF99006 + + fileRef + 290221507373808ABAA4054B + isa + PBXBuildFile + + F3B7C44428DC09B4933F043E + + buildActionMask + 2147483647 + files + + 531197FDF80BC84527CCAF02 + + isa + PBXFrameworksBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + F3E77A78BED9A830D2670005 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWUtilityButtonView.m + path + SWTableViewCell/PodFiles/SWUtilityButtonView.m + sourceTree + <group> + + F44EDFC44AEF1BC95DB7FA7D + + fileRef + 15C57B0A0D754AA9967330DF + isa + PBXBuildFile + + F49B17CD5DB7BF511AD95FE0 + + fileRef + FC45931EABC40836F3C02FDB + isa + PBXBuildFile + + F5336FA18F2792224B01F5AD + + fileRef + 971BBE7FBC532FD0C3684E99 + isa + PBXBuildFile + + F5AD41E8F4E3CBFFE9D0A6AD + + buildConfigurationList + 82D7942CFFB4B5F9A8039B0E + buildPhases + + E2D8E0AC81FFF45B5643EB4C + 0E941574580314BABC46EF00 + 59DD36BD9A4D804D5A701ED2 + + buildRules + + dependencies + + isa + PBXNativeTarget + name + Pods-FMDB + productName + Pods-FMDB + productReference + 0398B69338481EC817F6F6EB + productType + com.apple.product-type.library.static + + F5FB40E1554F5686F97998FA + + isa + PBXFileReference + lastKnownFileType + wrapper.framework + name + QuartzCore.framework + path + Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS7.1.sdk/System/Library/Frameworks/QuartzCore.framework + sourceTree + DEVELOPER_DIR + + F6CDC7E60CF17930F7262034 + + baseConfigurationReference + F20B4E0EAAA530D24685A4E2 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + F6E91A553C49F4862B78C4F1 + + fileRef + FFF0E1F586F1C9698F168012 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + F7446765000306425A8653CB + + children + + 9AC054684C72878BFD1354BD + 54AF66B17C0AEFF7AE1E5828 + B49FB948DC12B27713617596 + EA063A5FA969AA2475F21918 + 060110539E4022EC7547DC8A + 76F2FB474F9C57ED0AB606BB + E11A8E6E65928AF83EDA8DEF + 071305CB59F3D8E013288619 + + isa + PBXGroup + name + AFNetworking + path + AFNetworking + sourceTree + <group> + + F78D23F252315D98B9BE3FA6 + + fileRef + 7A75EF39F7B6094E98E9D58F + isa + PBXBuildFile + + F8219A50BB91E25BFDDAA0AD + + fileRef + 96B82497505EF98401B50E1D + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + F85DB5D3718ADE63303C06E7 + + children + + 74ED67273EBDF1D93351D598 + F20B4E0EAAA530D24685A4E2 + 3FE2CB4E3BF724BF9DADD804 + 5161C757881F6F6873559967 + + isa + PBXGroup + name + Support Files + path + ../Target Support Files/Pods-SVProgressHUD + sourceTree + <group> + + FA2858642D021A2940D97851 + + fileRef + 63B65631DCD63B55E53DCE03 + isa + PBXBuildFile + + FA9D9250626EDCE049F74048 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + SVModalWebViewController.h + path + SVWebViewController/SVModalWebViewController.h + sourceTree + <group> + + FAFFA27183B7E1544DC2D54D + + buildActionMask + 2147483647 + files + + 3396072C759A0E898549D6E7 + 97959B6C405A6219826BAFBE + DE2CEF2D7F7D4D643900FCE5 + 96E033AF44F3F21FB871FC01 + 730266F29F62BC3EB931952F + 9C079AF4CCEEC69481F2BF10 + + isa + PBXSourcesBuildPhase + runOnlyForDeploymentPostprocessing + 0 + + FB388FD7B6E8D0EC4EFA5D58 + + buildConfigurations + + 47BC372C33FCDDB0603FF870 + A19CDB887CB102ECC06C0723 + + defaultConfigurationIsVisible + 0 + defaultConfigurationName + Release + isa + XCConfigurationList + + FB392C3A7B8813F8724C2732 + + fileRef + 6D6492CFDFC03E3EEED90937 + isa + PBXBuildFile + + FB6C8948A46CF245ECD20949 + + fileRef + 573C8CC99C8641490B222C89 + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + FC45931EABC40836F3C02FDB + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SWLongPressGestureRecognizer.m + path + SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.m + sourceTree + <group> + + FC51B49E4686DFD82E09DE0B + + baseConfigurationReference + E3C180F70C4829EC3E7C8741 + buildSettings + + ALWAYS_SEARCH_USER_PATHS + NO + COPY_PHASE_STRIP + NO + DSTROOT + /tmp/xcodeproj.dst + GCC_DYNAMIC_NO_PIC + NO + GCC_OPTIMIZATION_LEVEL + 0 + GCC_PRECOMPILE_PREFIX_HEADER + YES + GCC_PREFIX_HEADER + Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch + GCC_PREPROCESSOR_DEFINITIONS + + DEBUG=1 + $(inherited) + + GCC_SYMBOLS_PRIVATE_EXTERN + NO + INSTALL_PATH + $(BUILT_PRODUCTS_DIR) + IPHONEOS_DEPLOYMENT_TARGET + 7.0 + OTHER_LDFLAGS + + OTHER_LIBTOOLFLAGS + + PRODUCT_NAME + $(TARGET_NAME) + PUBLIC_HEADERS_FOLDER_PATH + $(TARGET_NAME) + SDKROOT + iphoneos + SKIP_INSTALL + YES + + isa + XCBuildConfiguration + name + Debug + + FC5FC75F692847F3591B34B3 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + text.script.sh + path + Pods-resources.sh + sourceTree + <group> + + FC77BBB341E0605E8ED130FB + + fileRef + A6D689B150BE62B7DB1AC767 + isa + PBXBuildFile + + FD317A4CDFFEF6932C841E62 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.h + name + UIImage+MultiFormat.h + path + SDWebImage/UIImage+MultiFormat.h + sourceTree + <group> + + FD93687F5220E28F92C0D41E + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + SDWebImageManager.m + path + SDWebImage/SDWebImageManager.m + sourceTree + <group> + + FDAFE1F6255ECC888D7503AB + + fileRef + AADE27D38FBFB33465D0DA5F + isa + PBXBuildFile + settings + + COMPILER_FLAGS + -DOS_OBJECT_USE_OBJC=0 + + + FE4113033936F46AED1AC492 + + fileRef + 217FA4FB15D4EDE83A84233D + isa + PBXBuildFile + + FED8EC57D00423F3832AA2A9 + + fileRef + AF131B236DD5AB2E742ADEF2 + isa + PBXBuildFile + + FFF0E1F586F1C9698F168012 + + includeInIndex + 1 + isa + PBXFileReference + lastKnownFileType + sourcecode.c.objc + name + FMDatabaseQueue.m + path + src/fmdb/FMDatabaseQueue.m + sourceTree + <group> + + + rootObject + 003A31C6AADD74836B88341F + + diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/LICENSE b/iOSStudy/iOSStudy/Pods/SDWebImage/LICENSE new file mode 100644 index 0000000..ae783e1 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/LICENSE @@ -0,0 +1,20 @@ +Copyright (c) 2009 Olivier Poitrey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/README.md b/iOSStudy/iOSStudy/Pods/SDWebImage/README.md new file mode 100644 index 0000000..9bbcca5 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/README.md @@ -0,0 +1,280 @@ +Web Image +========= +[![Build Status](http://img.shields.io/travis/rs/SDWebImage/master.svg?style=flat)](https://travis-ci.org/rs/SDWebImage) +[![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) +[![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/) +[![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html) + +This library provides a category for UIImageView with support for remote images coming from the web. + +It provides: + +- An UIImageView category adding web image and cache management to the Cocoa Touch framework +- An asynchronous image downloader +- An asynchronous memory + disk image caching with automatic cache expiration handling +- Animated GIF support +- WebP format support +- A background image decompression +- A guarantee that the same URL won't be downloaded several times +- A guarantee that bogus URLs won't be retried again and again +- A guarantee that main thread will never be blocked +- Performances! +- Use GCD and ARC +- Arm64 support + +NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 2.0 and requires iOS 5.1.1 +minimum deployement version. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat). + +[How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F) + +Who Use It +---------- + +Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list. + +How To Use +---------- + +API documentation is available at [http://hackemist.com/SDWebImage/doc/](http://hackemist.com/SDWebImage/doc/) + +### Using UIImageView+WebCache category with UITableView + +Just #import the UIImageView+WebCache.h header, and call the setImageWithURL:placeholderImage: +method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be +handled for you, from async downloads to caching management. + +```objective-c +#import + +... + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *MyIdentifier = @"MyIdentifier"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; + + if (cell == nil) + { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault + reuseIdentifier:MyIdentifier] autorelease]; + } + + // Here we use the new provided setImageWithURL: method to load the web image + [cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"]]; + + cell.textLabel.text = @"My Text"; + return cell; +} +``` + +### Using blocks + +With blocks, you can be notified about the image download progress and whenever the image retrival +has completed with success or not: + +```objective-c +// Here we use the new provided setImageWithURL: method to load the web image +[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder.png"] + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType) {... completion code here ...}]; +``` + +Note: neither your success nor failure block will be call if your image request is canceled before completion. + +### Using SDWebImageManager + +The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the +asynchronous downloader with the image cache store. You can use this class directly to benefit +from web image downloading with caching in another context than a UIView (ie: with Cocoa). + +Here is a simple example of how to use SDWebImageManager: + +```objective-c +SDWebImageManager *manager = [SDWebImageManager sharedManager]; +[manager downloadWithURL:imageURL + options:0 + progress:^(NSInteger receivedSize, NSInteger expectedSize) + { + // progression tracking code + } + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) + { + if (image) + { + // do something with image + } + }]; +``` + +### Using Asynchronous Image Downloader Independently + +It's also possible to use the async image downloader independently: + +```objective-c +[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL + options:0 + progress:^(NSInteger receivedSize, NSInteger expectedSize) + { + // progression tracking code + } + completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) + { + if (image && finished) + { + // do something with image + } + }]; +``` + +### Using Asynchronous Image Caching Independently + +It is also possible to use the aync based image cache store independently. SDImageCache +maintains a memory cache and an optional disk cache. Disk cache write operations are performed +asynchronous so it doesn't add unnecessary latency to the UI. + +The SDImageCache class provides a singleton instance for convenience but you can create your own +instance if you want to create separated cache namespace. + +To lookup the cache, you use the `queryDiskCacheForKey:done:` method. If the method returns nil, it means the cache +doesn't currently own the image. You are thus responsible for generating and caching it. The cache +key is an application unique identifier for the image to cache. It is generally the absolute URL of +the image. + +```objective-c +SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"]; +[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) +{ + // image is not nil if image was found +}]; +``` + +By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache. +You can prevent this from happening by calling the alternative method `imageFromMemoryCacheForKey:`. + +To store an image into the cache, you use the storeImage:forKey: method: + +```objective-c +[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey]; +``` + +By default, the image will be stored in memory cache as well as on disk cache (asynchronously). If +you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative +third argument. + +### Using cache key filter + +Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic +(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter that +takes the NSURL as input, and output a cache key NSString. + +The following example sets a filter in the application delegate that will remove any query-string from +the URL before to use it as a cache key: + +```objective-c +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions +{ + SDWebImageManager.sharedManager.cacheKeyFilter:^(NSURL *url) + { + url = [[[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path] autorelease]; + return [url absoluteString]; + }; + + // Your app init code... + return YES; +} +``` + + +Common Problems +--------------- + +### Using dynamic image size with UITableViewCell + +UITableView determins the size of the image by the first image set for a cell. If your remote images +don't have the same size as your placeholder image, you may experience strange anamorphic scaling issue. +The following article gives a way to workaround this issue: + +[http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/](http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/) + + +### Handle image refresh + +SDWebImage does very aggressive caching by default. It ignores all kind of caching control header returned by the HTTP server and cache the returned images with no time restriction. It implies your images URLs are static URLs pointing to images that never change. If the pointed image happen to change, some parts of the URL should change accordingly. + +If you don't control the image server you're using, you may not be able to change the URL when its content is updated. This is the case for Facebook avatar URLs for instance. In such case, you may use the `SDWebImageRefreshCached` flag. This will slightly degrade the performance but will respect the HTTP caching control headers: + +``` objective-c +[imageView setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"] + placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"] + options:SDWebImageRefreshCached]; +``` + +### Add a progress indicator + +See this category: https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage + +Installation +------------ + +There are three ways to use SDWebImage in your project: +- using Cocoapods +- copying all the files into your project +- importing the project as a static library + +### Installation with CocoaPods + +[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the [Get Started](http://cocoapods.org/#get_started) section for more details. + +#### Podfile +``` +platform :ios, '6.1' +pod 'SDWebImage', '~>3.6' +``` + +### Add the SDWebImage project to your project + +- Download and unzip the last version of the framework from the [download page](https://github.com/rs/SDWebImage/releases) +- Right-click on the project navigator and select "Add Files to "Your Project": +- In the dialog, select SDWebImage.framework: +- Check the "Copy items into destination group's folder (if needed)" checkbox + +### Add dependencies + +- In you application project app’s target settings, find the "Build Phases" section and open the "Link Binary With Libraries" block: +- Click the "+" button again and select the "ImageIO.framework", this is needed by the progressive download feature: + +### Add Linker Flag + +Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag: + +![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg) + +Alternatively, if this causes compilation problems with frameworks that extend optional libraries, such as Parse, RestKit or opencv2, instead of the -ObjC flag use: + +``` +-force_load SDWebImage.framework/Versions/Current/SDWebImage +``` + +### Import headers in your source files + +In the source files where you need to use the library, import the header file: + +```objective-c +#import +``` + +### Build Project + +At this point your workspace should build without error. If you are having problem, post to the Issue and the +community can help you solve it. + +Future Enhancements +------------------- + +- LRU memory cache cleanup instead of reset on memory warning + +## Licenses + +All source code is licensed under the [MIT License](https://raw.github.com/rs/SDWebImage/master/LICENSE). diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.h new file mode 100644 index 0000000..69c76dc --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.h @@ -0,0 +1,26 @@ +// +// Created by Fabrice Aneche on 06/01/14. +// Copyright (c) 2014 Dailymotion. All rights reserved. +// + +#import + +@interface NSData (ImageContentType) + +/** + * Compute the content type for an image data + * + * @param data the input data + * + * @return the content type as string (i.e. image/jpeg, image/gif) + */ ++ (NSString *)sd_contentTypeForImageData:(NSData *)data; + +@end + + +@interface NSData (ImageContentTypeDeprecated) + ++ (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`"); + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.m new file mode 100644 index 0000000..0941cfa --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/NSData+ImageContentType.m @@ -0,0 +1,49 @@ +// +// Created by Fabrice Aneche on 06/01/14. +// Copyright (c) 2014 Dailymotion. All rights reserved. +// + +#import "NSData+ImageContentType.h" + + +@implementation NSData (ImageContentType) + ++ (NSString *)sd_contentTypeForImageData:(NSData *)data { + uint8_t c; + [data getBytes:&c length:1]; + switch (c) { + case 0xFF: + return @"image/jpeg"; + case 0x89: + return @"image/png"; + case 0x47: + return @"image/gif"; + case 0x49: + case 0x4D: + return @"image/tiff"; + case 0x52: + // R as RIFF for WEBP + if ([data length] < 12) { + return nil; + } + + NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding]; + if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) { + return @"image/webp"; + } + + return nil; + } + return nil; +} + +@end + + +@implementation NSData (ImageContentTypeDeprecated) + ++ (NSString *)contentTypeForImageData:(NSData *)data { + return [self sd_contentTypeForImageData:data]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h new file mode 100644 index 0000000..bde9d5d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.h @@ -0,0 +1,241 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +typedef NS_ENUM(NSInteger, SDImageCacheType) { + /** + * The image wasn't available the SDWebImage caches, but was downloaded from the web. + */ + SDImageCacheTypeNone, + /** + * The image was obtained from the disk cache. + */ + SDImageCacheTypeDisk, + /** + * The image was obtained from the memory cache. + */ + SDImageCacheTypeMemory +}; + +typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType); + +typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache); + +typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize); + +/** + * SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed + * asynchronous so it doesn’t add unnecessary latency to the UI. + */ +@interface SDImageCache : NSObject + +/** + * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory. + */ +@property (assign, nonatomic) NSUInteger maxMemoryCost; + +/** + * The maximum length of time to keep an image in the cache, in seconds + */ +@property (assign, nonatomic) NSInteger maxCacheAge; + +/** + * The maximum size of the cache, in bytes. + */ +@property (assign, nonatomic) NSUInteger maxCacheSize; + +/** + * Returns global shared cache instance + * + * @return SDImageCache global instance + */ ++ (SDImageCache *)sharedImageCache; + +/** + * Init a new cache store with a specific namespace + * + * @param ns The namespace to use for this cache store + */ +- (id)initWithNamespace:(NSString *)ns; + +/** + * Add a read-only cache path to search for images pre-cached by SDImageCache + * Useful if you want to bundle pre-loaded images with your app + * + * @param path The path to use for this read-only cache path + */ +- (void)addReadOnlyCachePath:(NSString *)path; + +/** + * Store an image into memory and disk cache at the given key. + * + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL + */ +- (void)storeImage:(UIImage *)image forKey:(NSString *)key; + +/** + * Store an image into memory and optionally disk cache at the given key. + * + * @param image The image to store + * @param key The unique image cache key, usually it's image absolute URL + * @param toDisk Store the image to disk cache if YES + */ +- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk; + +/** + * Store an image into memory and optionally disk cache at the given key. + * + * @param image The image to store + * @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage + * @param imageData The image data as returned by the server, this representation will be used for disk storage + * instead of converting the given image object into a storable/compressed image format in order + * to save quality and CPU + * @param key The unique image cache key, usually it's image absolute URL + * @param toDisk Store the image to disk cache if YES + */ +- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk; + +/** + * Query the disk cache asynchronously. + * + * @param key The unique key used to store the wanted image + */ +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock; + +/** + * Query the memory cache synchronously. + * + * @param key The unique key used to store the wanted image + */ +- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key; + +/** + * Query the disk cache synchronously after checking the memory cache. + * + * @param key The unique key used to store the wanted image + */ +- (UIImage *)imageFromDiskCacheForKey:(NSString *)key; + +/** + * Remove the image from memory and disk cache synchronously + * + * @param key The unique image cache key + */ +- (void)removeImageForKey:(NSString *)key; + + +/** + * Remove the image from memory and disk cache synchronously + * + * @param key The unique image cache key + * @param completionBlock An block that should be executed after the image has been removed (optional) + */ +- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion; + +/** + * Remove the image from memory and optionally disk cache synchronously + * + * @param key The unique image cache key + * @param fromDisk Also remove cache entry from disk if YES + */ +- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk; + +/** + * Remove the image from memory and optionally disk cache synchronously + * + * @param key The unique image cache key + * @param fromDisk Also remove cache entry from disk if YES + * @param completionBlock An block that should be executed after the image has been removed (optional) + */ +- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion; + +/** + * Clear all memory cached images + */ +- (void)clearMemory; + +/** + * Clear all disk cached images. Non-blocking method - returns immediately. + * @param completionBlock An block that should be executed after cache expiration completes (optional) + */ +- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion; + +/** + * Clear all disk cached images + * @see clearDiskOnCompletion: + */ +- (void)clearDisk; + +/** + * Remove all expired cached image from disk. Non-blocking method - returns immediately. + * @param completionBlock An block that should be executed after cache expiration completes (optional) + */ +- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock; + +/** + * Remove all expired cached image from disk + * @see cleanDiskWithCompletionBlock: + */ +- (void)cleanDisk; + +/** + * Get the size used by the disk cache + */ +- (NSUInteger)getSize; + +/** + * Get the number of images in the disk cache + */ +- (NSUInteger)getDiskCount; + +/** + * Asynchronously calculate the disk cache's size. + */ +- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock; + +/** + * Async check if image exists in disk cache already (does not load the image) + * + * @param key the key describing the url + * @param completionBlock the block to be executed when the check is done. + * @note the completion block will be always executed on the main queue + */ +- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; + +/** + * Check if image exists in disk cache already (does not load the image) + * + * @param key the key describing the url + * + * @return YES if an image exists for the given key + */ +- (BOOL)diskImageExistsWithKey:(NSString *)key; + +/** + * Get the cache path for a certain key (needs the cache path root folder) + * + * @param key the key (can be obtained from url using cacheKeyForURL) + * @param path the cach path root folder + * + * @return the cache path + */ +- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path; + +/** + * Get the default cache path for a certain key + * + * @param key the key (can be obtained from url using cacheKeyForURL) + * + * @return the default cache path + */ +- (NSString *)defaultCachePathForKey:(NSString *)key; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m new file mode 100644 index 0000000..59c3471 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDImageCache.m @@ -0,0 +1,534 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDImageCache.h" +#import "SDWebImageDecoder.h" +#import "UIImage+MultiFormat.h" +#import + +static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week +// PNG signature bytes and data (below) +static unsigned char kPNGSignatureBytes[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A}; +static NSData *kPNGSignatureData = nil; + +BOOL ImageDataHasPNGPreffix(NSData *data); + +BOOL ImageDataHasPNGPreffix(NSData *data) { + NSUInteger pngSignatureLength = [kPNGSignatureData length]; + if ([data length] >= pngSignatureLength) { + if ([[data subdataWithRange:NSMakeRange(0, pngSignatureLength)] isEqualToData:kPNGSignatureData]) { + return YES; + } + } + + return NO; +} + +@interface SDImageCache () + +@property (strong, nonatomic) NSCache *memCache; +@property (strong, nonatomic) NSString *diskCachePath; +@property (strong, nonatomic) NSMutableArray *customPaths; +@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue; + +@end + + +@implementation SDImageCache { + NSFileManager *_fileManager; +} + ++ (SDImageCache *)sharedImageCache { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + kPNGSignatureData = [NSData dataWithBytes:kPNGSignatureBytes length:8]; + }); + return instance; +} + +- (id)init { + return [self initWithNamespace:@"default"]; +} + +- (id)initWithNamespace:(NSString *)ns { + if ((self = [super init])) { + NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns]; + + // Create IO serial queue + _ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL); + + // Init default values + _maxCacheAge = kDefaultCacheMaxCacheAge; + + // Init the memory cache + _memCache = [[NSCache alloc] init]; + _memCache.name = fullNamespace; + + // Init the disk cache + NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES); + _diskCachePath = [paths[0] stringByAppendingPathComponent:fullNamespace]; + + dispatch_sync(_ioQueue, ^{ + _fileManager = [NSFileManager new]; + }); + +#if TARGET_OS_IPHONE + // Subscribe to app events + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(clearMemory) + name:UIApplicationDidReceiveMemoryWarningNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(cleanDisk) + name:UIApplicationWillTerminateNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(backgroundCleanDisk) + name:UIApplicationDidEnterBackgroundNotification + object:nil]; +#endif + } + + return self; +} + +- (void)dealloc { + [[NSNotificationCenter defaultCenter] removeObserver:self]; + SDDispatchQueueRelease(_ioQueue); +} + +- (void)addReadOnlyCachePath:(NSString *)path { + if (!self.customPaths) { + self.customPaths = [NSMutableArray new]; + } + + if (![self.customPaths containsObject:path]) { + [self.customPaths addObject:path]; + } +} + +- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path { + NSString *filename = [self cachedFileNameForKey:key]; + return [path stringByAppendingPathComponent:filename]; +} + +- (NSString *)defaultCachePathForKey:(NSString *)key { + return [self cachePathForKey:key inPath:self.diskCachePath]; +} + +#pragma mark SDImageCache (private) + +- (NSString *)cachedFileNameForKey:(NSString *)key { + const char *str = [key UTF8String]; + if (str == NULL) { + str = ""; + } + unsigned char r[CC_MD5_DIGEST_LENGTH]; + CC_MD5(str, (CC_LONG)strlen(str), r); + NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", + r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; + + return filename; +} + +#pragma mark ImageCache + +- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk { + if (!image || !key) { + return; + } + + [self.memCache setObject:image forKey:key cost:image.size.height * image.size.width * image.scale]; + + if (toDisk) { + dispatch_async(self.ioQueue, ^{ + NSData *data = imageData; + + if (image && (recalculate || !data)) { +#if TARGET_OS_IPHONE + // We need to determine if the image is a PNG or a JPEG + // PNGs are easier to detect because they have a unique signature (http://www.w3.org/TR/PNG-Structure.html) + // The first eight bytes of a PNG file always contain the following (decimal) values: + // 137 80 78 71 13 10 26 10 + + // We assume the image is PNG, in case the imageData is nil (i.e. if trying to save a UIImage directly), + // we will consider it PNG to avoid loosing the transparency + BOOL imageIsPng = YES; + + // But if we have an image data, we will look at the preffix + if ([imageData length] >= [kPNGSignatureData length]) { + imageIsPng = ImageDataHasPNGPreffix(imageData); + } + + if (imageIsPng) { + data = UIImagePNGRepresentation(image); + } + else { + data = UIImageJPEGRepresentation(image, (CGFloat)1.0); + } +#else + data = [NSBitmapImageRep representationOfImageRepsInArray:image.representations usingType: NSJPEGFileType properties:nil]; +#endif + } + + if (data) { + if (![_fileManager fileExistsAtPath:_diskCachePath]) { + [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; + } + + [_fileManager createFileAtPath:[self defaultCachePathForKey:key] contents:data attributes:nil]; + } + }); + } +} + +- (void)storeImage:(UIImage *)image forKey:(NSString *)key { + [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:YES]; +} + +- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk { + [self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk]; +} + +- (BOOL)diskImageExistsWithKey:(NSString *)key { + BOOL exists = NO; + + // this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance + // from apple docs on NSFileManager: The methods of the shared NSFileManager object can be called from multiple threads safely. + exists = [[NSFileManager defaultManager] fileExistsAtPath:[self defaultCachePathForKey:key]]; + + return exists; +} + +- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { + dispatch_async(_ioQueue, ^{ + BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]]; + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(exists); + }); + } + }); +} + +- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key { + return [self.memCache objectForKey:key]; +} + +- (UIImage *)imageFromDiskCacheForKey:(NSString *)key { + // First check the in-memory cache... + UIImage *image = [self imageFromMemoryCacheForKey:key]; + if (image) { + return image; + } + + // Second check the disk cache... + UIImage *diskImage = [self diskImageForKey:key]; + if (diskImage) { + CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale; + [self.memCache setObject:diskImage forKey:key cost:cost]; + } + + return diskImage; +} + +- (NSData *)diskImageDataBySearchingAllPathsForKey:(NSString *)key { + NSString *defaultPath = [self defaultCachePathForKey:key]; + NSData *data = [NSData dataWithContentsOfFile:defaultPath]; + if (data) { + return data; + } + + for (NSString *path in self.customPaths) { + NSString *filePath = [self cachePathForKey:key inPath:path]; + NSData *imageData = [NSData dataWithContentsOfFile:filePath]; + if (imageData) { + return imageData; + } + } + + return nil; +} + +- (UIImage *)diskImageForKey:(NSString *)key { + NSData *data = [self diskImageDataBySearchingAllPathsForKey:key]; + if (data) { + UIImage *image = [UIImage sd_imageWithData:data]; + image = [self scaledImageForKey:key image:image]; + image = [UIImage decodedImageWithImage:image]; + return image; + } + else { + return nil; + } +} + +- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image { + return SDScaledImageForKey(key, image); +} + +- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock { + if (!doneBlock) { + return nil; + } + + if (!key) { + doneBlock(nil, SDImageCacheTypeNone); + return nil; + } + + // First check the in-memory cache... + UIImage *image = [self imageFromMemoryCacheForKey:key]; + if (image) { + doneBlock(image, SDImageCacheTypeMemory); + return nil; + } + + NSOperation *operation = [NSOperation new]; + dispatch_async(self.ioQueue, ^{ + if (operation.isCancelled) { + return; + } + + @autoreleasepool { + UIImage *diskImage = [self diskImageForKey:key]; + if (diskImage) { + CGFloat cost = diskImage.size.height * diskImage.size.width * diskImage.scale; + [self.memCache setObject:diskImage forKey:key cost:cost]; + } + + dispatch_async(dispatch_get_main_queue(), ^{ + doneBlock(diskImage, SDImageCacheTypeDisk); + }); + } + }); + + return operation; +} + +- (void)removeImageForKey:(NSString *)key { + [self removeImageForKey:key withCompletion:nil]; +} + +- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion { + [self removeImageForKey:key fromDisk:YES withCompletion:completion]; +} + +- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk { + [self removeImageForKey:key fromDisk:fromDisk withCompletion:nil]; +} + +- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion { + + if (key == nil) { + return; + } + + [self.memCache removeObjectForKey:key]; + + if (fromDisk) { + dispatch_async(self.ioQueue, ^{ + [_fileManager removeItemAtPath:[self defaultCachePathForKey:key] error:nil]; + + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(); + }); + } + }); + } else if (completion){ + completion(); + } + +} + +- (void)setMaxMemoryCost:(NSUInteger)maxMemoryCost { + self.memCache.totalCostLimit = maxMemoryCost; +} + +- (NSUInteger)maxMemoryCost { + return self.memCache.totalCostLimit; +} + +- (void)clearMemory { + [self.memCache removeAllObjects]; +} + +- (void)clearDisk { + [self clearDiskOnCompletion:nil]; +} + +- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion +{ + dispatch_async(self.ioQueue, ^{ + [_fileManager removeItemAtPath:self.diskCachePath error:nil]; + [_fileManager createDirectoryAtPath:self.diskCachePath + withIntermediateDirectories:YES + attributes:nil + error:NULL]; + + if (completion) { + dispatch_async(dispatch_get_main_queue(), ^{ + completion(); + }); + } + }); +} + +- (void)cleanDisk { + [self cleanDiskWithCompletionBlock:nil]; +} + +- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock { + dispatch_async(self.ioQueue, ^{ + NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; + NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey]; + + // This enumerator prefetches useful properties for our cache files. + NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL + includingPropertiesForKeys:resourceKeys + options:NSDirectoryEnumerationSkipsHiddenFiles + errorHandler:NULL]; + + NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge]; + NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary]; + NSUInteger currentCacheSize = 0; + + // Enumerate all of the files in the cache directory. This loop has two purposes: + // + // 1. Removing files that are older than the expiration date. + // 2. Storing file attributes for the size-based cleanup pass. + NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init]; + for (NSURL *fileURL in fileEnumerator) { + NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL]; + + // Skip directories. + if ([resourceValues[NSURLIsDirectoryKey] boolValue]) { + continue; + } + + // Remove files that are older than the expiration date; + NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey]; + if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) { + [urlsToDelete addObject:fileURL]; + continue; + } + + // Store a reference to this file and account for its total size. + NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; + currentCacheSize += [totalAllocatedSize unsignedIntegerValue]; + [cacheFiles setObject:resourceValues forKey:fileURL]; + } + + for (NSURL *fileURL in urlsToDelete) { + [_fileManager removeItemAtURL:fileURL error:nil]; + } + + // If our remaining disk cache exceeds a configured maximum size, perform a second + // size-based cleanup pass. We delete the oldest files first. + if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) { + // Target half of our maximum cache size for this cleanup pass. + const NSUInteger desiredCacheSize = self.maxCacheSize / 2; + + // Sort the remaining cache files by their last modification time (oldest first). + NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent + usingComparator:^NSComparisonResult(id obj1, id obj2) { + return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]]; + }]; + + // Delete files until we fall below our desired cache size. + for (NSURL *fileURL in sortedFiles) { + if ([_fileManager removeItemAtURL:fileURL error:nil]) { + NSDictionary *resourceValues = cacheFiles[fileURL]; + NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey]; + currentCacheSize -= [totalAllocatedSize unsignedIntegerValue]; + + if (currentCacheSize < desiredCacheSize) { + break; + } + } + } + } + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(); + }); + } + }); +} + +- (void)backgroundCleanDisk { + UIApplication *application = [UIApplication sharedApplication]; + __block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{ + // Clean up any unfinished task business by marking where you + // stopped or ending the task outright. + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; + + // Start the long-running task and return immediately. + [self cleanDiskWithCompletionBlock:^{ + [application endBackgroundTask:bgTask]; + bgTask = UIBackgroundTaskInvalid; + }]; +} + +- (NSUInteger)getSize { + __block NSUInteger size = 0; + dispatch_sync(self.ioQueue, ^{ + NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath]; + for (NSString *fileName in fileEnumerator) { + NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName]; + NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil]; + size += [attrs fileSize]; + } + }); + return size; +} + +- (NSUInteger)getDiskCount { + __block NSUInteger count = 0; + dispatch_sync(self.ioQueue, ^{ + NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath]; + count = [[fileEnumerator allObjects] count]; + }); + return count; +} + +- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock { + NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES]; + + dispatch_async(self.ioQueue, ^{ + NSUInteger fileCount = 0; + NSUInteger totalSize = 0; + + NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL + includingPropertiesForKeys:@[NSFileSize] + options:NSDirectoryEnumerationSkipsHiddenFiles + errorHandler:NULL]; + + for (NSURL *fileURL in fileEnumerator) { + NSNumber *fileSize; + [fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL]; + totalSize += [fileSize unsignedIntegerValue]; + fileCount += 1; + } + + if (completionBlock) { + dispatch_async(dispatch_get_main_queue(), ^{ + completionBlock(fileCount, totalSize); + }); + } + }); +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.h new file mode 100644 index 0000000..a0555fd --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.h @@ -0,0 +1,70 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Jamie Pinkham + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import + +#ifdef __OBJC_GC__ +#error SDWebImage does not support Objective-C Garbage Collection +#endif + +#if __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 +#error SDWebImage doesn't support Deployement Target version < 5.0 +#endif + +#if !TARGET_OS_IPHONE +#import +#ifndef UIImage +#define UIImage NSImage +#endif +#ifndef UIImageView +#define UIImageView NSImageView +#endif +#else + +#import + +#endif + +#ifndef NS_ENUM +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#endif + +#ifndef NS_OPTIONS +#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type +#endif + +#if OS_OBJECT_USE_OBJC + #undef SDDispatchQueueRelease + #undef SDDispatchQueueSetterSementics + #define SDDispatchQueueRelease(q) + #define SDDispatchQueueSetterSementics strong +#else +#undef SDDispatchQueueRelease +#undef SDDispatchQueueSetterSementics +#define SDDispatchQueueRelease(q) (dispatch_release(q)) +#define SDDispatchQueueSetterSementics assign +#endif + +extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image); + +typedef void(^SDWebImageNoParamsBlock)(); + +#define dispatch_main_sync_safe(block)\ + if ([NSThread isMainThread]) {\ + block();\ + } else {\ + dispatch_sync(dispatch_get_main_queue(), block);\ + } + +#define dispatch_main_async_safe(block)\ + if ([NSThread isMainThread]) {\ + block();\ + } else {\ + dispatch_async(dispatch_get_main_queue(), block);\ + } diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.m new file mode 100644 index 0000000..8c7d345 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageCompat.m @@ -0,0 +1,45 @@ +// +// SDWebImageCompat.m +// SDWebImage +// +// Created by Olivier Poitrey on 11/12/12. +// Copyright (c) 2012 Dailymotion. All rights reserved. +// + +#import "SDWebImageCompat.h" + +#if !__has_feature(objc_arc) +#error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag +#endif + +inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { + if (!image) { + return nil; + } + + if ([image.images count] > 0) { + NSMutableArray *scaledImages = [NSMutableArray array]; + + for (UIImage *tempImage in image.images) { + [scaledImages addObject:SDScaledImageForKey(key, tempImage)]; + } + + return [UIImage animatedImageWithImages:scaledImages duration:image.duration]; + } + else { + if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { + CGFloat scale = 1.0; + if (key.length >= 8) { + // Search @2x. at the end of the string, before a 3 to 4 extension length (only if key len is 8 or more @2x. + 4 len ext) + NSRange range = [key rangeOfString:@"@2x." options:0 range:NSMakeRange(key.length - 8, 5)]; + if (range.location != NSNotFound) { + scale = 2.0; + } + } + + UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation]; + image = scaledImage; + } + return image; + } +} diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.h new file mode 100644 index 0000000..0176a7b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.h @@ -0,0 +1,18 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * Created by james on 9/28/11. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" + +@interface UIImage (ForceDecode) + ++ (UIImage *)decodedImageWithImage:(UIImage *)image; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.m new file mode 100644 index 0000000..79ddb30 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDecoder.m @@ -0,0 +1,72 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * Created by james on 9/28/11. + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDecoder.h" + +@implementation UIImage (ForceDecode) + ++ (UIImage *)decodedImageWithImage:(UIImage *)image { + if (image.images) { + // Do not decode animated images + return image; + } + + CGImageRef imageRef = image.CGImage; + CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); + CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize}; + + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef); + + int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask); + BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone || + infoMask == kCGImageAlphaNoneSkipFirst || + infoMask == kCGImageAlphaNoneSkipLast); + + // CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB. + // https://developer.apple.com/library/mac/#qa/qa1037/_index.html + if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) { + // Unset the old alpha info. + bitmapInfo &= ~kCGBitmapAlphaInfoMask; + + // Set noneSkipFirst. + bitmapInfo |= kCGImageAlphaNoneSkipFirst; + } + // Some PNGs tell us they have alpha but only 3 components. Odd. + else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) { + // Unset the old alpha info. + bitmapInfo &= ~kCGBitmapAlphaInfoMask; + bitmapInfo |= kCGImageAlphaPremultipliedFirst; + } + + // It calculates the bytes-per-row based on the bitsPerComponent and width arguments. + CGContextRef context = CGBitmapContextCreate(NULL, + imageSize.width, + imageSize.height, + CGImageGetBitsPerComponent(imageRef), + 0, + colorSpace, + bitmapInfo); + CGColorSpaceRelease(colorSpace); + + // If failed, return undecompressed image + if (!context) return image; + + CGContextDrawImage(context, imageRect, imageRef); + CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context); + + CGContextRelease(context); + + UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation]; + CGImageRelease(decompressedImageRef); + return decompressedImage; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h new file mode 100644 index 0000000..008231a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.h @@ -0,0 +1,173 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageOperation.h" + +typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) { + SDWebImageDownloaderLowPriority = 1 << 0, + SDWebImageDownloaderProgressiveDownload = 1 << 1, + + /** + * By default, request prevent the of NSURLCache. With this flag, NSURLCache + * is used with default policies. + */ + SDWebImageDownloaderUseNSURLCache = 1 << 2, + + /** + * Call completion block with nil image/imageData if the image was read from NSURLCache + * (to be combined with `SDWebImageDownloaderUseNSURLCache`). + */ + + SDWebImageDownloaderIgnoreCachedResponse = 1 << 3, + /** + * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for + * extra time in background to let the request finish. If the background task expires the operation will be cancelled. + */ + + SDWebImageDownloaderContinueInBackground = 1 << 4, + + /** + * Handles cookies stored in NSHTTPCookieStore by setting + * NSMutableURLRequest.HTTPShouldHandleCookies = YES; + */ + SDWebImageDownloaderHandleCookies = 1 << 5, + + /** + * Enable to allow untrusted SSL ceriticates. + * Useful for testing purposes. Use with caution in production. + */ + SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6, + + /** + * Put the image in the high priority queue. + */ + SDWebImageDownloaderHighPriority = 1 << 7, + + +}; + +typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) { + /** + * Default value. All download operations will execute in queue style (first-in-first-out). + */ + SDWebImageDownloaderFIFOExecutionOrder, + + /** + * All download operations will execute in stack style (last-in-first-out). + */ + SDWebImageDownloaderLIFOExecutionOrder +}; + +extern NSString *const SDWebImageDownloadStartNotification; +extern NSString *const SDWebImageDownloadStopNotification; + +typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize); + +typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished); + +typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers); + +/** + * Asynchronous downloader dedicated and optimized for image loading. + */ +@interface SDWebImageDownloader : NSObject + +@property (assign, nonatomic) NSInteger maxConcurrentDownloads; + +/** + * Shows the current amount of downloads that still need to be downloaded + */ + +@property (readonly, nonatomic) NSUInteger currentDownloadCount; + + +/** + * The timeout value (in seconds) for the download operation. Default: 15.0. + */ +@property (assign, nonatomic) NSTimeInterval downloadTimeout; + + +/** + * Changes download operations execution order. Default value is `SDWebImageDownloaderFIFOExecutionOrder`. + */ +@property (assign, nonatomic) SDWebImageDownloaderExecutionOrder executionOrder; + +/** + * Singleton method, returns the shared instance + * + * @return global shared instance of downloader class + */ ++ (SDWebImageDownloader *)sharedDownloader; + +/** + * Set username + */ +@property (strong, nonatomic) NSString *username; + +/** + * Set password + */ +@property (strong, nonatomic) NSString *password; + +/** + * Set filter to pick headers for downloading image HTTP request. + * + * This block will be invoked for each downloading image request, returned + * NSDictionary will be used as headers in corresponding HTTP request. + */ +@property (nonatomic, copy) SDWebImageDownloaderHeadersFilterBlock headersFilter; + +/** + * Set a value for a HTTP header to be appended to each download HTTP request. + * + * @param value The value for the header field. Use `nil` value to remove the header. + * @param field The name of the header field to set. + */ +- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field; + +/** + * Returns the value of the specified HTTP header field. + * + * @return The value associated with the header field field, or `nil` if there is no corresponding header field. + */ +- (NSString *)valueForHTTPHeaderField:(NSString *)field; + +/** + * Creates a SDWebImageDownloader async downloader instance with a given URL + * + * The delegate will be informed when the image is finish downloaded or an error has happen. + * + * @see SDWebImageDownloaderDelegate + * + * @param url The URL to the image to download + * @param options The options to be used for this download + * @param progressBlock A block called repeatedly while the image is downloading + * @param completedBlock A block called once the download is completed. + * If the download succeeded, the image parameter is set, in case of error, + * error parameter is set with the error. The last parameter is always YES + * if SDWebImageDownloaderProgressiveDownload isn't use. With the + * SDWebImageDownloaderProgressiveDownload option, this block is called + * repeatedly with the partial image object and the finished argument set to NO + * before to be called a last time with the full image and finished argument + * set to YES. In case of error, the finished argument is always YES. + * + * @return A cancellable SDWebImageOperation + */ +- (id )downloadImageWithURL:(NSURL *)url + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock; + +/** + * Sets the download queue suspension state + */ +- (void)setSuspended:(BOOL)suspended; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m new file mode 100644 index 0000000..60914db --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloader.m @@ -0,0 +1,225 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloader.h" +#import "SDWebImageDownloaderOperation.h" +#import + +NSString *const SDWebImageDownloadStartNotification = @"SDWebImageDownloadStartNotification"; +NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification"; + +static NSString *const kProgressCallbackKey = @"progress"; +static NSString *const kCompletedCallbackKey = @"completed"; + +@interface SDWebImageDownloader () + +@property (strong, nonatomic) NSOperationQueue *downloadQueue; +@property (weak, nonatomic) NSOperation *lastAddedOperation; +@property (strong, nonatomic) NSMutableDictionary *URLCallbacks; +@property (strong, nonatomic) NSMutableDictionary *HTTPHeaders; +// This queue is used to serialize the handling of the network responses of all the download operation in a single queue +@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue; + +@end + +@implementation SDWebImageDownloader + ++ (void)initialize { + // Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator ) + // To use it, just add #import "SDNetworkActivityIndicator.h" in addition to the SDWebImage import + if (NSClassFromString(@"SDNetworkActivityIndicator")) { + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Warc-performSelector-leaks" + id activityIndicator = [NSClassFromString(@"SDNetworkActivityIndicator") performSelector:NSSelectorFromString(@"sharedActivityIndicator")]; +#pragma clang diagnostic pop + + // Remove observer in case it was previously added. + [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStartNotification object:nil]; + [[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStopNotification object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:activityIndicator + selector:NSSelectorFromString(@"startActivity") + name:SDWebImageDownloadStartNotification object:nil]; + [[NSNotificationCenter defaultCenter] addObserver:activityIndicator + selector:NSSelectorFromString(@"stopActivity") + name:SDWebImageDownloadStopNotification object:nil]; + } +} + ++ (SDWebImageDownloader *)sharedDownloader { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (id)init { + if ((self = [super init])) { + _executionOrder = SDWebImageDownloaderFIFOExecutionOrder; + _downloadQueue = [NSOperationQueue new]; + _downloadQueue.maxConcurrentOperationCount = 2; + _URLCallbacks = [NSMutableDictionary new]; + _HTTPHeaders = [NSMutableDictionary dictionaryWithObject:@"image/webp,image/*;q=0.8" forKey:@"Accept"]; + _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT); + _downloadTimeout = 15.0; + } + return self; +} + +- (void)dealloc { + [self.downloadQueue cancelAllOperations]; + SDDispatchQueueRelease(_barrierQueue); +} + +- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field { + if (value) { + self.HTTPHeaders[field] = value; + } + else { + [self.HTTPHeaders removeObjectForKey:field]; + } +} + +- (NSString *)valueForHTTPHeaderField:(NSString *)field { + return self.HTTPHeaders[field]; +} + +- (void)setMaxConcurrentDownloads:(NSInteger)maxConcurrentDownloads { + _downloadQueue.maxConcurrentOperationCount = maxConcurrentDownloads; +} + +- (NSUInteger)currentDownloadCount { + return _downloadQueue.operationCount; +} + +- (NSInteger)maxConcurrentDownloads { + return _downloadQueue.maxConcurrentOperationCount; +} + +- (id )downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock { + __block SDWebImageDownloaderOperation *operation; + __weak SDWebImageDownloader *wself = self; + + [self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{ + NSTimeInterval timeoutInterval = wself.downloadTimeout; + if (timeoutInterval == 0.0) { + timeoutInterval = 15.0; + } + + // In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise + NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:(options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeoutInterval]; + request.HTTPShouldHandleCookies = (options & SDWebImageDownloaderHandleCookies); + request.HTTPShouldUsePipelining = YES; + if (wself.headersFilter) { + request.allHTTPHeaderFields = wself.headersFilter(url, [wself.HTTPHeaders copy]); + } + else { + request.allHTTPHeaderFields = wself.HTTPHeaders; + } + operation = [[SDWebImageDownloaderOperation alloc] initWithRequest:request + options:options + progress:^(NSInteger receivedSize, NSInteger expectedSize) { + SDWebImageDownloader *sself = wself; + if (!sself) return; + NSArray *callbacksForURL = [sself callbacksForURL:url]; + for (NSDictionary *callbacks in callbacksForURL) { + SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey]; + if (callback) callback(receivedSize, expectedSize); + } + } + completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { + SDWebImageDownloader *sself = wself; + if (!sself) return; + NSArray *callbacksForURL = [sself callbacksForURL:url]; + if (finished) { + [sself removeCallbacksForURL:url]; + } + for (NSDictionary *callbacks in callbacksForURL) { + SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey]; + if (callback) callback(image, data, error, finished); + } + } + cancelled:^{ + SDWebImageDownloader *sself = wself; + if (!sself) return; + [sself removeCallbacksForURL:url]; + }]; + + if (wself.username && wself.password) { + operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession]; + } + + if (options & SDWebImageDownloaderHighPriority) { + operation.queuePriority = NSOperationQueuePriorityHigh; + } else if (options & SDWebImageDownloaderLowPriority) { + operation.queuePriority = NSOperationQueuePriorityLow; + } + + [wself.downloadQueue addOperation:operation]; + if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) { + // Emulate LIFO execution order by systematically adding new operations as last operation's dependency + [wself.lastAddedOperation addDependency:operation]; + wself.lastAddedOperation = operation; + } + }]; + + return operation; +} + +- (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock andCompletedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageNoParamsBlock)createCallback { + // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. + if (url == nil) { + if (completedBlock != nil) { + completedBlock(nil, nil, nil, NO); + } + return; + } + + dispatch_barrier_sync(self.barrierQueue, ^{ + BOOL first = NO; + if (!self.URLCallbacks[url]) { + self.URLCallbacks[url] = [NSMutableArray new]; + first = YES; + } + + // Handle single download of simultaneous download request for the same URL + NSMutableArray *callbacksForURL = self.URLCallbacks[url]; + NSMutableDictionary *callbacks = [NSMutableDictionary new]; + if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy]; + if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy]; + [callbacksForURL addObject:callbacks]; + self.URLCallbacks[url] = callbacksForURL; + + if (first) { + createCallback(); + } + }); +} + +- (NSArray *)callbacksForURL:(NSURL *)url { + __block NSArray *callbacksForURL; + dispatch_sync(self.barrierQueue, ^{ + callbacksForURL = self.URLCallbacks[url]; + }); + return [callbacksForURL copy]; +} + +- (void)removeCallbacksForURL:(NSURL *)url { + dispatch_barrier_async(self.barrierQueue, ^{ + [self.URLCallbacks removeObjectForKey:url]; + }); +} + +- (void)setSuspended:(BOOL)suspended { + [self.downloadQueue setSuspended:suspended]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h new file mode 100644 index 0000000..21a3106 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.h @@ -0,0 +1,60 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageDownloader.h" +#import "SDWebImageOperation.h" + +@interface SDWebImageDownloaderOperation : NSOperation + +/** + * The request used by the operation's connection. + */ +@property (strong, nonatomic, readonly) NSURLRequest *request; + +/** + * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. + * + * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. + */ +@property (nonatomic, assign) BOOL shouldUseCredentialStorage; + +/** + * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. + * + * This will be overridden by any shared credentials that exist for the username or password of the request URL, if present. + */ +@property (nonatomic, strong) NSURLCredential *credential; + +/** + * The SDWebImageDownloaderOptions for the receiver. + */ +@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options; + +/** + * Initializes a `SDWebImageDownloaderOperation` object + * + * @see SDWebImageDownloaderOperation + * + * @param request the URL request + * @param options downloader options + * @param progressBlock the block executed when a new chunk of data arrives. + * @note the progress block is executed on a background queue + * @param completedBlock the block executed when the download is done. + * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue + * @param cancelBlock the block executed if the download (operation) is cancelled + * + * @return the initialized instance + */ +- (id)initWithRequest:(NSURLRequest *)request + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock + cancelled:(SDWebImageNoParamsBlock)cancelBlock; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m new file mode 100644 index 0000000..333e316 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageDownloaderOperation.m @@ -0,0 +1,414 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageDownloaderOperation.h" +#import "SDWebImageDecoder.h" +#import "UIImage+MultiFormat.h" +#import +#import "SDWebImageManager.h" + +@interface SDWebImageDownloaderOperation () + +@property (copy, nonatomic) SDWebImageDownloaderProgressBlock progressBlock; +@property (copy, nonatomic) SDWebImageDownloaderCompletedBlock completedBlock; +@property (copy, nonatomic) SDWebImageNoParamsBlock cancelBlock; + +@property (assign, nonatomic, getter = isExecuting) BOOL executing; +@property (assign, nonatomic, getter = isFinished) BOOL finished; +@property (assign, nonatomic) NSInteger expectedSize; +@property (strong, nonatomic) NSMutableData *imageData; +@property (strong, nonatomic) NSURLConnection *connection; +@property (strong, atomic) NSThread *thread; + +#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 +@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId; +#endif + +@end + +@implementation SDWebImageDownloaderOperation { + size_t width, height; + UIImageOrientation orientation; + BOOL responseFromCached; +} + +@synthesize executing = _executing; +@synthesize finished = _finished; + +- (id)initWithRequest:(NSURLRequest *)request + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock + cancelled:(SDWebImageNoParamsBlock)cancelBlock { + if ((self = [super init])) { + _request = request; + _shouldUseCredentialStorage = YES; + _options = options; + _progressBlock = [progressBlock copy]; + _completedBlock = [completedBlock copy]; + _cancelBlock = [cancelBlock copy]; + _executing = NO; + _finished = NO; + _expectedSize = 0; + responseFromCached = YES; // Initially wrong until `connection:willCacheResponse:` is called or not called + } + return self; +} + +- (void)start { + @synchronized (self) { + if (self.isCancelled) { + self.finished = YES; + [self reset]; + return; + } + +#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 + if ([self shouldContinueWhenAppEntersBackground]) { + __weak __typeof__ (self) wself = self; + self.backgroundTaskId = [[UIApplication sharedApplication] beginBackgroundTaskWithExpirationHandler:^{ + __strong __typeof (wself) sself = wself; + + if (sself) { + [sself cancel]; + + [[UIApplication sharedApplication] endBackgroundTask:sself.backgroundTaskId]; + sself.backgroundTaskId = UIBackgroundTaskInvalid; + } + }]; + } +#endif + + self.executing = YES; + self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO]; + self.thread = [NSThread currentThread]; + } + + [self.connection start]; + + if (self.connection) { + if (self.progressBlock) { + self.progressBlock(0, NSURLResponseUnknownLength); + } + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self]; + + if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) { + // Make sure to run the runloop in our background thread so it can process downloaded data + // Note: we use a timeout to work around an issue with NSURLConnection cancel under iOS 5 + // not waking up the runloop, leading to dead threads (see https://github.com/rs/SDWebImage/issues/466) + CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); + } + else { + CFRunLoopRun(); + } + + if (!self.isFinished) { + [self.connection cancel]; + [self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:@{NSURLErrorFailingURLErrorKey : self.request.URL}]]; + } + } + else { + if (self.completedBlock) { + self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES); + } + } + +#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 + if (self.backgroundTaskId != UIBackgroundTaskInvalid) { + [[UIApplication sharedApplication] endBackgroundTask:self.backgroundTaskId]; + self.backgroundTaskId = UIBackgroundTaskInvalid; + } +#endif +} + +- (void)cancel { + @synchronized (self) { + if (self.thread) { + [self performSelector:@selector(cancelInternalAndStop) onThread:self.thread withObject:nil waitUntilDone:NO]; + } + else { + [self cancelInternal]; + } + } +} + +- (void)cancelInternalAndStop { + if (self.isFinished) return; + [self cancelInternal]; + CFRunLoopStop(CFRunLoopGetCurrent()); +} + +- (void)cancelInternal { + if (self.isFinished) return; + [super cancel]; + if (self.cancelBlock) self.cancelBlock(); + + if (self.connection) { + [self.connection cancel]; + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; + + // As we cancelled the connection, its callback won't be called and thus won't + // maintain the isFinished and isExecuting flags. + if (self.isExecuting) self.executing = NO; + if (!self.isFinished) self.finished = YES; + } + + [self reset]; +} + +- (void)done { + self.finished = YES; + self.executing = NO; + [self reset]; +} + +- (void)reset { + self.cancelBlock = nil; + self.completedBlock = nil; + self.progressBlock = nil; + self.connection = nil; + self.imageData = nil; + self.thread = nil; +} + +- (void)setFinished:(BOOL)finished { + [self willChangeValueForKey:@"isFinished"]; + _finished = finished; + [self didChangeValueForKey:@"isFinished"]; +} + +- (void)setExecuting:(BOOL)executing { + [self willChangeValueForKey:@"isExecuting"]; + _executing = executing; + [self didChangeValueForKey:@"isExecuting"]; +} + +- (BOOL)isConcurrent { + return YES; +} + +#pragma mark NSURLConnection (delegate) + +- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { + if (![response respondsToSelector:@selector(statusCode)] || [((NSHTTPURLResponse *)response) statusCode] < 400) { + NSInteger expected = response.expectedContentLength > 0 ? (NSInteger)response.expectedContentLength : 0; + self.expectedSize = expected; + if (self.progressBlock) { + self.progressBlock(0, expected); + } + + self.imageData = [[NSMutableData alloc] initWithCapacity:expected]; + } + else { + [self.connection cancel]; + + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + + if (self.completedBlock) { + self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); + } + CFRunLoopStop(CFRunLoopGetCurrent()); + [self done]; + } +} + +- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { + [self.imageData appendData:data]; + + if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock) { + // The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/ + // Thanks to the author @Nyx0uf + + // Get the total bytes downloaded + const NSInteger totalSize = self.imageData.length; + + // Update the data source, we must pass ALL the data, not just the new bytes + CGImageSourceRef imageSource = CGImageSourceCreateIncremental(NULL); + CGImageSourceUpdateData(imageSource, (__bridge CFDataRef)self.imageData, totalSize == self.expectedSize); + + if (width + height == 0) { + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); + if (properties) { + NSInteger orientationValue = -1; + CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight); + if (val) CFNumberGetValue(val, kCFNumberLongType, &height); + val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth); + if (val) CFNumberGetValue(val, kCFNumberLongType, &width); + val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); + if (val) CFNumberGetValue(val, kCFNumberNSIntegerType, &orientationValue); + CFRelease(properties); + + // When we draw to Core Graphics, we lose orientation information, + // which means the image below born of initWithCGIImage will be + // oriented incorrectly sometimes. (Unlike the image born of initWithData + // in connectionDidFinishLoading.) So save it here and pass it on later. + orientation = [[self class] orientationFromPropertyValue:(orientationValue == -1 ? 1 : orientationValue)]; + } + + } + + if (width + height > 0 && totalSize < self.expectedSize) { + // Create the image + CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL); + +#ifdef TARGET_OS_IPHONE + // Workaround for iOS anamorphic image + if (partialImageRef) { + const size_t partialHeight = CGImageGetHeight(partialImageRef); + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst); + CGColorSpaceRelease(colorSpace); + if (bmContext) { + CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = partialHeight}, partialImageRef); + CGImageRelease(partialImageRef); + partialImageRef = CGBitmapContextCreateImage(bmContext); + CGContextRelease(bmContext); + } + else { + CGImageRelease(partialImageRef); + partialImageRef = nil; + } + } +#endif + + if (partialImageRef) { + UIImage *image = [UIImage imageWithCGImage:partialImageRef scale:1 orientation:orientation]; + NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; + UIImage *scaledImage = [self scaledImageForKey:key image:image]; + image = [UIImage decodedImageWithImage:scaledImage]; + CGImageRelease(partialImageRef); + dispatch_main_sync_safe(^{ + if (self.completedBlock) { + self.completedBlock(image, nil, nil, NO); + } + }); + } + } + + CFRelease(imageSource); + } + + if (self.progressBlock) { + self.progressBlock(self.imageData.length, self.expectedSize); + } +} + ++ (UIImageOrientation)orientationFromPropertyValue:(NSInteger)value { + switch (value) { + case 1: + return UIImageOrientationUp; + case 3: + return UIImageOrientationDown; + case 8: + return UIImageOrientationLeft; + case 6: + return UIImageOrientationRight; + case 2: + return UIImageOrientationUpMirrored; + case 4: + return UIImageOrientationDownMirrored; + case 5: + return UIImageOrientationLeftMirrored; + case 7: + return UIImageOrientationRightMirrored; + default: + return UIImageOrientationUp; + } +} + +- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image { + return SDScaledImageForKey(key, image); +} + +- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { + SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock; + @synchronized(self) { + CFRunLoopStop(CFRunLoopGetCurrent()); + self.thread = nil; + self.connection = nil; + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + } + + if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) { + responseFromCached = NO; + } + + if (completionBlock) + { + if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { + completionBlock(nil, nil, nil, YES); + } + else { + UIImage *image = [UIImage sd_imageWithData:self.imageData]; + NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; + image = [self scaledImageForKey:key image:image]; + + // Do not force decoding animated GIFs + if (!image.images) { + image = [UIImage decodedImageWithImage:image]; + } + if (CGSizeEqualToSize(image.size, CGSizeZero)) { + completionBlock(nil, nil, [NSError errorWithDomain:@"SDWebImageErrorDomain" code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES); + } + else { + completionBlock(image, self.imageData, nil, YES); + } + } + } + self.completionBlock = nil; + [self done]; +} + +- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { + CFRunLoopStop(CFRunLoopGetCurrent()); + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:nil]; + + if (self.completedBlock) { + self.completedBlock(nil, nil, error, YES); + } + + [self done]; +} + +- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { + responseFromCached = NO; // If this method is called, it means the response wasn't read from cache + if (self.request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData) { + // Prevents caching of responses + return nil; + } + else { + return cachedResponse; + } +} + +- (BOOL)shouldContinueWhenAppEntersBackground { + return self.options & SDWebImageDownloaderContinueInBackground; +} + +- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection { + return self.shouldUseCredentialStorage; +} + +- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ + if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) { + NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + } else { + if ([challenge previousFailureCount] == 0) { + if (self.credential) { + [[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge]; + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } else { + [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + } + } +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h new file mode 100644 index 0000000..6bb0dcf --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.h @@ -0,0 +1,285 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageOperation.h" +#import "SDWebImageDownloader.h" +#import "SDImageCache.h" + +typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { + /** + * By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying. + * This flag disable this blacklisting. + */ + SDWebImageRetryFailed = 1 << 0, + + /** + * By default, image downloads are started during UI interactions, this flags disable this feature, + * leading to delayed download on UIScrollView deceleration for instance. + */ + SDWebImageLowPriority = 1 << 1, + + /** + * This flag disables on-disk caching + */ + SDWebImageCacheMemoryOnly = 1 << 2, + + /** + * This flag enables progressive download, the image is displayed progressively during download as a browser would do. + * By default, the image is only displayed once completely downloaded. + */ + SDWebImageProgressiveDownload = 1 << 3, + + /** + * Even if the image is cached, respect the HTTP response cache control, and refresh the image from remote location if needed. + * The disk caching will be handled by NSURLCache instead of SDWebImage leading to slight performance degradation. + * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics. + * If a cached image is refreshed, the completion block is called once with the cached image and again with the final image. + * + * Use this flag only if you can't make your URLs static with embeded cache busting parameter. + */ + SDWebImageRefreshCached = 1 << 4, + + /** + * In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for + * extra time in background to let the request finish. If the background task expires the operation will be cancelled. + */ + SDWebImageContinueInBackground = 1 << 5, + + /** + * Handles cookies stored in NSHTTPCookieStore by setting + * NSMutableURLRequest.HTTPShouldHandleCookies = YES; + */ + SDWebImageHandleCookies = 1 << 6, + + /** + * Enable to allow untrusted SSL ceriticates. + * Useful for testing purposes. Use with caution in production. + */ + SDWebImageAllowInvalidSSLCertificates = 1 << 7, + + /** + * By default, image are loaded in the order they were queued. This flag move them to + * the front of the queue and is loaded immediately instead of waiting for the current queue to be loaded (which + * could take a while). + */ + SDWebImageHighPriority = 1 << 8, + + /** + * By default, placeholder images are loaded while the image is loading. This flag will delay the loading + * of the placeholder image until after the image has finished loading. + */ + SDWebImageDelayPlaceholder = 1 << 9 +}; + +typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL); + +typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL); + +typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url); + + +@class SDWebImageManager; + +@protocol SDWebImageManagerDelegate + +@optional + +/** + * Controls which image should be downloaded when the image is not found in the cache. + * + * @param imageManager The current `SDWebImageManager` + * @param imageURL The url of the image to be downloaded + * + * @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied. + */ +- (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL; + +/** + * Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory. + * NOTE: This method is called from a global queue in order to not to block the main thread. + * + * @param imageManager The current `SDWebImageManager` + * @param image The image to transform + * @param imageURL The url of the image to transform + * + * @return The transformed image object. + */ +- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL; + +@end + +/** + * The SDWebImageManager is the class behind the UIImageView+WebCache category and likes. + * It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache). + * You can use this class directly to benefit from web image downloading with caching in another context than + * a UIView. + * + * Here is a simple example of how to use SDWebImageManager: + * + * @code + +SDWebImageManager *manager = [SDWebImageManager sharedManager]; +[manager downloadWithURL:imageURL + options:0 + progress:nil + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (image) { + // do something with image + } + }]; + + * @endcode + */ +@interface SDWebImageManager : NSObject + +@property (weak, nonatomic) id delegate; + +@property (strong, nonatomic, readonly) SDImageCache *imageCache; +@property (strong, nonatomic, readonly) SDWebImageDownloader *imageDownloader; + +/** + * The cache filter is a block used each time SDWebImageManager need to convert an URL into a cache key. This can + * be used to remove dynamic part of an image URL. + * + * The following example sets a filter in the application delegate that will remove any query-string from the + * URL before to use it as a cache key: + * + * @code + +[[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) { + url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; + return [url absoluteString]; +}]; + + * @endcode + */ +@property (copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter; + +/** + * Returns global SDWebImageManager instance. + * + * @return SDWebImageManager shared instance + */ ++ (SDWebImageManager *)sharedManager; + +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @param url The URL to the image + * @param options A mask to specify options to use for this request + * @param progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. + * + * This parameter is required. + * + * This block has no return value and takes the requested UIImage as first parameter. + * In case of error the image parameter is nil and the second parameter may contain an NSError. + * + * The third parameter is an `SDImageCacheType` enum indicating if the image was retrived from the local cache + * or from the memory cache or from the network. + * + * The last parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is + * downloading. This block is thus called repetidly with a partial image. When image is fully downloaded, the + * block is called a last time with the full image and the last parameter set to YES. + * + * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation + */ +- (id )downloadImageWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock; + +/** + * Saves image to cache for given URL + * + * @param image The image to cache + * @param url The URL to the image + * + */ + +- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url; + +/** + * Cancel all current opreations + */ +- (void)cancelAll; + +/** + * Check one or more operations running + */ +- (BOOL)isRunning; + +/** + * Check if image has already been cached + * + * @param url image url + * + * @return if the image was already cached + */ +- (BOOL)cachedImageExistsForURL:(NSURL *)url; + +/** + * Check if image has already been cached on disk only + * + * @param url image url + * + * @return if the image was already cached (disk only) + */ +- (BOOL)diskImageExistsForURL:(NSURL *)url; + +/** + * Async check if image has already been cached + * + * @param url image url + * @param completionBlock the block to be executed when the check is finished + * + * @note the completion block is always executed on the main queue + */ +- (void)cachedImageExistsForURL:(NSURL *)url + completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; + +/** + * Async check if image has already been cached on disk only + * + * @param url image url + * @param completionBlock the block to be executed when the check is finished + * + * @note the completion block is always executed on the main queue + */ +- (void)diskImageExistsForURL:(NSURL *)url + completion:(SDWebImageCheckCacheCompletionBlock)completionBlock; + + +/** + *Return the cache key for a given URL + */ +- (NSString *)cacheKeyForURL:(NSURL *)url; + +@end + + +#pragma mark - Deprecated + +typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionBlock`"); +typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionWithFinishedBlock`"); + + +@interface SDWebImageManager (Deprecated) + +/** + * Downloads the image at the given URL if not present in cache or return the cached version otherwise. + * + * @deprecated This method has been deprecated. Use `downloadImageWithURL:options:progress:completed:` + */ +- (id )downloadWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletedWithFinishedBlock)completedBlock __deprecated_msg("Method deprecated. Use `downloadImageWithURL:options:progress:completed:`"); + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m new file mode 100644 index 0000000..2781ec8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageManager.m @@ -0,0 +1,346 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageManager.h" +#import + +@interface SDWebImageCombinedOperation : NSObject + +@property (assign, nonatomic, getter = isCancelled) BOOL cancelled; +@property (copy, nonatomic) SDWebImageNoParamsBlock cancelBlock; +@property (strong, nonatomic) NSOperation *cacheOperation; + +@end + +@interface SDWebImageManager () + +@property (strong, nonatomic, readwrite) SDImageCache *imageCache; +@property (strong, nonatomic, readwrite) SDWebImageDownloader *imageDownloader; +@property (strong, nonatomic) NSMutableArray *failedURLs; +@property (strong, nonatomic) NSMutableArray *runningOperations; + +@end + +@implementation SDWebImageManager + ++ (id)sharedManager { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (id)init { + if ((self = [super init])) { + _imageCache = [self createCache]; + _imageDownloader = [SDWebImageDownloader sharedDownloader]; + _failedURLs = [NSMutableArray new]; + _runningOperations = [NSMutableArray new]; + } + return self; +} + +- (SDImageCache *)createCache { + return [SDImageCache sharedImageCache]; +} + +- (NSString *)cacheKeyForURL:(NSURL *)url { + if (self.cacheKeyFilter) { + return self.cacheKeyFilter(url); + } + else { + return [url absoluteString]; + } +} + +- (BOOL)cachedImageExistsForURL:(NSURL *)url { + NSString *key = [self cacheKeyForURL:url]; + if ([self.imageCache imageFromMemoryCacheForKey:key] != nil) return YES; + return [self.imageCache diskImageExistsWithKey:key]; +} + +- (BOOL)diskImageExistsForURL:(NSURL *)url { + NSString *key = [self cacheKeyForURL:url]; + return [self.imageCache diskImageExistsWithKey:key]; +} + +- (void)cachedImageExistsForURL:(NSURL *)url + completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { + NSString *key = [self cacheKeyForURL:url]; + + BOOL isInMemoryCache = ([self.imageCache imageFromMemoryCacheForKey:key] != nil); + + if (isInMemoryCache) { + // making sure we call the completion block on the main queue + dispatch_async(dispatch_get_main_queue(), ^{ + if (completionBlock) { + completionBlock(YES); + } + }); + return; + } + + [self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) { + // the completion block of checkDiskCacheForImageWithKey:completion: is always called on the main queue, no need to further dispatch + if (completionBlock) { + completionBlock(isInDiskCache); + } + }]; +} + +- (void)diskImageExistsForURL:(NSURL *)url + completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { + NSString *key = [self cacheKeyForURL:url]; + + [self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) { + // the completion block of checkDiskCacheForImageWithKey:completion: is always called on the main queue, no need to further dispatch + if (completionBlock) { + completionBlock(isInDiskCache); + } + }]; +} + +- (id )downloadImageWithURL:(NSURL *)url + options:(SDWebImageOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageCompletionWithFinishedBlock)completedBlock { + // Invoking this method without a completedBlock is pointless + NSParameterAssert(completedBlock); + + // Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't + // throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString. + if ([url isKindOfClass:NSString.class]) { + url = [NSURL URLWithString:(NSString *)url]; + } + + // Prevents app crashing on argument type error like sending NSNull instead of NSURL + if (![url isKindOfClass:NSURL.class]) { + url = nil; + } + + __block SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new]; + __weak SDWebImageCombinedOperation *weakOperation = operation; + + BOOL isFailedUrl = NO; + @synchronized (self.failedURLs) { + isFailedUrl = [self.failedURLs containsObject:url]; + } + + if (!url || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { + dispatch_main_sync_safe(^{ + NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; + completedBlock(nil, error, SDImageCacheTypeNone, YES, url); + }); + return operation; + } + + @synchronized (self.runningOperations) { + [self.runningOperations addObject:operation]; + } + NSString *key = [self cacheKeyForURL:url]; + + operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) { + if (operation.isCancelled) { + @synchronized (self.runningOperations) { + [self.runningOperations removeObject:operation]; + } + + return; + } + + if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { + if (image && options & SDWebImageRefreshCached) { + dispatch_main_sync_safe(^{ + // If image was found in the cache bug SDWebImageRefreshCached is provided, notify about the cached image + // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. + completedBlock(image, nil, cacheType, YES, url); + }); + } + + // download if no image or requested to refresh anyway, and download allowed by delegate + SDWebImageDownloaderOptions downloaderOptions = 0; + if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority; + if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload; + if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache; + if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground; + if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies; + if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates; + if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority; + if (image && options & SDWebImageRefreshCached) { + // force progressive off if image already cached but forced refreshing + downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload; + // ignore image read from NSURLCache if image if cached but force refreshing + downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; + } + id subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { + if (weakOperation.isCancelled) { + // Do nothing if the operation was cancelled + // See #699 for more details + // if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data + } + else if (error) { + dispatch_main_sync_safe(^{ + if (!weakOperation.isCancelled) { + completedBlock(nil, error, SDImageCacheTypeNone, finished, url); + } + }); + + if (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut) { + @synchronized (self.failedURLs) { + [self.failedURLs addObject:url]; + } + } + } + else { + BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly); + + if (options & SDWebImageRefreshCached && image && !downloadedImage) { + // Image refresh hit the NSURLCache cache, do not call the completion block + } + // NOTE: We don't call transformDownloadedImage delegate method on animated images as most transformation code would mangle it + else if (downloadedImage && !downloadedImage.images && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) { + dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ + UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url]; + + if (transformedImage && finished) { + BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage]; + [self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imageData:data forKey:key toDisk:cacheOnDisk]; + } + + dispatch_main_sync_safe(^{ + if (!weakOperation.isCancelled) { + completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); + } + }); + }); + } + else { + if (downloadedImage && finished) { + [self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk]; + } + + dispatch_main_sync_safe(^{ + if (!weakOperation.isCancelled) { + completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); + } + }); + } + } + + if (finished) { + @synchronized (self.runningOperations) { + [self.runningOperations removeObject:operation]; + } + } + }]; + operation.cancelBlock = ^{ + [subOperation cancel]; + + @synchronized (self.runningOperations) { + [self.runningOperations removeObject:weakOperation]; + } + }; + } + else if (image) { + dispatch_main_sync_safe(^{ + if (!weakOperation.isCancelled) { + completedBlock(image, nil, cacheType, YES, url); + } + }); + @synchronized (self.runningOperations) { + [self.runningOperations removeObject:operation]; + } + } + else { + // Image not in cache and download disallowed by delegate + dispatch_main_sync_safe(^{ + if (!weakOperation.isCancelled) { + completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); + } + }); + @synchronized (self.runningOperations) { + [self.runningOperations removeObject:operation]; + } + } + }]; + + return operation; +} + +- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url { + if (image && url) { + NSString *key = [self cacheKeyForURL:url]; + [self.imageCache storeImage:image forKey:key toDisk:YES]; + } +} + +- (void)cancelAll { + @synchronized (self.runningOperations) { + [self.runningOperations makeObjectsPerformSelector:@selector(cancel)]; + [self.runningOperations removeAllObjects]; + } +} + +- (BOOL)isRunning { + return self.runningOperations.count > 0; +} + +@end + + +@implementation SDWebImageCombinedOperation + +- (void)setCancelBlock:(SDWebImageNoParamsBlock)cancelBlock { + // check if the operation is already cancelled, then we just call the cancelBlock + if (self.isCancelled) { + if (cancelBlock) { + cancelBlock(); + } + _cancelBlock = nil; // don't forget to nil the cancelBlock, otherwise we will get crashes + } else { + _cancelBlock = [cancelBlock copy]; + } +} + +- (void)cancel { + self.cancelled = YES; + if (self.cacheOperation) { + [self.cacheOperation cancel]; + self.cacheOperation = nil; + } + if (self.cancelBlock) { + self.cancelBlock(); + + // TODO: this is a temporary fix to #809. + // Until we can figure the exact cause of the crash, going with the ivar instead of the setter +// self.cancelBlock = nil; + _cancelBlock = nil; + } +} + +@end + + +@implementation SDWebImageManager (Deprecated) + +// deprecated method, uses the non deprecated method +// adapter for the completion block +- (id )downloadWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedWithFinishedBlock)completedBlock { + return [self downloadImageWithURL:url + options:options + progress:progressBlock + completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType, finished); + } + }]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageOperation.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageOperation.h new file mode 100644 index 0000000..71094ee --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImageOperation.h @@ -0,0 +1,15 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import + +@protocol SDWebImageOperation + +- (void)cancel; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h new file mode 100644 index 0000000..4f14fa2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.h @@ -0,0 +1,98 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageManager.h" + +@class SDWebImagePrefetcher; + +@protocol SDWebImagePrefetcherDelegate + +@optional + +/** + * Called when an image was prefetched. + * + * @param imagePrefetcher The current image prefetcher + * @param imageURL The image url that was prefetched + * @param finishedCount The total number of images that were prefetched (successful or not) + * @param totalCount The total number of images that were to be prefetched + */ +- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount; + +/** + * Called when all images are prefetched. + * @param imagePrefetcher The current image prefetcher + * @param totalCount The total number of images that were prefetched (whether successful or not) + * @param skippedCount The total number of images that were skipped + */ +- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount; + +@end + +typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls); +typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls); + +/** + * Prefetch some URLs in the cache for future use. Images are downloaded in low priority. + */ +@interface SDWebImagePrefetcher : NSObject + +/** + * The web image manager + */ +@property (strong, nonatomic, readonly) SDWebImageManager *manager; + +/** + * Maximum number of URLs to prefetch at the same time. Defaults to 3. + */ +@property (nonatomic, assign) NSUInteger maxConcurrentDownloads; + +/** + * SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority. + */ +@property (nonatomic, assign) SDWebImageOptions options; + +@property (weak, nonatomic) id delegate; + +/** + * Return the global image prefetcher instance. + */ ++ (SDWebImagePrefetcher *)sharedImagePrefetcher; + +/** + * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, + * currently one image is downloaded at a time, + * and skips images for failed downloads and proceed to the next image in the list + * + * @param urls list of URLs to prefetch + */ +- (void)prefetchURLs:(NSArray *)urls; + +/** + * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, + * currently one image is downloaded at a time, + * and skips images for failed downloads and proceed to the next image in the list + * + * @param urls list of URLs to prefetch + * @param progressBlock block to be called when progress updates; + * first parameter is the number of completed (successful or not) requests, + * second parameter is the total number of images originally requested to be prefetched + * @param completionBlock block to be called when prefetching is completed + * first param is the number of completed (successful or not) requests, + * second parameter is the number of skipped requests + */ +- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock; + +/** + * Remove and cancel queued list + */ +- (void)cancelPrefetching; + + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m new file mode 100644 index 0000000..4087e4a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/SDWebImagePrefetcher.m @@ -0,0 +1,138 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImagePrefetcher.h" + +#if !defined(DEBUG) && !defined (SD_VERBOSE) +#define NSLog(...) +#endif + +@interface SDWebImagePrefetcher () + +@property (strong, nonatomic) SDWebImageManager *manager; +@property (strong, nonatomic) NSArray *prefetchURLs; +@property (assign, nonatomic) NSUInteger requestedCount; +@property (assign, nonatomic) NSUInteger skippedCount; +@property (assign, nonatomic) NSUInteger finishedCount; +@property (assign, nonatomic) NSTimeInterval startedTime; +@property (copy, nonatomic) SDWebImagePrefetcherCompletionBlock completionBlock; +@property (copy, nonatomic) SDWebImagePrefetcherProgressBlock progressBlock; + +@end + +@implementation SDWebImagePrefetcher + ++ (SDWebImagePrefetcher *)sharedImagePrefetcher { + static dispatch_once_t once; + static id instance; + dispatch_once(&once, ^{ + instance = [self new]; + }); + return instance; +} + +- (id)init { + if ((self = [super init])) { + _manager = [SDWebImageManager new]; + _options = SDWebImageLowPriority; + self.maxConcurrentDownloads = 3; + } + return self; +} + +- (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads { + self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads; +} + +- (NSUInteger)maxConcurrentDownloads { + return self.manager.imageDownloader.maxConcurrentDownloads; +} + +- (void)startPrefetchingAtIndex:(NSUInteger)index { + if (index >= self.prefetchURLs.count) return; + self.requestedCount++; + [self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!finished) return; + self.finishedCount++; + + if (image) { + if (self.progressBlock) { + self.progressBlock(self.finishedCount,[self.prefetchURLs count]); + } + NSLog(@"Prefetched %@ out of %@", @(self.finishedCount), @(self.prefetchURLs.count)); + } + else { + if (self.progressBlock) { + self.progressBlock(self.finishedCount,[self.prefetchURLs count]); + } + NSLog(@"Prefetched %@ out of %@ (Failed)", @(self.finishedCount), @(self.prefetchURLs.count)); + + // Add last failed + self.skippedCount++; + } + if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) { + [self.delegate imagePrefetcher:self + didPrefetchURL:self.prefetchURLs[index] + finishedCount:self.finishedCount + totalCount:self.prefetchURLs.count + ]; + } + + if (self.prefetchURLs.count > self.requestedCount) { + dispatch_async(dispatch_get_main_queue(), ^{ + [self startPrefetchingAtIndex:self.requestedCount]; + }); + } + else if (self.finishedCount == self.requestedCount) { + [self reportStatus]; + if (self.completionBlock) { + self.completionBlock(self.finishedCount, self.skippedCount); + self.completionBlock = nil; + } + } + }]; +} + +- (void)reportStatus { + NSUInteger total = [self.prefetchURLs count]; + NSLog(@"Finished prefetching (%@ successful, %@ skipped, timeElasped %.2f)", @(total - self.skippedCount), @(self.skippedCount), CFAbsoluteTimeGetCurrent() - self.startedTime); + if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) { + [self.delegate imagePrefetcher:self + didFinishWithTotalCount:(total - self.skippedCount) + skippedCount:self.skippedCount + ]; + } +} + +- (void)prefetchURLs:(NSArray *)urls { + [self prefetchURLs:urls progress:nil completed:nil]; +} + +- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock { + [self cancelPrefetching]; // Prevent duplicate prefetch request + self.startedTime = CFAbsoluteTimeGetCurrent(); + self.prefetchURLs = urls; + self.completionBlock = completionBlock; + self.progressBlock = progressBlock; + + // Starts prefetching from the very first image on the list with the max allowed concurrency + NSUInteger listCount = self.prefetchURLs.count; + for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { + [self startPrefetchingAtIndex:i]; + } +} + +- (void)cancelPrefetching { + self.prefetchURLs = nil; + self.skippedCount = 0; + self.requestedCount = 0; + self.finishedCount = 0; + [self.manager cancelAll]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h new file mode 100644 index 0000000..7a6e867 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.h @@ -0,0 +1,229 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIButtonView. + */ +@interface UIButton (WebCache) + +/** + * Get the current image URL. + */ +- (NSURL *)sd_currentImageURL; + +/** + * Get the image URL for a control state. + * + * @param state Which state you want to know the URL for. The values are described in UIControlState. + */ +- (NSURL *)sd_imageURLForState:(UIControlState)state; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state; + +/** + * Set the imageView `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the backgroundImageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state; + +/** + * Set the backgroundImageView `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; + +/** + * Set the backgroundImageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +/** + * Set the backgroundImageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the backgroundImageView `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param state The state that uses the specified title. The values are described in UIControlState. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the backgroundImageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Cancel the current image download + */ +- (void)sd_cancelImageLoadForState:(UIControlState)state; + +/** + * Cancel the current backgroundImage download + */ +- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state; + +@end + + +@interface UIButton (WebCacheDeprecated) + +- (NSURL *)currentImageURL __deprecated_msg("Use `sd_currentImageURL`"); +- (NSURL *)imageURLForState:(UIControlState)state __deprecated_msg("Use `sd_imageURLForState:`"); + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:`"); + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:completed:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:completed:`"); +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:completed:`"); + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:`"); + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:completed:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:completed:`"); +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:completed:`"); + +- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelImageLoadForState:`"); +- (void)cancelBackgroundImageLoadForState:(UIControlState)state __deprecated_msg("Use `sd_cancelBackgroundImageLoadForState:`"); + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.m new file mode 100644 index 0000000..8e076ae --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIButton+WebCache.m @@ -0,0 +1,260 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIButton+WebCache.h" +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" + +static char imageURLStorageKey; + +@implementation UIButton (WebCache) + +- (NSURL *)sd_currentImageURL { + NSURL *url = self.imageURLStorage[@(self.state)]; + + if (!url) { + url = self.imageURLStorage[@(UIControlStateNormal)]; + } + + return url; +} + +- (NSURL *)sd_imageURLForState:(UIControlState)state { + return self.imageURLStorage[@(state)]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + + [self setImage:placeholder forState:state]; + [self sd_cancelImageLoadForState:state]; + + if (!url) { + [self.imageURLStorage removeObjectForKey:@(state)]; + + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + + return; + } + + self.imageURLStorage[@(state)] = url; + + __weak UIButton *wself = self; + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe(^{ + __strong UIButton *sself = wself; + if (!sself) return; + if (image) { + [sself setImage:image forState:state]; + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; + [self sd_setImageLoadOperation:operation forState:state]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock]; +} + +- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_cancelImageLoadForState:state]; + + [self setBackgroundImage:placeholder forState:state]; + + if (url) { + __weak UIButton *wself = self; + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe(^{ + __strong UIButton *sself = wself; + if (!sself) return; + if (image) { + [sself setBackgroundImage:image forState:state]; + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; + [self sd_setBackgroundImageLoadOperation:operation forState:state]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + } +} + +- (void)sd_setImageLoadOperation:(id)operation forState:(UIControlState)state { + [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; +} + +- (void)sd_cancelImageLoadForState:(UIControlState)state { + [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]]; +} + +- (void)sd_setBackgroundImageLoadOperation:(id)operation forState:(UIControlState)state { + [self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; +} + +- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state { + [self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]]; +} + +- (NSMutableDictionary *)imageURLStorage { + NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey); + if (!storage) + { + storage = [NSMutableDictionary dictionary]; + objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + } + + return storage; +} + +@end + + +@implementation UIButton (WebCacheDeprecated) + +- (NSURL *)currentImageURL { + return [self sd_currentImageURL]; +} + +- (NSURL *)imageURLForState:(UIControlState)state { + return [self sd_imageURLForState:state]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)cancelCurrentImageLoad { + // in a backwards compatible manner, cancel for current state + [self sd_cancelImageLoadForState:self.state]; +} + +- (void)cancelBackgroundImageLoadForState:(UIControlState)state { + [self sd_cancelBackgroundImageLoadForState:state]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.h new file mode 100755 index 0000000..084f424 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.h @@ -0,0 +1,19 @@ +// +// UIImage+GIF.h +// LBGIFImage +// +// Created by Laurin Brandner on 06.01.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import + +@interface UIImage (GIF) + ++ (UIImage *)sd_animatedGIFNamed:(NSString *)name; + ++ (UIImage *)sd_animatedGIFWithData:(NSData *)data; + +- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.m new file mode 100755 index 0000000..a703637 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+GIF.m @@ -0,0 +1,158 @@ +// +// UIImage+GIF.m +// LBGIFImage +// +// Created by Laurin Brandner on 06.01.12. +// Copyright (c) 2012 __MyCompanyName__. All rights reserved. +// + +#import "UIImage+GIF.h" +#import + +@implementation UIImage (GIF) + ++ (UIImage *)sd_animatedGIFWithData:(NSData *)data { + if (!data) { + return nil; + } + + CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL); + + size_t count = CGImageSourceGetCount(source); + + UIImage *animatedImage; + + if (count <= 1) { + animatedImage = [[UIImage alloc] initWithData:data]; + } + else { + NSMutableArray *images = [NSMutableArray array]; + + NSTimeInterval duration = 0.0f; + + for (size_t i = 0; i < count; i++) { + CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL); + + duration += [self sd_frameDurationAtIndex:i source:source]; + + [images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]]; + + CGImageRelease(image); + } + + if (!duration) { + duration = (1.0f / 10.0f) * count; + } + + animatedImage = [UIImage animatedImageWithImages:images duration:duration]; + } + + CFRelease(source); + + return animatedImage; +} + ++ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source { + float frameDuration = 0.1f; + CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil); + NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties; + NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary]; + + NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime]; + if (delayTimeUnclampedProp) { + frameDuration = [delayTimeUnclampedProp floatValue]; + } + else { + + NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime]; + if (delayTimeProp) { + frameDuration = [delayTimeProp floatValue]; + } + } + + // Many annoying ads specify a 0 duration to make an image flash as quickly as possible. + // We follow Firefox's behavior and use a duration of 100 ms for any frames that specify + // a duration of <= 10 ms. See and + // for more information. + + if (frameDuration < 0.011f) { + frameDuration = 0.100f; + } + + CFRelease(cfFrameProperties); + return frameDuration; +} + ++ (UIImage *)sd_animatedGIFNamed:(NSString *)name { + CGFloat scale = [UIScreen mainScreen].scale; + + if (scale > 1.0f) { + NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"]; + + NSData *data = [NSData dataWithContentsOfFile:retinaPath]; + + if (data) { + return [UIImage sd_animatedGIFWithData:data]; + } + + NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; + + data = [NSData dataWithContentsOfFile:path]; + + if (data) { + return [UIImage sd_animatedGIFWithData:data]; + } + + return [UIImage imageNamed:name]; + } + else { + NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"]; + + NSData *data = [NSData dataWithContentsOfFile:path]; + + if (data) { + return [UIImage sd_animatedGIFWithData:data]; + } + + return [UIImage imageNamed:name]; + } +} + +- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size { + if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) { + return self; + } + + CGSize scaledSize = size; + CGPoint thumbnailPoint = CGPointZero; + + CGFloat widthFactor = size.width / self.size.width; + CGFloat heightFactor = size.height / self.size.height; + CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor; + scaledSize.width = self.size.width * scaleFactor; + scaledSize.height = self.size.height * scaleFactor; + + if (widthFactor > heightFactor) { + thumbnailPoint.y = (size.height - scaledSize.height) * 0.5; + } + else if (widthFactor < heightFactor) { + thumbnailPoint.x = (size.width - scaledSize.width) * 0.5; + } + + NSMutableArray *scaledImages = [NSMutableArray array]; + + UIGraphicsBeginImageContextWithOptions(size, NO, 0.0); + + for (UIImage *image in self.images) { + [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; + UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); + + [scaledImages addObject:newImage]; + } + + UIGraphicsEndImageContext(); + + return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.h new file mode 100644 index 0000000..186ebc0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.h @@ -0,0 +1,15 @@ +// +// UIImage+MultiFormat.h +// SDWebImage +// +// Created by Olivier Poitrey on 07/06/13. +// Copyright (c) 2013 Dailymotion. All rights reserved. +// + +#import + +@interface UIImage (MultiFormat) + ++ (UIImage *)sd_imageWithData:(NSData *)data; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.m new file mode 100644 index 0000000..5395280 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImage+MultiFormat.m @@ -0,0 +1,114 @@ +// +// UIImage+MultiFormat.m +// SDWebImage +// +// Created by Olivier Poitrey on 07/06/13. +// Copyright (c) 2013 Dailymotion. All rights reserved. +// + +#import "UIImage+MultiFormat.h" +#import "UIImage+GIF.h" +#import "NSData+ImageContentType.h" +#import + +#ifdef SD_WEBP +#import "UIImage+WebP.h" +#endif + +@implementation UIImage (MultiFormat) + ++ (UIImage *)sd_imageWithData:(NSData *)data { + UIImage *image; + NSString *imageContentType = [NSData sd_contentTypeForImageData:data]; + if ([imageContentType isEqualToString:@"image/gif"]) { + image = [UIImage sd_animatedGIFWithData:data]; + } +#ifdef SD_WEBP + else if ([imageContentType isEqualToString:@"image/webp"]) + { + image = [UIImage sd_imageWithWebPData:data]; + } +#endif + else { + image = [[UIImage alloc] initWithData:data]; + UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data]; + if (orientation != UIImageOrientationUp) { + image = [UIImage imageWithCGImage:image.CGImage + scale:image.scale + orientation:orientation]; + } + } + + + return image; +} + + ++(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData { + UIImageOrientation result = UIImageOrientationUp; + CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL); + if (imageSource) { + CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL); + if (properties) { + CFTypeRef val; + int exifOrientation; + val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation); + if (val) { + CFNumberGetValue(val, kCFNumberIntType, &exifOrientation); + result = [self sd_exifOrientationToiOSOrientation:exifOrientation]; + } // else - if it's not set it remains at up + CFRelease((CFTypeRef) properties); + } else { + //NSLog(@"NO PROPERTIES, FAIL"); + } + CFRelease(imageSource); + } + return result; +} + +#pragma mark EXIF orientation tag converter +// Convert an EXIF image orientation to an iOS one. +// reference see here: http://sylvana.net/jpegcrop/exif_orientation.html ++ (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation { + UIImageOrientation orientation = UIImageOrientationUp; + switch (exifOrientation) { + case 1: + orientation = UIImageOrientationUp; + break; + + case 3: + orientation = UIImageOrientationDown; + break; + + case 8: + orientation = UIImageOrientationLeft; + break; + + case 6: + orientation = UIImageOrientationRight; + break; + + case 2: + orientation = UIImageOrientationUpMirrored; + break; + + case 4: + orientation = UIImageOrientationDownMirrored; + break; + + case 5: + orientation = UIImageOrientationLeftMirrored; + break; + + case 7: + orientation = UIImageOrientationRightMirrored; + break; + default: + break; + } + return orientation; +} + + + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h new file mode 100644 index 0000000..6b00366 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.h @@ -0,0 +1,100 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageCompat.h" +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state. + */ +@interface UIImageView (HighlightedWebCache) + +/** + * Set the imageView `highlightedImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setHighlightedImageWithURL:(NSURL *)url; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options; + +/** + * Set the imageView `highlightedImage` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `highlightedImage` with an `url` and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Cancel the current download + */ +- (void)sd_cancelCurrentHighlightedImageLoad; + +@end + + +@interface UIImageView (HighlightedWebCacheDeprecated) + +- (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`"); +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`"); + +- (void)cancelCurrentHighlightedImageLoad __deprecated_msg("Use `sd_cancelCurrentHighlightedImageLoad`"); + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.m new file mode 100644 index 0000000..ae73610 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+HighlightedWebCache.m @@ -0,0 +1,107 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImageView+HighlightedWebCache.h" +#import "UIView+WebCacheOperation.h" + +#define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage" + +@implementation UIImageView (HighlightedWebCache) + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; +} + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; +} + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_cancelCurrentHighlightedImageLoad]; + + if (url) { + __weak UIImageView *wself = self; + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe (^ + { + if (!wself) return; + if (image) { + wself.highlightedImage = image; + [wself setNeedsLayout]; + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; + [self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + } +} + +- (void)sd_cancelCurrentHighlightedImageLoad { + [self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey]; +} + +@end + + +@implementation UIImageView (HighlightedWebCacheDeprecated) + +- (void)setHighlightedImageWithURL:(NSURL *)url { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)cancelCurrentHighlightedImageLoad { + [self sd_cancelCurrentHighlightedImageLoad]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h new file mode 100644 index 0000000..717d393 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.h @@ -0,0 +1,201 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "SDWebImageCompat.h" +#import "SDWebImageManager.h" + +/** + * Integrates SDWebImage async downloading and caching of remote images with UIImageView. + * + * Usage with a UITableViewCell sub-class: + * + * @code + +#import + +... + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + static NSString *MyIdentifier = @"MyIdentifier"; + + UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; + + if (cell == nil) { + cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] + autorelease]; + } + + // Here we use the provided sd_setImageWithURL: method to load the web image + // Ensure you use a placeholder image otherwise cells will be initialized with no image + [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"] + placeholderImage:[UIImage imageNamed:@"placeholder"]]; + + cell.textLabel.text = @"My Text"; + return cell; +} + + * @endcode + */ +@interface UIImageView (WebCache) + +/** + * Get the current image URL. + * + * Note that because of the limitations of categories this property can get out of sync + * if you use sd_setImage: directly. + */ +- (NSURL *)sd_imageURL; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + */ +- (void)sd_setImageWithURL:(NSURL *)url; + +/** + * Set the imageView `image` with an `url` and a placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @see sd_setImageWithURL:placeholderImage:options: + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options; + +/** + * Set the imageView `image` with an `url`. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url`, placeholder and custom options. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Set the imageView `image` with an `url` and a optionaly placeholder image. + * + * The download is asynchronous and cached. + * + * @param url The url for the image. + * @param placeholder The image to be set initially, until the image request finishes. + * @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values. + * @param progressBlock A block called while image is downloading + * @param completedBlock A block called when operation has been completed. This block has no return value + * and takes the requested UIImage as first parameter. In case of error the image parameter + * is nil and the second parameter may contain an NSError. The third parameter is a Boolean + * indicating if the image was retrived from the local cache of from the network. + * The forth parameter is the original image url. + */ +- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; + +/** + * Download an array of images and starts them in an animation loop + * + * @param arrayOfURLs An array of NSURL + */ +- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs; + +/** + * Cancel the current download + */ +- (void)sd_cancelCurrentImageLoad; + +- (void)sd_cancelCurrentAnimationImagesLoad; + +@end + + +@interface UIImageView (WebCacheDeprecated) + +- (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`"); + +- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options`"); + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`"); +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:progress:completed:`"); + +- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs __deprecated_msg("Use `sd_setAnimationImagesWithURLs:`"); + +- (void)cancelCurrentArrayLoad __deprecated_msg("Use `sd_cancelCurrentAnimationImagesLoad`"); + +- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`"); + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m new file mode 100644 index 0000000..51663dd --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIImageView+WebCache.m @@ -0,0 +1,195 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIImageView+WebCache.h" +#import "objc/runtime.h" +#import "UIView+WebCacheOperation.h" + +static char imageURLKey; + +@implementation UIImageView (WebCache) + +- (void)sd_setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock]; +} + +- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { + [self sd_cancelCurrentImageLoad]; + objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + + if (!(options & SDWebImageDelayPlaceholder)) { + self.image = placeholder; + } + + if (url) { + __weak UIImageView *wself = self; + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe(^{ + if (!wself) return; + if (image) { + wself.image = image; + [wself setNeedsLayout]; + } else { + if ((options & SDWebImageDelayPlaceholder)) { + wself.image = placeholder; + [wself setNeedsLayout]; + } + } + if (completedBlock && finished) { + completedBlock(image, error, cacheType, url); + } + }); + }]; + [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"]; + } else { + dispatch_main_async_safe(^{ + NSError *error = [NSError errorWithDomain:@"SDWebImageErrorDomain" code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; + if (completedBlock) { + completedBlock(nil, error, SDImageCacheTypeNone, url); + } + }); + } +} + +- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { + NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; + UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; + + [self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock]; +} + +- (NSURL *)sd_imageURL { + return objc_getAssociatedObject(self, &imageURLKey); +} + +- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { + [self sd_cancelCurrentAnimationImagesLoad]; + __weak UIImageView *wself = self; + + NSMutableArray *operationsArray = [[NSMutableArray alloc] init]; + + for (NSURL *logoImageURL in arrayOfURLs) { + id operation = [SDWebImageManager.sharedManager downloadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { + if (!wself) return; + dispatch_main_sync_safe(^{ + __strong UIImageView *sself = wself; + [sself stopAnimating]; + if (sself && image) { + NSMutableArray *currentImages = [[sself animationImages] mutableCopy]; + if (!currentImages) { + currentImages = [[NSMutableArray alloc] init]; + } + [currentImages addObject:image]; + + sself.animationImages = currentImages; + [sself setNeedsLayout]; + } + [sself startAnimating]; + }); + }]; + [operationsArray addObject:operation]; + } + + [self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"]; +} + +- (void)sd_cancelCurrentImageLoad { + [self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"]; +} + +- (void)sd_cancelCurrentAnimationImagesLoad { + [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"]; +} + +@end + + +@implementation UIImageView (WebCacheDeprecated) + +- (NSURL *)imageURL { + return [self sd_imageURL]; +} + +- (void)setImageWithURL:(NSURL *)url { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil]; +} + +- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { + [self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) { + if (completedBlock) { + completedBlock(image, error, cacheType); + } + }]; +} + +- (void)cancelCurrentArrayLoad { + [self sd_cancelCurrentAnimationImagesLoad]; +} + +- (void)cancelCurrentImageLoad { + [self sd_cancelCurrentImageLoad]; +} + +- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs { + [self sd_setAnimationImagesWithURLs:arrayOfURLs]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.h b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.h new file mode 100644 index 0000000..6719036 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.h @@ -0,0 +1,36 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import +#import "SDWebImageManager.h" + +@interface UIView (WebCacheOperation) + +/** + * Set the image load operation (storage in a UIView based dictionary) + * + * @param operation the operation + * @param key key for storing the operation + */ +- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key; + +/** + * Cancel all operations for the current UIView and key + * + * @param key key for identifying the operations + */ +- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key; + +/** + * Just remove the operations corresponding to the current UIView and key without cancelling them + * + * @param key key for identifying the operations + */ +- (void)sd_removeImageLoadOperationWithKey:(NSString *)key; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.m b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.m new file mode 100644 index 0000000..9219478 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SDWebImage/SDWebImage/UIView+WebCacheOperation.m @@ -0,0 +1,55 @@ +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +#import "UIView+WebCacheOperation.h" +#import "objc/runtime.h" + +static char loadOperationKey; + +@implementation UIView (WebCacheOperation) + +- (NSMutableDictionary *)operationDictionary { + NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey); + if (operations) { + return operations; + } + operations = [NSMutableDictionary dictionary]; + objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + return operations; +} + +- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key { + [self sd_cancelImageLoadOperationWithKey:key]; + NSMutableDictionary *operationDictionary = [self operationDictionary]; + [operationDictionary setObject:operation forKey:key]; +} + +- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key { + // Cancel in progress downloader from queue + NSMutableDictionary *operationDictionary = [self operationDictionary]; + id operations = [operationDictionary objectForKey:key]; + if (operations) { + if ([operations isKindOfClass:[NSArray class]]) { + for (id operation in operations) { + if (operation) { + [operation cancel]; + } + } + } else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){ + [(id) operations cancel]; + } + [operationDictionary removeObjectForKey:key]; + } +} + +- (void)sd_removeImageLoadOperationWithKey:(NSString *)key { + NSMutableDictionary *operationDictionary = [self operationDictionary]; + [operationDictionary removeObjectForKey:key]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/LICENSE.txt b/iOSStudy/iOSStudy/Pods/SVProgressHUD/LICENSE.txt new file mode 100644 index 0000000..5bcd8b4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/LICENSE.txt @@ -0,0 +1,26 @@ +Copyright (c) 2011-2014 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +A different license may apply to other resources included in this package, +including Freepik Icons. Please consult their +respective headers for the terms of their individual licenses. \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/README.md b/iOSStudy/iOSStudy/Pods/SVProgressHUD/README.md new file mode 100644 index 0000000..214d2a4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/README.md @@ -0,0 +1,137 @@ +# SVProgressHUD + +`SVProgressHUD` is a clean and easy-to-use HUD meant to display the progress of an ongoing task. + +![SVProgressHUD](http://f.cl.ly/items/2G1F1Z0M0k0h2U3V1p39/SVProgressHUD.gif) + +## Installation + +### From CocoaPods + +[CocoaPods](http://cocoapods.org) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries like `SVProgressHUD` in your projects. Simply add the following line to your [Podfile](http://guides.cocoapods.org/using/using-cocoapods.html): + +```ruby +pod 'SVProgressHUD' +``` + +If you want to use the latest features of `SVProgressHUD` add `:head`: + +```ruby +pod 'SVProgressHUD', :head +``` + +This pulls from the `master` branch directly. We are usually careful about what we push there and this is the version we use ourselves in all of our projects. + +### Manually + +* Drag the `SVProgressHUD/SVProgressHUD` folder into your project. +* Take care that `SVProgressHUD.bundle` is added to `Targets->Build Phases->Copy Bundle Resources`. +* Add the **QuartzCore** framework to your project. + +## Usage + +(see sample Xcode project in `/Demo`) + +`SVProgressHUD` is created as a singleton (i.e. it doesn't need to be explicitly allocated and instantiated; you directly call `[SVProgressHUD method]`). + +**Use `SVProgressHUD` wisely! Only use it if you absolutely need to perform a task before taking the user forward. Bad use case examples: pull to refresh, infinite scrolling, sending message.** + +Using `SVProgressHUD` in your app will usually look as simple as this (using Grand Central Dispatch): + +```objective-c +[SVProgressHUD show]; +dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ + // time-consuming task + dispatch_async(dispatch_get_main_queue(), ^{ + [SVProgressHUD dismiss]; + }); +}); +``` + +### Showing the HUD + +You can show the status of indeterminate tasks using one of the following: + +```objective-c ++ (void)show; ++ (void)showWithMaskType:(SVProgressHUDMaskType)maskType; ++ (void)showWithStatus:(NSString*)string; ++ (void)showWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType; +``` + +If you'd like the HUD to reflect the progress of a task, use one of these: + +```objective-c ++ (void)showProgress:(CGFloat)progress; ++ (void)showProgress:(CGFloat)progress status:(NSString*)status; ++ (void)showProgress:(CGFloat)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; +``` + +### Dismissing the HUD + +It can be dismissed right away using: + +```objective-c ++ (void)dismiss; +``` + +If you'd like to stack HUDs, you can balance out every show call using: + +```objective-c ++ (void)popActivity; +``` + +The HUD will get dismissed once the `popActivity` calls will match the number of show calls. + +Or show a confirmation glyph before before getting dismissed a little bit later. The display time depends on the length of the given string (between 0.5 and 5 seconds). + +```objective-c ++ (void)showInfoWithStatus:(NSString *)string; ++ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType; ++ (void)showSuccessWithStatus:(NSString*)string; ++ (void)showSuccessWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType; ++ (void)showErrorWithStatus:(NSString *)string; ++ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType; ++ (void)showImage:(UIImage*)image status:(NSString*)string; ++ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; +``` + +## Customization + +`SVProgressHUD` can be customized via the following methods: + +```objective-c ++ (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor] ++ (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor] ++ (void)setRingThickness:(CGFloat)width; // default is 4 pt ++ (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] ++ (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik ++ (void)setSuccessImage:(UIImage*)image; // default is bundled success image from Freepik ++ (void)setErrorImage:(UIImage*)image; // default is bundled error image from Freepik ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone +``` + +## Notifications + +`SVProgressHUD` posts four notifications via `NSNotificationCenter` in response to being shown/dismissed: +* `SVProgressHUDWillAppearNotification` when the show animation starts +* `SVProgressHUDDidAppearNotification` when the show animation completes +* `SVProgressHUDWillDisappearNotification` when the dismiss animation starts +* `SVProgressHUDDidDisappearNotification` when the dismiss animation completes + +Each notification passes a `userInfo` dictionary holding the HUD's status string (if any), retrievable via `SVProgressHUDStatusUserInfoKey`. + +`SVProgressHUD` also posts `SVProgressHUDDidReceiveTouchEventNotification` when users touch on the overall screen or `SVProgressHUDDidTouchDownInsideNotification` when a user touches on the HUD directly. For this notifications `userInfo` is not passed but the object parameter contains the `UIEvent` that related to the touch. + +## Contributing to this project + +If you have feature requests or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/samvermette/SVProgressHUD/issues/new). Please take a moment to +review the guidelines written by [Nicolas Gallagher](https://github.com/necolas/): + +* [Bug reports](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#bugs) +* [Feature requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#features) +* [Pull requests](https://github.com/necolas/issue-guidelines/blob/master/CONTRIBUTING.md#pull-requests) + +## Credits + +`SVProgressHUD` is brought to you by [Sam Vermette](http://samvermette.com) and [contributors to the project](https://github.com/samvermette/SVProgressHUD/contributors). If you're using `SVProgressHUD` in your project, attribution would be very appreciated. The info, success and error icons are made by [Freepik](http://www.freepik.com) from [Flaticon](www.flaticon.com) and are licensed under [Creative Commons BY 3.0](http://creativecommons.org/licenses/by/3.0/). diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h new file mode 100644 index 0000000..734f9e7 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.h @@ -0,0 +1,18 @@ +// +// SVIndefiniteAnimatedView.h +// SVProgressHUD +// +// Created by Guillaume Campagna on 2014-12-05. +// +// + +#import + +@interface SVIndefiniteAnimatedView : UIView + +@property (nonatomic, assign) CGFloat strokeThickness; +@property (nonatomic, assign) CGFloat radius; +@property (nonatomic, strong) UIColor *strokeColor; + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m new file mode 100644 index 0000000..7cad180 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVIndefiniteAnimatedView.m @@ -0,0 +1,131 @@ +// +// SVIndefiniteAnimatedView.m +// SVProgressHUD +// +// Created by Guillaume Campagna on 2014-12-05. +// +// + +#import "SVIndefiniteAnimatedView.h" + +#pragma mark SVIndefiniteAnimatedView + +@interface SVIndefiniteAnimatedView () + +@property (nonatomic, strong) CAShapeLayer *indefiniteAnimatedLayer; + +@end + +@implementation SVIndefiniteAnimatedView + +- (void)willMoveToSuperview:(UIView *)newSuperview { + if (newSuperview) { + [self layoutAnimatedLayer]; + } else { + [_indefiniteAnimatedLayer removeFromSuperlayer]; + _indefiniteAnimatedLayer = nil; + } +} + +- (void)layoutAnimatedLayer { + CALayer *layer = self.indefiniteAnimatedLayer; + + [self.layer addSublayer:layer]; + layer.position = CGPointMake(CGRectGetWidth(self.bounds) - CGRectGetWidth(layer.bounds) / 2, CGRectGetHeight(self.bounds) - CGRectGetHeight(layer.bounds) / 2); +} + +- (CAShapeLayer*)indefiniteAnimatedLayer { + if(!_indefiniteAnimatedLayer) { + CGPoint arcCenter = CGPointMake(self.radius+self.strokeThickness/2+5, self.radius+self.strokeThickness/2+5); + CGRect rect = CGRectMake(0.0f, 0.0f, arcCenter.x*2, arcCenter.y*2); + + UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:arcCenter + radius:self.radius + startAngle:M_PI*3/2 + endAngle:M_PI/2+M_PI*5 + clockwise:YES]; + + _indefiniteAnimatedLayer = [CAShapeLayer layer]; + _indefiniteAnimatedLayer.contentsScale = [[UIScreen mainScreen] scale]; + _indefiniteAnimatedLayer.frame = rect; + _indefiniteAnimatedLayer.fillColor = [UIColor clearColor].CGColor; + _indefiniteAnimatedLayer.strokeColor = self.strokeColor.CGColor; + _indefiniteAnimatedLayer.lineWidth = self.strokeThickness; + _indefiniteAnimatedLayer.lineCap = kCALineCapRound; + _indefiniteAnimatedLayer.lineJoin = kCALineJoinBevel; + _indefiniteAnimatedLayer.path = smoothedPath.CGPath; + + CALayer *maskLayer = [CALayer layer]; + maskLayer.contents = (id)[[UIImage imageNamed:@"SVProgressHUD.bundle/angle-mask"] CGImage]; + maskLayer.frame = _indefiniteAnimatedLayer.bounds; + _indefiniteAnimatedLayer.mask = maskLayer; + + NSTimeInterval animationDuration = 1; + CAMediaTimingFunction *linearCurve = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; + + CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"]; + animation.fromValue = 0; + animation.toValue = [NSNumber numberWithFloat:M_PI*2]; + animation.duration = animationDuration; + animation.timingFunction = linearCurve; + animation.removedOnCompletion = NO; + animation.repeatCount = INFINITY; + animation.fillMode = kCAFillModeForwards; + animation.autoreverses = NO; + [_indefiniteAnimatedLayer.mask addAnimation:animation forKey:@"rotate"]; + + CAAnimationGroup *animationGroup = [CAAnimationGroup animation]; + animationGroup.duration = animationDuration; + animationGroup.repeatCount = INFINITY; + animationGroup.removedOnCompletion = NO; + animationGroup.timingFunction = linearCurve; + + CABasicAnimation *strokeStartAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"]; + strokeStartAnimation.fromValue = @0.015; + strokeStartAnimation.toValue = @0.515; + + CABasicAnimation *strokeEndAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"]; + strokeEndAnimation.fromValue = @0.485; + strokeEndAnimation.toValue = @0.985; + + animationGroup.animations = @[strokeStartAnimation, strokeEndAnimation]; + [_indefiniteAnimatedLayer addAnimation:animationGroup forKey:@"progress"]; + + } + return _indefiniteAnimatedLayer; +} + +- (void)setFrame:(CGRect)frame { + [super setFrame:frame]; + + if (self.superview) { + [self layoutAnimatedLayer]; + } +} + +- (void)setRadius:(CGFloat)radius { + _radius = radius; + + [_indefiniteAnimatedLayer removeFromSuperlayer]; + _indefiniteAnimatedLayer = nil; + + if (self.superview) { + [self layoutAnimatedLayer]; + } +} + +- (void)setStrokeColor:(UIColor *)strokeColor { + _strokeColor = strokeColor; + _indefiniteAnimatedLayer.strokeColor = strokeColor.CGColor; +} + +- (void)setStrokeThickness:(CGFloat)strokeThickness { + _strokeThickness = strokeThickness; + _indefiniteAnimatedLayer.lineWidth = _strokeThickness; +} + +- (CGSize)sizeThatFits:(CGSize)size { + return CGSizeMake((self.radius+self.strokeThickness/2+5)*2, (self.radius+self.strokeThickness/2+5)*2); +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png new file mode 100644 index 0000000..84d1f7c Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png new file mode 100644 index 0000000..4aa036e Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png new file mode 100644 index 0000000..2a4cd17 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/angle-mask@3x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png new file mode 100644 index 0000000..3a0c20f Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png new file mode 100644 index 0000000..b8bc16c Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png new file mode 100644 index 0000000..4cf4c4f Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/error@3x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png new file mode 100644 index 0000000..2a31018 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png new file mode 100644 index 0000000..1429252 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png new file mode 100644 index 0000000..1aadb13 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/info@3x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png new file mode 100644 index 0000000..481caf8 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png new file mode 100644 index 0000000..c33f9f3 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png new file mode 100644 index 0000000..c6063d0 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle/success@3x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h new file mode 100644 index 0000000..da2992d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.h @@ -0,0 +1,78 @@ +// +// SVProgressHUD.h +// +// Copyright 2011-2014 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVProgressHUD +// + +#import +#import + +extern NSString * const SVProgressHUDDidReceiveTouchEventNotification; +extern NSString * const SVProgressHUDDidTouchDownInsideNotification; +extern NSString * const SVProgressHUDWillDisappearNotification; +extern NSString * const SVProgressHUDDidDisappearNotification; +extern NSString * const SVProgressHUDWillAppearNotification; +extern NSString * const SVProgressHUDDidAppearNotification; + +extern NSString * const SVProgressHUDStatusUserInfoKey; + +typedef NS_ENUM(NSUInteger, SVProgressHUDMaskType) { + SVProgressHUDMaskTypeNone = 1, // allow user interactions while HUD is displayed + SVProgressHUDMaskTypeClear, // don't allow user interactions + SVProgressHUDMaskTypeBlack, // don't allow user interactions and dim the UI in the back of the HUD + SVProgressHUDMaskTypeGradient // don't allow user interactions and dim the UI with a a-la-alert-view background gradient +}; + +@interface SVProgressHUD : UIView + +#pragma mark - Customization + ++ (void)setBackgroundColor:(UIColor*)color; // default is [UIColor whiteColor] ++ (void)setForegroundColor:(UIColor*)color; // default is [UIColor blackColor] ++ (void)setRingThickness:(CGFloat)width; // default is 4 pt ++ (void)setFont:(UIFont*)font; // default is [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline] ++ (void)setInfoImage:(UIImage*)image; // default is the bundled info image provided by Freepik ++ (void)setSuccessImage:(UIImage*)image; // default is the bundled success image provided by Freepik ++ (void)setErrorImage:(UIImage*)image; // default is the bundled error image provided by Freepik ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType; // default is SVProgressHUDMaskTypeNone + +#pragma mark - Show Methods + ++ (void)show; ++ (void)showWithMaskType:(SVProgressHUDMaskType)maskType; ++ (void)showWithStatus:(NSString*)status; ++ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; + ++ (void)showProgress:(float)progress; ++ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType; ++ (void)showProgress:(float)progress status:(NSString*)status; ++ (void)showProgress:(float)progress status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; + ++ (void)setStatus:(NSString*)string; // change the HUD loading status while it's showing + +// stops the activity indicator, shows a glyph + status, and dismisses HUD a little bit later ++ (void)showInfoWithStatus:(NSString *)string; ++ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType; + ++ (void)showSuccessWithStatus:(NSString*)string; ++ (void)showSuccessWithStatus:(NSString*)string maskType:(SVProgressHUDMaskType)maskType; + ++ (void)showErrorWithStatus:(NSString *)string; ++ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType; + +// use 28x28 white pngs ++ (void)showImage:(UIImage*)image status:(NSString*)status; ++ (void)showImage:(UIImage*)image status:(NSString*)status maskType:(SVProgressHUDMaskType)maskType; + ++ (void)setOffsetFromCenter:(UIOffset)offset; ++ (void)resetOffsetFromCenter; + ++ (void)popActivity; // decrease activity count, if activity count == 0 the HUD is dismissed ++ (void)dismiss; + ++ (BOOL)isVisible; + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m new file mode 100644 index 0000000..43c6c6a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVProgressHUD/SVProgressHUD/SVProgressHUD.m @@ -0,0 +1,946 @@ +// +// SVProgressHUD.m +// +// Copyright 2011-2014 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVProgressHUD +// + +#if !__has_feature(objc_arc) +#error SVProgressHUD is ARC only. Either turn on ARC for the project or use -fobjc-arc flag +#endif + +#import "SVProgressHUD.h" +#import "SVIndefiniteAnimatedView.h" +#import + +NSString * const SVProgressHUDDidReceiveTouchEventNotification = @"SVProgressHUDDidReceiveTouchEventNotification"; +NSString * const SVProgressHUDDidTouchDownInsideNotification = @"SVProgressHUDDidTouchDownInsideNotification"; +NSString * const SVProgressHUDWillDisappearNotification = @"SVProgressHUDWillDisappearNotification"; +NSString * const SVProgressHUDDidDisappearNotification = @"SVProgressHUDDidDisappearNotification"; +NSString * const SVProgressHUDWillAppearNotification = @"SVProgressHUDWillAppearNotification"; +NSString * const SVProgressHUDDidAppearNotification = @"SVProgressHUDDidAppearNotification"; + +NSString * const SVProgressHUDStatusUserInfoKey = @"SVProgressHUDStatusUserInfoKey"; + +static UIColor *SVProgressHUDBackgroundColor; +static UIColor *SVProgressHUDForegroundColor; +static CGFloat SVProgressHUDRingThickness; +static UIFont *SVProgressHUDFont; +static UIImage *SVProgressHUDInfoImage; +static UIImage *SVProgressHUDSuccessImage; +static UIImage *SVProgressHUDErrorImage; +static SVProgressHUDMaskType SVProgressHUDDefaultMaskType; + +static const CGFloat SVProgressHUDRingRadius = 18; +static const CGFloat SVProgressHUDRingNoTextRadius = 24; +static const CGFloat SVProgressHUDParallaxDepthPoints = 10; +static const CGFloat SVProgressHUDUndefinedProgress = -1; + +@interface SVProgressHUD () + +@property (nonatomic, readwrite) SVProgressHUDMaskType maskType; +@property (nonatomic, strong, readonly) NSTimer *fadeOutTimer; +@property (nonatomic, readonly, getter = isClear) BOOL clear; + +@property (nonatomic, strong) UIControl *overlayView; +@property (nonatomic, strong) UIView *hudView; +@property (nonatomic, strong) UILabel *stringLabel; +@property (nonatomic, strong) UIImageView *imageView; +@property (nonatomic, strong) SVIndefiniteAnimatedView *indefiniteAnimatedView; + +@property (nonatomic, readwrite) CGFloat progress; +@property (nonatomic, readwrite) NSUInteger activityCount; +@property (nonatomic, strong) CAShapeLayer *backgroundRingLayer; +@property (nonatomic, strong) CAShapeLayer *ringLayer; + +@property (nonatomic, readonly) CGFloat visibleKeyboardHeight; +@property (nonatomic, assign) UIOffset offsetFromCenter; + + +- (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType; +- (void)showImage:(UIImage*)image status:(NSString*)status duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType; + +- (void)dismiss; + +- (void)setStatus:(NSString*)string; +- (void)registerNotifications; +- (NSDictionary *)notificationUserInfo; +- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle; +- (void)positionHUD:(NSNotification*)notification; +- (NSTimeInterval)displayDurationForString:(NSString*)string; + +@end + + +@implementation SVProgressHUD + ++ (SVProgressHUD*)sharedView { + static dispatch_once_t once; + static SVProgressHUD *sharedView; + dispatch_once(&once, ^ { sharedView = [[self alloc] initWithFrame:[[UIScreen mainScreen] bounds]]; }); + return sharedView; +} + + +#pragma mark - Setters + ++ (void)setStatus:(NSString *)string { + [[self sharedView] setStatus:string]; +} + ++ (void)setBackgroundColor:(UIColor *)color { + [self sharedView].hudView.backgroundColor = color; + SVProgressHUDBackgroundColor = color; +} + ++ (void)setForegroundColor:(UIColor *)color { + [self sharedView]; + SVProgressHUDForegroundColor = color; +} + ++ (void)setFont:(UIFont *)font { + [self sharedView]; + SVProgressHUDFont = font; +} + ++ (void)setRingThickness:(CGFloat)width { + [self sharedView]; + SVProgressHUDRingThickness = width; +} + ++ (void)setInfoImage:(UIImage*)image{ + [self sharedView]; + SVProgressHUDInfoImage = image; +} + ++ (void)setSuccessImage:(UIImage *)image { + [self sharedView]; + SVProgressHUDSuccessImage = image; +} + ++ (void)setErrorImage:(UIImage *)image { + [self sharedView]; + SVProgressHUDErrorImage = image; +} + ++ (void)setDefaultMaskType:(SVProgressHUDMaskType)maskType{ + [self sharedView]; + SVProgressHUDDefaultMaskType = maskType; +} + + +#pragma mark - Show Methods + ++ (void)show { + [self showWithStatus:nil]; +} + ++ (void)showWithMaskType:(SVProgressHUDMaskType)maskType { + [self showProgress:SVProgressHUDUndefinedProgress maskType:maskType]; +} + ++ (void)showWithStatus:(NSString *)status { + [self showProgress:SVProgressHUDUndefinedProgress status:status]; +} + ++ (void)showWithStatus:(NSString*)status maskType:(SVProgressHUDMaskType)maskType { + [self showProgress:SVProgressHUDUndefinedProgress status:status maskType:maskType]; +} + ++ (void)showProgress:(float)progress { + [self sharedView]; + [self showProgress:progress maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showProgress:(float)progress maskType:(SVProgressHUDMaskType)maskType{ + [self showProgress:progress status:nil maskType:maskType]; +} + ++ (void)showProgress:(float)progress status:(NSString *)status { + [self sharedView]; + [self showProgress:progress status:status maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showProgress:(float)progress status:(NSString *)status maskType:(SVProgressHUDMaskType)maskType { + [[self sharedView] showProgress:progress status:status maskType:maskType]; +} + + +#pragma mark - Show then dismiss methods + ++ (void)showInfoWithStatus:(NSString *)string { + [self sharedView]; + [self showInfoWithStatus:string maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showInfoWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType { + [self sharedView]; + [self showImage:SVProgressHUDInfoImage status:string maskType:maskType]; +} + ++ (void)showSuccessWithStatus:(NSString *)string { + [self sharedView]; + [self showSuccessWithStatus:string maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showSuccessWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType { + [self sharedView]; + [self showImage:SVProgressHUDSuccessImage status:string maskType:maskType]; +} + ++ (void)showErrorWithStatus:(NSString *)string { + [self sharedView]; + [self showErrorWithStatus:string maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showErrorWithStatus:(NSString *)string maskType:(SVProgressHUDMaskType)maskType { + [self sharedView]; + [self showImage:SVProgressHUDErrorImage status:string maskType:maskType]; +} + ++ (void)showImage:(UIImage *)image status:(NSString *)string { + [self sharedView]; + [self showImage:image status:string maskType:SVProgressHUDDefaultMaskType]; +} + ++ (void)showImage:(UIImage *)image status:(NSString *)string maskType:(SVProgressHUDMaskType)maskType { + NSTimeInterval displayInterval = [[self sharedView] displayDurationForString:string]; + [[self sharedView] showImage:image status:string duration:displayInterval maskType:maskType]; +} + + +#pragma mark - Dismiss Methods + ++ (void)popActivity { + if([self sharedView].activityCount > 0) + [self sharedView].activityCount--; + if([self sharedView].activityCount == 0) + [[self sharedView] dismiss]; +} + ++ (void)dismiss { + if ([self isVisible]) { + [[self sharedView] dismiss]; + } +} + + +#pragma mark - Offset + ++ (void)setOffsetFromCenter:(UIOffset)offset { + [self sharedView].offsetFromCenter = offset; +} + ++ (void)resetOffsetFromCenter { + [self setOffsetFromCenter:UIOffsetZero]; +} + + +#pragma mark - Instance Methods + +- (id)initWithFrame:(CGRect)frame { + if ((self = [super initWithFrame:frame])) { + self.userInteractionEnabled = NO; + self.backgroundColor = [UIColor clearColor]; + self.alpha = 0.0f; + self.activityCount = 0; + + SVProgressHUDBackgroundColor = [UIColor whiteColor]; + SVProgressHUDForegroundColor = [UIColor blackColor]; + if ([UIFont respondsToSelector:@selector(preferredFontForTextStyle:)]) { + SVProgressHUDFont = [UIFont preferredFontForTextStyle:UIFontTextStyleSubheadline]; + } else { + SVProgressHUDFont = [UIFont systemFontOfSize:14.0f]; + SVProgressHUDBackgroundColor = [UIColor colorWithWhite:0.0f alpha:0.8f]; + SVProgressHUDForegroundColor = [UIColor whiteColor]; + } + if ([[UIImage class] instancesRespondToSelector:@selector(imageWithRenderingMode:)]) { + SVProgressHUDInfoImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/info"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + SVProgressHUDSuccessImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/success"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + SVProgressHUDErrorImage = [[UIImage imageNamed:@"SVProgressHUD.bundle/error"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + } else { + SVProgressHUDInfoImage = [UIImage imageNamed:@"SVProgressHUD.bundle/info"]; + SVProgressHUDSuccessImage = [UIImage imageNamed:@"SVProgressHUD.bundle/success"]; + SVProgressHUDErrorImage = [UIImage imageNamed:@"SVProgressHUD.bundle/error"]; + } + SVProgressHUDRingThickness = 2; + SVProgressHUDDefaultMaskType = SVProgressHUDMaskTypeNone; + } + + return self; +} + +- (void)drawRect:(CGRect)rect { + CGContextRef context = UIGraphicsGetCurrentContext(); + + switch (self.maskType) { + case SVProgressHUDMaskTypeBlack: { + + [[UIColor colorWithWhite:0 alpha:0.5] set]; + CGContextFillRect(context, self.bounds); + + break; + } + case SVProgressHUDMaskTypeGradient: { + + size_t locationsCount = 2; + CGFloat locations[2] = {0.0f, 1.0f}; + CGFloat colors[8] = {0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.75f}; + CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); + CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, colors, locations, locationsCount); + CGColorSpaceRelease(colorSpace); + + CGFloat freeHeight = CGRectGetHeight(self.bounds) - self.visibleKeyboardHeight; + + CGPoint center = CGPointMake(CGRectGetWidth(self.bounds)/2, freeHeight/2); + float radius = MIN(CGRectGetWidth(self.bounds) , CGRectGetHeight(self.bounds)) ; + CGContextDrawRadialGradient (context, gradient, center, 0, center, radius, kCGGradientDrawsAfterEndLocation); + CGGradientRelease(gradient); + + break; + } + default: + break; + } +} + +- (void)updatePosition { + + CGFloat hudWidth = 100.0f; + CGFloat hudHeight = 100.0f; + CGFloat stringHeightBuffer = 20.0f; + CGFloat stringAndContentHeightBuffer = 80.0f; + + CGFloat stringWidth = 0.0f; + CGFloat stringHeight = 0.0f; + CGRect labelRect = CGRectZero; + + NSString *string = self.stringLabel.text; + + // Check if an image or progress ring is displayed + BOOL imageUsed = (self.imageView.image) || (self.imageView.hidden); + BOOL progressUsed = (self.progress != SVProgressHUDUndefinedProgress) && (self.progress >= 0.0f); + + if(string) { + CGSize constraintSize = CGSizeMake(200.0f, 300.0f); + CGRect stringRect; + if ([string respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { + stringRect = [string boundingRectWithSize:constraintSize + options:(NSStringDrawingUsesFontLeading|NSStringDrawingTruncatesLastVisibleLine|NSStringDrawingUsesLineFragmentOrigin) + attributes:@{NSFontAttributeName: self.stringLabel.font} + context:NULL]; + } else { + CGSize stringSize; + + if ([string respondsToSelector:@selector(sizeWithAttributes:)]) + stringSize = [string sizeWithAttributes:@{NSFontAttributeName:[UIFont fontWithName:self.stringLabel.font.fontName size:self.stringLabel.font.pointSize]}]; + else +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated" + stringSize = [string sizeWithFont:self.stringLabel.font constrainedToSize:CGSizeMake(200.0f, 300.0f)]; +#pragma clang diagnostic pop + + stringRect = CGRectMake(0.0f, 0.0f, stringSize.width, stringSize.height); + } + stringWidth = stringRect.size.width; + stringHeight = ceil(CGRectGetHeight(stringRect)); + + if (imageUsed || progressUsed) + hudHeight = stringAndContentHeightBuffer + stringHeight; + else + hudHeight = stringHeightBuffer + stringHeight; + + if(stringWidth > hudWidth) + hudWidth = ceil(stringWidth/2)*2; + + CGFloat labelRectY = (imageUsed || progressUsed) ? 68.0f : 9.0f; + + if(hudHeight > 100.0f) { + labelRect = CGRectMake(12.0f, labelRectY, hudWidth, stringHeight); + hudWidth += 24.0f; + } else { + hudWidth += 24.0f; + labelRect = CGRectMake(0.0f, labelRectY, hudWidth, stringHeight); + } + } + + self.hudView.bounds = CGRectMake(0.0f, 0.0f, hudWidth, hudHeight); + + if(string) + self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, 36.0f); + else + self.imageView.center = CGPointMake(CGRectGetWidth(self.hudView.bounds)/2, CGRectGetHeight(self.hudView.bounds)/2); + + self.stringLabel.hidden = NO; + self.stringLabel.frame = labelRect; + + [CATransaction begin]; + [CATransaction setValue:(id)kCFBooleanTrue forKey:kCATransactionDisableActions]; + + if(string) { + self.indefiniteAnimatedView.radius = SVProgressHUDRingRadius; + [self.indefiniteAnimatedView sizeToFit]; + + CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f); + self.indefiniteAnimatedView.center = center; + + if(self.progress != SVProgressHUDUndefinedProgress) + self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), 36.0f); + } else { + self.indefiniteAnimatedView.radius = SVProgressHUDRingNoTextRadius; + [self.indefiniteAnimatedView sizeToFit]; + + CGPoint center = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2); + self.indefiniteAnimatedView.center = center; + + if(self.progress != SVProgressHUDUndefinedProgress) + self.backgroundRingLayer.position = self.ringLayer.position = CGPointMake((CGRectGetWidth(self.hudView.bounds)/2), CGRectGetHeight(self.hudView.bounds)/2); + } + + [CATransaction commit]; +} + +- (void)setStatus:(NSString *)string { + self.stringLabel.text = string; + [self updatePosition]; + +} + +- (void)setFadeOutTimer:(NSTimer *)newTimer { + if(_fadeOutTimer) + [_fadeOutTimer invalidate], _fadeOutTimer = nil; + + if(newTimer) + _fadeOutTimer = newTimer; +} + + +- (void)registerNotifications { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIApplicationDidChangeStatusBarOrientationNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardWillHideNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardDidHideNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardWillShowNotification + object:nil]; + + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(positionHUD:) + name:UIKeyboardDidShowNotification + object:nil]; +} + + +- (NSDictionary *)notificationUserInfo{ + return (self.stringLabel.text ? @{SVProgressHUDStatusUserInfoKey : self.stringLabel.text} : nil); +} + + +- (void)positionHUD:(NSNotification*)notification { + + CGFloat keyboardHeight = 0.0f; + double animationDuration = 0.0; + + self.frame = UIScreen.mainScreen.bounds; + + UIInterfaceOrientation orientation = UIApplication.sharedApplication.statusBarOrientation; + // no transforms applied to window in iOS 8, but only if compiled with iOS 8 sdk as base sdk, otherwise system supports old rotation logic. + BOOL ignoreOrientation = NO; +#if __IPHONE_OS_VERSION_MAX_ALLOWED >= 80000 + if ([[NSProcessInfo processInfo] respondsToSelector:@selector(operatingSystemVersion)]) { + ignoreOrientation = YES; + } +#endif + + if(notification) { + NSDictionary* keyboardInfo = [notification userInfo]; + CGRect keyboardFrame = [[keyboardInfo valueForKey:UIKeyboardFrameBeginUserInfoKey] CGRectValue]; + animationDuration = [[keyboardInfo valueForKey:UIKeyboardAnimationDurationUserInfoKey] doubleValue]; + + if(notification.name == UIKeyboardWillShowNotification || notification.name == UIKeyboardDidShowNotification) { + if(ignoreOrientation || UIInterfaceOrientationIsPortrait(orientation)) + keyboardHeight = CGRectGetHeight(keyboardFrame); + else + keyboardHeight = CGRectGetWidth(keyboardFrame); + } + } else { + keyboardHeight = self.visibleKeyboardHeight; + } + + CGRect orientationFrame = self.bounds; + CGRect statusBarFrame = UIApplication.sharedApplication.statusBarFrame; + + if(!ignoreOrientation && UIInterfaceOrientationIsLandscape(orientation)) { + float temp = CGRectGetWidth(orientationFrame); + orientationFrame.size.width = CGRectGetHeight(orientationFrame); + orientationFrame.size.height = temp; + + temp = CGRectGetWidth(statusBarFrame); + statusBarFrame.size.width = CGRectGetHeight(statusBarFrame); + statusBarFrame.size.height = temp; + } + + CGFloat activeHeight = CGRectGetHeight(orientationFrame); + + if(keyboardHeight > 0) + activeHeight += CGRectGetHeight(statusBarFrame)*2; + + activeHeight -= keyboardHeight; + CGFloat posY = floor(activeHeight*0.45); + CGFloat posX = CGRectGetWidth(orientationFrame)/2; + + CGPoint newCenter; + CGFloat rotateAngle; + + if (ignoreOrientation) { + rotateAngle = 0.0; + newCenter = CGPointMake(posX, posY); + } else { + switch (orientation) { + case UIInterfaceOrientationPortraitUpsideDown: + rotateAngle = M_PI; + newCenter = CGPointMake(posX, CGRectGetHeight(orientationFrame)-posY); + break; + case UIInterfaceOrientationLandscapeLeft: + rotateAngle = -M_PI/2.0f; + newCenter = CGPointMake(posY, posX); + break; + case UIInterfaceOrientationLandscapeRight: + rotateAngle = M_PI/2.0f; + newCenter = CGPointMake(CGRectGetHeight(orientationFrame)-posY, posX); + break; + default: // as UIInterfaceOrientationPortrait + rotateAngle = 0.0; + newCenter = CGPointMake(posX, posY); + break; + } + } + + if(notification) { + [UIView animateWithDuration:animationDuration + delay:0 + options:UIViewAnimationOptionAllowUserInteraction + animations:^{ + [self moveToPoint:newCenter rotateAngle:rotateAngle]; + [self.hudView setNeedsDisplay]; + } completion:NULL]; + } else { + [self moveToPoint:newCenter rotateAngle:rotateAngle]; + [self.hudView setNeedsDisplay]; + } + +} + +- (void)moveToPoint:(CGPoint)newCenter rotateAngle:(CGFloat)angle { + self.hudView.transform = CGAffineTransformMakeRotation(angle); + self.hudView.center = CGPointMake(newCenter.x + self.offsetFromCenter.horizontal, newCenter.y + self.offsetFromCenter.vertical); +} + +- (void)overlayViewDidReceiveTouchEvent:(id)sender forEvent:(UIEvent *)event { + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidReceiveTouchEventNotification object:event]; + + UITouch *touch = event.allTouches.anyObject; + CGPoint touchLocation = [touch locationInView:self]; + + if (CGRectContainsPoint(self.hudView.frame, touchLocation)) { + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidTouchDownInsideNotification object:event]; + } +} + + +#pragma mark - Master show/dismiss methods + +- (void)showProgress:(float)progress status:(NSString*)string maskType:(SVProgressHUDMaskType)hudMaskType { + if(!self.overlayView.superview){ + NSEnumerator *frontToBackWindows = [UIApplication.sharedApplication.windows reverseObjectEnumerator]; + UIScreen *mainScreen = UIScreen.mainScreen; + + for (UIWindow *window in frontToBackWindows) + if (window.screen == mainScreen && window.windowLevel == UIWindowLevelNormal) { + [window addSubview:self.overlayView]; + break; + } + } else { + // Ensure that overlay will be exactly on top of rootViewController (which may be changed during runtime). + [self.overlayView.superview bringSubviewToFront:self.overlayView]; + } + + if(!self.superview) + [self.overlayView addSubview:self]; + + self.fadeOutTimer = nil; + self.imageView.hidden = YES; + self.maskType = hudMaskType; + self.progress = progress; + + self.stringLabel.text = string; + [self updatePosition]; + + if(progress >= 0) { + self.imageView.image = nil; + self.imageView.hidden = NO; + [self.indefiniteAnimatedView removeFromSuperview]; + + self.ringLayer.strokeEnd = progress; + + if(progress == 0) + self.activityCount++; + } else { + self.activityCount++; + [self cancelRingLayerAnimation]; + [self.hudView addSubview:self.indefiniteAnimatedView]; + } + + if(self.maskType != SVProgressHUDMaskTypeNone) { + self.overlayView.userInteractionEnabled = YES; + self.accessibilityLabel = string; + self.isAccessibilityElement = YES; + } else { + self.overlayView.userInteractionEnabled = NO; + self.hudView.accessibilityLabel = string; + self.hudView.isAccessibilityElement = YES; + } + + [self.overlayView setHidden:NO]; + self.overlayView.backgroundColor = [UIColor clearColor]; + [self positionHUD:nil]; + + if(self.alpha != 1 || self.hudView.alpha != 1) { + NSDictionary *userInfo = [self notificationUserInfo]; + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillAppearNotification + object:nil + userInfo:userInfo]; + + [self registerNotifications]; + self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1.3, 1.3); + + if(self.isClear) { + self.alpha = 1; + self.hudView.alpha = 0; + } + + [UIView animateWithDuration:0.15 + delay:0 + options:UIViewAnimationOptionAllowUserInteraction | UIViewAnimationCurveEaseOut | UIViewAnimationOptionBeginFromCurrentState + animations:^{ + self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 1/1.3, 1/1.3); + + if(self.isClear) // handle iOS 7 and 8 UIToolbar which not answers well to hierarchy opacity change + self.hudView.alpha = 1; + else + self.alpha = 1; + } + completion:^(BOOL finished){ + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidAppearNotification + object:nil + userInfo:userInfo]; + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string); + }]; + + [self setNeedsDisplay]; + } +} + +- (UIImage *)image:(UIImage *)image withTintColor:(UIColor *)color{ + CGRect rect = CGRectMake(0.0f, 0.0f, image.size.width, image.size.height); + UIGraphicsBeginImageContextWithOptions(rect.size, NO, image.scale); + CGContextRef c = UIGraphicsGetCurrentContext(); + [image drawInRect:rect]; + CGContextSetFillColorWithColor(c, [color CGColor]); + CGContextSetBlendMode(c, kCGBlendModeSourceAtop); + CGContextFillRect(c, rect); + UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return tintedImage; +} + +- (void)showImage:(UIImage *)image status:(NSString *)string duration:(NSTimeInterval)duration maskType:(SVProgressHUDMaskType)hudMaskType { + self.progress = SVProgressHUDUndefinedProgress; + [self cancelRingLayerAnimation]; + + if(![self.class isVisible]) + [self.class show]; + + if ([self.imageView respondsToSelector:@selector(setTintColor:)]) { + self.imageView.tintColor = SVProgressHUDForegroundColor; + } else { + image = [self image:image withTintColor:SVProgressHUDForegroundColor]; + } + self.imageView.image = image; + self.imageView.hidden = NO; + self.maskType = hudMaskType; + + self.stringLabel.text = string; + [self updatePosition]; + [self.indefiniteAnimatedView removeFromSuperview]; + + if(self.maskType != SVProgressHUDMaskTypeNone) { + self.accessibilityLabel = string; + self.isAccessibilityElement = YES; + } else { + self.hudView.accessibilityLabel = string; + self.hudView.isAccessibilityElement = YES; + } + + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + UIAccessibilityPostNotification(UIAccessibilityAnnouncementNotification, string); + + self.fadeOutTimer = [NSTimer timerWithTimeInterval:duration target:self selector:@selector(dismiss) userInfo:nil repeats:NO]; + [[NSRunLoop mainRunLoop] addTimer:self.fadeOutTimer forMode:NSRunLoopCommonModes]; +} + +- (void)dismiss { + NSDictionary *userInfo = [self notificationUserInfo]; + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDWillDisappearNotification + object:nil + userInfo:userInfo]; + + self.activityCount = 0; + [UIView animateWithDuration:0.15 + delay:0 + options:UIViewAnimationCurveEaseIn | UIViewAnimationOptionAllowUserInteraction + animations:^{ + self.hudView.transform = CGAffineTransformScale(self.hudView.transform, 0.8f, 0.8f); + if(self.isClear) // handle iOS 7 UIToolbar not answer well to hierarchy opacity change + self.hudView.alpha = 0.0f; + else + self.alpha = 0.0f; + } + completion:^(BOOL finished){ + if(self.alpha == 0.0f || self.hudView.alpha == 0.0f) { + self.alpha = 0.0f; + self.hudView.alpha = 0.0f; + + [[NSNotificationCenter defaultCenter] removeObserver:self]; + [self cancelRingLayerAnimation]; + [_hudView removeFromSuperview]; + _hudView = nil; + + [_overlayView removeFromSuperview]; + _overlayView = nil; + + [_indefiniteAnimatedView removeFromSuperview]; + _indefiniteAnimatedView = nil; + + UIAccessibilityPostNotification(UIAccessibilityScreenChangedNotification, nil); + + [[NSNotificationCenter defaultCenter] postNotificationName:SVProgressHUDDidDisappearNotification + object:nil + userInfo:userInfo]; + + // Tell the rootViewController to update the StatusBar appearance + UIViewController *rootController = [[UIApplication sharedApplication] keyWindow].rootViewController; + if ([rootController respondsToSelector:@selector(setNeedsStatusBarAppearanceUpdate)]) { + [rootController setNeedsStatusBarAppearanceUpdate]; + } + // uncomment to make sure UIWindow is gone from app.windows + //NSLog(@"%@", [UIApplication sharedApplication].windows); + //NSLog(@"keyWindow = %@", [UIApplication sharedApplication].keyWindow); + } + }]; +} + + +#pragma mark - Ring progress animation + +- (SVIndefiniteAnimatedView *)indefiniteAnimatedView { + if (_indefiniteAnimatedView == nil) { + _indefiniteAnimatedView = [[SVIndefiniteAnimatedView alloc] initWithFrame:CGRectZero]; + _indefiniteAnimatedView.strokeThickness = SVProgressHUDRingThickness; + _indefiniteAnimatedView.strokeColor = SVProgressHUDForegroundColor; + _indefiniteAnimatedView.radius = self.stringLabel.text ? SVProgressHUDRingRadius : SVProgressHUDRingNoTextRadius; + [_indefiniteAnimatedView sizeToFit]; + } + return _indefiniteAnimatedView; +} + +- (CAShapeLayer *)ringLayer { + if(!_ringLayer) { + CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2); + _ringLayer = [self createRingLayerWithCenter:center + radius:SVProgressHUDRingRadius + lineWidth:SVProgressHUDRingThickness + color:SVProgressHUDForegroundColor]; + [self.hudView.layer addSublayer:_ringLayer]; + } + return _ringLayer; +} + +- (CAShapeLayer *)backgroundRingLayer { + if(!_backgroundRingLayer) { + CGPoint center = CGPointMake(CGRectGetWidth(_hudView.frame)/2, CGRectGetHeight(_hudView.frame)/2); + _backgroundRingLayer = [self createRingLayerWithCenter:center + radius:SVProgressHUDRingRadius + lineWidth:SVProgressHUDRingThickness + color:[SVProgressHUDForegroundColor colorWithAlphaComponent:0.1f]]; + _backgroundRingLayer.strokeEnd = 1; + [self.hudView.layer addSublayer:_backgroundRingLayer]; + } + return _backgroundRingLayer; +} + +- (void)cancelRingLayerAnimation { + [CATransaction begin]; + [CATransaction setDisableActions:YES]; + [_hudView.layer removeAllAnimations]; + + _ringLayer.strokeEnd = 0.0f; + if (_ringLayer.superlayer) { + [_ringLayer removeFromSuperlayer]; + } + _ringLayer = nil; + + if (_backgroundRingLayer.superlayer) { + [_backgroundRingLayer removeFromSuperlayer]; + } + _backgroundRingLayer = nil; + + [CATransaction commit]; +} + +- (CAShapeLayer *)createRingLayerWithCenter:(CGPoint)center radius:(CGFloat)radius lineWidth:(CGFloat)lineWidth color:(UIColor *)color { + + UIBezierPath* smoothedPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(radius, radius) radius:radius startAngle:-M_PI_2 endAngle:(M_PI + M_PI_2) clockwise:YES]; + + CAShapeLayer *slice = [CAShapeLayer layer]; + slice.contentsScale = [[UIScreen mainScreen] scale]; + slice.frame = CGRectMake(center.x-radius, center.y-radius, radius*2, radius*2); + slice.fillColor = [UIColor clearColor].CGColor; + slice.strokeColor = color.CGColor; + slice.lineWidth = lineWidth; + slice.lineCap = kCALineCapRound; + slice.lineJoin = kCALineJoinBevel; + slice.path = smoothedPath.CGPath; + + return slice; +} + +#pragma mark - Utilities + ++ (BOOL)isVisible { + return ([self sharedView].alpha == 1); +} + + +#pragma mark - Getters + +- (NSTimeInterval)displayDurationForString:(NSString*)string { + return MIN((float)string.length*0.06 + 0.5, 5.0); +} + +- (BOOL)isClear { // used for iOS 7 and above + return (self.maskType == SVProgressHUDMaskTypeClear || self.maskType == SVProgressHUDMaskTypeNone); +} + +- (UIControl *)overlayView { + if(!_overlayView) { + _overlayView = [[UIControl alloc] initWithFrame:[UIScreen mainScreen].bounds]; + _overlayView.autoresizingMask = UIViewAutoresizingFlexibleWidth | UIViewAutoresizingFlexibleHeight; + _overlayView.backgroundColor = [UIColor clearColor]; + [_overlayView addTarget:self action:@selector(overlayViewDidReceiveTouchEvent:forEvent:) forControlEvents:UIControlEventTouchDown]; + } + return _overlayView; +} + +- (UIView *)hudView { + if(!_hudView) { + _hudView = [[UIView alloc] initWithFrame:CGRectZero]; + _hudView.backgroundColor = SVProgressHUDBackgroundColor; + _hudView.layer.cornerRadius = 14; + _hudView.layer.masksToBounds = YES; + + _hudView.autoresizingMask = (UIViewAutoresizingFlexibleBottomMargin | UIViewAutoresizingFlexibleTopMargin | + UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleLeftMargin); + + if ([_hudView respondsToSelector:@selector(addMotionEffect:)]) { + UIInterpolatingMotionEffect *effectX = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.x" type: UIInterpolatingMotionEffectTypeTiltAlongHorizontalAxis]; + effectX.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); + effectX.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); + + UIInterpolatingMotionEffect *effectY = [[UIInterpolatingMotionEffect alloc] initWithKeyPath: @"center.y" type: UIInterpolatingMotionEffectTypeTiltAlongVerticalAxis]; + effectY.minimumRelativeValue = @(-SVProgressHUDParallaxDepthPoints); + effectY.maximumRelativeValue = @(SVProgressHUDParallaxDepthPoints); + + UIMotionEffectGroup *effectGroup = [[UIMotionEffectGroup alloc] init]; + effectGroup.motionEffects = @[effectX, effectY]; + [_hudView addMotionEffect:effectGroup]; + } + } + + if(!_hudView.superview) + [self addSubview:_hudView]; + + return _hudView; +} + +- (UILabel *)stringLabel { + if (!_stringLabel) { + _stringLabel = [[UILabel alloc] initWithFrame:CGRectZero]; + _stringLabel.backgroundColor = [UIColor clearColor]; + _stringLabel.adjustsFontSizeToFitWidth = YES; + _stringLabel.textAlignment = NSTextAlignmentCenter; + _stringLabel.baselineAdjustment = UIBaselineAdjustmentAlignCenters; + _stringLabel.numberOfLines = 0; + } + + if(!_stringLabel.superview) + [self.hudView addSubview:_stringLabel]; + + _stringLabel.textColor = SVProgressHUDForegroundColor; + _stringLabel.font = SVProgressHUDFont; + + return _stringLabel; +} + +- (UIImageView *)imageView { + if (!_imageView) + _imageView = [[UIImageView alloc] initWithFrame:CGRectMake(0.0f, 0.0f, 28.0f, 28.0f)]; + + if(!_imageView.superview) + [self.hudView addSubview:_imageView]; + + return _imageView; +} + + +- (CGFloat)visibleKeyboardHeight { + UIWindow *keyboardWindow = nil; + for (UIWindow *testWindow in [[UIApplication sharedApplication] windows]) { + if(![[testWindow class] isEqual:[UIWindow class]]) { + keyboardWindow = testWindow; + break; + } + } + + for (__strong UIView *possibleKeyboard in [keyboardWindow subviews]) { + if ([possibleKeyboard isKindOfClass:NSClassFromString(@"UIPeripheralHostView")] || [possibleKeyboard isKindOfClass:NSClassFromString(@"UIKeyboard")]) { + return CGRectGetHeight(possibleKeyboard.bounds); + } else if ([possibleKeyboard isKindOfClass:NSClassFromString(@"UIInputSetContainerView")]) { + for (__strong UIView *possibleKeyboardSubview in [possibleKeyboard subviews]) { + if ([possibleKeyboardSubview isKindOfClass:NSClassFromString(@"UIInputSetHostView")]) { + return CGRectGetHeight(possibleKeyboardSubview.bounds); + } + } + } + } + + return 0; +} + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/LICENSE.txt b/iOSStudy/iOSStudy/Pods/SVWebViewController/LICENSE.txt new file mode 100644 index 0000000..0dfab08 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/LICENSE.txt @@ -0,0 +1,22 @@ +Copyright (c) 2011 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/README.md b/iOSStudy/iOSStudy/Pods/SVWebViewController/README.md new file mode 100644 index 0000000..c8d1736 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/README.md @@ -0,0 +1,52 @@ +# SVWebViewController + +SVWebViewController is a simple inline browser for your iOS 7 app. + +![SVWebViewController](http://cl.ly/SQVO/download/GitHub.png) + +**SVWebViewController features:** + +* iPhone and iPad distinct UIs +* full landscape orientation support +* back, forward, stop/refresh and share buttons +* Open in Safari and Chrome UIActivities +* navbar title set to the currently visible web page +* talks with `setNetworkActivityIndicatorVisible` + +## Installation + +### CocoaPods + +I'm not a big fan of CocoaPods, so tend to not keep it updated. If you really want to use SVWebViewController with CocoaPods, I suggest you use `pod 'SVWebViewController', :head` to pull from the `master` branch directly. I'm usually careful about what I push there and is the version I use myself in all my projects. + +### Manually + +* Drag the `SVWebViewController/SVWebViewController` folder into your project. +* `#import "SVWebViewController.h"` + +## Usage + +(see sample Xcode project in `/Demo`) + +Just like any UIViewController, SVWebViewController can be pushed into a UINavigationController stack: + +```objective-c +SVWebViewController *webViewController = [[SVWebViewController alloc] initWithAddress:@"http://google.com"]; +[self.navigationController pushViewController:webViewController animated:YES]; +``` + +It can also be presented modally using `SVModalWebViewController`: + +```objective-c +SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:@"http://google.com"]; +[self presentModalViewController:webViewController animated:YES completion:NULL]; +``` + +### SVWebViewControllerActivity + +Starting in iOS 6 Apple uses `UIActivity` to let you show additional sharing methods in share sheets. `SVWebViewController` comes with "Open in Safari" and "Open in Chrome" activities. You can easily add your own activity by subclassing `SVWebViewControllerActivity` which takes care of a few things automatically for you. Have a look at the Safari and Chrome activities for implementation examples. Feel free to send it as a pull request once you're done! + + +## Credits + +SVWebViewController is brought to you by [Sam Vermette](http://samvermette.com) and [contributors to the project](https://github.com/samvermette/SVWebViewController/contributors). If you have feature suggestions or bug reports, feel free to help out by sending pull requests or by [creating new issues](https://github.com/samvermette/SVWebViewController/issues/new). If you're using SVWebViewController in your project, attribution is always appreciated. \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.h b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.h new file mode 100644 index 0000000..aa4d84c --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.h @@ -0,0 +1,20 @@ +// +// SVModalWebViewController.h +// +// Created by Oliver Letterer on 13.08.11. +// Copyright 2011 Home. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import + +@class SVWebViewController; + +@interface SVModalWebViewController : UINavigationController + +- (id)initWithAddress:(NSString*)urlString; +- (id)initWithURL:(NSURL *)URL; + +@property (nonatomic, strong) UIColor *barsTintColor; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.m b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.m new file mode 100644 index 0000000..f801fa2 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVModalWebViewController.m @@ -0,0 +1,50 @@ +// +// SVModalWebViewController.m +// +// Created by Oliver Letterer on 13.08.11. +// Copyright 2011 Home. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVModalWebViewController.h" +#import "SVWebViewController.h" + +@interface SVModalWebViewController () + +@property (nonatomic, strong) SVWebViewController *webViewController; + +@end + + +@implementation SVModalWebViewController + +#pragma mark - Initialization + + +- (id)initWithAddress:(NSString*)urlString { + return [self initWithURL:[NSURL URLWithString:urlString]]; +} + +- (id)initWithURL:(NSURL *)URL { + self.webViewController = [[SVWebViewController alloc] initWithURL:URL]; + if (self = [super initWithRootViewController:self.webViewController]) { + UIBarButtonItem *doneButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone + target:self.webViewController + action:@selector(doneButtonClicked:)]; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) + self.webViewController.navigationItem.leftBarButtonItem = doneButton; + else + self.webViewController.navigationItem.rightBarButtonItem = doneButton; + } + return self; +} + +- (void)viewWillAppear:(BOOL)animated { + [super viewWillAppear:NO]; + + self.webViewController.title = self.title; + self.navigationBar.tintColor = self.barsTintColor; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png new file mode 100644 index 0000000..195b4fd Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png new file mode 100644 index 0000000..2ef9aca Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png new file mode 100644 index 0000000..453bc79 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png new file mode 100644 index 0000000..5746bec Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h new file mode 100644 index 0000000..fc904ae --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.h @@ -0,0 +1,16 @@ +// +// SVWebViewController.h +// +// Created by Sam Vermette on 08.11.10. +// Copyright 2010 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVModalWebViewController.h" + +@interface SVWebViewController : UIViewController +@property(nonatomic,copy)NSString*urlString; +- (id)initWithAddress:(NSString*)urlString; +- (id)initWithURL:(NSURL*)URL; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m new file mode 100644 index 0000000..80d97d6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/SVWebViewController.m @@ -0,0 +1,297 @@ +// +// SVWebViewController.m +// +// Created by Sam Vermette on 08.11.10. +// Copyright 2010 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVWebViewControllerActivityChrome.h" +#import "SVWebViewControllerActivitySafari.h" +#import "SVWebViewController.h" +#import +@interface SVWebViewController () + +@property (nonatomic, strong) UIBarButtonItem *backBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *forwardBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *refreshBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *stopBarButtonItem; +@property (nonatomic, strong) UIBarButtonItem *actionBarButtonItem; + +@property (nonatomic, strong) UIWebView *webView; +@property (nonatomic, strong) NSURL *URL; + +- (id)initWithAddress:(NSString*)urlString; +- (id)initWithURL:(NSURL*)URL; +- (void)loadURL:(NSURL*)URL; + +- (void)updateToolbarItems; + +- (void)goBackClicked:(UIBarButtonItem *)sender; +- (void)goForwardClicked:(UIBarButtonItem *)sender; +- (void)reloadClicked:(UIBarButtonItem *)sender; +- (void)stopClicked:(UIBarButtonItem *)sender; +- (void)actionButtonClicked:(UIBarButtonItem *)sender; + +@end + + +@implementation SVWebViewController + +#pragma mark - Initialization + +- (void)dealloc { + [self.webView stopLoading]; + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; + self.webView.delegate = nil; +} + +- (id)initWithAddress:(NSString *)urlString { + + if (urlString) { + urlString = _urlString; + } + return [self initWithURL:[NSURL URLWithString:urlString]]; +} + +-(void)setUrlString:(NSString *)urlString{ + if (urlString) { + _urlString = urlString; + } +} + +- (id)initWithURL:(NSURL*)pageURL { + + + if(self = [super init]) { + self.URL = pageURL; + } + + return self; +} + +- (void)loadURL:(NSURL *)pageURL { + [self.webView loadRequest:[NSURLRequest requestWithURL:pageURL]]; +} + +#pragma mark - View lifecycle + +- (void)loadView { + self.view = self.webView; + [self loadURL:self.URL]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + [self updateToolbarItems]; +} + +- (void)viewDidUnload { + [super viewDidUnload]; + self.webView = nil; + _backBarButtonItem = nil; + _forwardBarButtonItem = nil; + _refreshBarButtonItem = nil; + _stopBarButtonItem = nil; + _actionBarButtonItem = nil; +} + +- (void)viewWillAppear:(BOOL)animated { + NSAssert(self.navigationController, @"SVWebViewController needs to be contained in a UINavigationController. If you are presenting SVWebViewController modally, use SVModalWebViewController instead."); + + [super viewWillAppear:animated]; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { + [self.navigationController setToolbarHidden:NO animated:animated]; + } +} + +- (void)viewWillDisappear:(BOOL)animated { + [super viewWillDisappear:animated]; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) { + [self.navigationController setToolbarHidden:YES animated:animated]; + } +} + +- (void)viewDidDisappear:(BOOL)animated { + [super viewDidDisappear:animated]; + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; +} + +- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)toInterfaceOrientation { + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) + return YES; + + return toInterfaceOrientation != UIInterfaceOrientationPortraitUpsideDown; +} + +#pragma mark - Getters + +- (UIWebView*)webView { + if(!_webView) { + _webView = [[UIWebView alloc] initWithFrame:[UIScreen mainScreen].bounds]; + _webView.delegate = self; + _webView.scalesPageToFit = YES; + } + return _webView; +} + +- (UIBarButtonItem *)backBarButtonItem { + if (!_backBarButtonItem) { + _backBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"SVWebViewController.bundle/SVWebViewControllerBack"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(goBackClicked:)]; + _backBarButtonItem.width = 18.0f; + } + return _backBarButtonItem; +} + +- (UIBarButtonItem *)forwardBarButtonItem { + if (!_forwardBarButtonItem) { + _forwardBarButtonItem = [[UIBarButtonItem alloc] initWithImage:[UIImage imageNamed:@"SVWebViewController.bundle/SVWebViewControllerNext"] + style:UIBarButtonItemStylePlain + target:self + action:@selector(goForwardClicked:)]; + _forwardBarButtonItem.width = 18.0f; + } + return _forwardBarButtonItem; +} + +- (UIBarButtonItem *)refreshBarButtonItem { + if (!_refreshBarButtonItem) { + _refreshBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemRefresh target:self action:@selector(reloadClicked:)]; + } + return _refreshBarButtonItem; +} + +- (UIBarButtonItem *)stopBarButtonItem { + if (!_stopBarButtonItem) { + _stopBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemStop target:self action:@selector(stopClicked:)]; + } + return _stopBarButtonItem; +} + +- (UIBarButtonItem *)actionBarButtonItem { + if (!_actionBarButtonItem) { + _actionBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemAction target:self action:@selector(actionButtonClicked:)]; + } + return _actionBarButtonItem; +} + +#pragma mark - Toolbar + +- (void)updateToolbarItems { + self.backBarButtonItem.enabled = self.self.webView.canGoBack; + self.forwardBarButtonItem.enabled = self.self.webView.canGoForward; + self.actionBarButtonItem.enabled = !self.self.webView.isLoading; + + UIBarButtonItem *refreshStopBarButtonItem = self.self.webView.isLoading ? self.stopBarButtonItem : self.refreshBarButtonItem; + + UIBarButtonItem *fixedSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; + UIBarButtonItem *flexibleSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil]; + + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) { + CGFloat toolbarWidth = 250.0f; + fixedSpace.width = 35.0f; + + NSArray *items = [NSArray arrayWithObjects: + fixedSpace, + refreshStopBarButtonItem, + fixedSpace, + self.backBarButtonItem, + fixedSpace, + self.forwardBarButtonItem, + fixedSpace, + self.actionBarButtonItem, + nil]; + + UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0.0f, 0.0f, toolbarWidth, 44.0f)]; + toolbar.items = items; + toolbar.barStyle = self.navigationController.navigationBar.barStyle; + toolbar.tintColor = self.navigationController.navigationBar.tintColor; + self.navigationItem.rightBarButtonItems = items.reverseObjectEnumerator.allObjects; + } + + else { + NSArray *items = [NSArray arrayWithObjects: + fixedSpace, + self.backBarButtonItem, + flexibleSpace, + self.forwardBarButtonItem, + flexibleSpace, + refreshStopBarButtonItem, + flexibleSpace, + self.actionBarButtonItem, + fixedSpace, + nil]; + + self.navigationController.toolbar.barStyle = self.navigationController.navigationBar.barStyle; + self.navigationController.toolbar.tintColor = self.navigationController.navigationBar.tintColor; + self.toolbarItems = items; + } +} + +#pragma mark - UIWebViewDelegate + +- (void)webViewDidStartLoad:(UIWebView *)webView { + + [SVProgressHUD show]; + + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:YES]; + [self updateToolbarItems]; +} + + +- (void)webViewDidFinishLoad:(UIWebView *)webView { + + [SVProgressHUD dismiss]; + + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; + + self.navigationItem.title = [webView stringByEvaluatingJavaScriptFromString:@"document.title"]; + [self updateToolbarItems]; + + +} + +- (void)webView:(UIWebView *)webView didFailLoadWithError:(NSError *)error { + [[UIApplication sharedApplication] setNetworkActivityIndicatorVisible:NO]; + [self updateToolbarItems]; + + [SVProgressHUD dismiss]; +} + +#pragma mark - Target actions + +- (void)goBackClicked:(UIBarButtonItem *)sender { + [self.webView goBack]; +} + +- (void)goForwardClicked:(UIBarButtonItem *)sender { + [self.webView goForward]; +} + +- (void)reloadClicked:(UIBarButtonItem *)sender { + [self.webView reload]; +} + +- (void)stopClicked:(UIBarButtonItem *)sender { + [self.webView stopLoading]; + [self updateToolbarItems]; +} + +- (void)actionButtonClicked:(id)sender { + NSArray *activities = @[[SVWebViewControllerActivitySafari new], [SVWebViewControllerActivityChrome new]]; + + UIActivityViewController *activityController = [[UIActivityViewController alloc] initWithActivityItems:@[self.self.webView.request.URL] applicationActivities:activities]; + [self presentViewController:activityController animated:YES completion:nil]; +} + +- (void)doneButtonClicked:(id)sender { + [SVProgressHUD dismiss]; + [self dismissViewControllerAnimated:YES completion:NULL]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png new file mode 100644 index 0000000..cd19edb Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png new file mode 100644 index 0000000..5c8b081 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h new file mode 100644 index 0000000..6525193 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.h @@ -0,0 +1,13 @@ +// +// SVWebViewControllerActivityChrome.h +// +// Created by Sam Vermette on 11 Nov, 2013. +// Copyright 2013 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVWebViewControllerActivity.h" + +@interface SVWebViewControllerActivityChrome : SVWebViewControllerActivity + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m new file mode 100644 index 0000000..f50f68e --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome.m @@ -0,0 +1,38 @@ +// +// SVWebViewControllerActivityChrome.h +// +// Created by Sam Vermette on 11 Nov, 2013. +// Copyright 2013 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVWebViewControllerActivityChrome.h" + +@implementation SVWebViewControllerActivityChrome + +- (NSString *)schemePrefix { + return @"googlechrome://"; +} + +- (NSString *)activityTitle { + return NSLocalizedStringFromTable(@"Open in Chrome", @"SVWebViewController", nil); +} + +- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { + for (id activityItem in activityItems) { + if ([activityItem isKindOfClass:[NSURL class]] && [[UIApplication sharedApplication] canOpenURL:[NSURL URLWithString:self.schemePrefix]]) { + return YES; + } + } + return NO; +} + +- (void)performActivity { + NSString *openingURL = [self.URLToOpen.absoluteString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]; + NSURL *activityURL = [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", self.schemePrefix, openingURL]]; + [[UIApplication sharedApplication] openURL:activityURL]; + + [self activityDidFinish:YES]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png new file mode 100644 index 0000000..565e0ce Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.h b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.h new file mode 100644 index 0000000..1d643e8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.h @@ -0,0 +1,16 @@ +// +// SVWebViewControllerActivity.h +// SVWeb +// +// Created by Sam Vermette on 11/11/2013. +// +// + +#import + +@interface SVWebViewControllerActivity : UIActivity + +@property (nonatomic, strong) NSURL *URLToOpen; +@property (nonatomic, strong) NSString *schemePrefix; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.m b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.m new file mode 100644 index 0000000..df362b6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/SVWebViewControllerActivity.m @@ -0,0 +1,32 @@ +// +// SVWebViewControllerActivity.m +// SVWeb +// +// Created by Sam Vermette on 11/11/2013. +// +// + +#import "SVWebViewControllerActivity.h" + +@implementation SVWebViewControllerActivity + +- (NSString *)activityType { + return NSStringFromClass([self class]); +} + +- (UIImage *)activityImage { + if (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) + return [UIImage imageNamed:[self.activityType stringByAppendingString:@"-iPad"]]; + else + return [UIImage imageNamed:self.activityType]; +} + +- (void)prepareWithActivityItems:(NSArray *)activityItems { + for (id activityItem in activityItems) { + if ([activityItem isKindOfClass:[NSURL class]]) { + self.URLToOpen = activityItem; + } + } +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png new file mode 100644 index 0000000..31f2ca8 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad@2x.png new file mode 100644 index 0000000..856e4d0 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h new file mode 100644 index 0000000..11d4c27 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.h @@ -0,0 +1,13 @@ +// +// SVWebViewControllerActivitySafari.h +// +// Created by Sam Vermette on 11 Nov, 2013. +// Copyright 2013 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + +#import "SVWebViewControllerActivity.h" + +@interface SVWebViewControllerActivitySafari : SVWebViewControllerActivity + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m new file mode 100644 index 0000000..5235684 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari.m @@ -0,0 +1,32 @@ +// +// SVWebViewControllerActivitySafari.m +// +// Created by Sam Vermette on 11 Nov, 2013. +// Copyright 2013 Sam Vermette. All rights reserved. +// +// https://github.com/samvermette/SVWebViewController + + +#import "SVWebViewControllerActivitySafari.h" + +@implementation SVWebViewControllerActivitySafari + +- (NSString *)activityTitle { + return NSLocalizedStringFromTable(@"Open in Safari", @"SVWebViewController", nil); +} + +- (BOOL)canPerformWithActivityItems:(NSArray *)activityItems { + for (id activityItem in activityItems) { + if ([activityItem isKindOfClass:[NSURL class]] && [[UIApplication sharedApplication] canOpenURL:activityItem]) { + return YES; + } + } + return NO; +} + +- (void)performActivity { + BOOL completed = [[UIApplication sharedApplication] openURL:self.URLToOpen]; + [self activityDidFinish:completed]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png new file mode 100644 index 0000000..b0dc8c7 Binary files /dev/null and b/iOSStudy/iOSStudy/Pods/SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png differ diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/LICENCE b/iOSStudy/iOSStudy/Pods/SWTableViewCell/LICENCE new file mode 100644 index 0000000..89b15e0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/LICENCE @@ -0,0 +1,19 @@ +Copyright (c) 2013 Christopher Wendel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/README.md b/iOSStudy/iOSStudy/Pods/SWTableViewCell/README.md new file mode 100644 index 0000000..acccd4a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/README.md @@ -0,0 +1,249 @@ +SWTableViewCell +=============== + +

+ +An easy-to-use UITableViewCell subclass that implements a swipeable content view which exposes utility buttons (similar to iOS 7 Mail Application) + +##Usage +In your Podfile: +
pod 'SWTableViewCell', '~> 0.3.7'
+ +Or just clone this repo and manually add source to project + +##Functionality +###Right Utility Buttons +Utility buttons that become visible on the right side of the Table View Cell when the user swipes left. This behavior is similar to that seen in the iOS apps Mail and Reminders. + +

+ +###Left Utility Buttons +Utility buttons that become visible on the left side of the Table View Cell when the user swipes right. + +

+ +###Features +* Dynamic utility button scalling. As you add more buttons to a cell, the other buttons on that side get smaller to make room +* Smart selection: The cell will pick up touch events and either scroll the cell back to center or fire the delegate method `- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath` +

+So the cell will not be considered selected when the user touches the cell while utility buttons are visible, instead the cell will slide back into place (same as iOS 7 Mail App functionality) +* Create utilty buttons with either a title or an icon along with a RGB color +* Tested on iOS 6.1 and above, including iOS 7 + +##Usage + +###Standard Table View Cells + +In your `tableView:cellForRowAtIndexPath:` method you set up the SWTableView cell and add an arbitrary amount of utility buttons to it using the included `NSMutableArray+SWUtilityButtons` category. + +```objc +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { + static NSString *cellIdentifier = @"Cell"; + + SWTableViewCell *cell = (SWTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier]; + + if (cell == nil) { + cell = [[SWTableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:cellIdentifier]; + cell.leftUtilityButtons = [self leftButtons]; + cell.rightUtilityButtons = [self rightButtons]; + cell.delegate = self; + } + + NSDate *dateObject = _testArray[indexPath.row]; + cell.textLabel.text = [dateObject description]; + cell.detailTextLabel.text = @"Some detail text"; + + return cell; +} + +- (NSArray *)rightButtons +{ + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:0.78f green:0.78f blue:0.8f alpha:1.0] + title:@"More"]; + [rightUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:1.0f green:0.231f blue:0.188 alpha:1.0f] + title:@"Delete"]; + + return rightUtilityButtons; +} + +- (NSArray *)leftButtons +{ + NSMutableArray *leftUtilityButtons = [NSMutableArray new]; + + [leftUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:0.07 green:0.75f blue:0.16f alpha:1.0] + icon:[UIImage imageNamed:@"check.png"]]; + [leftUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:1.0f green:1.0f blue:0.35f alpha:1.0] + icon:[UIImage imageNamed:@"clock.png"]]; + [leftUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:1.0f green:0.231f blue:0.188f alpha:1.0] + icon:[UIImage imageNamed:@"cross.png"]]; + [leftUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:0.55f green:0.27f blue:0.07f alpha:1.0] + icon:[UIImage imageNamed:@"list.png"]]; + + return leftUtilityButtons; +} +``` + +###Custom Table View Cells + +Thanks to [Matt Bowman](https://github.com/MattCBowman) you can now create custom table view cells using Interface Builder that have the capabilities of an SWTableViewCell + +The first step is to design your cell either in a standalone nib or inside of a +table view using prototype cells. Make sure to set the custom class on the +cell in interface builder to the subclass you made for it: + +

+ +Then set the cell reuse identifier: + +

+ +When writing your custom table view cell's code, make sure your cell is a +subclass of SWTableViewCell: + +```objc + +#import + +@interface MyCustomTableViewCell : SWTableViewCell + +@property (weak, nonatomic) UILabel *customLabel; +@property (weak, nonatomic) UIImageView *customImageView; + +@end + +``` + +If you are using a separate nib and not a prototype cell, you'll need to be sure to register the nib in your table view: + +```objc + +- (void)viewDidLoad +{ + [super viewDidLoad]; + + [self.tableView registerNib:[UINib nibWithNibName:@"MyCustomTableViewCellNibFileName" bundle:nil] forCellReuseIdentifier:@"MyCustomCell"]; +} + +``` + +Then, in the `tableView:cellForRowAtIndexPath:` method of your `UITableViewDelegate` (usually your view controller), initialize your custom cell: + +```objc +- (UITableViewCell*)tableView:(UITableView*)tableView cellForRowAtIndexPath:(NSIndexPath*)indexPath +{ + static NSString *cellIdentifier = @"MyCustomCell"; + + MyCustomTableViewCell *cell = (MyCustomTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier + forIndexPath:indexPath]; + + cell.leftUtilityButtons = [self leftButtons]; + cell.rightUtilityButtons = [self rightButtons]; + cell.delegate = self; + + cell.customLabel.text = @"Some Text"; + cell.customImageView.image = [UIImage imageNamed:@"MyAwesomeTableCellImage"]; + [cell setCellHeight:cell.frame.size.height]; + return cell; +} +``` + +###Delegate + +The delegate `SWTableViewCellDelegate` is used by the developer to find out which button was pressed. There are five methods: + +```objc +// click event on left utility button +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerLeftUtilityButtonWithIndex:(NSInteger)index; + +// click event on right utility button +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index; + +// utility button open/close event +- (void)swipeableTableViewCell:(SWTableViewCell *)cell scrollingToState:(SWCellState)state; + +// prevent multiple cells from showing utilty buttons simultaneously +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell; + +// prevent cell(s) from displaying left/right utility buttons +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state; +``` + +The index signifies which utility button the user pressed, for each side the button indices are ordered from right to left 0...n + +####Example + +```objc +#pragma mark - SWTableViewDelegate + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerLeftUtilityButtonWithIndex:(NSInteger)index { + switch (index) { + case 0: + NSLog(@"check button was pressed"); + break; + case 1: + NSLog(@"clock button was pressed"); + break; + case 2: + NSLog(@"cross button was pressed"); + break; + case 3: + NSLog(@"list button was pressed"); + default: + break; + } +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index { + switch (index) { + case 0: + NSLog(@"More button was pressed"); + break; + case 1: + { + // Delete button was pressed + NSIndexPath *cellIndexPath = [self.tableView indexPathForCell:cell]; + + [_testArray removeObjectAtIndex:cellIndexPath.row]; + [self.tableView deleteRowsAtIndexPaths:@[cellIndexPath] + withRowAnimation:UITableViewRowAnimationAutomatic]; + break; + } + default: + break; + } +} +``` + +(This is all code from the included example project) + +###Gotchas + +#### Seperator Insets +* If you have left utility button on iOS 7, I recommend changing your Table View's seperatorInset so the seperator stretches the length of the screen +
 tableView.separatorInset = UIEdgeInsetsMake(0, 0, 0, 0); 
+ + +##Contributing +Use [Github issues](https://github.com/cewendel/SWTableViewCell/issues) to track bugs and feature requests. + +##Contact + +Chris Wendel + +- http://twitter.com/CEWendel + +## Licence + +MIT + + + + + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h new file mode 100644 index 0000000..87edf77 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.h @@ -0,0 +1,25 @@ +// +// NSMutableArray+SWUtilityButtons.h +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import + +@interface NSMutableArray (SWUtilityButtons) + +- (void)sw_addUtilityButtonWithColor:(UIColor *)color title:(NSString *)title; +- (void)sw_addUtilityButtonWithColor:(UIColor *)color attributedTitle:(NSAttributedString *)title; +- (void)sw_addUtilityButtonWithColor:(UIColor *)color icon:(UIImage *)icon; +- (void)sw_addUtilityButtonWithColor:(UIColor *)color normalIcon:(UIImage *)normalIcon selectedIcon:(UIImage *)selectedIcon; + +@end + + +@interface NSArray (SWUtilityButtons) + +- (BOOL)sw_isEqualToButtons:(NSArray *)buttons; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m new file mode 100644 index 0000000..2d32b75 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/NSMutableArray+SWUtilityButtons.m @@ -0,0 +1,92 @@ +// +// NSMutableArray+SWUtilityButtons.m +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "NSMutableArray+SWUtilityButtons.h" + +@implementation NSMutableArray (SWUtilityButtons) + +- (void)sw_addUtilityButtonWithColor:(UIColor *)color title:(NSString *)title +{ + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.backgroundColor = color; + [button setTitle:title forState:UIControlStateNormal]; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [button.titleLabel setAdjustsFontSizeToFitWidth:YES]; + [self addObject:button]; +} + +- (void)sw_addUtilityButtonWithColor:(UIColor *)color attributedTitle:(NSAttributedString *)title +{ + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.backgroundColor = color; + [button setAttributedTitle:title forState:UIControlStateNormal]; + [button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal]; + [self addObject:button]; +} + +- (void)sw_addUtilityButtonWithColor:(UIColor *)color icon:(UIImage *)icon +{ + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.backgroundColor = color; + [button setImage:icon forState:UIControlStateNormal]; + [self addObject:button]; +} + +- (void)sw_addUtilityButtonWithColor:(UIColor *)color normalIcon:(UIImage *)normalIcon selectedIcon:(UIImage *)selectedIcon { + UIButton *button = [UIButton buttonWithType:UIButtonTypeCustom]; + button.backgroundColor = color; + [button setImage:normalIcon forState:UIControlStateNormal]; + [button setImage:selectedIcon forState:UIControlStateHighlighted]; + [button setImage:selectedIcon forState:UIControlStateSelected]; + [self addObject:button]; +} + +@end + + +@implementation NSArray (SWUtilityButtons) + +- (BOOL)sw_isEqualToButtons:(NSArray *)buttons +{ + buttons = [buttons copy]; + if (!buttons || self.count != buttons.count) return NO; + + for (NSUInteger idx = 0; idx < self.count; idx++) { + id buttonA = self[idx]; + id buttonB = buttons[idx]; + if (![buttonA isKindOfClass:[UIButton class]] || ![buttonB isKindOfClass:[UIButton class]]) return NO; + if (![[self class] sw_button:buttonA isEqualToButton:buttonB]) return NO; + } + + return YES; +} + ++ (BOOL)sw_button:(UIButton *)buttonA isEqualToButton:(UIButton *)buttonB +{ + if (!buttonA || !buttonB) return NO; + + UIColor *backgroundColorA = buttonA.backgroundColor; + UIColor *backgroundColorB = buttonB.backgroundColor; + BOOL haveEqualBackgroundColors = (!backgroundColorA && !backgroundColorB) || [backgroundColorA isEqual:backgroundColorB]; + + NSString *titleA = [buttonA titleForState:UIControlStateNormal]; + NSString *titleB = [buttonB titleForState:UIControlStateNormal]; + BOOL haveEqualTitles = (!titleA && !titleB) || [titleA isEqualToString:titleB]; + + UIImage *normalIconA = [buttonA imageForState:UIControlStateNormal]; + UIImage *normalIconB = [buttonB imageForState:UIControlStateNormal]; + BOOL haveEqualNormalIcons = (!normalIconA && !normalIconB) || [normalIconA isEqual:normalIconB]; + + UIImage *selectedIconA = [buttonA imageForState:UIControlStateSelected]; + UIImage *selectedIconB = [buttonB imageForState:UIControlStateSelected]; + BOOL haveEqualSelectedIcons = (!selectedIconA && !selectedIconB) || [selectedIconA isEqual:selectedIconB]; + + return haveEqualBackgroundColors && haveEqualTitles && haveEqualNormalIcons && haveEqualSelectedIcons; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.h new file mode 100644 index 0000000..50fe75b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.h @@ -0,0 +1,13 @@ +// +// SWCellScrollView.h +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import + +@interface SWCellScrollView : UIScrollView + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.m new file mode 100644 index 0000000..56b394a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWCellScrollView.m @@ -0,0 +1,42 @@ +// +// SWCellScrollView.m +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "SWCellScrollView.h" + +@implementation SWCellScrollView + +- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer +{ + if (gestureRecognizer == self.panGestureRecognizer) { + CGPoint translation = [(UIPanGestureRecognizer*)gestureRecognizer translationInView:gestureRecognizer.view]; + return fabs(translation.y) <= fabs(translation.x); + } else { + return YES; + } +} + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer { + // Find out if the user is actively scrolling the tableView of which this is a member. + // If they are, return NO, and don't let the gesture recognizers work simultaneously. + // + // This works very well in maintaining user expectations while still allowing for the user to + // scroll the cell sideways when that is their true intent. + if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) { + + // Find the current scrolling velocity in that view, in the Y direction. + CGFloat yVelocity = [(UIPanGestureRecognizer*)gestureRecognizer velocityInView:gestureRecognizer.view].y; + + // Return YES iff the user is not actively scrolling up. + return fabs(yVelocity) <= 0.25; + + } + return YES; +} + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h new file mode 100644 index 0000000..a6f57e9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.h @@ -0,0 +1,15 @@ +// +// SWLongPressGestureRecognizer.h +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import +#import + +@interface SWLongPressGestureRecognizer : UILongPressGestureRecognizer + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.m new file mode 100644 index 0000000..2f2c519 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWLongPressGestureRecognizer.m @@ -0,0 +1,33 @@ +// +// SWLongPressGestureRecognizer.m +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "SWLongPressGestureRecognizer.h" + +@implementation SWLongPressGestureRecognizer + +-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event +{ + [super touchesBegan:touches withEvent:event]; +} + +-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event +{ + [super touchesMoved:touches withEvent:event]; + + self.state = UIGestureRecognizerStateFailed; +} + +-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event +{ + [super touchesEnded:touches withEvent:event]; + + self.state = UIGestureRecognizerStateFailed; +} + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.h new file mode 100644 index 0000000..50b2d11 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.h @@ -0,0 +1,52 @@ +// +// SWTableViewCell.h +// SWTableViewCell +// +// Created by Chris Wendel on 9/10/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import +#import +#import "SWCellScrollView.h" +#import "SWLongPressGestureRecognizer.h" +#import "SWUtilityButtonTapGestureRecognizer.h" +#import "NSMutableArray+SWUtilityButtons.h" + +@class SWTableViewCell; + +typedef NS_ENUM(NSInteger, SWCellState) +{ + kCellStateCenter, + kCellStateLeft, + kCellStateRight, +}; + +@protocol SWTableViewCellDelegate + +@optional +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerLeftUtilityButtonWithIndex:(NSInteger)index; +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index; +- (void)swipeableTableViewCell:(SWTableViewCell *)cell scrollingToState:(SWCellState)state; +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell; +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state; +- (void)swipeableTableViewCellDidEndScrolling:(SWTableViewCell *)cell; + +@end + +@interface SWTableViewCell : UITableViewCell + +@property (nonatomic, copy) NSArray *leftUtilityButtons; +@property (nonatomic, copy) NSArray *rightUtilityButtons; + +@property (nonatomic, weak) id delegate; + +- (void)setRightUtilityButtons:(NSArray *)rightUtilityButtons WithButtonWidth:(CGFloat) width; +- (void)setLeftUtilityButtons:(NSArray *)leftUtilityButtons WithButtonWidth:(CGFloat) width; +- (void)hideUtilityButtonsAnimated:(BOOL)animated; +- (void)showLeftUtilityButtonsAnimated:(BOOL)animated; +- (void)showRightUtilityButtonsAnimated:(BOOL)animated; + +- (BOOL)isUtilityButtonsHidden; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.m new file mode 100644 index 0000000..a7c2a2b --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWTableViewCell.m @@ -0,0 +1,800 @@ +// +// SWTableViewCell.m +// SWTableViewCell +// +// Created by Chris Wendel on 9/10/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "SWTableViewCell.h" +#import "SWUtilityButtonView.h" + +static NSString * const kTableViewCellContentView = @"UITableViewCellContentView"; + +#define kSectionIndexWidth 15 +#define kAccessoryTrailingSpace 15 +#define kLongPressMinimumDuration 0.16f + +@interface SWTableViewCell () + +@property (nonatomic, weak) UITableView *containingTableView; + +@property (nonatomic, strong) UIPanGestureRecognizer *tableViewPanGestureRecognizer; + +@property (nonatomic, assign) SWCellState cellState; // The state of the cell within the scroll view, can be left, right or middle +@property (nonatomic, assign) CGFloat additionalRightPadding; + +@property (nonatomic, strong) UIScrollView *cellScrollView; +@property (nonatomic, strong) SWUtilityButtonView *leftUtilityButtonsView, *rightUtilityButtonsView; +@property (nonatomic, strong) UIView *leftUtilityClipView, *rightUtilityClipView; +@property (nonatomic, strong) NSLayoutConstraint *leftUtilityClipConstraint, *rightUtilityClipConstraint; + +@property (nonatomic, strong) UILongPressGestureRecognizer *longPressGestureRecognizer; +@property (nonatomic, strong) UITapGestureRecognizer *tapGestureRecognizer; + +- (CGFloat)leftUtilityButtonsWidth; +- (CGFloat)rightUtilityButtonsWidth; +- (CGFloat)utilityButtonsPadding; + +- (CGPoint)contentOffsetForCellState:(SWCellState)state; +- (void)updateCellState; + +- (BOOL)shouldHighlight; + +@end + +@implementation SWTableViewCell { + UIView *_contentCellView; + BOOL layoutUpdating; +} + +#pragma mark Initializers + +- (instancetype)initWithCoder:(NSCoder *)aDecoder +{ + self = [super initWithCoder:aDecoder]; + + if (self) + { + [self initializer]; + } + + return self; +} + +- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier +{ + self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; + + if (self) + { + [self initializer]; + } + + return self; +} + +- (void)initializer +{ + layoutUpdating = NO; + // Set up scroll view that will host our cell content + self.cellScrollView = [[SWCellScrollView alloc] init]; + self.cellScrollView.translatesAutoresizingMaskIntoConstraints = NO; + self.cellScrollView.delegate = self; + self.cellScrollView.showsHorizontalScrollIndicator = NO; + self.cellScrollView.scrollsToTop = NO; + self.cellScrollView.scrollEnabled = YES; + + _contentCellView = [[UIView alloc] init]; + [self.cellScrollView addSubview:_contentCellView]; + + // Add the cell scroll view to the cell + UIView *contentViewParent = self; + UIView *clipViewParent = self.cellScrollView; + if (![NSStringFromClass([[self.subviews objectAtIndex:0] class]) isEqualToString:kTableViewCellContentView]) + { + // iOS 7 + contentViewParent = [self.subviews objectAtIndex:0]; + clipViewParent = self; + } + NSArray *cellSubviews = [contentViewParent subviews]; + [self insertSubview:self.cellScrollView atIndex:0]; + for (UIView *subview in cellSubviews) + { + [_contentCellView addSubview:subview]; + } + + // Set scroll view to perpetually have same frame as self. Specifying relative to superview doesn't work, since the latter UITableViewCellScrollView has different behaviour. + [self addConstraints:@[ + [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:self.cellScrollView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0], + ]]; + + self.tapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewTapped:)]; + self.tapGestureRecognizer.cancelsTouchesInView = NO; + self.tapGestureRecognizer.delegate = self; + [self.cellScrollView addGestureRecognizer:self.tapGestureRecognizer]; + + self.longPressGestureRecognizer = [[SWLongPressGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewPressed:)]; + self.longPressGestureRecognizer.cancelsTouchesInView = NO; + self.longPressGestureRecognizer.minimumPressDuration = kLongPressMinimumDuration; + self.longPressGestureRecognizer.delegate = self; + [self.cellScrollView addGestureRecognizer:self.longPressGestureRecognizer]; + + // Create the left and right utility button views, as well as vanilla UIViews in which to embed them. We can manipulate the latter in order to effect clipping according to scroll position. + // Such an approach is necessary in order for the utility views to sit on top to get taps, as well as allow the backgroundColor (and private UITableViewCellBackgroundView) to work properly. + + self.leftUtilityClipView = [[UIView alloc] init]; + self.leftUtilityClipConstraint = [NSLayoutConstraint constraintWithItem:self.leftUtilityClipView attribute:NSLayoutAttributeRight relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeLeft multiplier:1.0 constant:0.0]; + self.leftUtilityButtonsView = [[SWUtilityButtonView alloc] initWithUtilityButtons:nil + parentCell:self + utilityButtonSelector:@selector(leftUtilityButtonHandler:)]; + + self.rightUtilityClipView = [[UIView alloc] initWithFrame:self.bounds]; + self.rightUtilityClipConstraint = [NSLayoutConstraint constraintWithItem:self.rightUtilityClipView attribute:NSLayoutAttributeLeft relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeRight multiplier:1.0 constant:0.0]; + self.rightUtilityButtonsView = [[SWUtilityButtonView alloc] initWithUtilityButtons:nil + parentCell:self + utilityButtonSelector:@selector(rightUtilityButtonHandler:)]; + + + UIView *clipViews[] = { self.rightUtilityClipView, self.leftUtilityClipView }; + NSLayoutConstraint *clipConstraints[] = { self.rightUtilityClipConstraint, self.leftUtilityClipConstraint }; + UIView *buttonViews[] = { self.rightUtilityButtonsView, self.leftUtilityButtonsView }; + NSLayoutAttribute alignmentAttributes[] = { NSLayoutAttributeRight, NSLayoutAttributeLeft }; + + for (NSUInteger i = 0; i < 2; ++i) + { + UIView *clipView = clipViews[i]; + NSLayoutConstraint *clipConstraint = clipConstraints[i]; + UIView *buttonView = buttonViews[i]; + NSLayoutAttribute alignmentAttribute = alignmentAttributes[i]; + + clipConstraint.priority = UILayoutPriorityDefaultHigh; + + clipView.translatesAutoresizingMaskIntoConstraints = NO; + clipView.clipsToBounds = YES; + + [clipViewParent addSubview:clipView]; + [self addConstraints:@[ + // Pin the clipping view to the appropriate outer edges of the cell. + [NSLayoutConstraint constraintWithItem:clipView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:clipView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:self attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:clipView attribute:alignmentAttribute relatedBy:NSLayoutRelationEqual toItem:self attribute:alignmentAttribute multiplier:1.0 constant:0.0], + clipConstraint, + ]]; + + [clipView addSubview:buttonView]; + [self addConstraints:@[ + // Pin the button view to the appropriate outer edges of its clipping view. + [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeTop relatedBy:NSLayoutRelationEqual toItem:clipView attribute:NSLayoutAttributeTop multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeBottom relatedBy:NSLayoutRelationEqual toItem:clipView attribute:NSLayoutAttributeBottom multiplier:1.0 constant:0.0], + [NSLayoutConstraint constraintWithItem:buttonView attribute:alignmentAttribute relatedBy:NSLayoutRelationEqual toItem:clipView attribute:alignmentAttribute multiplier:1.0 constant:0.0], + + // Constrain the maximum button width so that at least a button's worth of contentView is left visible. (The button view will shrink accordingly.) + [NSLayoutConstraint constraintWithItem:buttonView attribute:NSLayoutAttributeWidth relatedBy:NSLayoutRelationLessThanOrEqual toItem:self.contentView attribute:NSLayoutAttributeWidth multiplier:1.0 constant:-kUtilityButtonWidthDefault], + ]]; + } +} + +static NSString * const kTableViewPanState = @"state"; + +- (void)removeOldTableViewPanObserver +{ + [_tableViewPanGestureRecognizer removeObserver:self forKeyPath:kTableViewPanState]; +} + +- (void)dealloc +{ + [self removeOldTableViewPanObserver]; +} + +- (void)setContainingTableView:(UITableView *)containingTableView +{ + [self removeOldTableViewPanObserver]; + + _tableViewPanGestureRecognizer = containingTableView.panGestureRecognizer; + + _containingTableView = containingTableView; + + if (containingTableView) + { + // Check if the UITableView will display Indices on the right. If that's the case, add a padding + if ([_containingTableView.dataSource respondsToSelector:@selector(sectionIndexTitlesForTableView:)]) + { + NSArray *indices = [_containingTableView.dataSource sectionIndexTitlesForTableView:_containingTableView]; + self.additionalRightPadding = indices == nil ? 0 : kSectionIndexWidth; + } + + _containingTableView.directionalLockEnabled = YES; + + [self.tapGestureRecognizer requireGestureRecognizerToFail:_containingTableView.panGestureRecognizer]; + + [_tableViewPanGestureRecognizer addObserver:self forKeyPath:kTableViewPanState options:0 context:nil]; + } +} + +- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context +{ + if([keyPath isEqualToString:kTableViewPanState] && object == _tableViewPanGestureRecognizer) + { + if(_tableViewPanGestureRecognizer.state == UIGestureRecognizerStateBegan) + { + CGPoint locationInTableView = [_tableViewPanGestureRecognizer locationInView:_containingTableView]; + + BOOL inCurrentCell = CGRectContainsPoint(self.frame, locationInTableView); + if(!inCurrentCell && _cellState != kCellStateCenter) + { + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:)]) + { + if([self.delegate swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:self]) + { + [self hideUtilityButtonsAnimated:YES]; + } + } + } + } + } +} + +- (void)setLeftUtilityButtons:(NSArray *)leftUtilityButtons +{ + if (![_leftUtilityButtons sw_isEqualToButtons:leftUtilityButtons]) { + _leftUtilityButtons = leftUtilityButtons; + + self.leftUtilityButtonsView.utilityButtons = leftUtilityButtons; + + [self.leftUtilityButtonsView layoutIfNeeded]; + [self layoutIfNeeded]; + } +} + +- (void)setLeftUtilityButtons:(NSArray *)leftUtilityButtons WithButtonWidth:(CGFloat) width +{ + _leftUtilityButtons = leftUtilityButtons; + + [self.leftUtilityButtonsView setUtilityButtons:leftUtilityButtons WithButtonWidth:width]; + + [self.leftUtilityButtonsView layoutIfNeeded]; + [self layoutIfNeeded]; +} + +- (void)setRightUtilityButtons:(NSArray *)rightUtilityButtons +{ + if (![_rightUtilityButtons sw_isEqualToButtons:rightUtilityButtons]) { + _rightUtilityButtons = rightUtilityButtons; + + self.rightUtilityButtonsView.utilityButtons = rightUtilityButtons; + + [self.rightUtilityButtonsView layoutIfNeeded]; + [self layoutIfNeeded]; + } +} + +- (void)setRightUtilityButtons:(NSArray *)rightUtilityButtons WithButtonWidth:(CGFloat) width +{ + _rightUtilityButtons = rightUtilityButtons; + + [self.rightUtilityButtonsView setUtilityButtons:rightUtilityButtons WithButtonWidth:width]; + + [self.rightUtilityButtonsView layoutIfNeeded]; + [self layoutIfNeeded]; +} + +#pragma mark - UITableViewCell overrides + +- (void)didMoveToSuperview +{ + self.containingTableView = nil; + UIView *view = self.superview; + + do { + if ([view isKindOfClass:[UITableView class]]) + { + self.containingTableView = (UITableView *)view; + break; + } + } while ((view = view.superview)); +} + +- (void)layoutSubviews +{ + [super layoutSubviews]; + + // Offset the contentView origin so that it appears correctly w/rt the enclosing scroll view (to which we moved it). + CGRect frame = self.contentView.frame; + frame.origin.x = [self leftUtilityButtonsWidth]; + _contentCellView.frame = frame; + + self.cellScrollView.contentSize = CGSizeMake(CGRectGetWidth(self.frame) + [self utilityButtonsPadding], CGRectGetHeight(self.frame)); + + if (!self.cellScrollView.isTracking && !self.cellScrollView.isDecelerating) + { + self.cellScrollView.contentOffset = [self contentOffsetForCellState:_cellState]; + } + + [self updateCellState]; +} + +- (void)setFrame:(CGRect)frame +{ + layoutUpdating = YES; + // Fix for new screen sizes + // Initially, the cell is still 320 points wide + // We need to layout our subviews again when this changes so our constraints clip to the right width + BOOL widthChanged = (self.frame.size.width != frame.size.width); + + [super setFrame:frame]; + + if (widthChanged) + { + [self layoutIfNeeded]; + } + layoutUpdating = NO; +} + +- (void)prepareForReuse +{ + [super prepareForReuse]; + + [self hideUtilityButtonsAnimated:NO]; +} + +- (void)setSelected:(BOOL)selected animated:(BOOL)animated +{ + // Work around stupid background-destroying override magic that UITableView seems to perform on contained buttons. + + [self.leftUtilityButtonsView pushBackgroundColors]; + [self.rightUtilityButtonsView pushBackgroundColors]; + + [super setSelected:selected animated:animated]; + + [self.leftUtilityButtonsView popBackgroundColors]; + [self.rightUtilityButtonsView popBackgroundColors]; +} + +- (void)didTransitionToState:(UITableViewCellStateMask)state { + [super didTransitionToState:state]; + + if (state == UITableViewCellStateDefaultMask) { + [self layoutSubviews]; + } +} + +#pragma mark - Selection handling + +- (BOOL)shouldHighlight +{ + BOOL shouldHighlight = YES; + + if ([self.containingTableView.delegate respondsToSelector:@selector(tableView:shouldHighlightRowAtIndexPath:)]) + { + NSIndexPath *cellIndexPath = [self.containingTableView indexPathForCell:self]; + + shouldHighlight = [self.containingTableView.delegate tableView:self.containingTableView shouldHighlightRowAtIndexPath:cellIndexPath]; + } + + return shouldHighlight; +} + +- (void)scrollViewPressed:(UIGestureRecognizer *)gestureRecognizer +{ + if (gestureRecognizer.state == UIGestureRecognizerStateBegan && !self.isHighlighted && self.shouldHighlight) + { + [self setHighlighted:YES animated:NO]; + } + + else if (gestureRecognizer.state == UIGestureRecognizerStateEnded) + { + // Cell is already highlighted; clearing it temporarily seems to address visual anomaly. + [self setHighlighted:NO animated:NO]; + [self scrollViewTapped:gestureRecognizer]; + } + + else if (gestureRecognizer.state == UIGestureRecognizerStateCancelled) + { + [self setHighlighted:NO animated:NO]; + } +} + +- (void)scrollViewTapped:(UIGestureRecognizer *)gestureRecognizer +{ + if (_cellState == kCellStateCenter) + { + if (self.isSelected) + { + [self deselectCell]; + } + else if (self.shouldHighlight) // UITableView refuses selection if highlight is also refused. + { + [self selectCell]; + } + } + else + { + // Scroll back to center + [self hideUtilityButtonsAnimated:YES]; + } +} + +- (void)selectCell +{ + if (_cellState == kCellStateCenter) + { + NSIndexPath *cellIndexPath = [self.containingTableView indexPathForCell:self]; + + if ([self.containingTableView.delegate respondsToSelector:@selector(tableView:willSelectRowAtIndexPath:)]) + { + cellIndexPath = [self.containingTableView.delegate tableView:self.containingTableView willSelectRowAtIndexPath:cellIndexPath]; + } + + if (cellIndexPath) + { + [self.containingTableView selectRowAtIndexPath:cellIndexPath animated:NO scrollPosition:UITableViewScrollPositionNone]; + + if ([self.containingTableView.delegate respondsToSelector:@selector(tableView:didSelectRowAtIndexPath:)]) + { + [self.containingTableView.delegate tableView:self.containingTableView didSelectRowAtIndexPath:cellIndexPath]; + } + } + } +} + +- (void)deselectCell +{ + if (_cellState == kCellStateCenter) + { + NSIndexPath *cellIndexPath = [self.containingTableView indexPathForCell:self]; + + if ([self.containingTableView.delegate respondsToSelector:@selector(tableView:willDeselectRowAtIndexPath:)]) + { + cellIndexPath = [self.containingTableView.delegate tableView:self.containingTableView willDeselectRowAtIndexPath:cellIndexPath]; + } + + if (cellIndexPath) + { + [self.containingTableView deselectRowAtIndexPath:cellIndexPath animated:NO]; + + if ([self.containingTableView.delegate respondsToSelector:@selector(tableView:didDeselectRowAtIndexPath:)]) + { + [self.containingTableView.delegate tableView:self.containingTableView didDeselectRowAtIndexPath:cellIndexPath]; + } + } + } +} + +#pragma mark - Utility buttons handling + +- (void)rightUtilityButtonHandler:(id)sender +{ + SWUtilityButtonTapGestureRecognizer *utilityButtonTapGestureRecognizer = (SWUtilityButtonTapGestureRecognizer *)sender; + NSUInteger utilityButtonIndex = utilityButtonTapGestureRecognizer.buttonIndex; + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:didTriggerRightUtilityButtonWithIndex:)]) + { + [self.delegate swipeableTableViewCell:self didTriggerRightUtilityButtonWithIndex:utilityButtonIndex]; + } +} + +- (void)leftUtilityButtonHandler:(id)sender +{ + SWUtilityButtonTapGestureRecognizer *utilityButtonTapGestureRecognizer = (SWUtilityButtonTapGestureRecognizer *)sender; + NSUInteger utilityButtonIndex = utilityButtonTapGestureRecognizer.buttonIndex; + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:didTriggerLeftUtilityButtonWithIndex:)]) + { + [self.delegate swipeableTableViewCell:self didTriggerLeftUtilityButtonWithIndex:utilityButtonIndex]; + } +} + +- (void)hideUtilityButtonsAnimated:(BOOL)animated +{ + if (_cellState != kCellStateCenter) + { + [self.cellScrollView setContentOffset:[self contentOffsetForCellState:kCellStateCenter] animated:animated]; + + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:scrollingToState:)]) + { + [self.delegate swipeableTableViewCell:self scrollingToState:kCellStateCenter]; + } + } +} + +- (void)showLeftUtilityButtonsAnimated:(BOOL)animated { + if (_cellState != kCellStateLeft) + { + [self.cellScrollView setContentOffset:[self contentOffsetForCellState:kCellStateLeft] animated:animated]; + + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:scrollingToState:)]) + { + [self.delegate swipeableTableViewCell:self scrollingToState:kCellStateLeft]; + } + } +} + +- (void)showRightUtilityButtonsAnimated:(BOOL)animated { + if (_cellState != kCellStateRight) + { + [self.cellScrollView setContentOffset:[self contentOffsetForCellState:kCellStateRight] animated:animated]; + + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:scrollingToState:)]) + { + [self.delegate swipeableTableViewCell:self scrollingToState:kCellStateRight]; + } + } +} + +- (BOOL)isUtilityButtonsHidden { + return _cellState == kCellStateCenter; +} + + +#pragma mark - Geometry helpers + +- (CGFloat)leftUtilityButtonsWidth +{ +#if CGFLOAT_IS_DOUBLE + return round(CGRectGetWidth(self.leftUtilityButtonsView.frame)); +#else + return roundf(CGRectGetWidth(self.leftUtilityButtonsView.frame)); +#endif +} + +- (CGFloat)rightUtilityButtonsWidth +{ +#if CGFLOAT_IS_DOUBLE + return round(CGRectGetWidth(self.rightUtilityButtonsView.frame) + self.additionalRightPadding); +#else + return roundf(CGRectGetWidth(self.rightUtilityButtonsView.frame) + self.additionalRightPadding); +#endif +} + +- (CGFloat)utilityButtonsPadding +{ +#if CGFLOAT_IS_DOUBLE + return round([self leftUtilityButtonsWidth] + [self rightUtilityButtonsWidth]); +#else + return roundf([self leftUtilityButtonsWidth] + [self rightUtilityButtonsWidth]); +#endif +} + +- (CGPoint)contentOffsetForCellState:(SWCellState)state +{ + CGPoint scrollPt = CGPointZero; + + switch (state) + { + case kCellStateCenter: + scrollPt.x = [self leftUtilityButtonsWidth]; + break; + + case kCellStateRight: + scrollPt.x = [self utilityButtonsPadding]; + break; + + case kCellStateLeft: + scrollPt.x = 0; + break; + } + + return scrollPt; +} + +- (void)updateCellState +{ + if(layoutUpdating == NO) + { + // Update the cell state according to the current scroll view contentOffset. + for (NSNumber *numState in @[ + @(kCellStateCenter), + @(kCellStateLeft), + @(kCellStateRight), + ]) + { + SWCellState cellState = numState.integerValue; + + if (CGPointEqualToPoint(self.cellScrollView.contentOffset, [self contentOffsetForCellState:cellState])) + { + _cellState = cellState; + break; + } + } + + // Update the clipping on the utility button views according to the current position. + CGRect frame = [self.contentView.superview convertRect:self.contentView.frame toView:self]; + frame.size.width = CGRectGetWidth(self.frame); + + self.leftUtilityClipConstraint.constant = MAX(0, CGRectGetMinX(frame) - CGRectGetMinX(self.frame)); + self.rightUtilityClipConstraint.constant = MIN(0, CGRectGetMaxX(frame) - CGRectGetMaxX(self.frame)); + + if (self.isEditing) { + self.leftUtilityClipConstraint.constant = 0; + self.cellScrollView.contentOffset = CGPointMake([self leftUtilityButtonsWidth], 0); + _cellState = kCellStateCenter; + } + + self.leftUtilityClipView.hidden = (self.leftUtilityClipConstraint.constant == 0); + self.rightUtilityClipView.hidden = (self.rightUtilityClipConstraint.constant == 0); + + if (self.accessoryType != UITableViewCellAccessoryNone && !self.editing) { + UIView *accessory = [self.cellScrollView.superview.subviews lastObject]; + + CGRect accessoryFrame = accessory.frame; + accessoryFrame.origin.x = CGRectGetWidth(frame) - CGRectGetWidth(accessoryFrame) - kAccessoryTrailingSpace + CGRectGetMinX(frame); + accessory.frame = accessoryFrame; + } + + // Enable or disable the gesture recognizers according to the current mode. + if (!self.cellScrollView.isDragging && !self.cellScrollView.isDecelerating) + { + self.tapGestureRecognizer.enabled = YES; + self.longPressGestureRecognizer.enabled = (_cellState == kCellStateCenter); + } + else + { + self.tapGestureRecognizer.enabled = NO; + self.longPressGestureRecognizer.enabled = NO; + } + + self.cellScrollView.scrollEnabled = !self.isEditing; + } +} + +#pragma mark - UIScrollViewDelegate + +- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset +{ + if (velocity.x >= 0.5f) + { + if (_cellState == kCellStateLeft || !self.rightUtilityButtons || self.rightUtilityButtonsWidth == 0.0) + { + _cellState = kCellStateCenter; + } + else + { + _cellState = kCellStateRight; + } + } + else if (velocity.x <= -0.5f) + { + if (_cellState == kCellStateRight || !self.leftUtilityButtons || self.leftUtilityButtonsWidth == 0.0) + { + _cellState = kCellStateCenter; + } + else + { + _cellState = kCellStateLeft; + } + } + else + { + CGFloat leftThreshold = [self contentOffsetForCellState:kCellStateLeft].x + (self.leftUtilityButtonsWidth / 2); + CGFloat rightThreshold = [self contentOffsetForCellState:kCellStateRight].x - (self.rightUtilityButtonsWidth / 2); + + if (targetContentOffset->x > rightThreshold) + { + _cellState = kCellStateRight; + } + else if (targetContentOffset->x < leftThreshold) + { + _cellState = kCellStateLeft; + } + else + { + _cellState = kCellStateCenter; + } + } + + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCell:scrollingToState:)]) + { + [self.delegate swipeableTableViewCell:self scrollingToState:_cellState]; + } + + if (_cellState != kCellStateCenter) + { + if ([self.delegate respondsToSelector:@selector(swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:)]) + { + for (SWTableViewCell *cell in [self.containingTableView visibleCells]) { + if (cell != self && [cell isKindOfClass:[SWTableViewCell class]] && [self.delegate swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:cell]) { + [cell hideUtilityButtonsAnimated:YES]; + } + } + } + } + + *targetContentOffset = [self contentOffsetForCellState:_cellState]; +} + +- (void)scrollViewDidScroll:(UIScrollView *)scrollView +{ + if (scrollView.contentOffset.x > [self leftUtilityButtonsWidth]) + { + if ([self rightUtilityButtonsWidth] > 0) + { + if (self.delegate && [self.delegate respondsToSelector:@selector(swipeableTableViewCell:canSwipeToState:)]) + { + BOOL shouldScroll = [self.delegate swipeableTableViewCell:self canSwipeToState:kCellStateRight]; + if (!shouldScroll) + { + scrollView.contentOffset = CGPointMake([self leftUtilityButtonsWidth], 0); + } + } + } + else + { + [scrollView setContentOffset:CGPointMake([self leftUtilityButtonsWidth], 0)]; + self.tapGestureRecognizer.enabled = YES; + } + } + else + { + // Expose the left button view + if ([self leftUtilityButtonsWidth] > 0) + { + if (self.delegate && [self.delegate respondsToSelector:@selector(swipeableTableViewCell:canSwipeToState:)]) + { + BOOL shouldScroll = [self.delegate swipeableTableViewCell:self canSwipeToState:kCellStateLeft]; + if (!shouldScroll) + { + scrollView.contentOffset = CGPointMake([self leftUtilityButtonsWidth], 0); + } + } + } + else + { + [scrollView setContentOffset:CGPointMake(0, 0)]; + self.tapGestureRecognizer.enabled = YES; + } + } + + [self updateCellState]; +} + +- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView +{ + [self updateCellState]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(swipeableTableViewCellDidEndScrolling:)]) { + [self.delegate swipeableTableViewCellDidEndScrolling:self]; + } +} + +- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView +{ + [self updateCellState]; + + if (self.delegate && [self.delegate respondsToSelector:@selector(swipeableTableViewCellDidEndScrolling:)]) { + [self.delegate swipeableTableViewCellDidEndScrolling:self]; + } +} + +-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate +{ + if (!decelerate) + { + self.tapGestureRecognizer.enabled = YES; + } + +} + +#pragma mark - UIGestureRecognizerDelegate + +- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer +{ + if ((gestureRecognizer == self.containingTableView.panGestureRecognizer && otherGestureRecognizer == self.longPressGestureRecognizer) + || (gestureRecognizer == self.longPressGestureRecognizer && otherGestureRecognizer == self.containingTableView.panGestureRecognizer)) + { + // Return YES so the pan gesture of the containing table view is not cancelled by the long press recognizer + return YES; + } + else + { + return NO; + } +} + +-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch +{ + return ![touch.view isKindOfClass:[UIControl class]]; +} + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h new file mode 100644 index 0000000..6d7e7c8 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.h @@ -0,0 +1,17 @@ +// +// SWUtilityButtonTapGestureRecognizer.h +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import +#import + +@interface SWUtilityButtonTapGestureRecognizer : UITapGestureRecognizer + +@property (nonatomic) NSUInteger buttonIndex; + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m new file mode 100644 index 0000000..549bc9f --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonTapGestureRecognizer.m @@ -0,0 +1,14 @@ +// +// SWUtilityButtonTapGestureRecognizer.m +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "SWUtilityButtonTapGestureRecognizer.h" + +@implementation SWUtilityButtonTapGestureRecognizer + +@end + diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.h b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.h new file mode 100644 index 0000000..c201220 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.h @@ -0,0 +1,27 @@ +// +// SWUtilityButtonView.h +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import +@class SWTableViewCell; + +#define kUtilityButtonWidthDefault 90 + +@interface SWUtilityButtonView : UIView + +- (id)initWithUtilityButtons:(NSArray *)utilityButtons parentCell:(SWTableViewCell *)parentCell utilityButtonSelector:(SEL)utilityButtonSelector; +- (id)initWithFrame:(CGRect)frame utilityButtons:(NSArray *)utilityButtons parentCell:(SWTableViewCell *)parentCell utilityButtonSelector:(SEL)utilityButtonSelector; + +@property (nonatomic, weak, readonly) SWTableViewCell *parentCell; +@property (nonatomic, copy) NSArray *utilityButtons; +@property (nonatomic, assign) SEL utilityButtonSelector; + +- (void)setUtilityButtons:(NSArray *)utilityButtons WithButtonWidth:(CGFloat)width; +- (void)pushBackgroundColors; +- (void)popBackgroundColors; + +@end diff --git a/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.m b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.m new file mode 100644 index 0000000..c36908f --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/SWTableViewCell/SWTableViewCell/PodFiles/SWUtilityButtonView.m @@ -0,0 +1,153 @@ +// +// SWUtilityButtonView.m +// SWTableViewCell +// +// Created by Matt Bowman on 11/27/13. +// Copyright (c) 2013 Chris Wendel. All rights reserved. +// + +#import "SWUtilityButtonView.h" +#import "SWUtilityButtonTapGestureRecognizer.h" + +@interface SWUtilityButtonView() + +@property (nonatomic, strong) NSLayoutConstraint *widthConstraint; +@property (nonatomic, strong) NSMutableArray *buttonBackgroundColors; + +@end + +@implementation SWUtilityButtonView + +#pragma mark - SWUtilityButonView initializers + +- (id)initWithUtilityButtons:(NSArray *)utilityButtons parentCell:(SWTableViewCell *)parentCell utilityButtonSelector:(SEL)utilityButtonSelector +{ + self = [self initWithFrame:CGRectZero utilityButtons:utilityButtons parentCell:parentCell utilityButtonSelector:utilityButtonSelector]; + + return self; +} + +- (id)initWithFrame:(CGRect)frame utilityButtons:(NSArray *)utilityButtons parentCell:(SWTableViewCell *)parentCell utilityButtonSelector:(SEL)utilityButtonSelector +{ + self = [super initWithFrame:frame]; + + if (self) { + self.translatesAutoresizingMaskIntoConstraints = NO; + + self.widthConstraint = [NSLayoutConstraint constraintWithItem:self + attribute:NSLayoutAttributeWidth + relatedBy:NSLayoutRelationEqual + toItem:nil + attribute:NSLayoutAttributeNotAnAttribute + multiplier:1.0 + constant:0.0]; // constant will be adjusted dynamically in -setUtilityButtons:. + self.widthConstraint.priority = UILayoutPriorityDefaultHigh; + [self addConstraint:self.widthConstraint]; + + _parentCell = parentCell; + self.utilityButtonSelector = utilityButtonSelector; + self.utilityButtons = utilityButtons; + } + + return self; +} + +#pragma mark Populating utility buttons + +- (void)setUtilityButtons:(NSArray *)utilityButtons +{ + // if no width specified, use the default width + [self setUtilityButtons:utilityButtons WithButtonWidth:kUtilityButtonWidthDefault]; +} + +- (void)setUtilityButtons:(NSArray *)utilityButtons WithButtonWidth:(CGFloat)width +{ + for (UIButton *button in _utilityButtons) + { + [button removeFromSuperview]; + } + + _utilityButtons = [utilityButtons copy]; + + if (utilityButtons.count) + { + NSUInteger utilityButtonsCounter = 0; + UIView *precedingView = nil; + + for (UIButton *button in _utilityButtons) + { + [self addSubview:button]; + button.translatesAutoresizingMaskIntoConstraints = NO; + + if (!precedingView) + { + // First button; pin it to the left edge. + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:|[button]" + options:0L + metrics:nil + views:NSDictionaryOfVariableBindings(button)]]; + } + else + { + // Subsequent button; pin it to the right edge of the preceding one, with equal width. + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"H:[precedingView][button(==precedingView)]" + options:0L + metrics:nil + views:NSDictionaryOfVariableBindings(precedingView, button)]]; + } + + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"V:|[button]|" + options:0L + metrics:nil + views:NSDictionaryOfVariableBindings(button)]]; + + + SWUtilityButtonTapGestureRecognizer *utilityButtonTapGestureRecognizer = [[SWUtilityButtonTapGestureRecognizer alloc] initWithTarget:_parentCell action:_utilityButtonSelector]; + utilityButtonTapGestureRecognizer.buttonIndex = utilityButtonsCounter; + [button addGestureRecognizer:utilityButtonTapGestureRecognizer]; + + utilityButtonsCounter++; + precedingView = button; + } + + // Pin the last button to the right edge. + [self addConstraints:[NSLayoutConstraint constraintsWithVisualFormat:@"[precedingView]|" + options:0L + metrics:nil + views:NSDictionaryOfVariableBindings(precedingView)]]; + } + + self.widthConstraint.constant = (width * utilityButtons.count); + + [self setNeedsLayout]; + + return; +} + +#pragma mark - + +- (void)pushBackgroundColors +{ + self.buttonBackgroundColors = [[NSMutableArray alloc] init]; + + for (UIButton *button in self.utilityButtons) + { + [self.buttonBackgroundColors addObject:button.backgroundColor]; + } +} + +- (void)popBackgroundColors +{ + NSEnumerator *e = self.utilityButtons.objectEnumerator; + + for (UIColor *color in self.buttonBackgroundColors) + { + UIButton *button = [e nextObject]; + button.backgroundColor = color; + } + + self.buttonBackgroundColors = nil; +} + +@end + diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig new file mode 100644 index 0000000..1b0bf9d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-AFNetworking.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/AFNetworking" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = ${PODS_AFNETWORKING_OTHER_LDFLAGS} -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-dummy.m new file mode 100644 index 0000000..c50a8c6 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_AFNetworking : NSObject +@end +@implementation PodsDummy_Pods_AFNetworking +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking.xcconfig new file mode 100644 index 0000000..c2f387a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-AFNetworking/Pods-AFNetworking.xcconfig @@ -0,0 +1 @@ +PODS_AFNETWORKING_OTHER_LDFLAGS = -framework "CoreGraphics" -framework "MobileCoreServices" -framework "Security" -framework "SystemConfiguration" \ No newline at end of file diff --git a/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-Private.xcconfig similarity index 100% rename from iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-Private.xcconfig rename to iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-Private.xcconfig diff --git a/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-dummy.m similarity index 100% rename from iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-dummy.m rename to iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-dummy.m diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB.xcconfig similarity index 100% rename from iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB.xcconfig rename to iOSStudy/iOSStudy/Pods/Target Support Files/Pods-FMDB/Pods-FMDB.xcconfig diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig new file mode 100644 index 0000000..82c7242 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-MJRefresh.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/MJRefresh" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-dummy.m new file mode 100644 index 0000000..cc6a260 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_MJRefresh : NSObject +@end +@implementation PodsDummy_Pods_MJRefresh +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-MJRefresh/Pods-MJRefresh.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig new file mode 100644 index 0000000..757ac0c --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-Mantle.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/Mantle" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = ${PODS_MANTLE_OTHER_LDFLAGS} -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-dummy.m new file mode 100644 index 0000000..ae4bd15 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_Mantle : NSObject +@end +@implementation PodsDummy_Pods_Mantle +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle.xcconfig new file mode 100644 index 0000000..9224ebf --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-Mantle/Pods-Mantle.xcconfig @@ -0,0 +1 @@ +PODS_MANTLE_OTHER_LDFLAGS = -framework "Foundation" \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig new file mode 100644 index 0000000..5cff63d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-SDWebImage.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SDWebImage" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = ${PODS_SDWEBIMAGE_OTHER_LDFLAGS} -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-dummy.m new file mode 100644 index 0000000..1e978bb --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SDWebImage : NSObject +@end +@implementation PodsDummy_Pods_SDWebImage +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage.xcconfig new file mode 100644 index 0000000..b82befe --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SDWebImage/Pods-SDWebImage.xcconfig @@ -0,0 +1 @@ +PODS_SDWEBIMAGE_OTHER_LDFLAGS = -framework "ImageIO" \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig new file mode 100644 index 0000000..ad76ac9 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-SVProgressHUD.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVProgressHUD" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = ${PODS_SVPROGRESSHUD_OTHER_LDFLAGS} -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-dummy.m new file mode 100644 index 0000000..e5c1fad --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SVProgressHUD : NSObject +@end +@implementation PodsDummy_Pods_SVProgressHUD +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD.xcconfig new file mode 100644 index 0000000..2ce71e0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVProgressHUD/Pods-SVProgressHUD.xcconfig @@ -0,0 +1 @@ +PODS_SVPROGRESSHUD_OTHER_LDFLAGS = -framework "QuartzCore" \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig new file mode 100644 index 0000000..efe0096 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-SVWebViewController.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SVWebViewController" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-dummy.m new file mode 100644 index 0000000..374040a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SVWebViewController : NSObject +@end +@implementation PodsDummy_Pods_SVWebViewController +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SVWebViewController/Pods-SVWebViewController.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig new file mode 100644 index 0000000..b29e583 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-Private.xcconfig @@ -0,0 +1,5 @@ +#include "Pods-SWTableViewCell.xcconfig" +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Build" "${PODS_ROOT}/Headers/Build/SWTableViewCell" "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = -ObjC +PODS_ROOT = ${SRCROOT} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-dummy.m new file mode 100644 index 0000000..2bd4320 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods_SWTableViewCell : NSObject +@end +@implementation PodsDummy_Pods_SWTableViewCell +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch new file mode 100644 index 0000000..95cf11d --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell-prefix.pch @@ -0,0 +1,5 @@ +#ifdef __OBJC__ +#import +#endif + +#import "Pods-environment.h" diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods-SWTableViewCell/Pods-SWTableViewCell.xcconfig new file mode 100644 index 0000000..e69de29 diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown new file mode 100644 index 0000000..3b2ec91 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.markdown @@ -0,0 +1,205 @@ +# Acknowledgements +This application makes use of the following third party libraries: + +## AFNetworking + +Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## FMDB + +If you are using FMDB in your project, I'd love to hear about it. Let Gus know +by sending an email to gus@flyingmeat.com. + +And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you +might consider purchasing a drink of their choosing if FMDB has been useful to +you. + +Finally, and shortly, this is the MIT License. + +Copyright (c) 2008-2014 Flying Meat Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +## MJRefresh + +Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + +## Mantle + +**Copyright (c) 2012 - 2014, GitHub, Inc.** +**All rights reserved.** + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +**This project uses portions of code from the Proton framework.** +**Proton is copyright (c) 2012, Bitswift, Inc.** +**All rights reserved.** + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +## SDWebImage + +Copyright (c) 2009 Olivier Poitrey + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + +## SVProgressHUD + +Copyright (c) 2011-2014 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +A different license may apply to other resources included in this package, +including Freepik Icons. Please consult their +respective headers for the terms of their individual licenses. + +## SVWebViewController + +Copyright (c) 2011 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +## SWTableViewCell + +Copyright (c) 2013 Christopher Wendel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +Generated by CocoaPods - http://cocoapods.org diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist new file mode 100644 index 0000000..b34b32a --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-acknowledgements.plist @@ -0,0 +1,263 @@ + + + + + PreferenceSpecifiers + + + FooterText + This application makes use of the following third party libraries: + Title + Acknowledgements + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013-2015 AFNetworking (http://afnetworking.com/) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + AFNetworking + Type + PSGroupSpecifier + + + FooterText + If you are using FMDB in your project, I'd love to hear about it. Let Gus know +by sending an email to gus@flyingmeat.com. + +And if you happen to come across either Gus Mueller or Rob Ryan in a bar, you +might consider purchasing a drink of their choosing if FMDB has been useful to +you. + +Finally, and shortly, this is the MIT License. + +Copyright (c) 2008-2014 Flying Meat Inc. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + Title + FMDB + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013-2014 MJRefresh (https://github.com/CoderMJLee/MJRefresh) + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + Title + MJRefresh + Type + PSGroupSpecifier + + + FooterText + **Copyright (c) 2012 - 2014, GitHub, Inc.** +**All rights reserved.** + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +--- + +**This project uses portions of code from the Proton framework.** +**Proton is copyright (c) 2012, Bitswift, Inc.** +**All rights reserved.** + +Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. + * Neither the name of the Bitswift, Inc. nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + Title + Mantle + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2009 Olivier Poitrey <rs@dailymotion.com> + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + + + Title + SDWebImage + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011-2014 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +A different license may apply to other resources included in this package, +including Freepik Icons. Please consult their +respective headers for the terms of their individual licenses. + Title + SVProgressHUD + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2011 Sam Vermette + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + Title + SVWebViewController + Type + PSGroupSpecifier + + + FooterText + Copyright (c) 2013 Christopher Wendel + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + Title + SWTableViewCell + Type + PSGroupSpecifier + + + FooterText + Generated by CocoaPods - http://cocoapods.org + Title + + Type + PSGroupSpecifier + + + StringsTable + Acknowledgements + Title + Acknowledgements + + diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-dummy.m b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-dummy.m new file mode 100644 index 0000000..ade64bd --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-dummy.m @@ -0,0 +1,5 @@ +#import +@interface PodsDummy_Pods : NSObject +@end +@implementation PodsDummy_Pods +@end diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h new file mode 100644 index 0000000..9ec3fd4 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-environment.h @@ -0,0 +1,116 @@ + +// To check if a library is compiled with CocoaPods you +// can use the `COCOAPODS` macro definition which is +// defined in the xcconfigs so it is available in +// headers also when they are imported in the client +// project. + + +// AFNetworking +#define COCOAPODS_POD_AVAILABLE_AFNetworking +#define COCOAPODS_VERSION_MAJOR_AFNetworking 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking 1 + +// AFNetworking/NSURLConnection +#define COCOAPODS_POD_AVAILABLE_AFNetworking_NSURLConnection +#define COCOAPODS_VERSION_MAJOR_AFNetworking_NSURLConnection 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_NSURLConnection 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLConnection 1 + +// AFNetworking/NSURLSession +#define COCOAPODS_POD_AVAILABLE_AFNetworking_NSURLSession +#define COCOAPODS_VERSION_MAJOR_AFNetworking_NSURLSession 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_NSURLSession 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_NSURLSession 1 + +// AFNetworking/Reachability +#define COCOAPODS_POD_AVAILABLE_AFNetworking_Reachability +#define COCOAPODS_VERSION_MAJOR_AFNetworking_Reachability 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_Reachability 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Reachability 1 + +// AFNetworking/Security +#define COCOAPODS_POD_AVAILABLE_AFNetworking_Security +#define COCOAPODS_VERSION_MAJOR_AFNetworking_Security 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_Security 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Security 1 + +// AFNetworking/Serialization +#define COCOAPODS_POD_AVAILABLE_AFNetworking_Serialization +#define COCOAPODS_VERSION_MAJOR_AFNetworking_Serialization 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_Serialization 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_Serialization 1 + +// AFNetworking/UIKit +#define COCOAPODS_POD_AVAILABLE_AFNetworking_UIKit +#define COCOAPODS_VERSION_MAJOR_AFNetworking_UIKit 2 +#define COCOAPODS_VERSION_MINOR_AFNetworking_UIKit 5 +#define COCOAPODS_VERSION_PATCH_AFNetworking_UIKit 1 + +// FMDB +#define COCOAPODS_POD_AVAILABLE_FMDB +#define COCOAPODS_VERSION_MAJOR_FMDB 2 +#define COCOAPODS_VERSION_MINOR_FMDB 5 +#define COCOAPODS_VERSION_PATCH_FMDB 0 + +// FMDB/common +#define COCOAPODS_POD_AVAILABLE_FMDB_common +#define COCOAPODS_VERSION_MAJOR_FMDB_common 2 +#define COCOAPODS_VERSION_MINOR_FMDB_common 5 +#define COCOAPODS_VERSION_PATCH_FMDB_common 0 + +// FMDB/standard +#define COCOAPODS_POD_AVAILABLE_FMDB_standard +#define COCOAPODS_VERSION_MAJOR_FMDB_standard 2 +#define COCOAPODS_VERSION_MINOR_FMDB_standard 5 +#define COCOAPODS_VERSION_PATCH_FMDB_standard 0 + +// MJRefresh +#define COCOAPODS_POD_AVAILABLE_MJRefresh +#define COCOAPODS_VERSION_MAJOR_MJRefresh 0 +#define COCOAPODS_VERSION_MINOR_MJRefresh 0 +#define COCOAPODS_VERSION_PATCH_MJRefresh 1 + +// Mantle +#define COCOAPODS_POD_AVAILABLE_Mantle +#define COCOAPODS_VERSION_MAJOR_Mantle 1 +#define COCOAPODS_VERSION_MINOR_Mantle 5 +#define COCOAPODS_VERSION_PATCH_Mantle 4 + +// Mantle/extobjc +#define COCOAPODS_POD_AVAILABLE_Mantle_extobjc +#define COCOAPODS_VERSION_MAJOR_Mantle_extobjc 1 +#define COCOAPODS_VERSION_MINOR_Mantle_extobjc 5 +#define COCOAPODS_VERSION_PATCH_Mantle_extobjc 4 + +// SDWebImage +#define COCOAPODS_POD_AVAILABLE_SDWebImage +#define COCOAPODS_VERSION_MAJOR_SDWebImage 3 +#define COCOAPODS_VERSION_MINOR_SDWebImage 7 +#define COCOAPODS_VERSION_PATCH_SDWebImage 1 + +// SDWebImage/Core +#define COCOAPODS_POD_AVAILABLE_SDWebImage_Core +#define COCOAPODS_VERSION_MAJOR_SDWebImage_Core 3 +#define COCOAPODS_VERSION_MINOR_SDWebImage_Core 7 +#define COCOAPODS_VERSION_PATCH_SDWebImage_Core 1 + +// SVProgressHUD +#define COCOAPODS_POD_AVAILABLE_SVProgressHUD +#define COCOAPODS_VERSION_MAJOR_SVProgressHUD 1 +#define COCOAPODS_VERSION_MINOR_SVProgressHUD 1 +#define COCOAPODS_VERSION_PATCH_SVProgressHUD 2 + +// SVWebViewController +#define COCOAPODS_POD_AVAILABLE_SVWebViewController +#define COCOAPODS_VERSION_MAJOR_SVWebViewController 1 +#define COCOAPODS_VERSION_MINOR_SVWebViewController 0 +#define COCOAPODS_VERSION_PATCH_SVWebViewController 0 + +// SWTableViewCell +#define COCOAPODS_POD_AVAILABLE_SWTableViewCell +#define COCOAPODS_VERSION_MAJOR_SWTableViewCell 0 +#define COCOAPODS_VERSION_MINOR_SWTableViewCell 3 +#define COCOAPODS_VERSION_PATCH_SWTableViewCell 7 + diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-resources.sh b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-resources.sh new file mode 100755 index 0000000..f0ee1a0 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods-resources.sh @@ -0,0 +1,87 @@ +#!/bin/sh +set -e + +mkdir -p "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" + +RESOURCES_TO_COPY=${PODS_ROOT}/resources-to-copy-${TARGETNAME}.txt +> "$RESOURCES_TO_COPY" + +install_resource() +{ + case $1 in + *.storyboard) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .storyboard`.storyboardc" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.xib) + echo "ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile ${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib ${PODS_ROOT}/$1 --sdk ${SDKROOT}" + ibtool --reference-external-strings-file --errors --warnings --notices --output-format human-readable-text --compile "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename \"$1\" .xib`.nib" "${PODS_ROOT}/$1" --sdk "${SDKROOT}" + ;; + *.framework) + echo "mkdir -p ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + mkdir -p "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + echo "rsync -av ${PODS_ROOT}/$1 ${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + rsync -av "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}" + ;; + *.xcdatamodel) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1"`.mom\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodel`.mom" + ;; + *.xcdatamodeld) + echo "xcrun momc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd\"" + xcrun momc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcdatamodeld`.momd" + ;; + *.xcmappingmodel) + echo "xcrun mapc \"${PODS_ROOT}/$1\" \"${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm\"" + xcrun mapc "${PODS_ROOT}/$1" "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/`basename "$1" .xcmappingmodel`.cdm" + ;; + *.xcassets) + ;; + /*) + echo "$1" + echo "$1" >> "$RESOURCES_TO_COPY" + ;; + *) + echo "${PODS_ROOT}/$1" + echo "${PODS_ROOT}/$1" >> "$RESOURCES_TO_COPY" + ;; + esac +} + install_resource "MJRefresh/MJRefreshExample/MJRefreshExample/MJRefresh/MJRefresh.bundle" + install_resource "SVProgressHUD/SVProgressHUD/SVProgressHUD.bundle" + install_resource "SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack.png" + install_resource "SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerBack@2x.png" + install_resource "SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext.png" + install_resource "SVWebViewController/SVWebViewController/SVWebViewController.bundle/SVWebViewControllerNext@2x.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome-iPad@2x.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Chrome/SVWebViewControllerActivityChrome@2x.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari-iPad@2x.png" + install_resource "SVWebViewController/SVWebViewController/UIActivities/Safari/SVWebViewControllerActivitySafari@2x.png" + install_resource "SVWebViewController/SVWebViewController/SVWebViewController.bundle" + +rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${CONFIGURATION_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +if [[ "${ACTION}" == "install" ]]; then + rsync -avr --copy-links --no-relative --exclude '*/.svn/*' --files-from="$RESOURCES_TO_COPY" / "${INSTALL_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi +rm -f "$RESOURCES_TO_COPY" + +if [[ -n "${WRAPPER_EXTENSION}" ]] && [ "`xcrun --find actool`" ] && [ `find . -name '*.xcassets' | wc -l` -ne 0 ] +then + case "${TARGETED_DEVICE_FAMILY}" in + 1,2) + TARGET_DEVICE_ARGS="--target-device ipad --target-device iphone" + ;; + 1) + TARGET_DEVICE_ARGS="--target-device iphone" + ;; + 2) + TARGET_DEVICE_ARGS="--target-device ipad" + ;; + *) + TARGET_DEVICE_ARGS="--target-device mac" + ;; + esac + find "${PWD}" -name "*.xcassets" -print0 | xargs -0 actool --output-format human-readable-text --notices --warnings --platform "${PLATFORM_NAME}" --minimum-deployment-target "${IPHONEOS_DEPLOYMENT_TARGET}" ${TARGET_DEVICE_ARGS} --compress-pngs --compile "${BUILT_PRODUCTS_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}" +fi diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig new file mode 100644 index 0000000..0d3ecc7 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.debug.xcconfig @@ -0,0 +1,6 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/FMDB" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-FMDB" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"sqlite3" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig new file mode 100644 index 0000000..0d3ecc7 --- /dev/null +++ b/iOSStudy/iOSStudy/Pods/Target Support Files/Pods/Pods.release.xcconfig @@ -0,0 +1,6 @@ +GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 +HEADER_SEARCH_PATHS = "${PODS_ROOT}/Headers/Public" "${PODS_ROOT}/Headers/Public/AFNetworking" "${PODS_ROOT}/Headers/Public/FMDB" "${PODS_ROOT}/Headers/Public/MJRefresh" "${PODS_ROOT}/Headers/Public/Mantle" "${PODS_ROOT}/Headers/Public/SDWebImage" "${PODS_ROOT}/Headers/Public/SVProgressHUD" "${PODS_ROOT}/Headers/Public/SVWebViewController" "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_CFLAGS = $(inherited) -isystem "${PODS_ROOT}/Headers/Public" -isystem "${PODS_ROOT}/Headers/Public/AFNetworking" -isystem "${PODS_ROOT}/Headers/Public/FMDB" -isystem "${PODS_ROOT}/Headers/Public/MJRefresh" -isystem "${PODS_ROOT}/Headers/Public/Mantle" -isystem "${PODS_ROOT}/Headers/Public/SDWebImage" -isystem "${PODS_ROOT}/Headers/Public/SVProgressHUD" -isystem "${PODS_ROOT}/Headers/Public/SVWebViewController" -isystem "${PODS_ROOT}/Headers/Public/SWTableViewCell" +OTHER_LDFLAGS = -ObjC -l"Pods-AFNetworking" -l"Pods-FMDB" -l"Pods-MJRefresh" -l"Pods-Mantle" -l"Pods-SDWebImage" -l"Pods-SVProgressHUD" -l"Pods-SVWebViewController" -l"Pods-SWTableViewCell" -l"sqlite3" -framework "CoreGraphics" -framework "Foundation" -framework "ImageIO" -framework "MobileCoreServices" -framework "QuartzCore" -framework "Security" -framework "SystemConfiguration" +OTHER_LIBTOOLFLAGS = $(OTHER_LDFLAGS) +PODS_ROOT = ${SRCROOT}/Pods \ No newline at end of file diff --git a/iOSStudy/iOSStudy/PushConfig.plist b/iOSStudy/iOSStudy/PushConfig.plist new file mode 100644 index 0000000..cf37ad1 --- /dev/null +++ b/iOSStudy/iOSStudy/PushConfig.plist @@ -0,0 +1,12 @@ + + + + + APS_FOR_PRODUCTION + 0 + APP_KEY + dde091a95582a679984b0bad + CHANNEL + Publish channel + + diff --git a/iOSStudy/iOSStudy/Reachability.h b/iOSStudy/iOSStudy/Reachability.h new file mode 100755 index 0000000..502c17a --- /dev/null +++ b/iOSStudy/iOSStudy/Reachability.h @@ -0,0 +1,95 @@ +/* + Copyright (c) 2011, Tony Million. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#import +#import + + +/** + * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X. + * + * @see http://nshipster.com/ns_enum-ns_options/ + **/ +#ifndef NS_ENUM +#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type +#endif + +extern NSString *const kReachabilityChangedNotification; + +typedef NS_ENUM(NSInteger, NetworkStatus) { + // Apple NetworkStatus Compatible Names. + NotReachable = 0, + ReachableViaWiFi = 2, + ReachableViaWWAN = 1 +}; + +@class Reachability; + +typedef void (^NetworkReachable)(Reachability * reachability); +typedef void (^NetworkUnreachable)(Reachability * reachability); + + +@interface Reachability : NSObject + +@property (nonatomic, copy) NetworkReachable reachableBlock; +@property (nonatomic, copy) NetworkUnreachable unreachableBlock; + +@property (nonatomic, assign) BOOL reachableOnWWAN; + + ++(instancetype)reachabilityWithHostname:(NSString*)hostname; +// This is identical to the function above, but is here to maintain +//compatibility with Apples original code. (see .m) ++(instancetype)reachabilityWithHostName:(NSString*)hostname; ++(instancetype)reachabilityForInternetConnection; ++(instancetype)reachabilityWithAddress:(void *)hostAddress; ++(instancetype)reachabilityForLocalWiFi; + +-(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref; + +-(BOOL)startNotifier; +-(void)stopNotifier; + +-(BOOL)isReachable; +-(BOOL)isReachableViaWWAN; +-(BOOL)isReachableViaWiFi; + +// WWAN may be available, but not active until a connection has been established. +// WiFi may require a connection for VPN on Demand. +-(BOOL)isConnectionRequired; // Identical DDG variant. +-(BOOL)connectionRequired; // Apple's routine. +// Dynamic, on demand connection? +-(BOOL)isConnectionOnDemand; +// Is user intervention required? +-(BOOL)isInterventionRequired; + +-(NetworkStatus)currentReachabilityStatus; +-(SCNetworkReachabilityFlags)reachabilityFlags; +-(NSString*)currentReachabilityString; +-(NSString*)currentReachabilityFlags; + +@end diff --git a/iOSStudy/iOSStudy/Reachability.m b/iOSStudy/iOSStudy/Reachability.m new file mode 100755 index 0000000..e2fd1d8 --- /dev/null +++ b/iOSStudy/iOSStudy/Reachability.m @@ -0,0 +1,469 @@ +/* + Copyright (c) 2011, Tony Million. + All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + */ + +#import "Reachability.h" + +#import +#import +#import +#import +#import +#import + + +NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification"; + + +@interface Reachability () + +@property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef; +@property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue; +@property (nonatomic, strong) id reachabilityObject; + +-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags; +-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags; + +@end + + +static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags) +{ + return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c", +#if TARGET_OS_IPHONE + (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-', +#else + 'X', +#endif + (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-', + (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-', + (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-', + (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-', + (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-', + (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-']; +} + +// Start listening for reachability notifications on the current run loop +static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info) +{ +#pragma unused (target) + + Reachability *reachability = ((__bridge Reachability*)info); + + // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool, + // but what the heck eh? + @autoreleasepool + { + [reachability reachabilityChanged:flags]; + } +} + + +@implementation Reachability + +#pragma mark - Class Constructor Methods + ++(instancetype)reachabilityWithHostName:(NSString*)hostname +{ + return [Reachability reachabilityWithHostname:hostname]; +} + ++(instancetype)reachabilityWithHostname:(NSString*)hostname +{ + SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]); + if (ref) + { + id reachability = [[self alloc] initWithReachabilityRef:ref]; + + return reachability; + } + + return nil; +} + ++(instancetype)reachabilityWithAddress:(void *)hostAddress +{ + SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress); + if (ref) + { + id reachability = [[self alloc] initWithReachabilityRef:ref]; + + return reachability; + } + + return nil; +} + ++(instancetype)reachabilityForInternetConnection +{ + struct sockaddr_in zeroAddress; + bzero(&zeroAddress, sizeof(zeroAddress)); + zeroAddress.sin_len = sizeof(zeroAddress); + zeroAddress.sin_family = AF_INET; + + return [self reachabilityWithAddress:&zeroAddress]; +} + ++(instancetype)reachabilityForLocalWiFi +{ + struct sockaddr_in localWifiAddress; + bzero(&localWifiAddress, sizeof(localWifiAddress)); + localWifiAddress.sin_len = sizeof(localWifiAddress); + localWifiAddress.sin_family = AF_INET; + // IN_LINKLOCALNETNUM is defined in as 169.254.0.0 + localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM); + + return [self reachabilityWithAddress:&localWifiAddress]; +} + + +// Initialization methods + +-(instancetype)initWithReachabilityRef:(SCNetworkReachabilityRef)ref +{ + self = [super init]; + if (self != nil) + { + self.reachableOnWWAN = YES; + self.reachabilityRef = ref; + + // We need to create a serial queue. + // We allocate this once for the lifetime of the notifier. + + self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL); + } + + return self; +} + +-(void)dealloc +{ + [self stopNotifier]; + + if(self.reachabilityRef) + { + CFRelease(self.reachabilityRef); + self.reachabilityRef = nil; + } + + self.reachableBlock = nil; + self.unreachableBlock = nil; + self.reachabilitySerialQueue = nil; +} + +#pragma mark - Notifier Methods + +// Notifier +// NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD +// - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS. +// INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want) + +-(BOOL)startNotifier +{ + // allow start notifier to be called multiple times + if(self.reachabilityObject && (self.reachabilityObject == self)) + { + return YES; + } + + + SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL }; + context.info = (__bridge void *)self; + + if(SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context)) + { + // Set it as our reachability queue, which will retain the queue + if(SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue)) + { + // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves + // woah + self.reachabilityObject = self; + return YES; + } + else + { +#ifdef DEBUG + NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError())); +#endif + + // UH OH - FAILURE - stop any callbacks! + SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); + } + } + else + { +#ifdef DEBUG + NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError())); +#endif + } + + // if we get here we fail at the internet + self.reachabilityObject = nil; + return NO; +} + +-(void)stopNotifier +{ + // First stop, any callbacks! + SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL); + + // Unregister target from the GCD serial dispatch queue. + SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL); + + self.reachabilityObject = nil; +} + +#pragma mark - reachability tests + +// This is for the case where you flick the airplane mode; +// you end up getting something like this: +//Reachability: WR ct----- +//Reachability: -- ------- +//Reachability: WR ct----- +//Reachability: -- ------- +// We treat this as 4 UNREACHABLE triggers - really apple should do better than this + +#define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection) + +-(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags +{ + BOOL connectionUP = YES; + + if(!(flags & kSCNetworkReachabilityFlagsReachable)) + connectionUP = NO; + + if( (flags & testcase) == testcase ) + connectionUP = NO; + +#if TARGET_OS_IPHONE + if(flags & kSCNetworkReachabilityFlagsIsWWAN) + { + // We're on 3G. + if(!self.reachableOnWWAN) + { + // We don't want to connect when on 3G. + connectionUP = NO; + } + } +#endif + + return connectionUP; +} + +-(BOOL)isReachable +{ + SCNetworkReachabilityFlags flags; + + if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + return NO; + + return [self isReachableWithFlags:flags]; +} + +-(BOOL)isReachableViaWWAN +{ +#if TARGET_OS_IPHONE + + SCNetworkReachabilityFlags flags = 0; + + if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + // Check we're REACHABLE + if(flags & kSCNetworkReachabilityFlagsReachable) + { + // Now, check we're on WWAN + if(flags & kSCNetworkReachabilityFlagsIsWWAN) + { + return YES; + } + } + } +#endif + + return NO; +} + +-(BOOL)isReachableViaWiFi +{ + SCNetworkReachabilityFlags flags = 0; + + if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + // Check we're reachable + if((flags & kSCNetworkReachabilityFlagsReachable)) + { +#if TARGET_OS_IPHONE + // Check we're NOT on WWAN + if((flags & kSCNetworkReachabilityFlagsIsWWAN)) + { + return NO; + } +#endif + return YES; + } + } + + return NO; +} + + +// WWAN may be available, but not active until a connection has been established. +// WiFi may require a connection for VPN on Demand. +-(BOOL)isConnectionRequired +{ + return [self connectionRequired]; +} + +-(BOOL)connectionRequired +{ + SCNetworkReachabilityFlags flags; + + if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + return (flags & kSCNetworkReachabilityFlagsConnectionRequired); + } + + return NO; +} + +// Dynamic, on demand connection? +-(BOOL)isConnectionOnDemand +{ + SCNetworkReachabilityFlags flags; + + if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && + (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand))); + } + + return NO; +} + +// Is user intervention required? +-(BOOL)isInterventionRequired +{ + SCNetworkReachabilityFlags flags; + + if (SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) && + (flags & kSCNetworkReachabilityFlagsInterventionRequired)); + } + + return NO; +} + + +#pragma mark - reachability status stuff + +-(NetworkStatus)currentReachabilityStatus +{ + if([self isReachable]) + { + if([self isReachableViaWiFi]) + return ReachableViaWiFi; + +#if TARGET_OS_IPHONE + return ReachableViaWWAN; +#endif + } + + return NotReachable; +} + +-(SCNetworkReachabilityFlags)reachabilityFlags +{ + SCNetworkReachabilityFlags flags = 0; + + if(SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags)) + { + return flags; + } + + return 0; +} + +-(NSString*)currentReachabilityString +{ + NetworkStatus temp = [self currentReachabilityStatus]; + + if(temp == ReachableViaWWAN) + { + // Updated for the fact that we have CDMA phones now! + return NSLocalizedString(@"Cellular", @""); + } + if (temp == ReachableViaWiFi) + { + return NSLocalizedString(@"WiFi", @""); + } + + return NSLocalizedString(@"No Connection", @""); +} + +-(NSString*)currentReachabilityFlags +{ + return reachabilityFlags([self reachabilityFlags]); +} + +#pragma mark - Callback function calls this method + +-(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags +{ + if([self isReachableWithFlags:flags]) + { + if(self.reachableBlock) + { + self.reachableBlock(self); + } + } + else + { + if(self.unreachableBlock) + { + self.unreachableBlock(self); + } + } + + // this makes sure the change notification happens on the MAIN THREAD + dispatch_async(dispatch_get_main_queue(), ^{ + [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification + object:self]; + }); +} + +#pragma mark - Debug Description + +- (NSString *) description +{ + NSString *description = [NSString stringWithFormat:@"<%@: %#x (%@)>", + NSStringFromClass([self class]), (unsigned int) self, [self currentReachabilityFlags]]; + return description; +} + +@end diff --git a/iOSStudy/iOSStudy/SettingTableViewController.h b/iOSStudy/iOSStudy/SettingTableViewController.h index 60ea577..766b042 100644 --- a/iOSStudy/iOSStudy/SettingTableViewController.h +++ b/iOSStudy/iOSStudy/SettingTableViewController.h @@ -7,7 +7,7 @@ // #import - -@interface SettingTableViewController : UITableViewController +#import +@interface SettingTableViewController : UITableViewController @end diff --git a/iOSStudy/iOSStudy/SettingTableViewController.m b/iOSStudy/iOSStudy/SettingTableViewController.m index e04db40..7a6cded 100644 --- a/iOSStudy/iOSStudy/SettingTableViewController.m +++ b/iOSStudy/iOSStudy/SettingTableViewController.m @@ -7,7 +7,8 @@ // #import "SettingTableViewController.h" - +#import "iRate.h" +#import "LicenesViewController.h" @interface SettingTableViewController () @end @@ -24,6 +25,93 @@ - (void)viewDidLoad { // self.navigationItem.rightBarButtonItem = self.editButtonItem; } +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { + + + + if (indexPath.section==0) { + switch (indexPath.row) { + case 0: + [self sendEmail]; + break; + case 1: + [self rateApp]; + break; + + default: + break; + } + } + + +} + +- (void) mailComposeController:(MFMailComposeViewController *)controller didFinishWithResult:(MFMailComposeResult)result error:(NSError *)error +{ + switch (result) + { + case MFMailComposeResultCancelled: + NSLog(@"Mail cancelled"); + break; + case MFMailComposeResultSaved: + NSLog(@"Mail saved"); + break; + case MFMailComposeResultSent: + NSLog(@"Mail sent"); + break; + case MFMailComposeResultFailed: + NSLog(@"Mail sent failure: %@", [error localizedDescription]); + break; + default: + break; + } + + // Close the Mail Interface + [self dismissViewControllerAnimated:YES completion:NULL]; +} + +#pragma mark -- 发送意见反馈 +-(void)sendEmail{ + + { + // Email Subject + NSString *emailTitle = @"意见反馈"; + // Email Content + NSString *messageBody = @"意见反馈"; + // To address + NSArray *toRecipents = [NSArray arrayWithObject:@"chenguandong@163.com"]; + + MFMailComposeViewController *mc = [[MFMailComposeViewController alloc] init]; + mc.mailComposeDelegate = self; + [mc setSubject:emailTitle]; + [mc setMessageBody:messageBody isHTML:NO]; + [mc setToRecipients:toRecipents]; + + // Present mail view controller on screen + [self presentViewController:mc animated:YES completion:NULL]; + } + +} + +#pragma mark -- 给应用评分 +-(void)rateApp{ + + [iRate sharedInstance].applicationBundleID = @"com.cgd.iOSStudy"; + /* + [iRate sharedInstance].onlyPromptIfLatestVersion = NO; + + //enable preview mode + [iRate sharedInstance].previewMode = YES; + + */ + + //mark as rated + [iRate sharedInstance].ratedThisVersion = YES; + + //launch app store + [[iRate sharedInstance] openRatingsPageInAppStore]; +} + - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. @@ -102,4 +190,19 @@ - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { } */ +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + LicenesViewController *coll = [segue destinationViewController]; + + NSLog(@"%@",segue.identifier); + + if ([segue.identifier isEqualToString:@"licenes"]) { + coll.htmlName = @"licenes.html"; + }else{ + coll.htmlName = @"about_us.html"; + } + + // Pass the selected object to the new view controller. +} + + @end diff --git a/iOSStudy/iOSStudy/Tools/CoreDataUtils.h b/iOSStudy/iOSStudy/Tools/CoreDataUtils.h new file mode 100644 index 0000000..5dd64a9 --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/CoreDataUtils.h @@ -0,0 +1,41 @@ +// +// CoreDataUtils.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface CoreDataUtils : NSObject +/** + * 检查数据是否在表中已经存在 + * + * @param tableName 表名 + * @param predicate 查询条件 + * + * @return YES 存在 NO不存在 + */ ++(BOOL)dataisExistTableName:(NSString*)tableName withPredicate:(NSPredicate*)predicate; + + +/** + * 查询数据 + * @param tableName 查询的表明称 + * @param predicate NSPredicate 查询条件 nil时表示没有查询条件 + * + * @return NSManagedObject 集合 + */ ++(NSArray*)queryDataFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)predicate; + + +/** + * 删除指定表中的数据 + + * + * @param tableName 表名 + * @param andNSPredicate 删除条件 为nil 删除所有数据 + */ ++(void)deleteDateFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)andNSPredicate; +@end diff --git a/iOSStudy/iOSStudy/Tools/CoreDataUtils.m b/iOSStudy/iOSStudy/Tools/CoreDataUtils.m new file mode 100644 index 0000000..c1fe7ec --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/CoreDataUtils.m @@ -0,0 +1,108 @@ +// +// CoreDataUtils.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "CoreDataUtils.h" +#import +#import "Constants .h" +@implementation CoreDataUtils + +/** + * 检查数据是否在表中已经存在 + * + * @param url http地址 + * @param tableName 表名 + * @param rowName 数据所在的列名 + * + * @return YES 存在 NO 不存在 + */ ++(BOOL)dataisExistTableName:(NSString*)tableName withPredicate:(NSPredicate*)predicate{ + + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:tableName inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + if (predicate) { + fetchRequest.predicate = predicate; + } + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + + //NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"%@ = %@",rowName, url]; + + + if (fetchedObjects.count!=0) { + // NSLog(@"111%lu",resultArr.count); + return YES; + }else{ + // NSLog(@"222%lu",resultArr.count); + return NO; + } + + +} + +/** + * 查询数据 + * @param tableName 查询的表明称 + * @param predicate NSPredicate 查询条件 nil时表示没有查询条件 + * + * @return NSManagedObject 集合 + */ ++(NSArray*)queryDataFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)predicate{ + + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:tableName inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + // NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url= %@", url]; + if (predicate) { + fetchRequest.predicate = predicate; + } + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + return [fetchedObjects filteredArrayUsingPredicate:predicate]; + + +} + + +/** + * 删除指定表中的数据 + + * + * @param tableName 表名 + * @param andNSPredicate 删除条件 为nil 删除所有数据 + */ ++(void)deleteDateFromTableName:(NSString*)tableName andNSPredicate:(NSPredicate*)andNSPredicate{ + //存储之前先删除原来的数据 + + //NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", @"11"]; + + NSArray* managerObjtList = [CoreDataUtils queryDataFromTableName:tableName andNSPredicate:andNSPredicate]; + + for (NSManagedObject *obct in managerObjtList) { + [SharedApp.managedObjectContext deleteObject:obct]; + } + + + NSError *error = nil; + if (![SharedApp.managedObjectContext save:&error]) { + NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); + return; + } + +} +@end diff --git a/iOSStudy/Tools/DBUtils.h b/iOSStudy/iOSStudy/Tools/DBUtils.h similarity index 100% rename from iOSStudy/Tools/DBUtils.h rename to iOSStudy/iOSStudy/Tools/DBUtils.h diff --git a/iOSStudy/Tools/DBUtils.m b/iOSStudy/iOSStudy/Tools/DBUtils.m similarity index 100% rename from iOSStudy/Tools/DBUtils.m rename to iOSStudy/iOSStudy/Tools/DBUtils.m diff --git a/iOSStudy/iOSStudy/Tools/HttpVersionTools.h b/iOSStudy/iOSStudy/Tools/HttpVersionTools.h new file mode 100644 index 0000000..fbb382d --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/HttpVersionTools.h @@ -0,0 +1,79 @@ +// +// HttpVersionTools.h +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + + +/** + * 网络请求成功回调 + */ +typedef void (^versionSuccess)(NSArray*versionLists); +/** + * 网络请求失败回调 + */ +typedef void (^versionError)(); + +/** + * 网络是否链接回调 + * + * @param isNetWorking YES 有网络 NO 没有网络 + */ +typedef void (^versionNetWorking)(BOOL isNetWorking); + + +@interface HttpVersionTools : NSObject + + +/** + * 得到当前服务器版本号列表 + * + * @return 服务器版本号列表 + */ ++(void)getVersions:(versionSuccess)v_success v_error:(versionError)v_error v_netWork:(versionNetWorking)v_netWork; + + +/** + * 判断版本号是否向服务器请求最新数据 + * + * @param url http请求地址 + * + * @return YES 发送请求 NO 不发送请求 + */ ++(BOOL)checkHttpVersion:(NSString*)url nowVersion:(NSString*)nowVersion; + + +/** + * 返回服务器当前url版本号 + * + * @param url http请求地址 + * + * @return 服务器当前url版本号 + */ ++(NSString*)getNowHttpVersion:(NSString*)url; + + +/** + * 得到URL本地版本号 + * + * @param url URL地址 + * + * @return !nil 本地版本号 nil 没有本地版本号 + */ ++(NSString*)getLocalHttpVersion:(NSString*)url; + + + +/** + * 存储当前服务器返回的版本号 + * + * @param url http 请求地址 + * @param version 版本号 + */ ++(void)saveNowHttpVersion:(NSString*)url version:(NSString*)version; + +@end diff --git a/iOSStudy/iOSStudy/Tools/HttpVersionTools.m b/iOSStudy/iOSStudy/Tools/HttpVersionTools.m new file mode 100644 index 0000000..668936b --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/HttpVersionTools.m @@ -0,0 +1,204 @@ +// +// HttpVersionTools.m +// iOSStudy +// +// Created by chenguandong on 15/4/2. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "HttpVersionTools.h" +#import "NetWorkTools.h" +#import "JsonTools.h" +#import +#import "VersionBean.h" +#import "CoreDataUtils.h" +@implementation HttpVersionTools + ++(void)getVersions:(versionSuccess)v_success v_error:(versionError)v_error v_netWork:(versionNetWorking)v_netWork{ + + + __block NSMutableArray*versionArr = [NSMutableArray arrayWithCapacity:5]; + + [NetWorkTools postHttp:Adress_versions success:^(AFHTTPRequestOperation *operation, id responseObject) { + + NSLog(@"JSON: %@", [operation responseString]); + + NSArray *dic = [JsonTools getJsonNSDictionary:[operation responseString]]; + + //将JSON数据和Model的属性进行绑定 + + NSArray *arr = [MTLJSONAdapter modelsOfClass:[VersionBean class] fromJSONArray:dic error:nil]; + + versionArr = [arr copy]; + +// for (VersionBean *vBean in versionArr) { +// NSLog(@"version =%@",vBean.urlVersion); +// } + + v_success(versionArr); + + } error:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + + v_error(); + + } isNetworking:^(BOOL isNetwork) { + + + v_netWork(isNetwork); + }]; + + +} + +/** + * 返回服务器当前url版本号 + * + * @param url http请求地址 + * + * @return 服务器当前url版本号 + */ ++(NSString*)getNowHttpVersion:(NSString*)url{ + + NSString *versionStr ; + for (VersionBean *vBean in SharedApp.versionLists) { + + + if ([vBean.url isEqualToString:url]) { + + versionStr = vBean.urlVersion; + return versionStr; + }else{ + versionStr = nil; + } + } + NSLog(@"nowVersion = %@",versionStr); + return versionStr; +} + + +/** + * 存储当前服务器返回的版本号 + * + * @param url http 请求地址 + * @param version 版本号 + */ ++(void)saveNowHttpVersion:(NSString*)url version:(NSString*)version{ + + NSString *log ; + + //当数据存在事后执行更新操作 + //[CoreDataUtils dataisExist:url inTable:CD_VersionsEntity tableRowName:@"url"] + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"%@ = %@",@"url", url]; + if ( + [CoreDataUtils dataisExistTableName:CD_VersionsEntity withPredicate:urlPredicate] + ) + + { + + + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"url= %@", url]; + + NSArray *managerList = [CoreDataUtils queryDataFromTableName:CD_VersionsEntity andNSPredicate:urlPredicate]; + + if (managerList.count!=0) { + NSManagedObject *updateObjt= managerList.firstObject; + [updateObjt setValue:url forKey:@"url"]; + [updateObjt setValue:version forKey:@"url_version"]; + } + + log = @"版本更新成功"; + + } + else + //当数据不存在的事后执行插入操作 + { + NSManagedObject *managerObjt =[NSEntityDescription insertNewObjectForEntityForName:CD_VersionsEntity inManagedObjectContext:SharedApp.managedObjectContext]; + + + [managerObjt setValue:url forKey:@"url"]; + [managerObjt setValue:version forKey:@"url_version"];; + + log = @"版本插入成功"; + + } + + NSError *error; + if (![SharedApp.managedObjectContext save:&error]) + { + NSLog(@"%@: %@", log,[error localizedDescription]); + + } + + +} + + + +/** + * 判断版本号是否向服务器请求最新数据 + * + * @param url http请求地址 + * + * @return YES 发送请求 NO 不发送请求 + */ ++(BOOL)checkHttpVersion:(NSString*)url nowVersion:(NSString*)nowVersion{ + + + + + if (nowVersion!=nil) { + //从数据库拿到URL 版本号 如果没有说明第一次请求 直接发送请求 + + if ([[self getLocalHttpVersion:url]floatValue]!=[nowVersion floatValue]) { + + + + return YES; + }else{ + return NO; + } + }else{ + return YES; + } + + +} + +/** + * 得到URL本地版本号 + * + * @param url URL地址 + * + * @return !nil 本地版本号 nil 没有本地版本号 + */ ++(NSString*)getLocalHttpVersion:(NSString*)url{ + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:CD_VersionsEntity inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url = %@", url]; + + + NSArray *resultArr = [fetchedObjects filteredArrayUsingPredicate:titlePredicate]; + if (resultArr.count!=0) { + NSLog(@"111%lu",resultArr.count); + + NSManagedObject *objt = resultArr[0]; + + + return [objt valueForKey:@"url_version"]; + }else{ + NSLog(@"没有查到本地版本%lu",resultArr.count); + return nil; + } + + +} + +@end diff --git a/iOSStudy/iOSStudy/Tools/JsonTools.h b/iOSStudy/iOSStudy/Tools/JsonTools.h new file mode 100644 index 0000000..efe9dfb --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/JsonTools.h @@ -0,0 +1,13 @@ +// +// JsonTools.h +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface JsonTools : NSObject ++(id)getJsonNSDictionary:(NSString *)jsonString; +@end diff --git a/iOSStudy/iOSStudy/Tools/JsonTools.m b/iOSStudy/iOSStudy/Tools/JsonTools.m new file mode 100644 index 0000000..ba064db --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/JsonTools.m @@ -0,0 +1,24 @@ +// +// JsonTools.m +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "JsonTools.h" + +@implementation JsonTools + + + ++(id)getJsonNSDictionary:(NSString *)jsonString{ + NSData *data = [ jsonString dataUsingEncoding:NSUTF8StringEncoding]; + //IOS5自带解析类NSJSONSerialization从response中解析出数据放到字典中 + id JsonObjectAll = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; + + + return JsonObjectAll; +} + +@end diff --git a/iOSStudy/iOSStudy/Tools/NetWorkTools.h b/iOSStudy/iOSStudy/Tools/NetWorkTools.h new file mode 100644 index 0000000..7187dec --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/NetWorkTools.h @@ -0,0 +1,29 @@ +// +// NetWorkTools.h +// iOSStudy +// +// Created by chenguandong on 15/1/31. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +#import "Constants .h" + +typedef void(^success)(AFHTTPRequestOperation *operation, id responseObject) ; +typedef void(^error)(AFHTTPRequestOperation *operation, NSError *error); +typedef void(^isNetwork) (BOOL isNetwork); + +@interface NetWorkTools : NSObject + + + ++ (instancetype)sharedInstance; + ++(void)postHttp:(NSString*)httpUrl success:(success)success error:(error)error isNetworking:(isNetwork)isNetworking; + +/* + *检查网络连接注册通知 + */ ++(void)checkNetworking; +@end diff --git a/iOSStudy/iOSStudy/Tools/NetWorkTools.m b/iOSStudy/iOSStudy/Tools/NetWorkTools.m new file mode 100644 index 0000000..007d513 --- /dev/null +++ b/iOSStudy/iOSStudy/Tools/NetWorkTools.m @@ -0,0 +1,109 @@ +// +// NetWorkTools.m +// iOSStudy +// +// Created by chenguandong on 15/1/31. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "NetWorkTools.h" +#import +#import "Reachability.h" +@implementation NetWorkTools + + ++ (instancetype)sharedInstance { + static dispatch_once_t once; + static id sharedInstance; + dispatch_once(&once, ^{ + sharedInstance = [[self alloc] init]; + }); + + return sharedInstance; +} + + ++(void)postHttp:(NSString*)httpUrl success:(success)success error:(error)error isNetworking:(isNetwork)isNetworking{ + + + if (SharedApp.isNetworking) { + AFHTTPRequestOperationManager *manager = [AFHTTPRequestOperationManager manager]; + manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript",@"text/html",@"text/plain", nil]; + [manager POST:httpUrl parameters:nil success:success failure:error]; + }else{ + + isNetworking(false); + + NSLog(@"REACHABLE!"); + [SVProgressHUD showErrorWithStatus:@"无网络连接" maskType:SVProgressHUDMaskTypeGradient]; + + double delayInSeconds = 3.0; dispatch_time_t + popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + // code to be executed on the main queue after delay + [SVProgressHUD dismiss]; + }); + + + } +} + + ++(void)checkNetworking{ + + + + + // Allocate a reachability object + Reachability* reach = [Reachability reachabilityWithHostname:@"http://www.baidu.com"]; + + // Set the blocks + reach.reachableBlock = ^(Reachability*reach) + { + // keep in mind this is called on a background thread + // and if you are updating the UI it needs to happen + // on the main thread, like this: + + NSLog(@"网络已经连接!"); + + + SharedApp.isNetworking = YES; + + [SVProgressHUD dismiss]; + + + }; + + reach.unreachableBlock = ^(Reachability*reach) + { + NSLog(@"网络断开!"); + + SharedApp.isNetworking = YES; + + dispatch_async(dispatch_get_main_queue(), ^{ + + [SVProgressHUD showErrorWithStatus:@"无网络连接" maskType:SVProgressHUDMaskTypeGradient]; + + double delayInSeconds = 2.0; + dispatch_time_t + popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); + dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ + // code to be executed on the main queue after delay + + [SVProgressHUD dismiss]; + }); + }); + + }; + + // Start the notifier, which will cause the reachability object to retain itself! + [reach startNotifier]; + + + +} + + + + +@end diff --git a/iOSStudy/iOSStudy/VideoTableViewController.h b/iOSStudy/iOSStudy/VideoTableViewController.h new file mode 100644 index 0000000..0c58b6d --- /dev/null +++ b/iOSStudy/iOSStudy/VideoTableViewController.h @@ -0,0 +1,18 @@ +// +// ThirdTableViewController.h +// iOSStudy +// +// Created by chenguandong on 15/2/10. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "VideoViewControllerViewModel.h" +#import +#import "BaseViewController.h" +@interface VideoTableViewController : BaseViewController + +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property(nonatomic,strong)VideoViewControllerViewModel *viewModel; +@property(nonatomic,copy)NSString* favouriteType; +@end diff --git a/iOSStudy/iOSStudy/VideoTableViewController.m b/iOSStudy/iOSStudy/VideoTableViewController.m new file mode 100644 index 0000000..b9de900 --- /dev/null +++ b/iOSStudy/iOSStudy/VideoTableViewController.m @@ -0,0 +1,219 @@ +// +// ThirdTableViewController.m +// iOSStudy +// +// Created by chenguandong on 15/2/10. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "VideoTableViewController.h" +#import "NetWorkTools.h" +#import "Constants .h" +#import +#import "JsonTools.h" +#import "BlogBean.h" +#import +#import "BlogDetailViewController.h" +#import +#import +#import "STBaseTableViewCell.h" +#import "UIImage+Resize.h" +#import +#import "STBaseTableViewCell.h" +@interface VideoTableViewController () + +@end + +@implementation VideoTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + + _tableView.delegate = self; + _tableView.dataSource = self; + + [self initViewData]; + + + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notificationReloadData:) name:notifacationVideoReload object:nil]; +} + +-(void)notificationReloadData:(NSNotification*)notifacation{ + + + [_tableView reloadData]; +} + +-(void)initViewData{ + + _favouriteType = TYPE_VIDEO_FAVOURITE_TYPE; + + _viewModel = [[VideoViewControllerViewModel alloc]init]; + + [self.tableView addLegendHeaderWithRefreshingBlock:^{ + [_viewModel getDate:^{ + [_tableView reloadData]; + + [self stopTableRefreshing]; + + } modelDataReload:^{ + [_tableView reloadData]; + } modelDataErrors:^{ + [self stopTableRefreshing]; + } modelDataIsNetworking:^(BOOL isNetWorking) { + [self stopTableRefreshing]; + } httpAdress:Adress_videos dataType:TYPE_VIDEO_SIMPLE_TYPE jsonClass:[VideoBean class]]; + }]; + + // 隐藏时间 + self.tableView.header.updatedTimeHidden = YES; + // 隐藏状态 + self.tableView.header.stateHidden = YES; + + [self.tableView.header beginRefreshing]; + + _tableView.rowHeight = 60; + + [self.tableView registerNib:[UINib nibWithNibName:@"STBaseTableViewCell" bundle:nil] forCellReuseIdentifier:@"VideoCell"]; +} + + + + + +/** + * 停止UITableView刷新 + */ +-(void)stopTableRefreshing{ + if ([_tableView.header isRefreshing]) { + [_tableView.header endRefreshing]; + } +} + + + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + +} + + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return [_viewModel getNumberOfRowsInSection]; +} + +// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: +// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + + + static NSString *cellIdentifier = @"VideoCell"; + + STBaseTableViewCell *cell = (STBaseTableViewCell *)[tableView dequeueReusableCellWithIdentifier:cellIdentifier + forIndexPath:indexPath]; + + + + cell.delegate = self; + + + + cell.title.text = [[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_title]; + cell.subtitle.text = [[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_subtitle]; + + + + NSLog(@"==%@", [[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_subtitle]); + + + cell.rightUtilityButtons =[_viewModel setRightSWCellButtons:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url] withType:_favouriteType]; + + + [cell.imageIcon setImageWithURL:[NSURL URLWithString:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_image_name]] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; + + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + return cell; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + + + SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url]]; + [self presentViewController:webViewController animated:NO completion:NULL]; +} + +-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ + + if ([segue.identifier isEqualToString:@"SVWebViewController"]) { + + + } +} + + +#pragma mark-- SWTableViewCell delagate + +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell +{ + + return YES; +} +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ + + return YES; + +} + +- (void)swipeableTableViewCellDidEndScrolling:(SWTableViewCell *)cell{ + + //根据侧滑按钮是否显示设置箭头标志 + if (cell.isUtilityButtonsHidden) { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + }else{ + cell.accessoryType = UITableViewCellAccessoryNone; + + } +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + + + NSIndexPath *indexPath = [_tableView indexPathForCell:cell]; + + + [_viewModel saveFavourite:indexPath favouriteType:_favouriteType]; + + + [cell hideUtilityButtonsAnimated:YES]; + + [_tableView reloadData]; + + + +} + + + + + +-(void)dealloc{ + _tableView.delegate = nil; + _tableView.dataSource = nil; + _viewModel = nil; + [[NSNotificationCenter defaultCenter]removeObserver:self name:notifacationVideoReload object:nil]; + +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + + +@end diff --git a/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.h b/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.h new file mode 100644 index 0000000..d89cec1 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.h @@ -0,0 +1,13 @@ +// +// BlogDetailViewController.h +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface BlogDetailViewController : UIViewController + +@end diff --git a/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.m b/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.m new file mode 100644 index 0000000..d1e511c --- /dev/null +++ b/iOSStudy/iOSStudy/ViewColl/BlogDetailViewController.m @@ -0,0 +1,40 @@ +// +// BlogDetailViewController.m +// iOSStudy +// +// Created by chenguandong on 15/2/5. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogDetailViewController.h" +#import "DBUtils.h" +@interface BlogDetailViewController () + +@end + +@implementation BlogDetailViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. + [DBUtils executeSQL:^(FMDatabase *db) { + + }]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.h b/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.h new file mode 100644 index 0000000..f507592 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.h @@ -0,0 +1,100 @@ +// +// FirstViewControllerViewModel.h +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "NetWorkTools.h" +#import "JsonTools.h" +#import "BlogBean.h" + + +/** + * 网络请求开始 + */ +typedef void (^modelPersistentReload)(); + +/** + * 网络请求成功回调 + */ +typedef void (^modelSuccess)(); +/** + * 网络请求失败回调 + */ +typedef void (^modelError)(); + +/** + * 网络是否链接回调 + * + * @param isNetWorking YES 有网络 NO 没有网络 + */ +typedef void (^modelNetWorking)(BOOL isNetWorking); + +@interface BlogViewControllerViewModel : NSObject +@property(nonatomic,strong)NSArray *array; + + +/** + * 获取table的行数 + * + * @return table的行数 + */ +- (NSInteger)getNumberOfRowsInSection; + +/** + * 获取cell的数据 + * + * @param indexPath indexPath + * + * @return cell的数据 + */ +-(NSManagedObject*)getBlogBean:(NSIndexPath *)indexPath; + + + +/** + * 添加收藏到数据库 + * + * @param indexPath indexPath + */ +-(void)saveFavourite:(NSIndexPath*)indexPath favouriteType:(NSString*)type; + + + + +/** + * 请求网络数据 + * + * @param modelDataSuccess 请求成功 + * @param modelDataStart 请求开始 + * @param modelDataErrors 请求失败 + * @param modelDataIsNetWoring 网络状态 + */ +-(void)getDate:(modelSuccess)modelDataSuccess modelDataReload:(modelPersistentReload)modelDataReload modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring httpAdress:(NSString*)httpAdress dataType:(NSString*)dataType jsonClass:(Class)myClass; + + +/** + * 设置SWTableViewCell 滑动文字 + * + * @param url url地址 + * @param type 1 博客 2 网址 3 视频 + * + * @return 要显示的Button集合 + */ +- (NSArray *)setRightSWCellButtons:(NSString*)url withType:(NSString*)type; + +#pragma mark -- 持久化所有数据 +-(void)persistenceDataWithType:(NSString*)type; + +/** + * 判断收藏的URL地址是否存在 + * + * @param url URL地址 + * + * @return YES 存在 NO 不存在 + */ +-(BOOL)isExistSimpleDataWithURL:(NSString*)url; +@end diff --git a/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.m b/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.m new file mode 100644 index 0000000..84911c4 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/BlogViewControllerViewModel.m @@ -0,0 +1,317 @@ +// +// FirstViewControllerViewModel.m +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "BlogViewControllerViewModel.h" +#import "FavouriteBean.h" +#import "Constants .h" +#import "BlogJsonBean.h" +#import "HttpVersionTools.h" +#import "CoreDataUtils.h" +#import +#import "EntityConstants.h" +@implementation BlogViewControllerViewModel +- (instancetype)init +{ + self = [super init]; + if (self) { + _array = [NSMutableArray array]; + + + } + return self; +} + +- (NSInteger)getNumberOfRowsInSection{ + + return _array.count; +} + + + +-(NSManagedObject*)getBlogBean:(NSIndexPath *)indexPath{ + + return _array[indexPath.row]; +} + + + +/** + * 请求网络数据 + * + * @param modelDataSuccess 请求成功 + * @param modelDataStart 请求开始 + * @param modelDataErrors 请求失败 + * @param modelDataIsNetWoring 网络状态 + */ +-(void)getDate:(modelSuccess)modelDataSuccess modelDataReload:(modelPersistentReload)modelDataReload modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring httpAdress:(NSString*)httpAdress dataType:(NSString*)dataType jsonClass:(Class)myClass{ + + + _array = [[self getPersistenceDataWithType:dataType]copy]; + + + modelDataReload(); + + __block NSString *versionStr; + + if ([HttpVersionTools checkHttpVersion:httpAdress nowVersion:[HttpVersionTools getNowHttpVersion:httpAdress]]) { + + // + + [NetWorkTools postHttp:httpAdress success:^(AFHTTPRequestOperation *operation, id responseObject) { + + NSLog(@"JSON: %@", [operation responseString]); + + NSDictionary *dic = [JsonTools getJsonNSDictionary:[operation responseString]]; + + //NSLog(@"jsonVersion=%@",dic[@"version"]); + + + versionStr =dic[@"version"]; + + //将JSON数据和Model的属性进行绑定 + + // NSLog(@"%@arr=",dic[@"bloglists"]); + + NSArray *arr = [MTLJSONAdapter modelsOfClass:myClass fromJSONArray:dic[@"bloglists"] error:nil]; + + + + _array = [arr copy]; + + + + //持久化数据 + [self persistenceDataWithType:dataType]; + + //当前最新版本号存入数据库 + + [HttpVersionTools saveNowHttpVersion:httpAdress version:versionStr]; + + _array = [[self getPersistenceDataWithType:dataType]copy]; + + modelDataSuccess(); + + + + } error:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + + modelDataErrors(); + + } isNetworking:^(BOOL isNetwork) { + + + modelDataIsNetWoring(isNetwork); + + + }]; + }else{ + //直接显示持久化数据 数据显示完毕 + modelDataSuccess(); + + NSLog(@"cout====%ld",_array.count); + } + + + + + +} + + + +#pragma mark -- 得到持久化的数据 +-(NSArray*)getPersistenceDataWithType:(NSString*)type{ + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + + + //指定对结果的排序方式 + NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:FavouriteBean_title ascending:NO]; + NSArray *sortDescriptions = [[NSArray alloc]initWithObjects:sortDescriptor, nil]; + [fetchRequest setSortDescriptors:sortDescriptions]; + + + + //查询条件 + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = %@",type]; + + fetchRequest.predicate = predicate; + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + return fetchedObjects; + +} + +#pragma mark -- 持久化所有数据 +-(void)persistenceDataWithType:(NSString*)type{ + + //删除已经存在的数据 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", type]; + [CoreDataUtils deleteDateFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + + for (BlogBean *bean in _array) { + + + NSManagedObject *favouriteBean =[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + + [favouriteBean setValue:bean.title forKey:FavouriteBean_title]; + [favouriteBean setValue:bean.subTitle forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:bean.image forKey:FavouriteBean_image_name]; + [favouriteBean setValue:bean.url forKey:FavouriteBean_url]; + [favouriteBean setValue:type forKey:FavouriteBean_type]; + + + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + +} + + +-(void)saveFavourite:(NSIndexPath*)indexPath favouriteType:(NSString*)type{ + + NSManagedObject *loveBean = _array[indexPath.row]; + + + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"url= %@ AND type=%@", [loveBean valueForKey:FavouriteBean_url],type]; + NSArray*favouriteList = [CoreDataUtils queryDataFromTableName:CD_FAVOURITE_BEAN andNSPredicate:urlPredicate]; + if (favouriteList.count!=0) { + NSLog(@"已经有这条数据了 ");//更新收藏的状态 + + + [SharedApp.managedObjectContext deleteObject:favouriteList[0]]; + + + NSError *error = nil; + [SharedApp.managedObjectContext save:&error]; + if (error) { + + NSLog(@"删除收藏失败%@",[error userInfo]); + }else{ + NSLog(@"删除收藏成功"); + } + }else{ + + //添加收藏 + NSManagedObject *favouriteBean = [NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_title] forKey:FavouriteBean_title]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_subtitle] forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_image_name] forKey:FavouriteBean_image_name]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_url] forKey:FavouriteBean_url]; + [favouriteBean setValue:type forKey:FavouriteBean_type]; + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + + + + + +} + + + + +/** + * 判断收藏的URL地址是否存在 + * + * @param url URL地址 + * + * @return YES 存在 NO 不存在 + */ +-(BOOL)isExistSimpleDataWithURL:(NSString*)url{ + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"%@ = %@",@"url", url]; + + return [CoreDataUtils dataisExistTableName:CD_FAVOURITE_BEAN withPredicate:urlPredicate]; +} + + +/** + * 判断URL 是否收藏过 + * + * @param url url 地址 + * @param type 收藏类型 1 博客 2 网址 3 视频 + * + * @return YES 收藏过了 NO 没有收藏过 + */ +-(BOOL)queryisFavourite:(NSString*)url withType:(NSString*)type{ + //判断当前条目是否收藏 显示收藏不收藏 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url= %@ AND type=%@", url,type]; + + NSArray *queryList = [CoreDataUtils queryDataFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + if (queryList.count!=0) { + NSLog(@"cout=%ld",queryList.count); + return YES; + }else{ + + return NO; + } +} + + +/** + * 设置SWTableViewCell 滑动文字 + * + * @param url url地址 + * @param type 1 博客 2 网址 3 视频 + * + * @return 要显示的Button集合 + */ +- (NSArray *)setRightSWCellButtons:(NSString*)url withType:(NSString*)type +{ + + + NSString *showText ; + + if ([self queryisFavourite:url withType:type]) { + showText = NSLocalizedString(@"unlove", nil); + }else{ + showText = NSLocalizedString(@"love", nil); + } + + + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:1.0f green:0.231f blue:0.188f alpha:1.0] + + title:showText]; + + + + return rightUtilityButtons; + + +} + + + + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.h b/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.h new file mode 100644 index 0000000..160f000 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.h @@ -0,0 +1,36 @@ +// +// FavouriteViewControllerViewModel.h +// iOSStudy +// +// Created by chenguandong on 15/4/6. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import + + + +@interface FavouriteViewControllerViewModel : NSObject + +@property(nonatomic,strong)NSMutableArray *array; + +- (NSInteger)getNumberOfRowsInSection; +/** + * 查询收藏的数据 + * + * @param type 查询的类型 + * + * @return 收藏数据的集合 + */ +-(NSArray*)getFavouriteData:(NSString*)type; + +/** + * 获取cell的数据 + * + * @param indexPath indexPath + * + * @return cell的数据 + */ +-(NSManagedObject*)getFavouriteObjtBean:(NSIndexPath *)indexPath; +@end diff --git a/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.m b/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.m new file mode 100644 index 0000000..e7b20ba --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/FavouriteViewControllerViewModel.m @@ -0,0 +1,47 @@ +// +// FavouriteViewControllerViewModel.m +// iOSStudy +// +// Created by chenguandong on 15/4/6. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "FavouriteViewControllerViewModel.h" +#import "CoreDataUtils.h" +#import "Constants .h" +@implementation FavouriteViewControllerViewModel + +- (instancetype)init +{ + self = [super init]; + if (self) { + _array = [NSMutableArray array]; + } + return self; +} +-(NSManagedObject*)getFavouriteObjtBean:(NSIndexPath *)indexPath{ + return _array[indexPath.row]; +} + + + +-(NSArray*)getFavouriteData:(NSString*)type{ + + + + NSPredicate *typePredicate = [NSPredicate predicateWithFormat:@"type= %@", type]; + NSArray *array = [CoreDataUtils queryDataFromTableName:CD_FAVOURITE_BEAN andNSPredicate:typePredicate]; + _array = [array copy]; + + NSLog(@"cout=%ld",_array.count); + + return _array; +} + +- (NSInteger)getNumberOfRowsInSection{ + + return _array.count; +} + + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h b/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h deleted file mode 100644 index cfbfc30..0000000 --- a/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h +++ /dev/null @@ -1,51 +0,0 @@ -// -// FirstViewControllerViewModel.h -// iOSStudy -// -// Created by chenguandong on 15/2/16. -// Copyright (c) 2015年 chenguandong. All rights reserved. -// - -#import -#import "NetWorkTools.h" -#import "JsonTools.h" -#import "BlogBean.h" -typedef void (^modelSuccess)(); -typedef void (^modelError)(); -typedef void (^modelNetWorking)(BOOL isNetWorking); - -@interface FirstViewControllerViewModel : NSObject -@property(nonatomic,strong)NSArray *array; - -/** - * 获取博客数据 - * - * @param modelDataSuccess 获取博客数据成功 - * @param modelDataErrors 获取博客数据失败 - * @param modelDataIsNetWoring 是否有网络 - */ --(void)getDate:(modelSuccess)modelDataSuccess modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring; - -/** - * 获取table的行数 - * - * @return table的行数 - */ -- (NSInteger)getNumberOfRowsInSection; - -/** - * 获取cell的数据 - * - * @param indexPath indexPath - * - * @return cell的数据 - */ --(BlogBean*)getBlogBean:(NSIndexPath *)indexPath; - - - - --(void)saveFavourite:(NSIndexPath*)indexPath; - --(BOOL)isExistURL:(NSString*)url; -@end diff --git a/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m b/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m deleted file mode 100644 index 2426222..0000000 --- a/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m +++ /dev/null @@ -1,214 +0,0 @@ -// -// FirstViewControllerViewModel.m -// iOSStudy -// -// Created by chenguandong on 15/2/16. -// Copyright (c) 2015年 chenguandong. All rights reserved. -// - -#import "FirstViewControllerViewModel.h" -#import "FavouriteBean.h" -#import "Constants .h" -@implementation FirstViewControllerViewModel -- (instancetype)init -{ - self = [super init]; - if (self) { - _array = [NSMutableArray array]; - } - return self; -} - -- (NSInteger)getNumberOfRowsInSection{ - - return _array.count; -} - - - --(BlogBean*)getBlogBean:(NSIndexPath *)indexPath{ - - return _array[indexPath.row]; -} - - --(void)getDate:(modelSuccess)modelDataSuccess modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring{ - - - _array = [[self getPersistenceData]copy]; - - modelDataSuccess(); - - - - - // - [NetWorkTools postHttp:Address_blogs success:^(AFHTTPRequestOperation *operation, id responseObject) { - - NSLog(@"JSON: %@", [operation responseString]); - - NSArray *dic = [JsonTools getJsonNSDictionary:[operation responseString]]; - - //将JSON数据和Model的属性进行绑定 - - NSArray *arr = [MTLJSONAdapter modelsOfClass:[BlogBean class] fromJSONArray:dic error:nil]; - - for (BlogBean *bean in arr) { - NSLog(@"%@",bean.image); - } - - _array = [arr copy]; - - - modelDataSuccess(); - - [self persistenceData]; - - } error:^(AFHTTPRequestOperation *operation, NSError *error) { - NSLog(@"Error: %@", error); - - modelDataErrors(); - - } isNetworking:^(BOOL isNetwork) { - - - modelDataIsNetWoring(isNetwork); - - - }]; - - -} - -#pragma mark -- 得到持久化的数据 --(NSArray*)getPersistenceData{ - NSError *error; - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; - NSEntityDescription *entity = [NSEntityDescription - entityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; - [fetchRequest setEntity:entity]; - - NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; - - NSMutableArray *blogArr = [NSMutableArray arrayWithCapacity:10]; - - - for (NSManagedObject *info in fetchedObjects) { - - BlogBean *blogBean = [[BlogBean alloc]init]; - blogBean.title = [info valueForKey:@"title"]; - blogBean.subTitle=[info valueForKey:@"subtitle"]; - blogBean.image = [info valueForKey:@"image_name"]; - blogBean.url = [info valueForKey:@"url"]; - [blogArr addObject:blogBean]; - - } - - return blogArr; - -} - -//持久化所有数据 --(void)persistenceData{ - - for (BlogBean *bean in _array) { - - if ([self isExistURL:bean.url]) { - NSLog(@"已经有这条数据了"); - }else{ - FavouriteBean *favouriteBean = (FavouriteBean*)[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; - - - favouriteBean.title = bean.title; - favouriteBean.subtitle = bean.subTitle; - favouriteBean.image_name = bean.image; - favouriteBean.url= bean.url; - favouriteBean.type =@"0"; - - - NSError *error; - BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; - if (!isSaveSuccess) { - NSLog(@"Error: %@,%@",error,[error userInfo]); - }else { - NSLog(@"Save successful favourite!"); - } - - - } - - } - -} - - --(void)saveFavourite:(NSIndexPath*)indexPath{ - - BlogBean *loveBean = _array[indexPath.row]; - - - if ([self isExistURL:loveBean.url]) { - NSLog(@"已经有这条数据了"); - }else{ - FavouriteBean *favouriteBean = (FavouriteBean*)[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; - - - favouriteBean.title = loveBean.title; - favouriteBean.subtitle = loveBean.subTitle; - favouriteBean.image_name = loveBean.image; - favouriteBean.url= loveBean.url; - favouriteBean.type =@"1"; - - - - NSError *error; - BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; - if (!isSaveSuccess) { - NSLog(@"Error: %@,%@",error,[error userInfo]); - }else { - NSLog(@"Save successful favourite!"); - } - - - } - - -} - -//检查这个URL在数据库是否存在 --(BOOL)isExistURL:(NSString*)url{ - NSError *error; - NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; - NSEntityDescription *entity = [NSEntityDescription - entityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; - [fetchRequest setEntity:entity]; - - NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; - - - for (NSManagedObject *info in fetchedObjects) { - NSLog(@"Name: %@", [info valueForKey:@"title"]); - /* - NSManagedObject *details = [info valueForKey:@"details"]; - NSLog(@"Zip: %@", [details valueForKey:@"zip"]); - */ - } - - - NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url = %@", url]; - - - NSArray *resultArr = [fetchedObjects filteredArrayUsingPredicate:titlePredicate]; - if (resultArr.count!=0) { - NSLog(@"111%lu",resultArr.count); - return YES; - }else{ - NSLog(@"222%lu",resultArr.count); - return NO; - } - - -} - - -@end diff --git a/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.h b/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.h new file mode 100644 index 0000000..9f7d89a --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.h @@ -0,0 +1,18 @@ +// +// FirstViewControllerViewModel.h +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "NetWorkTools.h" +#import "JsonTools.h" +#import "VideoBean.h" +#import "EntityConstants.h" +#import "CoreDataUtils.h" +#import "BlogViewControllerViewModel.h" +@interface VideoViewControllerViewModel : BlogViewControllerViewModel + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.m b/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.m new file mode 100644 index 0000000..adbfe95 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/VideoViewControllerViewModel.m @@ -0,0 +1,47 @@ +// +// FirstViewControllerViewModel.m +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "VideoViewControllerViewModel.h" + +@implementation VideoViewControllerViewModel + + +-(void)persistenceDataWithType:(NSString *)type{ + + //删除已经存在的数据 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", type]; + [CoreDataUtils deleteDateFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + + for (VideoBean *bean in self.array) { + + NSManagedObject *favouriteBean =[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + + [favouriteBean setValue:bean.title forKey:FavouriteBean_title]; + [favouriteBean setValue:bean.subTitle forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:bean.webImage forKey:FavouriteBean_image_name]; + [favouriteBean setValue:bean.webUrl forKey:FavouriteBean_url]; + [favouriteBean setValue:type forKey:FavouriteBean_type]; + + NSLog(@"==%@",bean.subTitle); + + + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + +} + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.h b/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.h new file mode 100644 index 0000000..c2602c8 --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.h @@ -0,0 +1,17 @@ +// +// FirstViewControllerViewModel.h +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "NetWorkTools.h" +#import "JsonTools.h" +#import "WebBean.h" +#import "BlogViewControllerViewModel.h" + +@interface WebViewControllerViewModel : BlogViewControllerViewModel + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.m b/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.m new file mode 100644 index 0000000..8b1015f --- /dev/null +++ b/iOSStudy/iOSStudy/ViewModel/WebViewControllerViewModel.m @@ -0,0 +1,48 @@ +// +// FirstViewControllerViewModel.m +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WebViewControllerViewModel.h" +#import "CoreDataUtils.h" +#import "EntityConstants.h" + +@implementation WebViewControllerViewModel + +-(void)persistenceDataWithType:(NSString *)type{ + + //删除已经存在的数据 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", type]; + [CoreDataUtils deleteDateFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + + for (WebBean *bean in self.array) { + + + NSManagedObject *favouriteBean =[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + + [favouriteBean setValue:bean.title forKey:FavouriteBean_title]; + [favouriteBean setValue:bean.subTitle forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:bean.webImage forKey:FavouriteBean_image_name]; + [favouriteBean setValue:bean.webUrl forKey:FavouriteBean_url]; + [favouriteBean setValue:type forKey:FavouriteBean_type]; + + + + + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + +} +@end diff --git a/iOSStudy/iOSStudy/WebViewController.h b/iOSStudy/iOSStudy/WebViewController.h new file mode 100644 index 0000000..813366c --- /dev/null +++ b/iOSStudy/iOSStudy/WebViewController.h @@ -0,0 +1,18 @@ +// +// SecondViewController.h +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "BaseViewController.h" +#import "WebViewControllerViewModel.h" +#import +@interface WebViewController : BaseViewController +@property (weak, nonatomic) IBOutlet UITableView *tableView; +@property(nonatomic,strong)WebViewControllerViewModel *viewModel; +@property(nonatomic,copy)NSString *favouriteType; +@end + diff --git a/iOSStudy/iOSStudy/WebViewController.m b/iOSStudy/iOSStudy/WebViewController.m new file mode 100644 index 0000000..bdfc0c7 --- /dev/null +++ b/iOSStudy/iOSStudy/WebViewController.m @@ -0,0 +1,208 @@ +// +// SecondViewController.m +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WebViewController.h" +#import "NetWorkTools.h" +#import "Constants .h" +#import +#import "JsonTools.h" +#import "BlogBean.h" +#import +#import "BlogDetailViewController.h" +#import +#import +#import +#import "EntityConstants.h" +#import "STBaseTableViewCell.h" +@interface WebViewController () + +@end + +@implementation WebViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + + _tableView.delegate = self; + _tableView.dataSource = self; + + [self initViewData]; + + + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(notificationReloadData:) name:notifacationWebReload object:nil]; +} + +-(void)notificationReloadData:(NSNotification*)notifacation{ + + + [_tableView reloadData]; +} + + +-(void)initViewData{ + + _favouriteType = TYPE_WEB_FAVOURITE_TYPE; + + _viewModel = [[WebViewControllerViewModel alloc]init]; + + [self.tableView addLegendHeaderWithRefreshingBlock:^{ + [_viewModel getDate:^{ + [_tableView reloadData]; + + [self stopTableRefreshing]; + + } modelDataReload:^{ + [_tableView reloadData]; + } modelDataErrors:^{ + [self stopTableRefreshing]; + } modelDataIsNetworking:^(BOOL isNetWorking) { + [self stopTableRefreshing]; + } httpAdress:Adress_webs dataType:TYPE_WEB_SIMPLE_TYPE jsonClass:[WebBean class]]; + + }]; + + + // 隐藏时间 + self.tableView.header.updatedTimeHidden = YES; + // 隐藏状态 + self.tableView.header.stateHidden = YES; + + [self.tableView.header beginRefreshing]; + + _tableView.rowHeight = 60; + + [self.tableView registerNib:[UINib nibWithNibName:@"STBaseTableViewCell" bundle:nil] forCellReuseIdentifier:@"WebCell"]; +} + +/** + * 停止UITableView刷新 + */ +-(void)stopTableRefreshing{ + if ([_tableView.header isRefreshing]) { + [_tableView.header endRefreshing]; + } +} + + + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + +} + + + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + return [_viewModel getNumberOfRowsInSection]; +} + +// Row display. Implementers should *always* try to reuse cells by setting each cell's reuseIdentifier and querying for available reusable cells with dequeueReusableCellWithIdentifier: +// Cell gets various attributes set automatically based on table (separators) and data source (accessory views, editing controls) + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + + static NSString *CellIdentifier = @"WebCell"; + STBaseTableViewCell *cell = (STBaseTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier + forIndexPath:indexPath]; + + + cell.delegate = self; + + + cell.title.text = [[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_title]; + cell.subtitle.text = [[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_subtitle]; + + + + cell.rightUtilityButtons =[_viewModel setRightSWCellButtons:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url] withType:_favouriteType]; + + + [cell.imageIcon setImageWithURL:[NSURL URLWithString:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_image_name]] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; + + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + return cell; +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + + SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url]]; + [self presentViewController:webViewController animated:NO completion:NULL]; +} + +-(void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender{ + + if ([segue.identifier isEqualToString:@"SVWebViewController"]) { + + + } +} + + +#pragma mark-- SWTableViewCell delagate + +- (BOOL)swipeableTableViewCellShouldHideUtilityButtonsOnSwipe:(SWTableViewCell *)cell +{ + + return YES; +} +- (BOOL)swipeableTableViewCell:(SWTableViewCell *)cell canSwipeToState:(SWCellState)state{ + + return YES; + +} + +- (void)swipeableTableViewCellDidEndScrolling:(SWTableViewCell *)cell{ + + //根据侧滑按钮是否显示设置箭头标志 + if (cell.isUtilityButtonsHidden) { + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + }else{ + cell.accessoryType = UITableViewCellAccessoryNone; + + } +} + +- (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ + + + NSIndexPath *indexPath = [_tableView indexPathForCell:cell]; + + + [_viewModel saveFavourite:indexPath favouriteType:_favouriteType]; + + + [cell hideUtilityButtonsAnimated:YES]; + + [_tableView reloadData]; + + + +} + + + + + + + +-(void)dealloc{ + _tableView.delegate = nil; + _tableView.dataSource = nil; + _viewModel = nil; + [[NSNotificationCenter defaultCenter]removeObserver:self name:notifacationWebReload object:nil]; + +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +@end diff --git a/iOSStudy/iOSStudy/WelcomeViewController.h b/iOSStudy/iOSStudy/WelcomeViewController.h new file mode 100644 index 0000000..3e7fff4 --- /dev/null +++ b/iOSStudy/iOSStudy/WelcomeViewController.h @@ -0,0 +1,15 @@ +// +// WelcomeViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +@interface WelcomeViewController : UIViewController +@property (weak, nonatomic) IBOutlet UIImageView *animationImageView; +@property (weak, nonatomic) IBOutlet FBShimmeringView *shinmmerView; + +@end diff --git a/iOSStudy/iOSStudy/WelcomeViewController.m b/iOSStudy/iOSStudy/WelcomeViewController.m new file mode 100644 index 0000000..a1f25f0 --- /dev/null +++ b/iOSStudy/iOSStudy/WelcomeViewController.m @@ -0,0 +1,100 @@ +// +// WelcomeViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WelcomeViewController.h" +#import "NetWorkTools.h" +#import "HttpVersionTools.h" +#import "MainTabBarViewController.h" +#import "VersionBean.h" +#import "NotificationCenterConstants.h" +@interface WelcomeViewController () + +@end + +@implementation WelcomeViewController + + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + + [_animationImageView startAnimating]; + + + + +} + +-(void)versionSuccess:(NSNotification*)notifacation{ + [self goNextPage]; + + +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(versionSuccess:) name:notifacationVersionSuccess object:nil]; + + NSMutableArray *imageArray = [NSMutableArray arrayWithCapacity:20]; + for (int i =1; i<21; i++) { + + NSString *imageName = [NSString stringWithFormat:@"anim_%.2d.png",i]; + + [imageArray addObject:[UIImage imageNamed:imageName]]; + } + + + _animationImageView.animationImages = imageArray; + _animationImageView.animationRepeatCount = 0; + _animationImageView.animationDuration = 10; + + + + + UILabel *loadingLabel = [[UILabel alloc] initWithFrame:_shinmmerView.bounds]; + loadingLabel.textColor = [UIColor whiteColor]; + loadingLabel.font =[UIFont systemFontOfSize:40]; + loadingLabel.textAlignment = NSTextAlignmentCenter; + loadingLabel.text = NSLocalizedString(@"loadData", nil); + + _shinmmerView.contentView = loadingLabel; + + // Start shimmering. + _shinmmerView.shimmering = YES; +} + +-(void)goNextPage{ + [self performSegueWithIdentifier:@"mainTab" sender:self]; +} + + + +-(void)viewWillDisappear:(BOOL)animated{ + [super viewWillDisappear:YES]; + + [_animationImageView stopAnimating]; + + [[NSNotificationCenter defaultCenter]removeObserver:self name:notifacationVersionSuccess object:nil]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/en.lproj/Localizable.strings b/iOSStudy/iOSStudy/en.lproj/Localizable.strings new file mode 100644 index 0000000..ccde9c5 --- /dev/null +++ b/iOSStudy/iOSStudy/en.lproj/Localizable.strings @@ -0,0 +1,11 @@ +/* + Localizable.strings + iOSStudy + + Created by chenguandong on 15/5/12. + Copyright (c) 2015年 chenguandong. All rights reserved. +*/ + +"loadData" = "updating data..."; +"love" = "love"; +"unlove" = "unlove"; \ No newline at end of file diff --git a/iOSStudy/iOSStudy/en.lproj/Main.strings b/iOSStudy/iOSStudy/en.lproj/Main.strings new file mode 100644 index 0000000..80f5d51 --- /dev/null +++ b/iOSStudy/iOSStudy/en.lproj/Main.strings @@ -0,0 +1,69 @@ + +/* Class = "UITabBarController"; title = "博客"; ObjectID = "49e-Tb-3d3"; */ +"49e-Tb-3d3.title" = "Blog"; + +/* Class = "UILabel"; text = "开源许可"; ObjectID = "5QR-7R-yRv"; */ +"5QR-7R-yRv.text" = "Open source license"; + +/* Class = "UITabBarItem"; title = "收藏"; ObjectID = "8Gx-f0-bsw"; */ +"8Gx-f0-bsw.title" = "Favourite"; + +/* Class = "UILabel"; text = "给应用评分"; ObjectID = "9Uv-G0-brC"; */ +"9Uv-G0-brC.text" = "Rate"; + +/* Class = "UILabel"; text = "Title"; ObjectID = "DUN-jA-nZ1"; */ +"DUN-jA-nZ1.text" = "Title"; + +/* Class = "UITabBarItem"; title = "设置"; ObjectID = "MEY-jV-QF5"; */ +"MEY-jV-QF5.title" = "Setting"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[0] = "博客"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[0]" = "Blog"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[1] = "网站"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[1]" = "Web"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[2] = "视频"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[2]" = "Video"; + +/* Class = "UINavigationItem"; title = "推荐博客"; ObjectID = "WaC-jM-KHt"; */ +"WaC-jM-KHt.title" = "Recommend Blog"; + +/* Class = "UITableViewSection"; footerTitle = "官方博客:http://iosstudy.lofter.com/"; ObjectID = "YWs-ix-bRc"; */ +"YWs-ix-bRc.footerTitle" = "BlogAdress:http://iosstudy.lofter.com/"; + +/* Class = "UITableViewSection"; headerTitle = "关于我们"; ObjectID = "YWs-ix-bRc"; */ +"YWs-ix-bRc.headerTitle" = "About us"; + +/* Class = "UINavigationItem"; title = "推荐网站"; ObjectID = "YiK-bv-9gx"; */ +"YiK-bv-9gx.title" = "Recommend Web"; + +/* Class = "UINavigationItem"; title = "开源协议"; ObjectID = "ZNU-fK-evW"; */ +"ZNU-fK-evW.title" = "Open source license"; + +/* Class = "UILabel"; text = "关于"; ObjectID = "ZgU-bl-sae"; */ +"ZgU-bl-sae.text" = "About"; + +/* Class = "UITabBarItem"; title = "博客"; ObjectID = "acW-dT-cKf"; */ +"acW-dT-cKf.title" = "Blog"; + +/* Class = "UITabBarItem"; title = "网站"; ObjectID = "cPa-gy-q4n"; */ +"cPa-gy-q4n.title" = "Web"; + +/* Class = "UITabBarItem"; title = "视频"; ObjectID = "fbE-WQ-JZW"; */ +"fbE-WQ-JZW.title" = "Video"; + +/* Class = "UINavigationItem"; title = "设置"; ObjectID = "gf0-0D-9bS"; */ +"gf0-0D-9bS.title" = "Setting"; + +/* Class = "UILabel"; text = "意见反馈"; ObjectID = "o5j-bN-LCE"; */ +"o5j-bN-LCE.text" = "Feedback"; + +/* Class = "UINavigationItem"; title = "推荐视频"; ObjectID = "otE-MF-bXm"; */ +"otE-MF-bXm.title" = "Recommend Video"; + +/* Class = "UILabel"; text = "Subtitle"; ObjectID = "rkz-vV-hB8"; */ +"rkz-vV-hB8.text" = "Subtitle"; + +/* Class = "UITableViewController"; title = "设置"; ObjectID = "wtw-i4-ZN0"; */ +"wtw-i4-ZN0.title" = "Setting"; diff --git a/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents b/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents index 6944e80..c2fcb8e 100644 --- a/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents +++ b/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents @@ -1,5 +1,5 @@ - + @@ -7,7 +7,12 @@ + + + + - + + \ No newline at end of file diff --git a/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.pbxproj b/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.pbxproj new file mode 100644 index 0000000..64141a9 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.pbxproj @@ -0,0 +1,929 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 46; + objects = { + +/* Begin PBXBuildFile section */ + 184F48AF1A93321700C5C22F /* SecondViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */; }; + 184F48B41A93340F00C5C22F /* WebBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 184F48B31A93340F00C5C22F /* WebBean.m */; }; + 185EEB4B1A98DC9900BFDB79 /* SettingTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 185EEB4A1A98DC9900BFDB79 /* SettingTableViewController.m */; }; + 185EEB4F1A98E0BA00BFDB79 /* tabbar_setting.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */; }; + 185EEB501A98E0BA00BFDB79 /* tabbar_setting@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */; }; + 185EEB511A98E0BA00BFDB79 /* tabbar_setting@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */; }; + 189EF8331A8399B100F19327 /* BlogBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8321A8399B100F19327 /* BlogBean.m */; }; + 189EF8361A839FC600F19327 /* JsonTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8351A839FC600F19327 /* JsonTools.m */; }; + 189EF83A1A83C3AF00F19327 /* BlogDetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 189EF8391A83C3AF00F19327 /* BlogDetailViewController.m */; }; + 18A998931A7C77D0002E7219 /* NetWorkTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 18A998921A7C77D0002E7219 /* NetWorkTools.m */; }; + 18AB47951A99969600E4C030 /* VideoBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47941A99969600E4C030 /* VideoBean.m */; }; + 18AB47981A99A51200E4C030 /* BaseTableViewCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */; }; + 18AB479B1A9C59CB00E4C030 /* UIImage+Resize.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */; }; + 18AB479F1A9C5E3300E4C030 /* VideoCell.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB479E1A9C5E3300E4C030 /* VideoCell.m */; }; + 18AB47A51A9C82FA00E4C030 /* AddBlogTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */; }; + 18AB47A81A9DA40500E4C030 /* DBUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47A71A9DA40500E4C030 /* DBUtils.m */; }; + 18AB47AB1AA415A400E4C030 /* FavouriteBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18AB47AA1AA415A400E4C030 /* FavouriteBean.m */; }; + 18B23B251A7A14D100E80854 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B241A7A14D100E80854 /* main.m */; }; + 18B23B281A7A14D100E80854 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B271A7A14D100E80854 /* AppDelegate.m */; }; + 18B23B2B1A7A14D100E80854 /* FirstViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2A1A7A14D100E80854 /* FirstViewController.m */; }; + 18B23B2E1A7A14D100E80854 /* SecondViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B2D1A7A14D100E80854 /* SecondViewController.m */; }; + 18B23B311A7A14D100E80854 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B2F1A7A14D100E80854 /* Main.storyboard */; }; + 18B23B331A7A14D100E80854 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B321A7A14D100E80854 /* Images.xcassets */; }; + 18B23B361A7A14D100E80854 /* LaunchScreen.xib in Resources */ = {isa = PBXBuildFile; fileRef = 18B23B341A7A14D100E80854 /* LaunchScreen.xib */; }; + 18B23B421A7A14D100E80854 /* iOSStudyTests.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B411A7A14D100E80854 /* iOSStudyTests.m */; }; + 18B23B4D1A7A234800E80854 /* BaseViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18B23B4C1A7A234800E80854 /* BaseViewController.m */; }; + 18C845091ACCFC690053884F /* HttpVersionTools.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845081ACCFC690053884F /* HttpVersionTools.m */; }; + 18C8450C1ACD41C40053884F /* BlogJsonBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C8450B1ACD41C40053884F /* BlogJsonBean.m */; }; + 18C8450F1ACE3E580053884F /* CoreDataUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C8450E1ACE3E580053884F /* CoreDataUtils.m */; }; + 18C845121ACE4A580053884F /* WelcomeViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845111ACE4A580053884F /* WelcomeViewController.m */; }; + 18C845151ACE56150053884F /* MainTabBarViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18C845141ACE56150053884F /* MainTabBarViewController.m */; }; + 18CECC0A1A91ACB7005598E4 /* FirstViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */; }; + 18D201161A95A6F400D5F095 /* icon_29.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010D1A95A6F400D5F095 /* icon_29.png */; }; + 18D201171A95A6F400D5F095 /* icon_40.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010E1A95A6F400D5F095 /* icon_40.png */; }; + 18D201181A95A6F400D5F095 /* icon_58.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2010F1A95A6F400D5F095 /* icon_58.png */; }; + 18D201191A95A6F400D5F095 /* icon_76.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201101A95A6F400D5F095 /* icon_76.png */; }; + 18D2011A1A95A6F400D5F095 /* icon_80.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201111A95A6F400D5F095 /* icon_80.png */; }; + 18D2011B1A95A6F400D5F095 /* icon_87.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201121A95A6F400D5F095 /* icon_87.png */; }; + 18D2011C1A95A6F400D5F095 /* icon_120.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201131A95A6F400D5F095 /* icon_120.png */; }; + 18D2011D1A95A6F400D5F095 /* icon_152.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201141A95A6F400D5F095 /* icon_152.png */; }; + 18D2011E1A95A6F400D5F095 /* icon_180.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201151A95A6F400D5F095 /* icon_180.png */; }; + 18D201221A95A70900D5F095 /* tabbar_blog.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2011F1A95A70900D5F095 /* tabbar_blog.png */; }; + 18D201231A95A70900D5F095 /* tabbar_blog@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201201A95A70900D5F095 /* tabbar_blog@2x.png */; }; + 18D201241A95A70900D5F095 /* tabbar_blog@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201211A95A70900D5F095 /* tabbar_blog@3x.png */; }; + 18D2012B1A95A9D600D5F095 /* tabbar_video.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201251A95A9D600D5F095 /* tabbar_video.png */; }; + 18D2012C1A95A9D600D5F095 /* tabbar_video@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201261A95A9D600D5F095 /* tabbar_video@2x.png */; }; + 18D2012D1A95A9D600D5F095 /* tabbar_video@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201271A95A9D600D5F095 /* tabbar_video@3x.png */; }; + 18D2012E1A95A9D600D5F095 /* tabbar_web.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201281A95A9D600D5F095 /* tabbar_web.png */; }; + 18D2012F1A95A9D600D5F095 /* tabbar_web@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201291A95A9D600D5F095 /* tabbar_web@2x.png */; }; + 18D201301A95A9D600D5F095 /* tabbar_web@3x.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2012A1A95A9D600D5F095 /* tabbar_web@3x.png */; }; + 18D201351A96090A00D5F095 /* app_img_640.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201321A96090A00D5F095 /* app_img_640.png */; }; + 18D201361A96090A00D5F095 /* app_img_1136.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201331A96090A00D5F095 /* app_img_1136.png */; }; + 18D201371A96090A00D5F095 /* app_img_iOS8.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201341A96090A00D5F095 /* app_img_iOS8.png */; }; + 18D2013C1A960B6100D5F095 /* app_img_768x1024.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201381A960B6100D5F095 /* app_img_768x1024.png */; }; + 18D2013D1A960B6100D5F095 /* app_img_1024x768.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D201391A960B6100D5F095 /* app_img_1024x768.png */; }; + 18D2013E1A960B6100D5F095 /* app_img_1536x2048.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */; }; + 18D2013F1A960B6100D5F095 /* app_img_2048x1536.png in Resources */ = {isa = PBXBuildFile; fileRef = 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */; }; + 18D201421A96143300D5F095 /* ThirdViewControllerViewModel.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */; }; + 18D4ECA61AD17F56009FE9F0 /* EntityConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */; }; + 18D908A71A8A205600B42A42 /* ThirdTableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */; }; + 18DF6D3D1A80D3BC005751E8 /* Reachability.m in Sources */ = {isa = PBXBuildFile; fileRef = 18DF6D3C1A80D3BC005751E8 /* Reachability.m */; }; + 18DF6D3F1A80D40D005751E8 /* SystemConfiguration.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */; }; + 18E016AA1ACAA898002A6E59 /* CoreData.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 18E016A91ACAA898002A6E59 /* CoreData.framework */; }; + 18E016E51ACAAB35002A6E59 /* iOSStudy.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = 18E016E31ACAAB35002A6E59 /* iOSStudy.xcdatamodeld */; }; + 18E6A0B51ACCF7FD00B28D32 /* VersionBean.m in Sources */ = {isa = PBXBuildFile; fileRef = 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */; }; + 54A0444849F1931415392FC1 /* libPods.a in Frameworks */ = {isa = PBXBuildFile; fileRef = E83ED1B8EA89BC57ACF91BA5 /* libPods.a */; }; +/* End PBXBuildFile section */ + +/* Begin PBXContainerItemProxy section */ + 18B23B3C1A7A14D100E80854 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = 18B23B171A7A14D000E80854 /* Project object */; + proxyType = 1; + remoteGlobalIDString = 18B23B1E1A7A14D000E80854; + remoteInfo = iOSStudy; + }; +/* End PBXContainerItemProxy section */ + +/* Begin PBXFileReference section */ + 05EB633B553B549AA5102110 /* Pods.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.debug.xcconfig; path = "Pods/Target Support Files/Pods/Pods.debug.xcconfig"; sourceTree = ""; }; + 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SecondViewControllerViewModel.m; path = iOSStudy/ViewModel/SecondViewControllerViewModel.m; sourceTree = ""; }; + 184F48B01A93323F00C5C22F /* SecondViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SecondViewControllerViewModel.h; path = iOSStudy/ViewModel/SecondViewControllerViewModel.h; sourceTree = ""; }; + 184F48B21A93340F00C5C22F /* WebBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebBean.h; path = Bean/webBean/WebBean.h; sourceTree = ""; }; + 184F48B31A93340F00C5C22F /* WebBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = WebBean.m; path = Bean/webBean/WebBean.m; sourceTree = ""; }; + 185EEB491A98DC9900BFDB79 /* SettingTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SettingTableViewController.h; sourceTree = ""; }; + 185EEB4A1A98DC9900BFDB79 /* SettingTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SettingTableViewController.m; sourceTree = ""; }; + 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_setting.png; path = " Resource/images/tabbar/tabbar_setting.png"; sourceTree = ""; }; + 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_setting@2x.png"; path = " Resource/images/tabbar/tabbar_setting@2x.png"; sourceTree = ""; }; + 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_setting@3x.png"; path = " Resource/images/tabbar/tabbar_setting@3x.png"; sourceTree = ""; }; + 189EF8311A8399B100F19327 /* BlogBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogBean.h; path = Bean/blogBean/BlogBean.h; sourceTree = ""; }; + 189EF8321A8399B100F19327 /* BlogBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogBean.m; path = Bean/blogBean/BlogBean.m; sourceTree = ""; }; + 189EF8341A839FC600F19327 /* JsonTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = JsonTools.h; path = Tools/JsonTools.h; sourceTree = ""; }; + 189EF8351A839FC600F19327 /* JsonTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = JsonTools.m; path = Tools/JsonTools.m; sourceTree = ""; }; + 189EF8381A83C3AF00F19327 /* BlogDetailViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogDetailViewController.h; path = ViewColl/BlogDetailViewController.h; sourceTree = ""; }; + 189EF8391A83C3AF00F19327 /* BlogDetailViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogDetailViewController.m; path = ViewColl/BlogDetailViewController.m; sourceTree = ""; }; + 18A998911A7C77D0002E7219 /* NetWorkTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NetWorkTools.h; path = Tools/NetWorkTools.h; sourceTree = ""; }; + 18A998921A7C77D0002E7219 /* NetWorkTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = NetWorkTools.m; path = Tools/NetWorkTools.m; sourceTree = ""; }; + 18AB47931A99969600E4C030 /* VideoBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoBean.h; path = Bean/videoBean/VideoBean.h; sourceTree = ""; }; + 18AB47941A99969600E4C030 /* VideoBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoBean.m; path = Bean/videoBean/VideoBean.m; sourceTree = ""; }; + 18AB47961A99A51200E4C030 /* BaseTableViewCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseTableViewCell.h; path = Base/BaseTableViewCell.h; sourceTree = ""; }; + 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BaseTableViewCell.m; path = Base/BaseTableViewCell.m; sourceTree = ""; }; + 18AB47991A9C59CB00E4C030 /* UIImage+Resize.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "UIImage+Resize.h"; path = "libs/UIImage+Resize.h"; sourceTree = ""; }; + 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "UIImage+Resize.m"; path = "libs/UIImage+Resize.m"; sourceTree = ""; }; + 18AB479D1A9C5E3300E4C030 /* VideoCell.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VideoCell.h; path = Cell/VideoCell.h; sourceTree = ""; }; + 18AB479E1A9C5E3300E4C030 /* VideoCell.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VideoCell.m; path = Cell/VideoCell.m; sourceTree = ""; }; + 18AB47A31A9C82FA00E4C030 /* AddBlogTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AddBlogTableViewController.h; sourceTree = ""; }; + 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AddBlogTableViewController.m; sourceTree = ""; }; + 18AB47A61A9DA40500E4C030 /* DBUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DBUtils.h; path = Tools/DBUtils.h; sourceTree = ""; }; + 18AB47A71A9DA40500E4C030 /* DBUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = DBUtils.m; path = Tools/DBUtils.m; sourceTree = ""; }; + 18AB47A91AA415A400E4C030 /* FavouriteBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FavouriteBean.h; path = Bean/FavouriteBean.h; sourceTree = ""; }; + 18AB47AA1AA415A400E4C030 /* FavouriteBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FavouriteBean.m; path = Bean/FavouriteBean.m; sourceTree = ""; }; + 18B23B1F1A7A14D000E80854 /* iOSStudy.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = iOSStudy.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 18B23B231A7A14D100E80854 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 18B23B241A7A14D100E80854 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; + 18B23B261A7A14D100E80854 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; + 18B23B271A7A14D100E80854 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; + 18B23B291A7A14D100E80854 /* FirstViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = FirstViewController.h; sourceTree = ""; }; + 18B23B2A1A7A14D100E80854 /* FirstViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = FirstViewController.m; sourceTree = ""; }; + 18B23B2C1A7A14D100E80854 /* SecondViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = SecondViewController.h; sourceTree = ""; }; + 18B23B2D1A7A14D100E80854 /* SecondViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = SecondViewController.m; sourceTree = ""; }; + 18B23B301A7A14D100E80854 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; + 18B23B321A7A14D100E80854 /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Images.xcassets; sourceTree = ""; }; + 18B23B351A7A14D100E80854 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/LaunchScreen.xib; sourceTree = ""; }; + 18B23B3B1A7A14D100E80854 /* iOSStudyTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = iOSStudyTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; + 18B23B401A7A14D100E80854 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 18B23B411A7A14D100E80854 /* iOSStudyTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = iOSStudyTests.m; sourceTree = ""; }; + 18B23B4B1A7A234800E80854 /* BaseViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BaseViewController.h; path = Base/BaseViewController.h; sourceTree = ""; }; + 18B23B4C1A7A234800E80854 /* BaseViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BaseViewController.m; path = Base/BaseViewController.m; sourceTree = ""; }; + 18C845071ACCFC690053884F /* HttpVersionTools.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = HttpVersionTools.h; path = Tools/HttpVersionTools.h; sourceTree = ""; }; + 18C845081ACCFC690053884F /* HttpVersionTools.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = HttpVersionTools.m; path = Tools/HttpVersionTools.m; sourceTree = ""; }; + 18C8450A1ACD41C40053884F /* BlogJsonBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BlogJsonBean.h; path = Bean/blogBean/BlogJsonBean.h; sourceTree = ""; }; + 18C8450B1ACD41C40053884F /* BlogJsonBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = BlogJsonBean.m; path = Bean/blogBean/BlogJsonBean.m; sourceTree = ""; }; + 18C8450D1ACE3E580053884F /* CoreDataUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = CoreDataUtils.h; path = Tools/CoreDataUtils.h; sourceTree = ""; }; + 18C8450E1ACE3E580053884F /* CoreDataUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = CoreDataUtils.m; path = Tools/CoreDataUtils.m; sourceTree = ""; }; + 18C845101ACE4A580053884F /* WelcomeViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WelcomeViewController.h; sourceTree = ""; }; + 18C845111ACE4A580053884F /* WelcomeViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = WelcomeViewController.m; sourceTree = ""; }; + 18C845131ACE56150053884F /* MainTabBarViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MainTabBarViewController.h; sourceTree = ""; }; + 18C845141ACE56150053884F /* MainTabBarViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = MainTabBarViewController.m; sourceTree = ""; }; + 18CECC081A91ACB6005598E4 /* FirstViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = FirstViewControllerViewModel.h; path = iOSStudy/ViewModel/FirstViewControllerViewModel.h; sourceTree = ""; }; + 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = FirstViewControllerViewModel.m; path = iOSStudy/ViewModel/FirstViewControllerViewModel.m; sourceTree = ""; }; + 18CECC101A921272005598E4 /* zh-Hans */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = "zh-Hans"; path = "zh-Hans.lproj/LaunchScreen.strings"; sourceTree = ""; }; + 18D2010D1A95A6F400D5F095 /* icon_29.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_29.png; path = " Resource/images/appicon/icon_29.png"; sourceTree = ""; }; + 18D2010E1A95A6F400D5F095 /* icon_40.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_40.png; path = " Resource/images/appicon/icon_40.png"; sourceTree = ""; }; + 18D2010F1A95A6F400D5F095 /* icon_58.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_58.png; path = " Resource/images/appicon/icon_58.png"; sourceTree = ""; }; + 18D201101A95A6F400D5F095 /* icon_76.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_76.png; path = " Resource/images/appicon/icon_76.png"; sourceTree = ""; }; + 18D201111A95A6F400D5F095 /* icon_80.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_80.png; path = " Resource/images/appicon/icon_80.png"; sourceTree = ""; }; + 18D201121A95A6F400D5F095 /* icon_87.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_87.png; path = " Resource/images/appicon/icon_87.png"; sourceTree = ""; }; + 18D201131A95A6F400D5F095 /* icon_120.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_120.png; path = " Resource/images/appicon/icon_120.png"; sourceTree = ""; }; + 18D201141A95A6F400D5F095 /* icon_152.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_152.png; path = " Resource/images/appicon/icon_152.png"; sourceTree = ""; }; + 18D201151A95A6F400D5F095 /* icon_180.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = icon_180.png; path = " Resource/images/appicon/icon_180.png"; sourceTree = ""; }; + 18D2011F1A95A70900D5F095 /* tabbar_blog.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_blog.png; path = " Resource/images/tabbar/tabbar_blog.png"; sourceTree = ""; }; + 18D201201A95A70900D5F095 /* tabbar_blog@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_blog@2x.png"; path = " Resource/images/tabbar/tabbar_blog@2x.png"; sourceTree = ""; }; + 18D201211A95A70900D5F095 /* tabbar_blog@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_blog@3x.png"; path = " Resource/images/tabbar/tabbar_blog@3x.png"; sourceTree = ""; }; + 18D201251A95A9D600D5F095 /* tabbar_video.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_video.png; path = " Resource/images/tabbar/tabbar_video.png"; sourceTree = ""; }; + 18D201261A95A9D600D5F095 /* tabbar_video@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_video@2x.png"; path = " Resource/images/tabbar/tabbar_video@2x.png"; sourceTree = ""; }; + 18D201271A95A9D600D5F095 /* tabbar_video@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_video@3x.png"; path = " Resource/images/tabbar/tabbar_video@3x.png"; sourceTree = ""; }; + 18D201281A95A9D600D5F095 /* tabbar_web.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = tabbar_web.png; path = " Resource/images/tabbar/tabbar_web.png"; sourceTree = ""; }; + 18D201291A95A9D600D5F095 /* tabbar_web@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_web@2x.png"; path = " Resource/images/tabbar/tabbar_web@2x.png"; sourceTree = ""; }; + 18D2012A1A95A9D600D5F095 /* tabbar_web@3x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "tabbar_web@3x.png"; path = " Resource/images/tabbar/tabbar_web@3x.png"; sourceTree = ""; }; + 18D201321A96090A00D5F095 /* app_img_640.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_640.png; path = " Resource/images/start_img/app_img_640.png"; sourceTree = ""; }; + 18D201331A96090A00D5F095 /* app_img_1136.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1136.png; path = " Resource/images/start_img/app_img_1136.png"; sourceTree = ""; }; + 18D201341A96090A00D5F095 /* app_img_iOS8.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_iOS8.png; path = " Resource/images/start_img/app_img_iOS8.png"; sourceTree = ""; }; + 18D201381A960B6100D5F095 /* app_img_768x1024.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_768x1024.png; path = " Resource/images/start_img/app_img_768x1024.png"; sourceTree = ""; }; + 18D201391A960B6100D5F095 /* app_img_1024x768.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1024x768.png; path = " Resource/images/start_img/app_img_1024x768.png"; sourceTree = ""; }; + 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_1536x2048.png; path = " Resource/images/start_img/app_img_1536x2048.png"; sourceTree = ""; }; + 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = app_img_2048x1536.png; path = " Resource/images/start_img/app_img_2048x1536.png"; sourceTree = ""; }; + 18D201401A96143300D5F095 /* ThirdViewControllerViewModel.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ThirdViewControllerViewModel.h; path = iOSStudy/ViewModel/ThirdViewControllerViewModel.h; sourceTree = ""; }; + 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = ThirdViewControllerViewModel.m; path = iOSStudy/ViewModel/ThirdViewControllerViewModel.m; sourceTree = ""; }; + 18D4ECA41AD17F56009FE9F0 /* EntityConstants.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = EntityConstants.h; path = Constants/EntityConstants.h; sourceTree = ""; }; + 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = EntityConstants.m; path = Constants/EntityConstants.m; sourceTree = ""; }; + 18D908A51A8A205600B42A42 /* ThirdTableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThirdTableViewController.h; sourceTree = ""; }; + 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThirdTableViewController.m; sourceTree = ""; }; + 18DF6D391A80CF76005751E8 /* Constants .h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "Constants .h"; path = "iOSStudy/Constants .h"; sourceTree = ""; }; + 18DF6D3B1A80D3BC005751E8 /* Reachability.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Reachability.h; sourceTree = ""; }; + 18DF6D3C1A80D3BC005751E8 /* Reachability.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = Reachability.m; sourceTree = ""; }; + 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SystemConfiguration.framework; path = System/Library/Frameworks/SystemConfiguration.framework; sourceTree = SDKROOT; }; + 18E016A91ACAA898002A6E59 /* CoreData.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreData.framework; path = System/Library/Frameworks/CoreData.framework; sourceTree = SDKROOT; }; + 18E016E41ACAAB35002A6E59 /* iOSStudy.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = iOSStudy.xcdatamodel; sourceTree = ""; }; + 18E6A0B31ACCF7FD00B28D32 /* VersionBean.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = VersionBean.h; path = Bean/versionBean/VersionBean.h; sourceTree = ""; }; + 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = VersionBean.m; path = Bean/versionBean/VersionBean.m; sourceTree = ""; }; + 2E2CC00A58FD0A745C574BAD /* Pods.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = Pods.release.xcconfig; path = "Pods/Target Support Files/Pods/Pods.release.xcconfig"; sourceTree = ""; }; + E83ED1B8EA89BC57ACF91BA5 /* libPods.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libPods.a; sourceTree = BUILT_PRODUCTS_DIR; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 18B23B1C1A7A14D000E80854 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 18E016AA1ACAA898002A6E59 /* CoreData.framework in Frameworks */, + 18DF6D3F1A80D40D005751E8 /* SystemConfiguration.framework in Frameworks */, + 54A0444849F1931415392FC1 /* libPods.a in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18B23B381A7A14D100E80854 /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 184F48B51A93341B00C5C22F /* webBean */ = { + isa = PBXGroup; + children = ( + 184F48B21A93340F00C5C22F /* WebBean.h */, + 184F48B31A93340F00C5C22F /* WebBean.m */, + ); + name = webBean; + sourceTree = ""; + }; + 189EF82F1A83994B00F19327 /* Bean */ = { + isa = PBXGroup; + children = ( + 18E6A0B21ACCF7C600B28D32 /* VersionBean */, + 18AB47921A99965A00E4C030 /* videoBean */, + 184F48B51A93341B00C5C22F /* webBean */, + 189EF8301A83996500F19327 /* blogBean */, + 18AB47A91AA415A400E4C030 /* FavouriteBean.h */, + 18AB47AA1AA415A400E4C030 /* FavouriteBean.m */, + ); + name = Bean; + sourceTree = ""; + }; + 189EF8301A83996500F19327 /* blogBean */ = { + isa = PBXGroup; + children = ( + 189EF8311A8399B100F19327 /* BlogBean.h */, + 189EF8321A8399B100F19327 /* BlogBean.m */, + 18C8450A1ACD41C40053884F /* BlogJsonBean.h */, + 18C8450B1ACD41C40053884F /* BlogJsonBean.m */, + ); + name = blogBean; + sourceTree = ""; + }; + 189EF8371A83C37B00F19327 /* ViewColl */ = { + isa = PBXGroup; + children = ( + 189EF8381A83C3AF00F19327 /* BlogDetailViewController.h */, + 189EF8391A83C3AF00F19327 /* BlogDetailViewController.m */, + ); + name = ViewColl; + sourceTree = ""; + }; + 18A998901A7C7772002E7219 /* Tools */ = { + isa = PBXGroup; + children = ( + 18A998911A7C77D0002E7219 /* NetWorkTools.h */, + 18A998921A7C77D0002E7219 /* NetWorkTools.m */, + 189EF8341A839FC600F19327 /* JsonTools.h */, + 189EF8351A839FC600F19327 /* JsonTools.m */, + 18AB47A61A9DA40500E4C030 /* DBUtils.h */, + 18AB47A71A9DA40500E4C030 /* DBUtils.m */, + 18C845071ACCFC690053884F /* HttpVersionTools.h */, + 18C845081ACCFC690053884F /* HttpVersionTools.m */, + 18C8450D1ACE3E580053884F /* CoreDataUtils.h */, + 18C8450E1ACE3E580053884F /* CoreDataUtils.m */, + ); + name = Tools; + sourceTree = ""; + }; + 18AB47921A99965A00E4C030 /* videoBean */ = { + isa = PBXGroup; + children = ( + 18AB47931A99969600E4C030 /* VideoBean.h */, + 18AB47941A99969600E4C030 /* VideoBean.m */, + ); + name = videoBean; + sourceTree = ""; + }; + 18AB479C1A9C5D7300E4C030 /* Cell */ = { + isa = PBXGroup; + children = ( + 18AB479D1A9C5E3300E4C030 /* VideoCell.h */, + 18AB479E1A9C5E3300E4C030 /* VideoCell.m */, + ); + name = Cell; + sourceTree = ""; + }; + 18B23B161A7A14D000E80854 = { + isa = PBXGroup; + children = ( + 18AB479C1A9C5D7300E4C030 /* Cell */, + 18CECC0B1A91ACD6005598E4 /* ViewModel */, + 189EF8371A83C37B00F19327 /* ViewColl */, + 189EF82F1A83994B00F19327 /* Bean */, + 18DF6D3A1A80D3A4005751E8 /* libs */, + 18DF6D391A80CF76005751E8 /* Constants .h */, + 18D4ECA41AD17F56009FE9F0 /* EntityConstants.h */, + 18D4ECA51AD17F56009FE9F0 /* EntityConstants.m */, + 18A998901A7C7772002E7219 /* Tools */, + 18B23B4E1A7A235E00E80854 /* Base */, + 18B23B211A7A14D000E80854 /* iOSStudy */, + 18B23B3E1A7A14D100E80854 /* iOSStudyTests */, + 18B23B201A7A14D000E80854 /* Products */, + A75E66DCB4F6E8ABD81B2B38 /* Pods */, + 910A021243EF9C731476BCA9 /* Frameworks */, + ); + sourceTree = ""; + }; + 18B23B201A7A14D000E80854 /* Products */ = { + isa = PBXGroup; + children = ( + 18B23B1F1A7A14D000E80854 /* iOSStudy.app */, + 18B23B3B1A7A14D100E80854 /* iOSStudyTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + 18B23B211A7A14D000E80854 /* iOSStudy */ = { + isa = PBXGroup; + children = ( + 18C845101ACE4A580053884F /* WelcomeViewController.h */, + 18C845111ACE4A580053884F /* WelcomeViewController.m */, + 18B23B261A7A14D100E80854 /* AppDelegate.h */, + 18B23B271A7A14D100E80854 /* AppDelegate.m */, + 18B23B291A7A14D100E80854 /* FirstViewController.h */, + 18B23B2A1A7A14D100E80854 /* FirstViewController.m */, + 18B23B2C1A7A14D100E80854 /* SecondViewController.h */, + 18B23B2D1A7A14D100E80854 /* SecondViewController.m */, + 18D908A51A8A205600B42A42 /* ThirdTableViewController.h */, + 18D908A61A8A205600B42A42 /* ThirdTableViewController.m */, + 185EEB491A98DC9900BFDB79 /* SettingTableViewController.h */, + 185EEB4A1A98DC9900BFDB79 /* SettingTableViewController.m */, + 18AB47A31A9C82FA00E4C030 /* AddBlogTableViewController.h */, + 18AB47A41A9C82FA00E4C030 /* AddBlogTableViewController.m */, + 18B23B2F1A7A14D100E80854 /* Main.storyboard */, + 18B23B321A7A14D100E80854 /* Images.xcassets */, + 18B23B341A7A14D100E80854 /* LaunchScreen.xib */, + 18B23B221A7A14D000E80854 /* Supporting Files */, + 18E016E31ACAAB35002A6E59 /* iOSStudy.xcdatamodeld */, + 18C845131ACE56150053884F /* MainTabBarViewController.h */, + 18C845141ACE56150053884F /* MainTabBarViewController.m */, + ); + path = iOSStudy; + sourceTree = ""; + }; + 18B23B221A7A14D000E80854 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 18D200F71A95A1FB00D5F095 /* Resource */, + 18B23B231A7A14D100E80854 /* Info.plist */, + 18B23B241A7A14D100E80854 /* main.m */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 18B23B3E1A7A14D100E80854 /* iOSStudyTests */ = { + isa = PBXGroup; + children = ( + 18B23B411A7A14D100E80854 /* iOSStudyTests.m */, + 18B23B3F1A7A14D100E80854 /* Supporting Files */, + ); + path = iOSStudyTests; + sourceTree = ""; + }; + 18B23B3F1A7A14D100E80854 /* Supporting Files */ = { + isa = PBXGroup; + children = ( + 18B23B401A7A14D100E80854 /* Info.plist */, + ); + name = "Supporting Files"; + sourceTree = ""; + }; + 18B23B4E1A7A235E00E80854 /* Base */ = { + isa = PBXGroup; + children = ( + 18B23B4B1A7A234800E80854 /* BaseViewController.h */, + 18B23B4C1A7A234800E80854 /* BaseViewController.m */, + 18AB47961A99A51200E4C030 /* BaseTableViewCell.h */, + 18AB47971A99A51200E4C030 /* BaseTableViewCell.m */, + ); + name = Base; + sourceTree = ""; + }; + 18CECC0B1A91ACD6005598E4 /* ViewModel */ = { + isa = PBXGroup; + children = ( + 18D201401A96143300D5F095 /* ThirdViewControllerViewModel.h */, + 18D201411A96143300D5F095 /* ThirdViewControllerViewModel.m */, + 18CECC081A91ACB6005598E4 /* FirstViewControllerViewModel.h */, + 18CECC091A91ACB7005598E4 /* FirstViewControllerViewModel.m */, + 184F48B01A93323F00C5C22F /* SecondViewControllerViewModel.h */, + 184F48AE1A93321700C5C22F /* SecondViewControllerViewModel.m */, + ); + name = ViewModel; + sourceTree = ""; + }; + 18D200F71A95A1FB00D5F095 /* Resource */ = { + isa = PBXGroup; + children = ( + 18D200F81A95A21A00D5F095 /* images */, + ); + name = " Resource"; + sourceTree = ""; + }; + 18D200F81A95A21A00D5F095 /* images */ = { + isa = PBXGroup; + children = ( + 18D201311A9608E600D5F095 /* startImg */, + 18D2010C1A95A6D500D5F095 /* tabBar */, + 18D2010B1A95A6C800D5F095 /* appIcon */, + ); + name = images; + sourceTree = ""; + }; + 18D2010B1A95A6C800D5F095 /* appIcon */ = { + isa = PBXGroup; + children = ( + 18D2010D1A95A6F400D5F095 /* icon_29.png */, + 18D2010E1A95A6F400D5F095 /* icon_40.png */, + 18D2010F1A95A6F400D5F095 /* icon_58.png */, + 18D201101A95A6F400D5F095 /* icon_76.png */, + 18D201111A95A6F400D5F095 /* icon_80.png */, + 18D201121A95A6F400D5F095 /* icon_87.png */, + 18D201131A95A6F400D5F095 /* icon_120.png */, + 18D201141A95A6F400D5F095 /* icon_152.png */, + 18D201151A95A6F400D5F095 /* icon_180.png */, + ); + name = appIcon; + sourceTree = ""; + }; + 18D2010C1A95A6D500D5F095 /* tabBar */ = { + isa = PBXGroup; + children = ( + 185EEB4C1A98E0BA00BFDB79 /* tabbar_setting.png */, + 185EEB4D1A98E0BA00BFDB79 /* tabbar_setting@2x.png */, + 185EEB4E1A98E0BA00BFDB79 /* tabbar_setting@3x.png */, + 18D201251A95A9D600D5F095 /* tabbar_video.png */, + 18D201261A95A9D600D5F095 /* tabbar_video@2x.png */, + 18D201271A95A9D600D5F095 /* tabbar_video@3x.png */, + 18D201281A95A9D600D5F095 /* tabbar_web.png */, + 18D201291A95A9D600D5F095 /* tabbar_web@2x.png */, + 18D2012A1A95A9D600D5F095 /* tabbar_web@3x.png */, + 18D2011F1A95A70900D5F095 /* tabbar_blog.png */, + 18D201201A95A70900D5F095 /* tabbar_blog@2x.png */, + 18D201211A95A70900D5F095 /* tabbar_blog@3x.png */, + ); + name = tabBar; + sourceTree = ""; + }; + 18D201311A9608E600D5F095 /* startImg */ = { + isa = PBXGroup; + children = ( + 18D201381A960B6100D5F095 /* app_img_768x1024.png */, + 18D201391A960B6100D5F095 /* app_img_1024x768.png */, + 18D2013A1A960B6100D5F095 /* app_img_1536x2048.png */, + 18D2013B1A960B6100D5F095 /* app_img_2048x1536.png */, + 18D201321A96090A00D5F095 /* app_img_640.png */, + 18D201331A96090A00D5F095 /* app_img_1136.png */, + 18D201341A96090A00D5F095 /* app_img_iOS8.png */, + ); + name = startImg; + sourceTree = ""; + }; + 18DF6D3A1A80D3A4005751E8 /* libs */ = { + isa = PBXGroup; + children = ( + 18AB47991A9C59CB00E4C030 /* UIImage+Resize.h */, + 18AB479A1A9C59CB00E4C030 /* UIImage+Resize.m */, + 18DF6D3B1A80D3BC005751E8 /* Reachability.h */, + 18DF6D3C1A80D3BC005751E8 /* Reachability.m */, + ); + name = libs; + sourceTree = ""; + }; + 18E6A0B21ACCF7C600B28D32 /* VersionBean */ = { + isa = PBXGroup; + children = ( + 18E6A0B31ACCF7FD00B28D32 /* VersionBean.h */, + 18E6A0B41ACCF7FD00B28D32 /* VersionBean.m */, + ); + name = VersionBean; + sourceTree = ""; + }; + 910A021243EF9C731476BCA9 /* Frameworks */ = { + isa = PBXGroup; + children = ( + 18E016A91ACAA898002A6E59 /* CoreData.framework */, + 18DF6D3E1A80D40D005751E8 /* SystemConfiguration.framework */, + E83ED1B8EA89BC57ACF91BA5 /* libPods.a */, + ); + name = Frameworks; + sourceTree = ""; + }; + A75E66DCB4F6E8ABD81B2B38 /* Pods */ = { + isa = PBXGroup; + children = ( + 05EB633B553B549AA5102110 /* Pods.debug.xcconfig */, + 2E2CC00A58FD0A745C574BAD /* Pods.release.xcconfig */, + ); + name = Pods; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 18B23B1E1A7A14D000E80854 /* iOSStudy */ = { + isa = PBXNativeTarget; + buildConfigurationList = 18B23B451A7A14D100E80854 /* Build configuration list for PBXNativeTarget "iOSStudy" */; + buildPhases = ( + 74FAA3BA176AE89704921297 /* Check Pods Manifest.lock */, + 18B23B1B1A7A14D000E80854 /* Sources */, + 18B23B1C1A7A14D000E80854 /* Frameworks */, + 18B23B1D1A7A14D000E80854 /* Resources */, + 2ACA4578B0EBE30E889C4283 /* Copy Pods Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = iOSStudy; + productName = iOSStudy; + productReference = 18B23B1F1A7A14D000E80854 /* iOSStudy.app */; + productType = "com.apple.product-type.application"; + }; + 18B23B3A1A7A14D100E80854 /* iOSStudyTests */ = { + isa = PBXNativeTarget; + buildConfigurationList = 18B23B481A7A14D100E80854 /* Build configuration list for PBXNativeTarget "iOSStudyTests" */; + buildPhases = ( + 18B23B371A7A14D100E80854 /* Sources */, + 18B23B381A7A14D100E80854 /* Frameworks */, + 18B23B391A7A14D100E80854 /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + 18B23B3D1A7A14D100E80854 /* PBXTargetDependency */, + ); + name = iOSStudyTests; + productName = iOSStudyTests; + productReference = 18B23B3B1A7A14D100E80854 /* iOSStudyTests.xctest */; + productType = "com.apple.product-type.bundle.unit-test"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 18B23B171A7A14D000E80854 /* Project object */ = { + isa = PBXProject; + attributes = { + LastUpgradeCheck = 0610; + ORGANIZATIONNAME = chenguandong; + TargetAttributes = { + 18B23B1E1A7A14D000E80854 = { + CreatedOnToolsVersion = 6.1.1; + }; + 18B23B3A1A7A14D100E80854 = { + CreatedOnToolsVersion = 6.1.1; + TestTargetID = 18B23B1E1A7A14D000E80854; + }; + }; + }; + buildConfigurationList = 18B23B1A1A7A14D000E80854 /* Build configuration list for PBXProject "iOSStudy" */; + compatibilityVersion = "Xcode 3.2"; + developmentRegion = English; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 18B23B161A7A14D000E80854; + productRefGroup = 18B23B201A7A14D000E80854 /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 18B23B1E1A7A14D000E80854 /* iOSStudy */, + 18B23B3A1A7A14D100E80854 /* iOSStudyTests */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 18B23B1D1A7A14D000E80854 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18D201351A96090A00D5F095 /* app_img_640.png in Resources */, + 18B23B311A7A14D100E80854 /* Main.storyboard in Resources */, + 18D201371A96090A00D5F095 /* app_img_iOS8.png in Resources */, + 185EEB501A98E0BA00BFDB79 /* tabbar_setting@2x.png in Resources */, + 18D2012D1A95A9D600D5F095 /* tabbar_video@3x.png in Resources */, + 18D201181A95A6F400D5F095 /* icon_58.png in Resources */, + 185EEB511A98E0BA00BFDB79 /* tabbar_setting@3x.png in Resources */, + 18D2011D1A95A6F400D5F095 /* icon_152.png in Resources */, + 18D201191A95A6F400D5F095 /* icon_76.png in Resources */, + 18D2011E1A95A6F400D5F095 /* icon_180.png in Resources */, + 18D2012B1A95A9D600D5F095 /* tabbar_video.png in Resources */, + 18D2013F1A960B6100D5F095 /* app_img_2048x1536.png in Resources */, + 185EEB4F1A98E0BA00BFDB79 /* tabbar_setting.png in Resources */, + 18D2013D1A960B6100D5F095 /* app_img_1024x768.png in Resources */, + 18D201161A95A6F400D5F095 /* icon_29.png in Resources */, + 18D2013C1A960B6100D5F095 /* app_img_768x1024.png in Resources */, + 18D2011B1A95A6F400D5F095 /* icon_87.png in Resources */, + 18D2012E1A95A9D600D5F095 /* tabbar_web.png in Resources */, + 18D201301A95A9D600D5F095 /* tabbar_web@3x.png in Resources */, + 18D2012C1A95A9D600D5F095 /* tabbar_video@2x.png in Resources */, + 18D2012F1A95A9D600D5F095 /* tabbar_web@2x.png in Resources */, + 18D201171A95A6F400D5F095 /* icon_40.png in Resources */, + 18D201361A96090A00D5F095 /* app_img_1136.png in Resources */, + 18D2011C1A95A6F400D5F095 /* icon_120.png in Resources */, + 18D201221A95A70900D5F095 /* tabbar_blog.png in Resources */, + 18B23B361A7A14D100E80854 /* LaunchScreen.xib in Resources */, + 18D2011A1A95A6F400D5F095 /* icon_80.png in Resources */, + 18D2013E1A960B6100D5F095 /* app_img_1536x2048.png in Resources */, + 18D201241A95A70900D5F095 /* tabbar_blog@3x.png in Resources */, + 18D201231A95A70900D5F095 /* tabbar_blog@2x.png in Resources */, + 18B23B331A7A14D100E80854 /* Images.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18B23B391A7A14D100E80854 /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXShellScriptBuildPhase section */ + 2ACA4578B0EBE30E889C4283 /* Copy Pods Resources */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Copy Pods Resources"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods/Pods-resources.sh\"\n"; + showEnvVarsInLog = 0; + }; + 74FAA3BA176AE89704921297 /* Check Pods Manifest.lock */ = { + isa = PBXShellScriptBuildPhase; + buildActionMask = 2147483647; + files = ( + ); + inputPaths = ( + ); + name = "Check Pods Manifest.lock"; + outputPaths = ( + ); + runOnlyForDeploymentPostprocessing = 0; + shellPath = /bin/sh; + shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n"; + showEnvVarsInLog = 0; + }; +/* End PBXShellScriptBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 18B23B1B1A7A14D000E80854 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18AB47981A99A51200E4C030 /* BaseTableViewCell.m in Sources */, + 18E016E51ACAAB35002A6E59 /* iOSStudy.xcdatamodeld in Sources */, + 18AB479F1A9C5E3300E4C030 /* VideoCell.m in Sources */, + 18B23B2E1A7A14D100E80854 /* SecondViewController.m in Sources */, + 18B23B4D1A7A234800E80854 /* BaseViewController.m in Sources */, + 18A998931A7C77D0002E7219 /* NetWorkTools.m in Sources */, + 18AB47A81A9DA40500E4C030 /* DBUtils.m in Sources */, + 18AB47A51A9C82FA00E4C030 /* AddBlogTableViewController.m in Sources */, + 18D908A71A8A205600B42A42 /* ThirdTableViewController.m in Sources */, + 18C8450C1ACD41C40053884F /* BlogJsonBean.m in Sources */, + 18AB479B1A9C59CB00E4C030 /* UIImage+Resize.m in Sources */, + 18D201421A96143300D5F095 /* ThirdViewControllerViewModel.m in Sources */, + 18AB47951A99969600E4C030 /* VideoBean.m in Sources */, + 18CECC0A1A91ACB7005598E4 /* FirstViewControllerViewModel.m in Sources */, + 189EF8361A839FC600F19327 /* JsonTools.m in Sources */, + 18D4ECA61AD17F56009FE9F0 /* EntityConstants.m in Sources */, + 18C845091ACCFC690053884F /* HttpVersionTools.m in Sources */, + 18E6A0B51ACCF7FD00B28D32 /* VersionBean.m in Sources */, + 18DF6D3D1A80D3BC005751E8 /* Reachability.m in Sources */, + 18B23B281A7A14D100E80854 /* AppDelegate.m in Sources */, + 184F48AF1A93321700C5C22F /* SecondViewControllerViewModel.m in Sources */, + 18B23B2B1A7A14D100E80854 /* FirstViewController.m in Sources */, + 189EF83A1A83C3AF00F19327 /* BlogDetailViewController.m in Sources */, + 185EEB4B1A98DC9900BFDB79 /* SettingTableViewController.m in Sources */, + 18C845121ACE4A580053884F /* WelcomeViewController.m in Sources */, + 18B23B251A7A14D100E80854 /* main.m in Sources */, + 18AB47AB1AA415A400E4C030 /* FavouriteBean.m in Sources */, + 184F48B41A93340F00C5C22F /* WebBean.m in Sources */, + 18C845151ACE56150053884F /* MainTabBarViewController.m in Sources */, + 18C8450F1ACE3E580053884F /* CoreDataUtils.m in Sources */, + 189EF8331A8399B100F19327 /* BlogBean.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; + 18B23B371A7A14D100E80854 /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 18B23B421A7A14D100E80854 /* iOSStudyTests.m in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin PBXTargetDependency section */ + 18B23B3D1A7A14D100E80854 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + target = 18B23B1E1A7A14D000E80854 /* iOSStudy */; + targetProxy = 18B23B3C1A7A14D100E80854 /* PBXContainerItemProxy */; + }; +/* End PBXTargetDependency section */ + +/* Begin PBXVariantGroup section */ + 18B23B2F1A7A14D100E80854 /* Main.storyboard */ = { + isa = PBXVariantGroup; + children = ( + 18B23B301A7A14D100E80854 /* Base */, + ); + name = Main.storyboard; + sourceTree = ""; + }; + 18B23B341A7A14D100E80854 /* LaunchScreen.xib */ = { + isa = PBXVariantGroup; + children = ( + 18B23B351A7A14D100E80854 /* Base */, + 18CECC101A921272005598E4 /* zh-Hans */, + ); + name = LaunchScreen.xib; + sourceTree = ""; + }; +/* End PBXVariantGroup section */ + +/* Begin XCBuildConfiguration section */ + 18B23B431A7A14D100E80854 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_DYNAMIC_NO_PIC = NO; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_SYMBOLS_PRIVATE_EXTERN = NO; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + }; + name = Debug; + }; + 18B23B441A7A14D100E80854 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; + CLANG_CXX_LIBRARY = "libc++"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; + COPY_PHASE_STRIP = YES; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + GCC_C_LANGUAGE_STANDARD = gnu99; + GCC_PRECOMPILE_PREFIX_HEADER = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 8.1; + MTL_ENABLE_DEBUG_INFO = NO; + SDKROOT = iphoneos; + TARGETED_DEVICE_FAMILY = "1,2"; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; + 18B23B461A7A14D100E80854 /* Debug */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 05EB633B553B549AA5102110 /* Pods.debug.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = iOSStudy/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Debug; + }; + 18B23B471A7A14D100E80854 /* Release */ = { + isa = XCBuildConfiguration; + baseConfigurationReference = 2E2CC00A58FD0A745C574BAD /* Pods.release.xcconfig */; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + INFOPLIST_FILE = iOSStudy/Info.plist; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + }; + name = Release; + }; + 18B23B491A7A14D100E80854 /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + INFOPLIST_FILE = iOSStudyTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSStudy.app/iOSStudy"; + }; + name = Debug; + }; + 18B23B4A1A7A14D100E80854 /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + BUNDLE_LOADER = "$(TEST_HOST)"; + FRAMEWORK_SEARCH_PATHS = ( + "$(SDKROOT)/Developer/Library/Frameworks", + "$(inherited)", + ); + INFOPLIST_FILE = iOSStudyTests/Info.plist; + LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; + PRODUCT_NAME = "$(TARGET_NAME)"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/iOSStudy.app/iOSStudy"; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 18B23B1A1A7A14D000E80854 /* Build configuration list for PBXProject "iOSStudy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18B23B431A7A14D100E80854 /* Debug */, + 18B23B441A7A14D100E80854 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 18B23B451A7A14D100E80854 /* Build configuration list for PBXNativeTarget "iOSStudy" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18B23B461A7A14D100E80854 /* Debug */, + 18B23B471A7A14D100E80854 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 18B23B481A7A14D100E80854 /* Build configuration list for PBXNativeTarget "iOSStudyTests" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 18B23B491A7A14D100E80854 /* Debug */, + 18B23B4A1A7A14D100E80854 /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCVersionGroup section */ + 18E016E31ACAAB35002A6E59 /* iOSStudy.xcdatamodeld */ = { + isa = XCVersionGroup; + children = ( + 18E016E41ACAAB35002A6E59 /* iOSStudy.xcdatamodel */, + ); + currentVersion = 18E016E41ACAAB35002A6E59 /* iOSStudy.xcdatamodel */; + path = iOSStudy.xcdatamodeld; + sourceTree = ""; + versionGroupType = wrapper.xcdatamodel; + }; +/* End XCVersionGroup section */ + }; + rootObject = 18B23B171A7A14D000E80854 /* Project object */; +} diff --git a/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b180e9c --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/iOSStudy/iOSStudy/iOSStudy.xcworkspace/contents.xcworkspacedata b/iOSStudy/iOSStudy/iOSStudy.xcworkspace/contents.xcworkspacedata new file mode 100644 index 0000000..b388a74 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,10 @@ + + + + + + + diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_01.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_01.png new file mode 100644 index 0000000..5f0edba Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_01.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_02.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_02.png new file mode 100644 index 0000000..0302620 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_02.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_03.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_03.png new file mode 100644 index 0000000..bab3e1d Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_03.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_04.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_04.png new file mode 100644 index 0000000..bde0b97 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_04.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_05.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_05.png new file mode 100644 index 0000000..ace856e Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_05.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_06.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_06.png new file mode 100644 index 0000000..465bb8c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_06.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_07.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_07.png new file mode 100644 index 0000000..dd6e3e7 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_07.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_08.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_08.png new file mode 100644 index 0000000..2d59d8e Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_08.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_09.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_09.png new file mode 100644 index 0000000..eec78a5 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_09.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_10.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_10.png new file mode 100644 index 0000000..1300c3e Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_10.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_11.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_11.png new file mode 100644 index 0000000..2f7894a Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_11.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_12.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_12.png new file mode 100644 index 0000000..7c696cc Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_12.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_13.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_13.png new file mode 100644 index 0000000..f722cfd Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_13.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_14.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_14.png new file mode 100644 index 0000000..9a818f3 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_14.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_15.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_15.png new file mode 100644 index 0000000..2674f6b Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_15.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_16.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_16.png new file mode 100644 index 0000000..2bc9102 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_16.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_17.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_17.png new file mode 100644 index 0000000..e848ab0 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_17.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_18.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_18.png new file mode 100644 index 0000000..e7a3beb Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_18.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_19.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_19.png new file mode 100644 index 0000000..da5547a Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_19.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_20.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_20.png new file mode 100644 index 0000000..aab8016 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/anim/anim_20.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png new file mode 100644 index 0000000..aa81067 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_120.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png new file mode 100644 index 0000000..cc11df5 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_152.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png new file mode 100644 index 0000000..90fbb4c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_180.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png new file mode 100644 index 0000000..9b8269a Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_29.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png new file mode 100644 index 0000000..8992f31 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_40.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png new file mode 100644 index 0000000..da710e0 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_58.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png new file mode 100644 index 0000000..43305f9 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_76.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png new file mode 100644 index 0000000..7e1939c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_80.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png new file mode 100644 index 0000000..72333c2 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/appicon/icon_87.png differ diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1024x768.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1024x768.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1024x768.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1024x768.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1136.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1136.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1136.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1136.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1536x2048.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1536x2048.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1536x2048.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_1536x2048.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_2048x1536.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_2048x1536.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_2048x1536.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_2048x1536.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_640.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_640.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_640.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_640.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_768x1024.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_768x1024.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_768x1024.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_768x1024.png diff --git a/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_iOS8.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_iOS8.png similarity index 100% rename from iOSStudy/iOSStudy/ Resource/images/start_img/app_img_iOS8.png rename to iOSStudy/iOSStudy/iOSStudy/ Resource/images/start_img/app_img_iOS8.png diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog.png new file mode 100644 index 0000000..90821f0 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@2x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@2x.png new file mode 100644 index 0000000..d364462 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@2x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@3x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@3x.png new file mode 100644 index 0000000..fe63597 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_blog@3x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting.png new file mode 100644 index 0000000..8b47168 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@2x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@2x.png new file mode 100644 index 0000000..a888e6d Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@2x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@3x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@3x.png new file mode 100644 index 0000000..cf7cfd3 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_setting@3x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video.png new file mode 100644 index 0000000..3b49f0a Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@2x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@2x.png new file mode 100644 index 0000000..c9b047d Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@2x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@3x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@3x.png new file mode 100644 index 0000000..110c32d Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_video@3x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web.png new file mode 100644 index 0000000..f1ad248 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@2x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@2x.png new file mode 100644 index 0000000..464aebd Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@2x.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@3x.png b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@3x.png new file mode 100644 index 0000000..ccfebff Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/ Resource/images/tabbar/tabbar_web@3x.png differ diff --git a/iOSStudy/iOSStudy/AddBlogTableViewController.h b/iOSStudy/iOSStudy/iOSStudy/AddBlogTableViewController.h similarity index 100% rename from iOSStudy/iOSStudy/AddBlogTableViewController.h rename to iOSStudy/iOSStudy/iOSStudy/AddBlogTableViewController.h diff --git a/iOSStudy/iOSStudy/AddBlogTableViewController.m b/iOSStudy/iOSStudy/iOSStudy/AddBlogTableViewController.m similarity index 100% rename from iOSStudy/iOSStudy/AddBlogTableViewController.m rename to iOSStudy/iOSStudy/iOSStudy/AddBlogTableViewController.m diff --git a/iOSStudy/iOSStudy/iOSStudy/AppDelegate.h b/iOSStudy/iOSStudy/iOSStudy/AppDelegate.h new file mode 100644 index 0000000..5c21979 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/AppDelegate.h @@ -0,0 +1,29 @@ +// +// AppDelegate.h +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import +@interface AppDelegate : UIResponder + +@property (strong, nonatomic) UIWindow *window; +@property(nonatomic,assign)__block BOOL isNetworking; +@property(nonatomic,copy)NSString *str; + +#pragma mark --version list +@property(nonatomic,strong)NSArray *versionLists; + + +#pragma mark --coreData +@property (readonly, strong, nonatomic) NSManagedObjectContext *managedObjectContext; +@property (readonly, strong, nonatomic) NSManagedObjectModel *managedObjectModel; +@property (readonly, strong, nonatomic) NSPersistentStoreCoordinator *persistentStoreCoordinator; + +- (void)saveContext; +- (NSURL *)applicationDocumentsDirectory; +@end + diff --git a/iOSStudy/iOSStudy/iOSStudy/AppDelegate.m b/iOSStudy/iOSStudy/iOSStudy/AppDelegate.m new file mode 100644 index 0000000..121b7e5 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/AppDelegate.m @@ -0,0 +1,174 @@ +// +// AppDelegate.m +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "AppDelegate.h" +#import "NetWorkTools.h" +@interface AppDelegate () + +@end + +@implementation AppDelegate + + +- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { + // Override point for customization after application launch. + // Do any additional setup after loading the view. + [NetWorkTools checkNetworking]; + + [self setGlobalStyle]; + + return YES; +} + +/** + * 设置全局样式 + */ +-(void)setGlobalStyle{ + + //设置tabBar的默认颜色 + [UITabBar appearance].tintColor = [UIColor redColor]; + + //设置tabBar背景颜色 + [UITabBar appearance].barTintColor = [UIColor whiteColor]; + + + //设置导航条的默认颜色 + [[UINavigationBar appearance] setBarTintColor:[UIColor whiteColor]]; + + //设置导航栏字体样式 + + NSShadow *shadow = [[NSShadow alloc] init]; + + shadow.shadowColor = [UIColor colorWithRed:0.0 green:0.0 blue:0.0 alpha:0.8]; + shadow.shadowOffset = CGSizeMake(0, 0); + + [[UINavigationBar appearance] setTitleTextAttributes: [NSDictionary dictionaryWithObjectsAndKeys: [UIColor redColor], NSForegroundColorAttributeName, shadow, NSShadowAttributeName, [UIFont fontWithName:@"HelveticaNeue-CondensedBlack" size:18.0], NSFontAttributeName, nil]]; + + + //导航返回按钮颜色 + [[UINavigationBar appearance] setTintColor:[UIColor redColor]]; +} + + +-(void)dealloc{ + // 删除通知对象 + [[NSNotificationCenter defaultCenter] removeObserver:self]; + +} + + +- (void)applicationWillResignActive:(UIApplication *)application { + // 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. + // 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. + +} + +- (void)applicationDidEnterBackground:(UIApplication *)application { + // 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. + // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. +} + +- (void)applicationWillEnterForeground:(UIApplication *)application { + // 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. + + +} + +- (void)applicationDidBecomeActive:(UIApplication *)application { + // 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. + + +} + +- (void)applicationWillTerminate:(UIApplication *)application { + // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. +} + + + +#pragma mark - Core Data stack + +@synthesize managedObjectContext = _managedObjectContext; +@synthesize managedObjectModel = _managedObjectModel; +@synthesize persistentStoreCoordinator = _persistentStoreCoordinator; + +- (NSURL *)applicationDocumentsDirectory { + // The directory the application uses to store the Core Data store file. This code uses a directory named "---.test" in the application's documents directory. + return [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject]; +} + +- (NSManagedObjectModel *)managedObjectModel { + // The managed object model for the application. It is a fatal error for the application not to be able to find and load its model. + if (_managedObjectModel != nil) { + return _managedObjectModel; + } + NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"iOSStudy" withExtension:@"momd"]; + _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL]; + return _managedObjectModel; +} + +- (NSPersistentStoreCoordinator *)persistentStoreCoordinator { + // The persistent store coordinator for the application. This implementation creates and return a coordinator, having added the store for the application to it. + if (_persistentStoreCoordinator != nil) { + return _persistentStoreCoordinator; + } + + // Create the coordinator and store + + _persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]]; + NSURL *storeURL = [[self applicationDocumentsDirectory] URLByAppendingPathComponent:@"iOSStudy.sqlite"]; + NSError *error = nil; + NSString *failureReason = @"There was an error creating or loading the application's saved data."; + if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:nil error:&error]) { + // Report any error we got. + NSMutableDictionary *dict = [NSMutableDictionary dictionary]; + dict[NSLocalizedDescriptionKey] = @"Failed to initialize the application's saved data"; + dict[NSLocalizedFailureReasonErrorKey] = failureReason; + dict[NSUnderlyingErrorKey] = error; + error = [NSError errorWithDomain:@"YOUR_ERROR_DOMAIN" code:9999 userInfo:dict]; + // Replace this with code to handle the error appropriately. + // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + + return _persistentStoreCoordinator; +} + + +- (NSManagedObjectContext *)managedObjectContext { + // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) + if (_managedObjectContext != nil) { + return _managedObjectContext; + } + + NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator]; + if (!coordinator) { + return nil; + } + _managedObjectContext = [[NSManagedObjectContext alloc] init]; + [_managedObjectContext setPersistentStoreCoordinator:coordinator]; + return _managedObjectContext; +} + +#pragma mark - Core Data Saving support + +- (void)saveContext { + NSManagedObjectContext *managedObjectContext = self.managedObjectContext; + if (managedObjectContext != nil) { + NSError *error = nil; + if ([managedObjectContext hasChanges] && ![managedObjectContext save:&error]) { + // Replace this implementation with code to handle the error appropriately. + // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. + NSLog(@"Unresolved error %@, %@", error, [error userInfo]); + abort(); + } + } +} + +@end diff --git a/iOSStudy/iOSStudy/Base.lproj/LaunchScreen.xib b/iOSStudy/iOSStudy/iOSStudy/Base.lproj/LaunchScreen.xib similarity index 100% rename from iOSStudy/iOSStudy/Base.lproj/LaunchScreen.xib rename to iOSStudy/iOSStudy/iOSStudy/Base.lproj/LaunchScreen.xib diff --git a/iOSStudy/iOSStudy/iOSStudy/Base.lproj/Main.storyboard b/iOSStudy/iOSStudy/iOSStudy/Base.lproj/Main.storyboard new file mode 100644 index 0000000..0276cb7 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Base.lproj/Main.storyboard @@ -0,0 +1,673 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/iOSStudy/iOSStudy/iOSStudy/Constants .h b/iOSStudy/iOSStudy/iOSStudy/Constants .h new file mode 100644 index 0000000..3bd3c31 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Constants .h @@ -0,0 +1,47 @@ +// +// Constants .h +// iOSStudy +// +// Created by chenguandong on 15/2/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + + +#import "AppDelegate.h" +#ifndef iOSStudy_Constants__h +#define iOSStudy_Constants__h + +#define Address_blogs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/blogs.json" +#define Adress_webs @"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/webs.json" +#define Adress_videos @"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/videos.json" + +#define Adress_versions @"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/versions.json" + +#define SharedApp ((AppDelegate *)[[UIApplication sharedApplication] delegate]) + +#define PATH_OF_DOCUMENT [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0] +/** + * 收藏的数据库表明 + */ +#define CD_FAVOURITE_BEAN @"FavouriteBean" + +/** + * http版本号数据库表明 + */ +#define CD_VersionsEntity @"VersionsEntity" + + +static NSString *const textNameFavourite = @"收藏"; +static NSString *const textNameUnFavourite = @"取消收藏"; + +static NSString *const TYPE_BLOG_SIMPLE_TYPE = @"1"; +static NSString *const TYPE_WEB_SIMPLE_TYPE = @"2"; +static NSString *const TYPE_VIDEO_SIMPLE_TYPE = @"3"; + +static NSString *const TYPE_BLOG_FAVOURITE_TYPE = @"11"; +static NSString *const TYPE_WEB_FAVOURITE_TYPE = @"22"; +static NSString *const TYPE_VIDEO_FAVOURITE_TYPE = @"33"; + + + +#endif diff --git a/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.h b/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.h new file mode 100644 index 0000000..7178d83 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.h @@ -0,0 +1,13 @@ +// +// FavouriteTableViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/6. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "FavouriteViewControllerViewModel.h" +@interface FavouriteTableViewController : UITableViewController +@property(nonatomic,strong)FavouriteViewControllerViewModel * viewModel; +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.m b/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.m new file mode 100644 index 0000000..4ced273 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/FavouriteTableViewController.m @@ -0,0 +1,169 @@ +// +// FavouriteTableViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/6. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "FavouriteTableViewController.h" +#import "Constants .h" +#import "EntityConstants.h" +#import "STBaseTableViewCell.h" +#import +#import +#import "NotificationCenterConstants.h" +typedef NS_ENUM(NSInteger, segmentedSelect) { + BlogSelect = 0, + WebSelect =1, + VideoSelect = 2 +}; + +@implementation FavouriteTableViewController +{ + NSString *favouriteType; +} + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + + [self reloadData]; +} +- (IBAction)changeFavouriteType:(id)sender { + + + + UISegmentedControl *seColl = (UISegmentedControl*)sender; + switch (seColl.selectedSegmentIndex) { + case BlogSelect: + + favouriteType =TYPE_BLOG_FAVOURITE_TYPE; + + break; + case WebSelect: + + favouriteType =TYPE_WEB_FAVOURITE_TYPE; + break; + case VideoSelect: + favouriteType =TYPE_VIDEO_FAVOURITE_TYPE; + + break; + + default: + break; + } + + + NSLog(@"%@",favouriteType); + + [_viewModel getFavouriteData:favouriteType]; + + [self.tableView reloadData]; + +} + +-(void)viewDidLoad{ + [super viewDidLoad]; + + favouriteType = TYPE_BLOG_FAVOURITE_TYPE; + + _viewModel = [[FavouriteViewControllerViewModel alloc]init]; + self.tableView.rowHeight = 60; + + [self.tableView registerNib:[UINib nibWithNibName:@"STBaseTableViewCell" bundle:nil] forCellReuseIdentifier:@"FCell"]; +} + + +-(void)reloadData{ + [_viewModel getFavouriteData:favouriteType]; + [self.tableView reloadData]; +} + +-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ + + return [_viewModel getNumberOfRowsInSection]; +} + + +-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ + + static NSString *CellIdentifier = @"FCell"; + STBaseTableViewCell *cell = (STBaseTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier + forIndexPath:indexPath]; + NSManagedObject *f_objt = _viewModel.array[indexPath.row]; + + cell.title.text = [f_objt valueForKey:FavouriteBean_title]; + + cell.subtitle.text = [f_objt valueForKey:FavouriteBean_subtitle]; + + + [cell.imageIcon setImageWithURL:[NSURL URLWithString:[f_objt valueForKey:FavouriteBean_image_name]] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; + + + + cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; + + return cell; + +} + + +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath +{ + // Return NO if you do not want the specified item to be editable. + return YES; +} + +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath +{ + + + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete object from database + + NSManagedObject *deleteObjt =[self.viewModel.array objectAtIndex:indexPath.row]; + + + [SharedApp.managedObjectContext deleteObject:deleteObjt]; + + NSError *error = nil; + if (![SharedApp.managedObjectContext save:&error]) { + NSLog(@"Can't Delete! %@ %@", error, [error localizedDescription]); + return; + } + + + + + + + + // Remove device from table view +// [self.viewModel.array removeObjectAtIndex:indexPath.row]; +// +// +// [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade]; + + [self reloadData]; + + if ([favouriteType isEqualToString:TYPE_BLOG_FAVOURITE_TYPE]) { + [[NSNotificationCenter defaultCenter]postNotificationName:notifacationBlogReload object:nil userInfo:nil]; + }else if ([favouriteType isEqualToString:TYPE_WEB_FAVOURITE_TYPE]){ + + [[NSNotificationCenter defaultCenter]postNotificationName:notifacationWebReload object:nil userInfo:nil]; + + }else{ + + [[NSNotificationCenter defaultCenter]postNotificationName:notifacationVideoReload object:nil userInfo:nil]; + } + + + } +} + +-(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ + SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[[_viewModel getFavouriteObjtBean:indexPath] valueForKey:FavouriteBean_url]]; + [self presentViewController:webViewController animated:NO completion:NULL]; +} + +@end diff --git a/iOSStudy/iOSStudy/FirstViewController.h b/iOSStudy/iOSStudy/iOSStudy/FirstViewController.h similarity index 88% rename from iOSStudy/iOSStudy/FirstViewController.h rename to iOSStudy/iOSStudy/iOSStudy/FirstViewController.h index 31f335a..b8c7853 100644 --- a/iOSStudy/iOSStudy/FirstViewController.h +++ b/iOSStudy/iOSStudy/iOSStudy/FirstViewController.h @@ -13,6 +13,7 @@ @interface FirstViewController : BaseViewController @property (weak, nonatomic) IBOutlet UITableView *tableView; @property(nonatomic,strong)FirstViewControllerViewModel *viewModel; - +@property(nonatomic,copy)NSString *favouriteType ; +-(void)initViewData; @end diff --git a/iOSStudy/iOSStudy/FirstViewController.m b/iOSStudy/iOSStudy/iOSStudy/FirstViewController.m similarity index 72% rename from iOSStudy/iOSStudy/FirstViewController.m rename to iOSStudy/iOSStudy/iOSStudy/FirstViewController.m index 619faa1..4110c20 100644 --- a/iOSStudy/iOSStudy/FirstViewController.m +++ b/iOSStudy/iOSStudy/iOSStudy/FirstViewController.m @@ -16,7 +16,7 @@ #import "BlogDetailViewController.h" #import #import - +#import "EntityConstants.h" @interface FirstViewController () @end @@ -26,41 +26,40 @@ @implementation FirstViewController - (void)viewDidLoad { [super viewDidLoad]; + + _favouriteType = TYPE_BLOG_FAVOURITE_TYPE; _tableView.delegate = self; _tableView.dataSource = self; + [self initViewData]; +} +-(void)initViewData{ _viewModel = [[FirstViewControllerViewModel alloc]init]; - - [self.tableView addHeaderWithCallback:^{ + + [_viewModel getDate:^{ - - [_tableView reloadData]; - + [_tableView reloadData]; + [self stopTableRefreshing]; - + } modelDataReload:^{ + [_tableView reloadData]; } modelDataErrors:^{ - [self stopTableRefreshing]; - } modelDataIsNetworking:^(BOOL isNetWorking) { - [self stopTableRefreshing]; - - }]; + } httpAdress:Address_blogs dataType:TYPE_BLOG_SIMPLE_TYPE jsonClass:[BlogBean class]]; + + + }]; - [self.tableView headerBeginRefreshing]; - - } - - /** * 停止UITableView刷新 */ @@ -93,40 +92,31 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N } - cell.rightUtilityButtons =[self rightButtons]; + cell.delegate = self; - cell.textLabel.text = [_viewModel getBlogBean:indexPath].title; - cell.detailTextLabel.text = [_viewModel getBlogBean:indexPath].subTitle; + cell.textLabel.text = [[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_title]; + cell.detailTextLabel.text = [[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_subtitle]; - [cell.imageView setImageWithURL:[NSURL URLWithString:[_viewModel getBlogBean:indexPath].image] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; + cell.rightUtilityButtons =[_viewModel setRightSWCellButtons:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_url] withType:TYPE_BLOG_FAVOURITE_TYPE]; + + + [cell.imageView setImageWithURL:[NSURL URLWithString:[[_viewModel getBlogBean:indexPath] valueForKey:FavouriteBean_image_name]] placeholderImage:[UIImage imageNamed:@"SVWebViewControllerActivitySafari-iPad.png"]]; return cell; } -#pragma mark --设置又滑菜单 -- (NSArray *)rightButtons -{ - NSMutableArray *rightUtilityButtons = [NSMutableArray new]; - [rightUtilityButtons sw_addUtilityButtonWithColor: - [UIColor colorWithRed:0.78f green:0.78f blue:0.8f alpha:1.0] - title:@"收藏"]; - [rightUtilityButtons sw_addUtilityButtonWithColor: - [UIColor colorWithRed:1.0f green:0.231f blue:0.188 alpha:1.0f] - title:@"不喜欢"]; - - return rightUtilityButtons; -} + -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{ - SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[_viewModel getBlogBean:indexPath].url]; + SVModalWebViewController *webViewController = [[SVModalWebViewController alloc] initWithAddress:[[_viewModel getBlogBean:indexPath]valueForKey:FavouriteBean_url]]; [self presentViewController:webViewController animated:NO completion:NULL]; } @@ -165,25 +155,20 @@ - (void)swipeableTableViewCellDidEndScrolling:(SWTableViewCell *)cell{ } - (void)swipeableTableViewCell:(SWTableViewCell *)cell didTriggerRightUtilityButtonWithIndex:(NSInteger)index{ - switch (index) { - case 0: - NSLog(@"不喜欢"); - { - NSIndexPath *indexPath = [_tableView indexPathForCell:cell]; - [_viewModel saveFavourite:indexPath]; - - } - break; - case 1: - NSLog(@"收藏"); - - break; - - default: - break; - } + + + NSIndexPath *indexPath = [_tableView indexPathForCell:cell]; + + + [_viewModel saveFavourite:indexPath favouriteType:_favouriteType]; + + [cell hideUtilityButtonsAnimated:YES]; + [_tableView reloadData]; + + + } diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/Contents.json b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 0000000..b11e5d5 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,80 @@ +{ + "images" : [ + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "icon_58-1.png", + "scale" : "2x" + }, + { + "size" : "29x29", + "idiom" : "iphone", + "filename" : "icon_87.png", + "scale" : "3x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "icon_80-1.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "iphone", + "filename" : "icon_120.png", + "scale" : "3x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_120-1.png", + "scale" : "2x" + }, + { + "size" : "60x60", + "idiom" : "iphone", + "filename" : "icon_180.png", + "scale" : "3x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "icon_29.png", + "scale" : "1x" + }, + { + "size" : "29x29", + "idiom" : "ipad", + "filename" : "icon_58.png", + "scale" : "2x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "icon_40.png", + "scale" : "1x" + }, + { + "size" : "40x40", + "idiom" : "ipad", + "filename" : "icon_80.png", + "scale" : "2x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_76.png", + "scale" : "1x" + }, + { + "size" : "76x76", + "idiom" : "ipad", + "filename" : "icon_152.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png new file mode 100644 index 0000000..aa81067 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120-1.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png new file mode 100644 index 0000000..aa81067 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_120.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png new file mode 100644 index 0000000..cc11df5 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_152.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png new file mode 100644 index 0000000..90fbb4c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_180.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png new file mode 100644 index 0000000..9b8269a Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_29.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png new file mode 100644 index 0000000..8992f31 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_40.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png new file mode 100644 index 0000000..da710e0 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58-1.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png new file mode 100644 index 0000000..da710e0 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_58.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png new file mode 100644 index 0000000..43305f9 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_76.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png new file mode 100644 index 0000000..7e1939c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80-1.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png new file mode 100644 index 0000000..7e1939c Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_80.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png new file mode 100644 index 0000000..72333c2 Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/AppIcon.appiconset/icon_87.png differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json new file mode 100644 index 0000000..851f4f0 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/Contents.json @@ -0,0 +1,57 @@ +{ + "images" : [ + { + "orientation" : "portrait", + "idiom" : "iphone", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "app_img_640.png", + "scale" : "2x" + }, + { + "extent" : "full-screen", + "idiom" : "iphone", + "subtype" : "retina4", + "filename" : "app_img_1136.png", + "minimum-system-version" : "7.0", + "orientation" : "portrait", + "scale" : "2x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "app_img_768x1024.png", + "scale" : "1x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "app_img_1024x768.png", + "scale" : "1x" + }, + { + "orientation" : "portrait", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "app_img_1536x2048.png", + "scale" : "2x" + }, + { + "orientation" : "landscape", + "idiom" : "ipad", + "extent" : "full-screen", + "minimum-system-version" : "7.0", + "filename" : "app_img_2048x1536.png", + "scale" : "2x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1024x768.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1024x768.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1024x768.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1024x768.png diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1136.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1136.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1136.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1136.png diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1536x2048.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1536x2048.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1536x2048.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_1536x2048.png diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_2048x1536.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_2048x1536.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_2048x1536.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_2048x1536.png diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_640.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_640.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_640.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_640.png diff --git a/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_768x1024.png b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_768x1024.png similarity index 100% rename from iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_768x1024.png rename to iOSStudy/iOSStudy/iOSStudy/Images.xcassets/LaunchImage.launchimage/app_img_768x1024.png diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/Contents.json b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/Contents.json new file mode 100644 index 0000000..33a7451 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "first.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/first.pdf b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/first.pdf new file mode 100644 index 0000000..47d911d Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/first.imageset/first.pdf differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/Contents.json b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/Contents.json new file mode 100644 index 0000000..03bd9c9 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "second.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/second.pdf b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/second.pdf new file mode 100644 index 0000000..401614e Binary files /dev/null and b/iOSStudy/iOSStudy/iOSStudy/Images.xcassets/second.imageset/second.pdf differ diff --git a/iOSStudy/iOSStudy/iOSStudy/Info.plist b/iOSStudy/iOSStudy/iOSStudy/Info.plist new file mode 100644 index 0000000..d666dd9 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/Info.plist @@ -0,0 +1,57 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + com.cgd.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + APPL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + LSRequiresIPhoneOS + + UILaunchStoryboardName + LaunchScreen + UIMainStoryboardFile + Main + UIRequiredDeviceCapabilities + + armv7 + + UIStatusBarTintParameters + + UINavigationBar + + Style + UIBarStyleDefault + Translucent + + + + UISupportedInterfaceOrientations + + UIInterfaceOrientationPortrait + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + UISupportedInterfaceOrientations~ipad + + UIInterfaceOrientationPortrait + UIInterfaceOrientationPortraitUpsideDown + UIInterfaceOrientationLandscapeLeft + UIInterfaceOrientationLandscapeRight + + + diff --git a/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.h b/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.h new file mode 100644 index 0000000..3b8fb14 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.h @@ -0,0 +1,14 @@ +// +// LicenesViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "BaseViewController.h" +@interface LicenesViewController :BaseViewController +@property (weak, nonatomic) IBOutlet UIWebView *webView; +@property(nonatomic,copy)NSString *htmlName; +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.m b/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.m new file mode 100644 index 0000000..efbf4f2 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/LicenesViewController.m @@ -0,0 +1,23 @@ +// +// LicenesViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "LicenesViewController.h" + +@implementation LicenesViewController + +-(void)viewDidLoad{ + [super viewDidLoad]; + + NSURL *url = [NSURL fileURLWithPath:[[NSBundle mainBundle]pathForResource:_htmlName ofType:nil]]; + NSURLRequest *request = [NSURLRequest requestWithURL:url]; + [_webView loadRequest:request]; +} + + + +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.h b/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.h new file mode 100644 index 0000000..73bb465 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.h @@ -0,0 +1,13 @@ +// +// MainTabBarViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface MainTabBarViewController : UITabBarController + +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.m b/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.m new file mode 100644 index 0000000..2fcd90a --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/MainTabBarViewController.m @@ -0,0 +1,37 @@ +// +// MainTabBarViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "MainTabBarViewController.h" + +@interface MainTabBarViewController () + +@end + +@implementation MainTabBarViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + // Do any additional setup after loading the view. +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/SecondViewController.h b/iOSStudy/iOSStudy/iOSStudy/SecondViewController.h similarity index 100% rename from iOSStudy/iOSStudy/SecondViewController.h rename to iOSStudy/iOSStudy/iOSStudy/SecondViewController.h diff --git a/iOSStudy/iOSStudy/SecondViewController.m b/iOSStudy/iOSStudy/iOSStudy/SecondViewController.m similarity index 100% rename from iOSStudy/iOSStudy/SecondViewController.m rename to iOSStudy/iOSStudy/iOSStudy/SecondViewController.m diff --git a/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.h b/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.h new file mode 100644 index 0000000..60ea577 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.h @@ -0,0 +1,13 @@ +// +// SettingTableViewController.h +// iOSStudy +// +// Created by chenguandong on 15/2/21. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface SettingTableViewController : UITableViewController + +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.m b/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.m new file mode 100644 index 0000000..e04db40 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/SettingTableViewController.m @@ -0,0 +1,105 @@ +// +// SettingTableViewController.m +// iOSStudy +// +// Created by chenguandong on 15/2/21. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "SettingTableViewController.h" + +@interface SettingTableViewController () + +@end + +@implementation SettingTableViewController + +- (void)viewDidLoad { + [super viewDidLoad]; + + // Uncomment the following line to preserve selection between presentations. + // self.clearsSelectionOnViewWillAppear = NO; + + // Uncomment the following line to display an Edit button in the navigation bar for this view controller. + // self.navigationItem.rightBarButtonItem = self.editButtonItem; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +#pragma mark - Table view data source + +/* +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { + + // Return the number of sections. + return 2; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section { + + // Return the number of rows in the section. + return 3; +} + */ + + +/* +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { +// UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"staticCell" forIndexPath:indexPath]; + + // Configure the cell... + + UITableViewCell *cell =[[UITableViewCell alloc]init]; + + return cell; +} +*/ + +/* +// Override to support conditional editing of the table view. +- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the specified item to be editable. + return YES; +} +*/ + +/* +// Override to support editing the table view. +- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath { + if (editingStyle == UITableViewCellEditingStyleDelete) { + // Delete the row from the data source + [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade]; + } else if (editingStyle == UITableViewCellEditingStyleInsert) { + // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view + } +} +*/ + +/* +// Override to support rearranging the table view. +- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath { +} +*/ + +/* +// Override to support conditional rearranging of the table view. +- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath { + // Return NO if you do not want the item to be re-orderable. + return YES; +} +*/ + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/ThirdTableViewController.h b/iOSStudy/iOSStudy/iOSStudy/ThirdTableViewController.h similarity index 100% rename from iOSStudy/iOSStudy/ThirdTableViewController.h rename to iOSStudy/iOSStudy/iOSStudy/ThirdTableViewController.h diff --git a/iOSStudy/iOSStudy/ThirdTableViewController.m b/iOSStudy/iOSStudy/iOSStudy/ThirdTableViewController.m similarity index 100% rename from iOSStudy/iOSStudy/ThirdTableViewController.m rename to iOSStudy/iOSStudy/iOSStudy/ThirdTableViewController.m diff --git a/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h b/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h new file mode 100644 index 0000000..855ec78 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.h @@ -0,0 +1,88 @@ +// +// FirstViewControllerViewModel.h +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "NetWorkTools.h" +#import "JsonTools.h" +#import "BlogBean.h" + + +/** + * 网络请求开始 + */ +typedef void (^modelPersistentReload)(); + +/** + * 网络请求成功回调 + */ +typedef void (^modelSuccess)(); +/** + * 网络请求失败回调 + */ +typedef void (^modelError)(); + +/** + * 网络是否链接回调 + * + * @param isNetWorking YES 有网络 NO 没有网络 + */ +typedef void (^modelNetWorking)(BOOL isNetWorking); + +@interface FirstViewControllerViewModel : NSObject +@property(nonatomic,strong)NSArray *array; + + +/** + * 获取table的行数 + * + * @return table的行数 + */ +- (NSInteger)getNumberOfRowsInSection; + +/** + * 获取cell的数据 + * + * @param indexPath indexPath + * + * @return cell的数据 + */ +-(NSManagedObject*)getBlogBean:(NSIndexPath *)indexPath; + + + +/** + * 添加收藏到数据库 + * + * @param indexPath indexPath + */ +-(void)saveFavourite:(NSIndexPath*)indexPath favouriteType:(NSString*)type; + + + + +/** + * 请求网络数据 + * + * @param modelDataSuccess 请求成功 + * @param modelDataStart 请求开始 + * @param modelDataErrors 请求失败 + * @param modelDataIsNetWoring 网络状态 + */ +-(void)getDate:(modelSuccess)modelDataSuccess modelDataReload:(modelPersistentReload)modelDataReload modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring httpAdress:(NSString*)httpAdress dataType:(NSString*)dataType jsonClass:(Class)myClass; + + +/** + * 设置SWTableViewCell 滑动文字 + * + * @param url url地址 + * @param type 1 博客 2 网址 3 视频 + * + * @return 要显示的Button集合 + */ +- (NSArray *)setRightSWCellButtons:(NSString*)url withType:(NSString*)type; +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m b/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m new file mode 100644 index 0000000..8f91f3e --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/ViewModel/FirstViewControllerViewModel.m @@ -0,0 +1,321 @@ +// +// FirstViewControllerViewModel.m +// iOSStudy +// +// Created by chenguandong on 15/2/16. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "FirstViewControllerViewModel.h" +#import "FavouriteBean.h" +#import "Constants .h" +#import "BlogJsonBean.h" +#import "HttpVersionTools.h" +#import "CoreDataUtils.h" +#import +#import "EntityConstants.h" +@implementation FirstViewControllerViewModel +- (instancetype)init +{ + self = [super init]; + if (self) { + _array = [NSMutableArray array]; + + + } + return self; +} + +- (NSInteger)getNumberOfRowsInSection{ + + return _array.count; +} + + + +-(NSManagedObject*)getBlogBean:(NSIndexPath *)indexPath{ + + return _array[indexPath.row]; +} + + + +/** + * 请求网络数据 + * + * @param modelDataSuccess 请求成功 + * @param modelDataStart 请求开始 + * @param modelDataErrors 请求失败 + * @param modelDataIsNetWoring 网络状态 + */ +-(void)getDate:(modelSuccess)modelDataSuccess modelDataReload:(modelPersistentReload)modelDataReload modelDataErrors:(modelError)modelDataErrors modelDataIsNetworking:(modelNetWorking)modelDataIsNetWoring httpAdress:(NSString*)httpAdress dataType:(NSString*)dataType jsonClass:(Class)myClass{ + + + _array = [[self getPersistenceDataWithType:dataType]copy]; + + + modelDataReload(); + + __block NSString *versionStr; + + if ([HttpVersionTools checkHttpVersion:httpAdress nowVersion:[HttpVersionTools getNowHttpVersion:httpAdress]]) { + + // + + [NetWorkTools postHttp:httpAdress success:^(AFHTTPRequestOperation *operation, id responseObject) { + + NSLog(@"JSON: %@", [operation responseString]); + + NSDictionary *dic = [JsonTools getJsonNSDictionary:[operation responseString]]; + + //NSLog(@"jsonVersion=%@",dic[@"version"]); + + + versionStr =dic[@"version"]; + + //将JSON数据和Model的属性进行绑定 + + // NSLog(@"%@arr=",dic[@"bloglists"]); + + NSArray *arr = [MTLJSONAdapter modelsOfClass:myClass fromJSONArray:dic[@"bloglists"] error:nil]; + + + + _array = [arr copy]; + + + + //持久化数据 + [self persistenceDataWithType:dataType]; + + //当前最新版本号存入数据库 + + [HttpVersionTools saveNowHttpVersion:httpAdress version:versionStr]; + + _array = [[self getPersistenceDataWithType:dataType]copy]; + + modelDataSuccess(); + + + + } error:^(AFHTTPRequestOperation *operation, NSError *error) { + NSLog(@"Error: %@", error); + + modelDataErrors(); + + } isNetworking:^(BOOL isNetwork) { + + + modelDataIsNetWoring(isNetwork); + + + }]; + }else{ + //直接显示持久化数据 数据显示完毕 + modelDataSuccess(); + + NSLog(@"cout====%ld",_array.count); + } + + + + + +} + + + +#pragma mark -- 得到持久化的数据 +-(NSArray*)getPersistenceDataWithType:(NSString*)type{ + NSError *error; + NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; + NSEntityDescription *entity = [NSEntityDescription + entityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + [fetchRequest setEntity:entity]; + + //查询条件 + NSPredicate *predicate = [NSPredicate predicateWithFormat:@"type = %@",type]; + + fetchRequest.predicate = predicate; + + NSArray *fetchedObjects = [SharedApp.managedObjectContext executeFetchRequest:fetchRequest error:&error]; + + + return fetchedObjects; + +} + +#pragma mark -- 持久化所有数据 +-(void)persistenceDataWithType:(NSString*)type{ + + //删除已经存在的数据 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"type= %@", type]; + [CoreDataUtils deleteDateFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + + for (BlogBean *bean in _array) { + + if ([self isExistSimpleDataWithURL:bean.url]) { + NSLog(@"已经有这条数据了"); + }else{ + NSManagedObject *favouriteBean =[NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + + [favouriteBean setValue:bean.title forKey:FavouriteBean_title]; + [favouriteBean setValue:bean.subTitle forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:bean.image forKey:FavouriteBean_image_name]; + [favouriteBean setValue:bean.url forKey:FavouriteBean_url]; + [favouriteBean setValue:TYPE_BLOG_SIMPLE_TYPE forKey:FavouriteBean_type]; + + + } + + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + +} + + +-(void)saveFavourite:(NSIndexPath*)indexPath favouriteType:(NSString*)type{ + + NSManagedObject *loveBean = _array[indexPath.row]; + + + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"url= %@ AND type=%@", [loveBean valueForKey:FavouriteBean_url],type]; + NSArray*favouriteList = [CoreDataUtils queryDataFromTableName:CD_FAVOURITE_BEAN andNSPredicate:urlPredicate]; + if (favouriteList.count!=0) { + NSLog(@"已经有这条数据了 ");//更新收藏的状态 + + + [SharedApp.managedObjectContext deleteObject:favouriteList[0]]; + + + NSError *error = nil; + [SharedApp.managedObjectContext save:&error]; + if (error) { + + NSLog(@"删除收藏失败%@",[error userInfo]); + }else{ + NSLog(@"删除收藏成功"); + } + }else{ + NSManagedObject *favouriteBean = [NSEntityDescription insertNewObjectForEntityForName:CD_FAVOURITE_BEAN inManagedObjectContext:SharedApp.managedObjectContext]; + + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_title] forKey:FavouriteBean_title]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_subtitle] forKey:FavouriteBean_subtitle]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_image_name] forKey:FavouriteBean_image_name]; + [favouriteBean setValue:[loveBean valueForKey:FavouriteBean_url] forKey:FavouriteBean_url]; + [favouriteBean setValue:TYPE_BLOG_FAVOURITE_TYPE forKey:FavouriteBean_type]; + } + + NSError *error; + BOOL isSaveSuccess =[SharedApp.managedObjectContext save:&error]; + if (!isSaveSuccess) { + NSLog(@"Error: %@,%@",error,[error userInfo]); + }else { + NSLog(@"Save successful favourite!"); + } + + + + + +} + + +/** + * 判断收藏的条目是否存在 + * + * @param url url地址 + * @param type url 类型 + * + * @return YES 存在 NO 不存在 + */ +//-(BOOL)isEXistFavouriteDataWithURL:(NSString*)url andUrlType:(NSString*)type{ +// +// NSPredicate *urlAndurlTypePredicate = [NSPredicate predicateWithFormat:@"url = %@ AND type=%@",url,TYPE_BLOG_FAVOURITE_TYPE]; +// +// return [CoreDataUtils dataisExistTableName:CD_FAVOURITE_BEAN withPredicate:urlAndurlTypePredicate]; +//} + +/** + * 判断收藏的URL地址是否存在 + * + * @param url URL地址 + * + * @return YES 存在 NO 不存在 + */ +-(BOOL)isExistSimpleDataWithURL:(NSString*)url{ + NSPredicate *urlPredicate = [NSPredicate predicateWithFormat:@"%@ = %@",@"url", url]; + + return [CoreDataUtils dataisExistTableName:CD_FAVOURITE_BEAN withPredicate:urlPredicate]; +} + + +/** + * 判断URL 是否收藏过 + * + * @param url url 地址 + * @param type 收藏类型 1 博客 2 网址 3 视频 + * + * @return YES 收藏过了 NO 没有收藏过 + */ +-(BOOL)queryisFavourite:(NSString*)url withType:(NSString*)type{ + //判断当前条目是否收藏 显示收藏不收藏 + NSPredicate *titlePredicate = [NSPredicate predicateWithFormat:@"url= %@ AND type=%@", url,type]; + + NSArray *queryList = [CoreDataUtils queryDataFromTableName:CD_FAVOURITE_BEAN andNSPredicate:titlePredicate]; + + if (queryList.count!=0) { + NSLog(@"cout=%ld",queryList.count); + return YES; + }else{ + + return NO; + } +} + + +/** + * 设置SWTableViewCell 滑动文字 + * + * @param url url地址 + * @param type 1 博客 2 网址 3 视频 + * + * @return 要显示的Button集合 + */ +- (NSArray *)setRightSWCellButtons:(NSString*)url withType:(NSString*)type +{ + + + NSString *showText ; + + if ([self queryisFavourite:url withType:type]) { + showText = textNameUnFavourite; + }else{ + showText = textNameFavourite; + } + + + NSMutableArray *rightUtilityButtons = [NSMutableArray new]; + [rightUtilityButtons sw_addUtilityButtonWithColor: + [UIColor colorWithRed:0.78f green:0.78f blue:0.8f alpha:1.0] + + title:showText]; + + return rightUtilityButtons; + + +} + + + + +@end diff --git a/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.h b/iOSStudy/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.h similarity index 100% rename from iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.h rename to iOSStudy/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.h diff --git a/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.m b/iOSStudy/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.m similarity index 100% rename from iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.m rename to iOSStudy/iOSStudy/iOSStudy/ViewModel/SecondViewControllerViewModel.m diff --git a/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.h b/iOSStudy/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.h similarity index 100% rename from iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.h rename to iOSStudy/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.h diff --git a/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.m b/iOSStudy/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.m similarity index 100% rename from iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.m rename to iOSStudy/iOSStudy/iOSStudy/ViewModel/ThirdViewControllerViewModel.m diff --git a/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.h b/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.h new file mode 100644 index 0000000..27587df --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.h @@ -0,0 +1,13 @@ +// +// WelcomeViewController.h +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import + +@interface WelcomeViewController : UIViewController + +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.m b/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.m new file mode 100644 index 0000000..6cb127a --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/WelcomeViewController.m @@ -0,0 +1,70 @@ +// +// WelcomeViewController.m +// iOSStudy +// +// Created by chenguandong on 15/4/3. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "WelcomeViewController.h" +#import +#import "NetWorkTools.h" +#import "HttpVersionTools.h" +#import "MainTabBarViewController.h" +#import +#import "VersionBean.h" +@interface WelcomeViewController () + +@end + +@implementation WelcomeViewController + + +-(void)viewWillAppear:(BOOL)animated{ + [super viewWillAppear:YES]; + NSLog(@"------checkNetworking"); + + [SVProgressHUD show]; +} + +- (void)viewDidLoad { + [super viewDidLoad]; + + + //获取服务器HTTP当前版本号 + SharedApp.isNetworking = YES; + [HttpVersionTools getVersions:^(NSArray *versionLists) { + SharedApp.versionLists = versionLists; + + for (VersionBean *vBean in SharedApp.versionLists) { + NSLog(@"version =%@",vBean.urlVersion); + } + + [self goNextPage]; + } v_error:^{ + [self goNextPage]; + } v_netWork:^(BOOL isNetWorking) { + [self goNextPage]; + }]; +} + +-(void)goNextPage{ + [self performSegueWithIdentifier:@"mainTab" sender:self]; +} + +- (void)didReceiveMemoryWarning { + [super didReceiveMemoryWarning]; + // Dispose of any resources that can be recreated. +} + +/* +#pragma mark - Navigation + +// In a storyboard-based application, you will often want to do a little preparation before navigation +- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { + // Get the new view controller using [segue destinationViewController]. + // Pass the selected object to the new view controller. +} +*/ + +@end diff --git a/iOSStudy/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents b/iOSStudy/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents new file mode 100644 index 0000000..c2fcb8e --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/iOSStudy.xcdatamodeld/iOSStudy.xcdatamodel/contents @@ -0,0 +1,18 @@ + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/iOSStudy/iOSStudy/iOSStudy/main.m b/iOSStudy/iOSStudy/iOSStudy/main.m new file mode 100644 index 0000000..0e7fc47 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudy/main.m @@ -0,0 +1,16 @@ +// +// main.m +// iOSStudy +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import "AppDelegate.h" + +int main(int argc, char * argv[]) { + @autoreleasepool { + return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); + } +} diff --git a/iOSStudy/iOSStudy/zh-Hans.lproj/LaunchScreen.strings b/iOSStudy/iOSStudy/iOSStudy/zh-Hans.lproj/LaunchScreen.strings similarity index 100% rename from iOSStudy/iOSStudy/zh-Hans.lproj/LaunchScreen.strings rename to iOSStudy/iOSStudy/iOSStudy/zh-Hans.lproj/LaunchScreen.strings diff --git a/iOSStudy/iOSStudy/iOSStudyTests/Info.plist b/iOSStudy/iOSStudy/iOSStudyTests/Info.plist new file mode 100644 index 0000000..fee913e --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudyTests/Info.plist @@ -0,0 +1,24 @@ + + + + + CFBundleDevelopmentRegion + en + CFBundleExecutable + $(EXECUTABLE_NAME) + CFBundleIdentifier + ---.$(PRODUCT_NAME:rfc1034identifier) + CFBundleInfoDictionaryVersion + 6.0 + CFBundleName + $(PRODUCT_NAME) + CFBundlePackageType + BNDL + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1 + + diff --git a/iOSStudy/iOSStudy/iOSStudyTests/iOSStudyTests.m b/iOSStudy/iOSStudy/iOSStudyTests/iOSStudyTests.m new file mode 100644 index 0000000..77f2841 --- /dev/null +++ b/iOSStudy/iOSStudy/iOSStudyTests/iOSStudyTests.m @@ -0,0 +1,40 @@ +// +// iOSStudyTests.m +// iOSStudyTests +// +// Created by chenguandong on 15/1/29. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import + +@interface iOSStudyTests : XCTestCase + +@end + +@implementation iOSStudyTests + +- (void)setUp { + [super setUp]; + // Put setup code here. This method is called before the invocation of each test method in the class. +} + +- (void)tearDown { + // Put teardown code here. This method is called after the invocation of each test method in the class. + [super tearDown]; +} + +- (void)testExample { + // This is an example of a functional test case. + XCTAssert(YES, @"Pass"); +} + +- (void)testPerformanceExample { + // This is an example of a performance test case. + [self measureBlock:^{ + // Put the code you want to measure the time of here. + }]; +} + +@end diff --git a/iOSStudy/iOSStudy/libs/UIImage+Resize.h b/iOSStudy/iOSStudy/libs/UIImage+Resize.h new file mode 100755 index 0000000..d3e1b1e --- /dev/null +++ b/iOSStudy/iOSStudy/libs/UIImage+Resize.h @@ -0,0 +1,37 @@ +/*********************************************************************************** + * + * Copyright (c) 2010 Olivier Halligon + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + *********************************************************************************** + * + * Any comment or suggestion welcome. Referencing this project in your AboutBox is appreciated. + * Please tell me if you use this class so we can cross-reference our projects. + * + ***********************************************************************************/ + + +#import +#import + +@interface UIImage(ResizeCategory) +-(UIImage*)resizedImageToSize:(CGSize)dstSize; +-(UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale; +@end diff --git a/iOSStudy/iOSStudy/libs/UIImage+Resize.m b/iOSStudy/iOSStudy/libs/UIImage+Resize.m new file mode 100755 index 0000000..60e4ea9 --- /dev/null +++ b/iOSStudy/iOSStudy/libs/UIImage+Resize.m @@ -0,0 +1,153 @@ +// +// UIImage+Resize.m +// +// Created by Olivier Halligon on 12/08/09. +// Copyright 2009 AliSoftware. All rights reserved. +// + +#import "UIImage+Resize.h" + +@implementation UIImage (ResizeCategory) + +-(UIImage*)resizedImageToSize:(CGSize)dstSize +{ + CGImageRef imgRef = self.CGImage; + // the below values are regardless of orientation : for UIImages from Camera, width>height (landscape) + CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which is dependant on the imageOrientation)! + + /* Don't resize if we already meet the required destination size. */ + if (CGSizeEqualToSize(srcSize, dstSize)) { + return self; + } + + CGFloat scaleRatio = dstSize.width / srcSize.width; + UIImageOrientation orient = self.imageOrientation; + CGAffineTransform transform = CGAffineTransformIdentity; + switch(orient) { + + case UIImageOrientationUp: //EXIF = 1 + transform = CGAffineTransformIdentity; + break; + + case UIImageOrientationUpMirrored: //EXIF = 2 + transform = CGAffineTransformMakeTranslation(srcSize.width, 0.0); + transform = CGAffineTransformScale(transform, -1.0, 1.0); + break; + + case UIImageOrientationDown: //EXIF = 3 + transform = CGAffineTransformMakeTranslation(srcSize.width, srcSize.height); + transform = CGAffineTransformRotate(transform, M_PI); + break; + + case UIImageOrientationDownMirrored: //EXIF = 4 + transform = CGAffineTransformMakeTranslation(0.0, srcSize.height); + transform = CGAffineTransformScale(transform, 1.0, -1.0); + break; + + case UIImageOrientationLeftMirrored: //EXIF = 5 + dstSize = CGSizeMake(dstSize.height, dstSize.width); + transform = CGAffineTransformMakeTranslation(srcSize.height, srcSize.width); + transform = CGAffineTransformScale(transform, -1.0, 1.0); + transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2); + break; + + case UIImageOrientationLeft: //EXIF = 6 + dstSize = CGSizeMake(dstSize.height, dstSize.width); + transform = CGAffineTransformMakeTranslation(0.0, srcSize.width); + transform = CGAffineTransformRotate(transform, 3.0 * M_PI_2); + break; + + case UIImageOrientationRightMirrored: //EXIF = 7 + dstSize = CGSizeMake(dstSize.height, dstSize.width); + transform = CGAffineTransformMakeScale(-1.0, 1.0); + transform = CGAffineTransformRotate(transform, M_PI_2); + break; + + case UIImageOrientationRight: //EXIF = 8 + dstSize = CGSizeMake(dstSize.height, dstSize.width); + transform = CGAffineTransformMakeTranslation(srcSize.height, 0.0); + transform = CGAffineTransformRotate(transform, M_PI_2); + break; + + default: + [NSException raise:NSInternalInconsistencyException format:@"Invalid image orientation"]; + + } + + ///////////////////////////////////////////////////////////////////////////// + // The actual resize: draw the image on a new context, applying a transform matrix + UIGraphicsBeginImageContextWithOptions(dstSize, NO, self.scale); + + CGContextRef context = UIGraphicsGetCurrentContext(); + + if (!context) { + return nil; + } + + if (orient == UIImageOrientationRight || orient == UIImageOrientationLeft) { + CGContextScaleCTM(context, -scaleRatio, scaleRatio); + CGContextTranslateCTM(context, -srcSize.height, 0); + } else { + CGContextScaleCTM(context, scaleRatio, -scaleRatio); + CGContextTranslateCTM(context, 0, -srcSize.height); + } + + CGContextConcatCTM(context, transform); + + // we use srcSize (and not dstSize) as the size to specify is in user space (and we use the CTM to apply a scaleRatio) + CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, srcSize.width, srcSize.height), imgRef); + UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext(); + UIGraphicsEndImageContext(); + + return resizedImage; +} + + + +///////////////////////////////////////////////////////////////////////////// + + + +-(UIImage*)resizedImageToFitInSize:(CGSize)boundingSize scaleIfSmaller:(BOOL)scale +{ + // get the image size (independant of imageOrientation) + CGImageRef imgRef = self.CGImage; + CGSize srcSize = CGSizeMake(CGImageGetWidth(imgRef), CGImageGetHeight(imgRef)); // not equivalent to self.size (which depends on the imageOrientation)! + + // adjust boundingSize to make it independant on imageOrientation too for farther computations + UIImageOrientation orient = self.imageOrientation; + switch (orient) { + case UIImageOrientationLeft: + case UIImageOrientationRight: + case UIImageOrientationLeftMirrored: + case UIImageOrientationRightMirrored: + boundingSize = CGSizeMake(boundingSize.height, boundingSize.width); + break; + default: + // NOP + break; + } + + // Compute the target CGRect in order to keep aspect-ratio + CGSize dstSize; + + if ( !scale && (srcSize.width < boundingSize.width) && (srcSize.height < boundingSize.height) ) { + //NSLog(@"Image is smaller, and we asked not to scale it in this case (scaleIfSmaller:NO)"); + dstSize = srcSize; // no resize (we could directly return 'self' here, but we draw the image anyway to take image orientation into account) + } else { + CGFloat wRatio = boundingSize.width / srcSize.width; + CGFloat hRatio = boundingSize.height / srcSize.height; + + if (wRatio < hRatio) { + //NSLog(@"Width imposed, Height scaled ; ratio = %f",wRatio); + dstSize = CGSizeMake(boundingSize.width, floorf(srcSize.height * wRatio)); + } else { + //NSLog(@"Height imposed, Width scaled ; ratio = %f",hRatio); + dstSize = CGSizeMake(floorf(srcSize.width * hRatio), boundingSize.height); + } + } + + return [self resizedImageToSize:dstSize]; +} + +@end diff --git a/iOSStudy/iOSStudy/zh-Hans.lproj/Localizable.strings b/iOSStudy/iOSStudy/zh-Hans.lproj/Localizable.strings new file mode 100644 index 0000000..cba4caa --- /dev/null +++ b/iOSStudy/iOSStudy/zh-Hans.lproj/Localizable.strings @@ -0,0 +1,10 @@ +/* + Localizable.strings + iOSStudy + + Created by chenguandong on 15/5/12. + Copyright (c) 2015年 chenguandong. All rights reserved. +*/ +"loadData" = "正在更新数据..."; +"love" = "收藏"; +"unlove" = "取消收藏"; \ No newline at end of file diff --git a/iOSStudy/iOSStudy/zh-Hans.lproj/Main.strings b/iOSStudy/iOSStudy/zh-Hans.lproj/Main.strings new file mode 100644 index 0000000..a880212 --- /dev/null +++ b/iOSStudy/iOSStudy/zh-Hans.lproj/Main.strings @@ -0,0 +1,69 @@ + +/* Class = "UITabBarController"; title = "博客"; ObjectID = "49e-Tb-3d3"; */ +"49e-Tb-3d3.title" = "博客"; + +/* Class = "UILabel"; text = "开源许可"; ObjectID = "5QR-7R-yRv"; */ +"5QR-7R-yRv.text" = "开源许可"; + +/* Class = "UITabBarItem"; title = "收藏"; ObjectID = "8Gx-f0-bsw"; */ +"8Gx-f0-bsw.title" = "收藏"; + +/* Class = "UILabel"; text = "给应用评分"; ObjectID = "9Uv-G0-brC"; */ +"9Uv-G0-brC.text" = "给应用评分"; + +/* Class = "UILabel"; text = "Title"; ObjectID = "DUN-jA-nZ1"; */ +"DUN-jA-nZ1.text" = "Title"; + +/* Class = "UITabBarItem"; title = "设置"; ObjectID = "MEY-jV-QF5"; */ +"MEY-jV-QF5.title" = "设置"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[0] = "博客"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[0]" = "博客"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[1] = "网站"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[1]" = "网站"; + +/* Class = "UISegmentedControl"; VcJ-XZ-Bc3.segmentTitles[2] = "视频"; ObjectID = "VcJ-XZ-Bc3"; */ +"VcJ-XZ-Bc3.segmentTitles[2]" = "视频"; + +/* Class = "UINavigationItem"; title = "推荐博客"; ObjectID = "WaC-jM-KHt"; */ +"WaC-jM-KHt.title" = "推荐博客"; + +/* Class = "UITableViewSection"; footerTitle = "官方博客:http://iosstudy.lofter.com/"; ObjectID = "YWs-ix-bRc"; */ +"YWs-ix-bRc.footerTitle" = "官方博客:http://iosstudy.lofter.com/"; + +/* Class = "UITableViewSection"; headerTitle = "关于我们"; ObjectID = "YWs-ix-bRc"; */ +"YWs-ix-bRc.headerTitle" = "关于我们"; + +/* Class = "UINavigationItem"; title = "推荐网站"; ObjectID = "YiK-bv-9gx"; */ +"YiK-bv-9gx.title" = "推荐网站"; + +/* Class = "UINavigationItem"; title = "开源协议"; ObjectID = "ZNU-fK-evW"; */ +"ZNU-fK-evW.title" = "开源协议"; + +/* Class = "UILabel"; text = "关于"; ObjectID = "ZgU-bl-sae"; */ +"ZgU-bl-sae.text" = "关于"; + +/* Class = "UITabBarItem"; title = "博客"; ObjectID = "acW-dT-cKf"; */ +"acW-dT-cKf.title" = "博客"; + +/* Class = "UITabBarItem"; title = "网站"; ObjectID = "cPa-gy-q4n"; */ +"cPa-gy-q4n.title" = "网站"; + +/* Class = "UITabBarItem"; title = "视频"; ObjectID = "fbE-WQ-JZW"; */ +"fbE-WQ-JZW.title" = "视频"; + +/* Class = "UINavigationItem"; title = "设置"; ObjectID = "gf0-0D-9bS"; */ +"gf0-0D-9bS.title" = "设置"; + +/* Class = "UILabel"; text = "意见反馈"; ObjectID = "o5j-bN-LCE"; */ +"o5j-bN-LCE.text" = "意见反馈"; + +/* Class = "UINavigationItem"; title = "推荐视频"; ObjectID = "otE-MF-bXm"; */ +"otE-MF-bXm.title" = "推荐视频"; + +/* Class = "UILabel"; text = "Subtitle"; ObjectID = "rkz-vV-hB8"; */ +"rkz-vV-hB8.text" = "Subtitle"; + +/* Class = "UITableViewController"; title = "设置"; ObjectID = "wtw-i4-ZN0"; */ +"wtw-i4-ZN0.title" = "设置"; diff --git a/iOSStudy/iOSStudyJsonData/blogs.json b/iOSStudy/iOSStudyJsonData/blogs.json new file mode 100644 index 0000000..5ca709d --- /dev/null +++ b/iOSStudy/iOSStudyJsonData/blogs.json @@ -0,0 +1 @@ +{"version":"6","bloglists":[{"name":"破船之家","title":"破船之家的技术博客","subTitle":"去留无意,漫随天外云卷云舒","image":"https://avatars1.githubusercontent.com/u/3365146?v\u003d3\u0026s\u003d460","url":"http://beyondvincent.com/","rssUrl":"http://beyondvincent.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"唐巧","title":"唐巧的技术博客","subTitle":"唐巧的技术博客记录下自己学习的点滴","image":"http://blog.devtang.com/images/weixin-qr.jpg","url":"http://blog.devtang.com","rssUrl":"http://blog.devtang.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"OneV\u0027s Den","title":"OneV\u0027s Den的技术博客","subTitle":"嗨,我是王巍 (@onevcat),一名来自中国的 iOS / Unity 开发者。现居日本,就职于 LINE。正在修行,探求创意之源。","image":"http://onevcat.com/content/images/2014/May/200.jpg","url":"http://onevcat.com/","rssUrl":"http://onevcat.com/rss/","date":"2015-01-30 17:08:03"},{"name":"Limboy","title":"Limboy的技术博客","subTitle":"对Web开发的各方面都比较熟悉,后将重心转移到iOS领域。2012年离开知乎后,与几个知乎员工一起做起了「Legend33 Studio」,在其中主要负责iOS开发,同时也参与产品/创意。首款作品「Once Touch」反响还不错,也被ifanr报道过,从此与iOS结缘。","image":"https://avatars2.githubusercontent.com/u/35974?v\u003d3\u0026s\u003d460","url":"http://limboy.me/","rssUrl":"http://feeds.feedburner.com/lzyy","date":"2015-01-30 17:08:03"},{"name":"刘坤","title":"刘坤的技术博客","subTitle":"嗨,我是刘坤,一名来自中国的 IOS 开发者,现就职于杭州阿里,花名‘念纪’,沉淀技术,寻求创意","image":"http://blog.cnbluebox.com/images/face_liukun.jpeg","url":"http://blog.cnbluebox.com/","rssUrl":"http://blog.cnbluebox.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"叶孤城___","title":"叶孤城___","subTitle":"ios开发者。Vim学习中","image":"http://tp1.sinaimg.cn/1438670852/180/5695641016/1","url":"http://www.jianshu.com/users/b82d2721ba07/latest_articles","rssUrl":"http://www.jianshu.com/users/b82d2721ba07/latest_articles","date":"2015-01-30 17:08:03"},{"name":"王轲","title":"王轲的技术博客","subTitle":"王轲, IndieBros Studio 创始人, 优秀的 iOS 开发工程师, 写的文章深入浅出, 很多问题分析透彻, 非常有条理性","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://www.iwangke.me/","rssUrl":"http://www.iwangke.me/atom.xml","date":"2015-01-30 17:08:03"},{"name":"txx\u0027s blog","title":"txx\u0027s blog","subTitle":"90 后 iOS 开发者, 人称虾神, 文章内容讲解大多浅白易懂, 很值得看","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://blog.txx.im/","rssUrl":"http://blog.txx.im/atom.xml","date":"2015-01-30 17:08:03"},{"name":"Read The Fucking Source Code","title":"Read The Fucking Source Code","subTitle":"Read The Fucking Source Code","image":"http://blog.brooklyn886.com/content/images/2014/May/1.jpeg","url":"http://blog.brooklyn886.com/","rssUrl":"http://blog.brooklyn886.com/","date":"2015-01-30 17:08:03"},{"name":"http://itjoy.org/","title":"http://itjoy.org/","subTitle":"http://itjoy.org/","image":"http://tp2.sinaimg.cn/2663764813/180/40006387168/1","url":"http://itjoy.org/","rssUrl":"http://itjoy.org/","date":"2015-01-30 17:08:03"}]} diff --git a/iOSStudy/iOSStudyJsonData/versions.json b/iOSStudy/iOSStudyJsonData/versions.json new file mode 100644 index 0000000..2b55054 --- /dev/null +++ b/iOSStudy/iOSStudyJsonData/versions.json @@ -0,0 +1,2 @@ +[{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/blogs.json","urlVersion":"6"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/webs.json","urlVersion":"1"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/videos.json","urlVersion":"1"}] + diff --git a/iOSStudy/iOSStudyJsonData/videos.json b/iOSStudy/iOSStudyJsonData/videos.json new file mode 100644 index 0000000..c59e8f4 --- /dev/null +++ b/iOSStudy/iOSStudyJsonData/videos.json @@ -0,0 +1,2 @@ +[{"videoLanguageType":"zh","title":"传智博客国内首部Swift教程(系统、全面、有深度)","subTitle":"传智博客Swift从入门到精通视频教程完整版","webImage":"http://www.itcast.cn/files/image/201406/20140611114331424.jpg","webUrl":"http://pan.baidu.com/s/1bndD3cz"},{"videoLanguageType":"zh","title":"传智博客iOS开发零基础入门教程","subTitle":"C基础 OC基础 MacOS基础 知识","webImage":"http://www.itcast.cn/files/image/201406/20140611114424706.jpg","webUrl":"http://pan.baidu.com/share/link?shareid\u003d3864330827\u0026uk\u003d3560277524"},{"videoLanguageType":"zh","title":"传智博客iOS开发进阶教程","subTitle":"一些高级和基础控件使用主要是UI的知识","webImage":"http://www.itcast.cn/files/image/201406/20140611115311661.jpg","webUrl":"http://pan.baidu.com/s/1pJDGOll"},{"videoLanguageType":"zh","title":"传智博客iOS开发快速入门教程","subTitle":"C OC基础教程","webImage":"http://www.itcast.cn/files/image/201406/20140611115327052.jpg","webUrl":"http://pan.baidu.com/share/link?shareid\u003d3691511572\u0026uk\u003d3560277524"}] + diff --git a/iOSStudy/iOSStudyJsonData/webs.json b/iOSStudy/iOSStudyJsonData/webs.json new file mode 100644 index 0000000..5f4499b --- /dev/null +++ b/iOSStudy/iOSStudyJsonData/webs.json @@ -0,0 +1,32 @@ +[ + { + "title": "objc中国", + "subTitile": "为中国 Objective-C 社区带来最佳实践和先进技术", + "webImage": "http://www.objc.io/images/covers/6-small.jpg", + "webUrl": "http://objccn.io/" + }, + { + "title": "objc", + "subTitile": "A periodical about best practices and advanced techniques for iOS and OS X development.", + "webImage": "http://www.objc.io/images/covers/4-small.jpg", + "webUrl": "http://www.objc.io/" + }, + { + "title": "AppCoda", + "subTitile": "AppCoda was founded in April 2012 as a personal blog. It was a place where I shared my iOS programming experience and helped beginners to kick start iOS app development. Since then, it has grown into a community for iOS developers with hundreds of thousands readers and a bunch of contributors, as well as, a free course and two books.", + "webImage": "http://www.appcoda.com/wp-content/themes/eleven40/images/favicon.ico", + "webUrl": "http://www.appcoda.com/ios-programming-course/" + }, + { + "title": "NShipster", + "subTitile": "大神Mattt Thompson的博客你懂的", + "webImage": "http://nshipster.cn/touch-icon-ipad-retina.png", + "webUrl": "http://nshipster.cn/" + }, + { + "title": "GoWhich", + "subTitile": "想你所想,做你所做,认真对待你的人生...", + "webImage": "https://avatars0.githubusercontent.com/u/1449203?v=3&s=460", + "webUrl": "http://www.gowhich.com/category/IOS" + } +] diff --git a/iOSStudy/libPushSDK-1.8.3.a b/iOSStudy/libPushSDK-1.8.3.a new file mode 100644 index 0000000..c03cb14 Binary files /dev/null and b/iOSStudy/libPushSDK-1.8.3.a differ diff --git a/iOSStudy/libs/NotificationCenterConstants.h b/iOSStudy/libs/NotificationCenterConstants.h new file mode 100644 index 0000000..26496b8 --- /dev/null +++ b/iOSStudy/libs/NotificationCenterConstants.h @@ -0,0 +1,17 @@ +// +// NotificationCenterConstants.h +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import +#import + +UIKIT_EXTERN NSString *const notifacationBlogReload; +UIKIT_EXTERN NSString *const notifacationWebReload; +UIKIT_EXTERN NSString *const notifacationVideoReload; + +//通知版本号更新成功 +UIKIT_EXTERN NSString *const notifacationVersionSuccess; diff --git a/iOSStudy/libs/NotificationCenterConstants.m b/iOSStudy/libs/NotificationCenterConstants.m new file mode 100644 index 0000000..8a7c243 --- /dev/null +++ b/iOSStudy/libs/NotificationCenterConstants.m @@ -0,0 +1,16 @@ +// +// NotificationCenterConstants.m +// iOSStudy +// +// Created by chenguandong on 15/4/9. +// Copyright (c) 2015年 chenguandong. All rights reserved. +// + +#import "NotificationCenterConstants.h" + + NSString *const notifacationBlogReload =@"notifacationBlogReload"; + NSString *const notifacationWebReload = @"notifacationWebReload"; + NSString *const notifacationVideoReload = @"notifacationVideoReload"; + +//通知版本号更新成功 + NSString *const notifacationVersionSuccess = @"notifacationVersionSuccess"; \ No newline at end of file diff --git a/iOSStudy/libs/UINavigationBar+Awesome.h b/iOSStudy/libs/UINavigationBar+Awesome.h new file mode 100755 index 0000000..c224e27 --- /dev/null +++ b/iOSStudy/libs/UINavigationBar+Awesome.h @@ -0,0 +1,16 @@ +// +// UINavigationBar+Awesome.h +// LTNavigationBar +// +// Created by ltebean on 15-2-15. +// Copyright (c) 2015 ltebean. All rights reserved. +// + +#import + +@interface UINavigationBar (Awesome) +- (void)lt_setBackgroundColor:(UIColor *)backgroundColor; +- (void)lt_setContentAlpha:(CGFloat)alpha; +- (void)lt_setTranslationY:(CGFloat)translationY; +- (void)lt_reset; +@end diff --git a/iOSStudy/libs/UINavigationBar+Awesome.m b/iOSStudy/libs/UINavigationBar+Awesome.m new file mode 100755 index 0000000..57041fa --- /dev/null +++ b/iOSStudy/libs/UINavigationBar+Awesome.m @@ -0,0 +1,88 @@ +// +// UINavigationBar+Awesome.m +// LTNavigationBar +// +// Created by ltebean on 15-2-15. +// Copyright (c) 2015 ltebean. All rights reserved. +// + +#import "UINavigationBar+Awesome.h" +#import + +@implementation UINavigationBar (Awesome) +static char overlayKey; +static char emptyImageKey; + +- (UIView *)overlay +{ + return objc_getAssociatedObject(self, &overlayKey); +} + +- (void)setOverlay:(UIView *)overlay +{ + objc_setAssociatedObject(self, &overlayKey, overlay, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (UIImage *)emptyImage +{ + return objc_getAssociatedObject(self, &emptyImageKey); +} + +- (void)setEmptyImage:(UIImage *)image +{ + objc_setAssociatedObject(self, &emptyImageKey, image, OBJC_ASSOCIATION_RETAIN_NONATOMIC); +} + +- (void)lt_setBackgroundColor:(UIColor *)backgroundColor +{ + if (!self.overlay) { + [self setBackgroundImage:[UIImage new] forBarMetrics:UIBarMetricsDefault]; + [self setShadowImage:[UIImage new]]; + self.overlay = [[UIView alloc] initWithFrame:CGRectMake(0, -20, [UIScreen mainScreen].bounds.size.width, 64)]; + self.overlay.userInteractionEnabled = NO; + self.overlay.autoresizingMask = UIViewAutoresizingFlexibleWidth|UIViewAutoresizingFlexibleHeight; + [self insertSubview:self.overlay atIndex:0]; + } + self.overlay.backgroundColor = backgroundColor; +} + +- (void)lt_setTranslationY:(CGFloat)translationY +{ + self.transform = CGAffineTransformMakeTranslation(0, translationY); +} + +- (void)lt_setContentAlpha:(CGFloat)alpha +{ + if (!self.overlay) { + [self lt_setBackgroundColor:self.barTintColor]; + } + [self setAlpha:alpha forSubviewsOfView:self]; + if (alpha == 1) { + if (!self.emptyImage) { + self.emptyImage = [UIImage new]; + } + self.backIndicatorImage = self.emptyImage; + } +} + +- (void)setAlpha:(CGFloat)alpha forSubviewsOfView:(UIView *)view +{ + for (UIView *subview in view.subviews) { + if (subview == self.overlay) { + continue; + } + subview.alpha = alpha; + [self setAlpha:alpha forSubviewsOfView:subview]; + } +} + +- (void)lt_reset +{ + [self setBackgroundImage:nil forBarMetrics:UIBarMetricsDefault]; + [self setShadowImage:nil]; + + [self.overlay removeFromSuperview]; + self.overlay = nil; +} + +@end diff --git a/iOSStudy/libs/iRate/iRate.bundle/ar.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ar.lproj/Localizable.strings new file mode 100755 index 0000000..38c59cb Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/ar.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/bn.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/bn.lproj/Localizable.strings new file mode 100755 index 0000000..a9f5977 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/bn.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/cs.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/cs.lproj/Localizable.strings new file mode 100755 index 0000000..e31014f --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/cs.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Ohodnotit %@"; +"iRateAppMessage" = "Pokud se vám líbí %@, našli byste si chvilku na ohodnocení aplikace? Nebude to trvat víc než minutu.\nDěkujeme za vaši podporu!"; +"iRateGameMessage" = "Pokud se vám %@ líbí, našli byste si chvilku na ohodnocení hry? Nebude to trvat víc než minutu. Děkujeme za vaši podporu!"; +"iRateCancelButton" = "Ne, děkuji"; +"iRateRateButton" = "Ohodnotit nyní"; +"iRateRemindButton" = "Připomenout později"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/da.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/da.lproj/Localizable.strings new file mode 100755 index 0000000..c4fbf79 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/da.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Vurdér %@"; +"iRateAppMessage" = "Hvis du kan lide at bruge %@, vil du så ikke bruge et øjeblik på at give en vurdering? Det tager ikke mere end et minut. Mange tak for hjælpen!"; +"iRateGameMessage" = "Hvis du kan lide at spille %@, vil du så ikke bruge et øjeblik på at vurdere det? Det tager ikke mere end et minut. Mange tak for hjælpen!"; +"iRateCancelButton" = "Nej tak"; +"iRateRateButton" = "Vurdér nu"; +"iRateRemindButton" = "Påmind mig senere"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/de-AT.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/de-AT.lproj/Localizable.strings new file mode 100755 index 0000000..fc060f7 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/de-AT.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Bewerte %@"; +"iRateAppMessage" = "Wenn dir %@ gefällt, würdest Du es bitte bewerten? Dies wird nicht länger als eine Minute dauern.\nDanke für die Unterstützung!"; +"iRateGameMessage" = "Wenn dir %@ gefällt, würdest Du es bitte bewerten? Dies wird nicht länger als eine Minute dauern. Danke für die Unterstützung!"; +"iRateCancelButton" = "Nein, danke"; +"iRateRateButton" = "Jetzt bewerten"; +"iRateRemindButton" = "Später erinnern"; \ No newline at end of file diff --git a/iOSStudy/libs/iRate/iRate.bundle/de.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/de.lproj/Localizable.strings new file mode 100755 index 0000000..399e881 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/de.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/el.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/el.lproj/Localizable.strings new file mode 100755 index 0000000..502c94a Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/el.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/en.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/en.lproj/Localizable.strings new file mode 100755 index 0000000..ddaf461 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/en.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/es.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/es.lproj/Localizable.strings new file mode 100755 index 0000000..dc96e46 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/es.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/fa.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/fa.lproj/Localizable.strings new file mode 100755 index 0000000..8f4c50c --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/fa.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "امتیاز دهی به %@"; +"iRateAppMessage" = "اگر شما از برنامه‌ی %@ لذت بردین، عالی میشه اگه با این برنامه در اپ‌استور امتیاز دهید! این کار بیشتر از ۱ دقیقه طول نمی‌کشد. با تشکر از حمایت شما!"; +"iRateGameMessage" ="اگر شما از بازی %@ لذت بردین، عالی میشه اگه با این برنامه در اپ‌استور امتیاز دهید! این کار بیشتر از ۱ دقیقه طول نمی‌کشد. با تشکر از حمایت شما!"; +"iRateCancelButton" = "نه، با تشکر"; +"iRateRateButton" = "می‌خوام امتیاز بدم"; +"iRateRemindButton" = "بعدا یادم بنداز"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/fr.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/fr.lproj/Localizable.strings new file mode 100755 index 0000000..22f78aa --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/fr.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Notez %@"; +"iRateAppMessage" = "Si vous aimez utiliser %@, n'oubliez pas de donner votre avis sur l'App Store. Cela ne prend qu'une minute. Merci d'avance pour votre soutien !"; +"iRateGameMessage" = "Si vous aimez jouer à %@, n'oubliez pas de donner votre avis sur l'App Store. Cela ne prend qu'une minute. Merci d'avance pour votre soutien !"; +"iRateCancelButton" = "Non, merci"; +"iRateRateButton" = "Noter maintenant"; +"iRateRemindButton" = "Me le rappeler ultérieurement"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/he.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/he.lproj/Localizable.strings new file mode 100755 index 0000000..ab9d492 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/he.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/hi.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/hi.lproj/Localizable.strings new file mode 100755 index 0000000..67a532e Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/hi.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/id.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/id.lproj/Localizable.strings new file mode 100755 index 0000000..3758921 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/id.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/it.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/it.lproj/Localizable.strings new file mode 100755 index 0000000..fc674ce Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/it.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/ja.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ja.lproj/Localizable.strings new file mode 100755 index 0000000..60c0710 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/ja.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/ko.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ko.lproj/Localizable.strings new file mode 100755 index 0000000..93599c3 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/ko.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/nl.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/nl.lproj/Localizable.strings new file mode 100755 index 0000000..e4dedf9 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/nl.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Beoordeel %@"; +"iRateAppMessage" = "Als het gebruik van %@ je bevalt, wil je dan een moment nemen om het te beoordelen? Het duurt nog geen minuut. Bedankt voor je steun!"; +"iRateGameMessage" = "Als het spelen van %@ je bevalt, wil je dan een moment nemen om het te beoordelen? Het duurt nog geen minuut. Bedankt voor je steun!"; +"iRateCancelButton" = "Nee, bedankt"; +"iRateRateButton" = "Beoordeel nu"; +"iRateRemindButton" = "Herinner me er later aan"; \ No newline at end of file diff --git a/iOSStudy/libs/iRate/iRate.bundle/no.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/no.lproj/Localizable.strings new file mode 100755 index 0000000..212909b Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/no.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/pa.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/pa.lproj/Localizable.strings new file mode 100755 index 0000000..3647d91 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/pa.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/pl.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/pl.lproj/Localizable.strings new file mode 100755 index 0000000..9d4f94d Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/pl.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/pt.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/pt.lproj/Localizable.strings new file mode 100755 index 0000000..6ff1900 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/pt.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/ru.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ru.lproj/Localizable.strings new file mode 100755 index 0000000..fdd3af9 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/ru.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/sk.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/sk.lproj/Localizable.strings new file mode 100755 index 0000000..84c739b --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/sk.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Ohodnotiť %@"; +"iRateAppMessage" = "Ak sa vám páči %@, našli by ste si chvíľku na ohodnotenie aplikácie? Nebude to trvať viac ako minútu.\nĎakujeme za vašu podporu!"; +"iRateGameMessage" = "Ak sa vám hra %@ páči, našli by ste si chvíľku na ohodnotenie aplikácie? Nebude to trvať viac ako minútu. Ďakujeme za vašu podporu!"; +"iRateCancelButton" = "Nie, Ďakujem"; +"iRateRateButton" = "Ohodnotiť teraz"; +"iRateRemindButton" = "Pripomenúť neskôr"; \ No newline at end of file diff --git a/iOSStudy/libs/iRate/iRate.bundle/sl.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/sl.lproj/Localizable.strings new file mode 100755 index 0000000..25112d2 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/sl.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/sv.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/sv.lproj/Localizable.strings new file mode 100755 index 0000000..22c1fa1 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/sv.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Betygsätt %@"; +"iRateAppMessage" = "Gillar du %@ och kan tänka dig att betygsätta den? Det tar inte mer än en minut. Tack för ditt stöd!"; +"iRateGameMessage" = "Gillar du att spela %@ och kan tänka dig att betygsätta det? Det tar inte mer än en minut. Tack för ditt stöd!"; +"iRateCancelButton" = "Nej tack"; +"iRateRateButton" = "Betygsätt nu!"; +"iRateRemindButton" = "Påminn mig senare"; \ No newline at end of file diff --git a/iOSStudy/libs/iRate/iRate.bundle/th.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/th.lproj/Localizable.strings new file mode 100755 index 0000000..7486e24 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/th.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/tr.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/tr.lproj/Localizable.strings new file mode 100755 index 0000000..807f929 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/tr.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/uk.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/uk.lproj/Localizable.strings new file mode 100755 index 0000000..055fe50 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/uk.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/ur-IN.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ur-IN.lproj/Localizable.strings new file mode 100755 index 0000000..b174a90 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/ur-IN.lproj/Localizable.strings @@ -0,0 +1,7 @@ +"iRateMessageTitle" = "کو ریٹ کیجیے %@"; +"iRateAppMessage" = "اگر آپ نے %@ کو مفید پایا ہے تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateGameMessage" = "اگر آپ %@ کھیل کر محظوظ ہوئے ہیں تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateCancelButton" = "نہیں، شکریہ"; +"iRateRateButton" = "ابھی ریٹ کیجیے"; +"iRateRemindButton" = "مجھے بعد میں یاد دلائیں"; +"iRateOkay" = "ٹھیک ہے"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/ur-PK.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ur-PK.lproj/Localizable.strings new file mode 100755 index 0000000..b174a90 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/ur-PK.lproj/Localizable.strings @@ -0,0 +1,7 @@ +"iRateMessageTitle" = "کو ریٹ کیجیے %@"; +"iRateAppMessage" = "اگر آپ نے %@ کو مفید پایا ہے تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateGameMessage" = "اگر آپ %@ کھیل کر محظوظ ہوئے ہیں تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateCancelButton" = "نہیں، شکریہ"; +"iRateRateButton" = "ابھی ریٹ کیجیے"; +"iRateRemindButton" = "مجھے بعد میں یاد دلائیں"; +"iRateOkay" = "ٹھیک ہے"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/ur.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/ur.lproj/Localizable.strings new file mode 100755 index 0000000..b174a90 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/ur.lproj/Localizable.strings @@ -0,0 +1,7 @@ +"iRateMessageTitle" = "کو ریٹ کیجیے %@"; +"iRateAppMessage" = "اگر آپ نے %@ کو مفید پایا ہے تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateGameMessage" = "اگر آپ %@ کھیل کر محظوظ ہوئے ہیں تو کیا آپ اپنے قیمتی وقت میں سے چند لمحے نکال کر اس کو ریٹ کریں گے؟ اس میں ایک منٹ سے زیادہ نہیں لگے گا، آپ کے تعاون کا شکریہ!"; +"iRateCancelButton" = "نہیں، شکریہ"; +"iRateRateButton" = "ابھی ریٹ کیجیے"; +"iRateRemindButton" = "مجھے بعد میں یاد دلائیں"; +"iRateOkay" = "ٹھیک ہے"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/vi.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/vi.lproj/Localizable.strings new file mode 100755 index 0000000..05b75cc --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.bundle/vi.lproj/Localizable.strings @@ -0,0 +1,6 @@ +"iRateMessageTitle" = "Đánh giá %@"; +"iRateAppMessage" = "Nếu thích sử dụng %@, bạn có muốn giành một chút thời gian để đánh giá nó? Sẽ không lâu hơn một phút. Cảm ơn sự hỗ trợ của bạn!"; +"iRateGameMessage" = "Nếu thích chơi %@, bạn có muốn giành một chút thời gian để đánh giá nó? Sẽ không lâu hơn một phút. Cảm ơn sự hỗ trợ của bạn!"; +"iRateCancelButton" = "Không, Cảm ơn"; +"iRateRateButton" = "Đánh Giá Ngay"; +"iRateRemindButton" = "Nhắc Tôi Sau"; diff --git a/iOSStudy/libs/iRate/iRate.bundle/zh-Hans.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/zh-Hans.lproj/Localizable.strings new file mode 100755 index 0000000..0db893b Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/zh-Hans.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.bundle/zh-Hant.lproj/Localizable.strings b/iOSStudy/libs/iRate/iRate.bundle/zh-Hant.lproj/Localizable.strings new file mode 100755 index 0000000..923de48 Binary files /dev/null and b/iOSStudy/libs/iRate/iRate.bundle/zh-Hant.lproj/Localizable.strings differ diff --git a/iOSStudy/libs/iRate/iRate.h b/iOSStudy/libs/iRate/iRate.h new file mode 100755 index 0000000..0844433 --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.h @@ -0,0 +1,169 @@ +// +// iRate.h +// +// Version 1.11.3 +// +// Created by Nick Lockwood on 26/01/2011. +// Copyright 2011 Charcoal Design +// +// Distributed under the permissive zlib license +// Get the latest version from here: +// +// https://github.com/nicklockwood/iRate +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + + +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wobjc-missing-property-synthesis" + + +#import +#undef weak_delegate +#if __has_feature(objc_arc_weak) && \ +(TARGET_OS_IPHONE || __MAC_OS_X_VERSION_MIN_REQUIRED >= __MAC_10_8) +#define weak_delegate weak +#else +#define weak_delegate unsafe_unretained +#endif + + +#import +#if TARGET_OS_IPHONE +#import +#define IRATE_EXTERN UIKIT_EXTERN +#else +#import +#define IRATE_EXTERN APPKIT_EXTERN +#endif + + +IRATE_EXTERN NSUInteger const iRateAppStoreGameGenreID; +IRATE_EXTERN NSString *const iRateErrorDomain; + +//localisation string keys +IRATE_EXTERN NSString *const iRateMessageTitleKey; //iRateMessageTitle +IRATE_EXTERN NSString *const iRateAppMessageKey; //iRateAppMessage +IRATE_EXTERN NSString *const iRateGameMessageKey; //iRateGameMessage +IRATE_EXTERN NSString *const iRateUpdateMessageKey; //iRateUpdateMessage +IRATE_EXTERN NSString *const iRateCancelButtonKey; //iRateCancelButton +IRATE_EXTERN NSString *const iRateRemindButtonKey; //iRateRemindButton +IRATE_EXTERN NSString *const iRateRateButtonKey; //iRateRateButton + +//notification keys +IRATE_EXTERN NSString *const iRateCouldNotConnectToAppStore; +IRATE_EXTERN NSString *const iRateDidDetectAppUpdate; +IRATE_EXTERN NSString *const iRateDidPromptForRating; +IRATE_EXTERN NSString *const iRateUserDidAttemptToRateApp; +IRATE_EXTERN NSString *const iRateUserDidDeclineToRateApp; +IRATE_EXTERN NSString *const iRateUserDidRequestReminderToRateApp; +IRATE_EXTERN NSString *const iRateDidOpenAppStore; + + +typedef NS_ENUM(NSUInteger, iRateErrorCode) +{ + iRateErrorBundleIdDoesNotMatchAppStore = 1, + iRateErrorApplicationNotFoundOnAppStore, + iRateErrorApplicationIsNotLatestVersion, + iRateErrorCouldNotOpenRatingPageURL +}; + + +@protocol iRateDelegate +@optional + +- (void)iRateCouldNotConnectToAppStore:(NSError *)error; +- (void)iRateDidDetectAppUpdate; +- (BOOL)iRateShouldPromptForRating; +- (void)iRateDidPromptForRating; +- (void)iRateUserDidAttemptToRateApp; +- (void)iRateUserDidDeclineToRateApp; +- (void)iRateUserDidRequestReminderToRateApp; +- (BOOL)iRateShouldOpenAppStore; +- (void)iRateDidOpenAppStore; + +@end + + +@interface iRate : NSObject + ++ (iRate *)sharedInstance; + +//app store ID - this is only needed if your +//bundle ID is not unique between iOS and Mac app stores +@property (nonatomic, assign) NSUInteger appStoreID; + +//application details - these are set automatically +@property (nonatomic, assign) NSUInteger appStoreGenreID; +@property (nonatomic, copy) NSString *appStoreCountry; +@property (nonatomic, copy) NSString *applicationName; +@property (nonatomic, copy) NSString *applicationVersion; +@property (nonatomic, copy) NSString *applicationBundleID; + +//usage settings - these have sensible defaults +@property (nonatomic, assign) NSUInteger usesUntilPrompt; +@property (nonatomic, assign) NSUInteger eventsUntilPrompt; +@property (nonatomic, assign) float daysUntilPrompt; +@property (nonatomic, assign) float usesPerWeekForPrompt; +@property (nonatomic, assign) float remindPeriod; + +//message text, you may wish to customise these +@property (nonatomic, copy) NSString *messageTitle; +@property (nonatomic, copy) NSString *message; +@property (nonatomic, copy) NSString *updateMessage; +@property (nonatomic, copy) NSString *cancelButtonLabel; +@property (nonatomic, copy) NSString *remindButtonLabel; +@property (nonatomic, copy) NSString *rateButtonLabel; + +//debugging and prompt overrides +@property (nonatomic, assign) BOOL useUIAlertControllerIfAvailable; +@property (nonatomic, assign) BOOL useAllAvailableLanguages; +@property (nonatomic, assign) BOOL promptForNewVersionIfUserRated; +@property (nonatomic, assign) BOOL onlyPromptIfLatestVersion; +@property (nonatomic, assign) BOOL onlyPromptIfMainWindowIsAvailable; +@property (nonatomic, assign) BOOL promptAtLaunch; +@property (nonatomic, assign) BOOL verboseLogging; +@property (nonatomic, assign) BOOL previewMode; + +//advanced properties for implementing custom behaviour +@property (nonatomic, strong) NSURL *ratingsURL; +@property (nonatomic, strong) NSDate *firstUsed; +@property (nonatomic, strong) NSDate *lastReminded; +@property (nonatomic, assign) NSUInteger usesCount; +@property (nonatomic, assign) NSUInteger eventCount; +@property (nonatomic, readonly) float usesPerWeek; +@property (nonatomic, assign) BOOL declinedThisVersion; +@property (nonatomic, readonly) BOOL declinedAnyVersion; +@property (nonatomic, assign) BOOL ratedThisVersion; +@property (nonatomic, readonly) BOOL ratedAnyVersion; +@property (nonatomic, weak_delegate) id delegate; + +//manually control behaviour +- (BOOL)shouldPromptForRating; +- (void)promptForRating; +- (void)promptIfNetworkAvailable; +- (void)promptIfAllCriteriaMet; +- (void)openRatingsPageInAppStore; +- (void)logEvent:(BOOL)deferPrompt; + +@end + + +#pragma clang diagnostic pop diff --git a/iOSStudy/libs/iRate/iRate.m b/iOSStudy/libs/iRate/iRate.m new file mode 100755 index 0000000..bc5e3eb --- /dev/null +++ b/iOSStudy/libs/iRate/iRate.m @@ -0,0 +1,1177 @@ +// +// iRate.m +// +// Version 1.11.3 +// +// Created by Nick Lockwood on 26/01/2011. +// Copyright 2011 Charcoal Design +// +// Distributed under the permissive zlib license +// Get the latest version from here: +// +// https://github.com/nicklockwood/iRate +// +// This software is provided 'as-is', without any express or implied +// warranty. In no event will the authors be held liable for any damages +// arising from the use of this software. +// +// Permission is granted to anyone to use this software for any purpose, +// including commercial applications, and to alter it and redistribute it +// freely, subject to the following restrictions: +// +// 1. The origin of this software must not be misrepresented; you must not +// claim that you wrote the original software. If you use this software +// in a product, an acknowledgment in the product documentation would be +// appreciated but is not required. +// +// 2. Altered source versions must be plainly marked as such, and must not be +// misrepresented as being the original software. +// +// 3. This notice may not be removed or altered from any source distribution. +// + + +#import "iRate.h" + + +#import +#if !__has_feature(objc_arc) +#error This class requires automatic reference counting +#endif + + +#pragma clang diagnostic ignored "-Wreceiver-is-weak" +#pragma clang diagnostic ignored "-Warc-repeated-use-of-weak" +#pragma clang diagnostic ignored "-Wobjc-missing-property-synthesis" +#pragma clang diagnostic ignored "-Wdirect-ivar-access" +#pragma clang diagnostic ignored "-Wunused-macros" +#pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wformat-nonliteral" +#pragma clang diagnostic ignored "-Wselector" +#pragma clang diagnostic ignored "-Wgnu" + + +NSUInteger const iRateAppStoreGameGenreID = 6014; +NSString *const iRateErrorDomain = @"iRateErrorDomain"; + + +NSString *const iRateMessageTitleKey = @"iRateMessageTitle"; +NSString *const iRateAppMessageKey = @"iRateAppMessage"; +NSString *const iRateGameMessageKey = @"iRateGameMessage"; +NSString *const iRateUpdateMessageKey = @"iRateUpdateMessage"; +NSString *const iRateCancelButtonKey = @"iRateCancelButton"; +NSString *const iRateRemindButtonKey = @"iRateRemindButton"; +NSString *const iRateRateButtonKey = @"iRateRateButton"; + +NSString *const iRateCouldNotConnectToAppStore = @"iRateCouldNotConnectToAppStore"; +NSString *const iRateDidDetectAppUpdate = @"iRateDidDetectAppUpdate"; +NSString *const iRateDidPromptForRating = @"iRateDidPromptForRating"; +NSString *const iRateUserDidAttemptToRateApp = @"iRateUserDidAttemptToRateApp"; +NSString *const iRateUserDidDeclineToRateApp = @"iRateUserDidDeclineToRateApp"; +NSString *const iRateUserDidRequestReminderToRateApp = @"iRateUserDidRequestReminderToRateApp"; +NSString *const iRateDidOpenAppStore = @"iRateDidOpenAppStore"; + +static NSString *const iRateAppStoreIDKey = @"iRateAppStoreID"; +static NSString *const iRateRatedVersionKey = @"iRateRatedVersionChecked"; +static NSString *const iRateDeclinedVersionKey = @"iRateDeclinedVersion"; +static NSString *const iRateLastRemindedKey = @"iRateLastReminded"; +static NSString *const iRateLastVersionUsedKey = @"iRateLastVersionUsed"; +static NSString *const iRateFirstUsedKey = @"iRateFirstUsed"; +static NSString *const iRateUseCountKey = @"iRateUseCount"; +static NSString *const iRateEventCountKey = @"iRateEventCount"; + +static NSString *const iRateMacAppStoreBundleID = @"com.apple.appstore"; +static NSString *const iRateAppLookupURLFormat = @"http://itunes.apple.com/%@/lookup"; + +static NSString *const iRateiOSAppStoreURLScheme = @"itms-apps"; +static NSString *const iRateiOSAppStoreURLFormat = @"itms-apps://itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=%@"; +static NSString *const iRateiOS7AppStoreURLFormat = @"itms-apps://itunes.apple.com/app/id%@"; +static NSString *const iRateMacAppStoreURLFormat = @"macappstore://itunes.apple.com/app/id%@"; + + +#define SECONDS_IN_A_DAY 86400.0 +#define SECONDS_IN_A_WEEK 604800.0 +#define MAC_APP_STORE_REFRESH_DELAY 5.0 +#define REQUEST_TIMEOUT 60.0 + + +@implementation NSObject (iRate) + +- (void)iRateCouldNotConnectToAppStore:(__unused NSError *)error {} +- (void)iRateDidDetectAppUpdate {} +- (BOOL)iRateShouldPromptForRating { return YES; } +- (void)iRateDidPromptForRating {} +- (void)iRateUserDidAttemptToRateApp {} +- (void)iRateUserDidDeclineToRateApp {} +- (void)iRateUserDidRequestReminderToRateApp {} +- (BOOL)iRateShouldOpenAppStore { return YES; } +- (void)iRateDidOpenAppStore {} + +@end + + +@interface iRate() + +@property (nonatomic, strong) id visibleAlert; +@property (nonatomic, assign) BOOL checkingForPrompt; +@property (nonatomic, assign) BOOL checkingForAppStoreID; + +@end + + +@implementation iRate + ++ (void)load +{ + [self performSelectorOnMainThread:@selector(sharedInstance) withObject:nil waitUntilDone:NO]; +} + ++ (iRate *)sharedInstance +{ + static iRate *sharedInstance = nil; + if (sharedInstance == nil) + { + sharedInstance = [[iRate alloc] init]; + } + return sharedInstance; +} + +- (NSString *)localizedStringForKey:(NSString *)key withDefault:(NSString *)defaultString +{ + static NSBundle *bundle = nil; + if (bundle == nil) + { + NSString *bundlePath = [[NSBundle mainBundle] pathForResource:@"iRate" ofType:@"bundle"]; + if (self.useAllAvailableLanguages) + { + bundle = [NSBundle bundleWithPath:bundlePath]; + NSString *language = [[NSLocale preferredLanguages] count]? [NSLocale preferredLanguages][0]: @"en"; + if (![[bundle localizations] containsObject:language]) + { + language = [language componentsSeparatedByString:@"-"][0]; + } + if ([[bundle localizations] containsObject:language]) + { + bundlePath = [bundle pathForResource:language ofType:@"lproj"]; + } + } + bundle = [NSBundle bundleWithPath:bundlePath] ?: [NSBundle mainBundle]; + } + defaultString = [bundle localizedStringForKey:key value:defaultString table:nil]; + return [[NSBundle mainBundle] localizedStringForKey:key value:defaultString table:nil]; +} + +- (iRate *)init +{ + if ((self = [super init])) + { + +#if TARGET_OS_IPHONE + + //register for iphone application events + if (&UIApplicationWillEnterForegroundNotification) + { + [[NSNotificationCenter defaultCenter] addObserver:self + selector:@selector(applicationWillEnterForeground) + name:UIApplicationWillEnterForegroundNotification + object:nil]; + } + +#endif + + //get country + self.appStoreCountry = [(NSLocale *)[NSLocale currentLocale] objectForKey:NSLocaleCountryCode]; + if ([self.appStoreCountry isEqualToString:@"150"]) + { + self.appStoreCountry = @"eu"; + } + else if ([[self.appStoreCountry stringByReplacingOccurrencesOfString:@"[A-Za-z]{2}" withString:@"" options:NSRegularExpressionSearch range:NSMakeRange(0, 2)] length]) + { + self.appStoreCountry = @"us"; + } + + //application version (use short version preferentially) + self.applicationVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"]; + if ([self.applicationVersion length] == 0) + { + self.applicationVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey]; + } + + //localised application name + self.applicationName = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleDisplayName"]; + if ([self.applicationName length] == 0) + { + self.applicationName = [[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleNameKey]; + } + + //bundle id + self.applicationBundleID = [[NSBundle mainBundle] bundleIdentifier]; + + //default settings + self.useAllAvailableLanguages = YES; + self.promptForNewVersionIfUserRated = NO; + self.onlyPromptIfLatestVersion = YES; + self.onlyPromptIfMainWindowIsAvailable = YES; + self.promptAtLaunch = YES; + self.usesUntilPrompt = 10; + self.eventsUntilPrompt = 10; + self.daysUntilPrompt = 10.0f; + self.usesPerWeekForPrompt = 0.0f; + self.remindPeriod = 1.0f; + self.verboseLogging = NO; + self.previewMode = NO; + +#if DEBUG + + //enable verbose logging in debug mode + self.verboseLogging = YES; + NSLog(@"iRate verbose logging enabled."); + +#endif + + //app launched + [self performSelectorOnMainThread:@selector(applicationLaunched) withObject:nil waitUntilDone:NO]; + } + return self; +} + +- (id)delegate +{ + if (_delegate == nil) + { + +#if TARGET_OS_IPHONE +#define APP_CLASS UIApplication +#else +#define APP_CLASS NSApplication +#endif + + _delegate = (id)[[APP_CLASS sharedApplication] delegate]; + } + return _delegate; +} + +- (NSString *)messageTitle +{ + return [_messageTitle ?: [self localizedStringForKey:iRateMessageTitleKey withDefault:@"Rate %@"] stringByReplacingOccurrencesOfString:@"%@" withString:self.applicationName]; +} + +- (NSString *)message +{ + NSString *message = _message; + if (!message) + { + message = (self.appStoreGenreID == iRateAppStoreGameGenreID)? [self localizedStringForKey:iRateGameMessageKey withDefault:@"If you enjoy playing %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!"]: [self localizedStringForKey:iRateAppMessageKey withDefault:@"If you enjoy using %@, would you mind taking a moment to rate it? It won’t take more than a minute. Thanks for your support!"]; + } + return [message stringByReplacingOccurrencesOfString:@"%@" withString:self.applicationName]; +} + +- (NSString *)updateMessage +{ + NSString *updateMessage = _updateMessage; + if (!updateMessage) + { + updateMessage = [self localizedStringForKey:iRateUpdateMessageKey withDefault:self.message]; + } + return [updateMessage stringByReplacingOccurrencesOfString:@"%@" withString:self.applicationName]; +} + +- (NSString *)cancelButtonLabel +{ + return _cancelButtonLabel ?: [self localizedStringForKey:iRateCancelButtonKey withDefault:@"No, Thanks"]; +} + +- (NSString *)rateButtonLabel +{ + return _rateButtonLabel ?: [self localizedStringForKey:iRateRateButtonKey withDefault:@"Rate It Now"]; +} + +- (NSString *)remindButtonLabel +{ + return _remindButtonLabel ?: [self localizedStringForKey:iRateRemindButtonKey withDefault:@"Remind Me Later"]; +} + +- (NSURL *)ratingsURL +{ + if (_ratingsURL) + { + return _ratingsURL; + } + + if (!self.appStoreID && self.verboseLogging) + { + NSLog(@"iRate could not find the App Store ID for this application. If the application is not intended for App Store release then you must specify a custom ratingsURL."); + } + + NSString *URLString; + +#if TARGET_OS_IPHONE + + float iOSVersion = [[UIDevice currentDevice].systemVersion floatValue]; + if (iOSVersion >= 7.0f && iOSVersion < 7.1f) + { + URLString = iRateiOS7AppStoreURLFormat; + } + else + { + URLString = iRateiOSAppStoreURLFormat; + } + +#else + + URLString = iRateMacAppStoreURLFormat; + +#endif + + return [NSURL URLWithString:[NSString stringWithFormat:URLString, @(self.appStoreID)]]; + +} + +- (NSUInteger)appStoreID +{ + return _appStoreID ?: [[[NSUserDefaults standardUserDefaults] objectForKey:iRateAppStoreIDKey] unsignedIntegerValue]; +} + +- (NSDate *)firstUsed +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:iRateFirstUsedKey]; +} + +- (void)setFirstUsed:(NSDate *)date +{ + [[NSUserDefaults standardUserDefaults] setObject:date forKey:iRateFirstUsedKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSDate *)lastReminded +{ + return [[NSUserDefaults standardUserDefaults] objectForKey:iRateLastRemindedKey]; +} + +- (void)setLastReminded:(NSDate *)date +{ + [[NSUserDefaults standardUserDefaults] setObject:date forKey:iRateLastRemindedKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSUInteger)usesCount +{ + return [[NSUserDefaults standardUserDefaults] integerForKey:iRateUseCountKey]; +} + +- (void)setUsesCount:(NSUInteger)count +{ + [[NSUserDefaults standardUserDefaults] setInteger:(NSInteger)count forKey:iRateUseCountKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (NSUInteger)eventCount +{ + return [[NSUserDefaults standardUserDefaults] integerForKey:iRateEventCountKey]; +} + +- (void)setEventCount:(NSUInteger)count +{ + [[NSUserDefaults standardUserDefaults] setInteger:(NSInteger)count forKey:iRateEventCountKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (float)usesPerWeek +{ + return (float)self.usesCount / ([[NSDate date] timeIntervalSinceDate:self.firstUsed] / SECONDS_IN_A_WEEK); +} + +- (BOOL)declinedThisVersion +{ + return [[[NSUserDefaults standardUserDefaults] objectForKey:iRateDeclinedVersionKey] isEqualToString:self.applicationVersion]; +} + +- (void)setDeclinedThisVersion:(BOOL)declined +{ + [[NSUserDefaults standardUserDefaults] setObject:(declined? self.applicationVersion: nil) forKey:iRateDeclinedVersionKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (BOOL)declinedAnyVersion +{ + return [(NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:iRateDeclinedVersionKey] length] != 0; +} + +- (BOOL)ratedVersion:(NSString *)version +{ + return [[[NSUserDefaults standardUserDefaults] objectForKey:iRateRatedVersionKey] isEqualToString:version]; +} + +- (BOOL)ratedThisVersion +{ + return [self ratedVersion:self.applicationVersion]; +} + +- (void)setRatedThisVersion:(BOOL)rated +{ + [[NSUserDefaults standardUserDefaults] setObject:(rated? self.applicationVersion: nil) forKey:iRateRatedVersionKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (BOOL)ratedAnyVersion +{ + return [(NSString *)[[NSUserDefaults standardUserDefaults] objectForKey:iRateRatedVersionKey] length] != 0; +} + +- (void)dealloc +{ + [[NSNotificationCenter defaultCenter] removeObserver:self]; +} + +- (void)incrementUseCount +{ + self.usesCount ++; +} + +- (void)incrementEventCount +{ + self.eventCount ++; +} + +- (BOOL)shouldPromptForRating +{ + //preview mode? + if (self.previewMode) + { + NSLog(@"iRate preview mode is enabled - make sure you disable this for release"); + return YES; + } + + //check if we've rated this version + else if (self.ratedThisVersion) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the user has already rated this version"); + } + return NO; + } + + //check if we've rated any version + else if (self.ratedAnyVersion && !self.promptForNewVersionIfUserRated) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the user has already rated this app, and promptForNewVersionIfUserRated is disabled"); + } + return NO; + } + + //check if we've declined to rate the app + else if (self.declinedAnyVersion) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the user has declined to rate the app"); + } + return NO; + } + + //check how long we've been using this version + else if ([[NSDate date] timeIntervalSinceDate:self.firstUsed] < self.daysUntilPrompt * SECONDS_IN_A_DAY) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the app was first used less than %g days ago", self.daysUntilPrompt); + } + return NO; + } + + //check how many times we've used it and the number of significant events + else if (self.usesCount < self.usesUntilPrompt && self.eventCount < self.eventsUntilPrompt) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the app has only been used %@ times and only %@ events have been logged", @(self.usesCount), @(self.eventCount)); + } + return NO; + } + + //check if usage frequency is high enough + else if (self.usesPerWeek < self.usesPerWeekForPrompt) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the app has only been used %g times per week on average since it was installed", self.usesPerWeek); + } + return NO; + } + + //check if within the reminder period + else if (self.lastReminded != nil && [[NSDate date] timeIntervalSinceDate:self.lastReminded] < self.remindPeriod * SECONDS_IN_A_DAY) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not prompt for rating because the user last asked to be reminded less than %g days ago", self.remindPeriod); + } + return NO; + } + + //lets prompt! + return YES; +} + +- (NSString *)valueForKey:(NSString *)key inJSON:(id)json +{ + if ([json isKindOfClass:[NSString class]]) + { + //use legacy parser + NSRange keyRange = [json rangeOfString:[NSString stringWithFormat:@"\"%@\"", key]]; + if (keyRange.location != NSNotFound) + { + NSInteger start = keyRange.location + keyRange.length; + NSRange valueStart = [json rangeOfString:@":" options:(NSStringCompareOptions)0 range:NSMakeRange(start, [(NSString *)json length] - start)]; + if (valueStart.location != NSNotFound) + { + start = valueStart.location + 1; + NSRange valueEnd = [json rangeOfString:@"," options:(NSStringCompareOptions)0 range:NSMakeRange(start, [(NSString *)json length] - start)]; + if (valueEnd.location != NSNotFound) + { + NSString *value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)]; + value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + while ([value hasPrefix:@"\""] && ![value hasSuffix:@"\""]) + { + if (valueEnd.location == NSNotFound) + { + break; + } + NSInteger newStart = valueEnd.location + 1; + valueEnd = [json rangeOfString:@"," options:(NSStringCompareOptions)0 range:NSMakeRange(newStart, [(NSString *)json length] - newStart)]; + value = [json substringWithRange:NSMakeRange(start, valueEnd.location - start)]; + value = [value stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; + } + + value = [value stringByTrimmingCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:@"\""]]; + value = [value stringByReplacingOccurrencesOfString:@"\\\\" withString:@"\\"]; + value = [value stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; + value = [value stringByReplacingOccurrencesOfString:@"\\\"" withString:@"\""]; + value = [value stringByReplacingOccurrencesOfString:@"\\n" withString:@"\n"]; + value = [value stringByReplacingOccurrencesOfString:@"\\r" withString:@"\r"]; + value = [value stringByReplacingOccurrencesOfString:@"\\t" withString:@"\t"]; + value = [value stringByReplacingOccurrencesOfString:@"\\f" withString:@"\f"]; + value = [value stringByReplacingOccurrencesOfString:@"\\b" withString:@"\f"]; + + while (YES) + { + NSRange unicode = [value rangeOfString:@"\\u"]; + if (unicode.location == NSNotFound || unicode.location + unicode.length == 0) + { + break; + } + + uint32_t c = 0; + NSString *hex = [value substringWithRange:NSMakeRange(unicode.location + 2, 4)]; + NSScanner *scanner = [NSScanner scannerWithString:hex]; + [scanner scanHexInt:&c]; + + if (c <= 0xffff) + { + value = [value stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6) withString:[NSString stringWithFormat:@"%C", (unichar)c]]; + } + else + { + //convert character to surrogate pair + uint16_t x = (uint16_t)c; + uint16_t u = (c >> 16) & ((1 << 5) - 1); + uint16_t w = (uint16_t)u - 1; + unichar high = 0xd800 | (w << 6) | x >> 10; + unichar low = (uint16_t)(0xdc00 | (x & ((1 << 10) - 1))); + + value = [value stringByReplacingCharactersInRange:NSMakeRange(unicode.location, 6) withString:[NSString stringWithFormat:@"%C%C", high, low]]; + } + } + return value; + } + } + } + } + else + { + return json[key]; + } + return nil; +} + +- (void)setAppStoreIDOnMainThread:(NSString *)appStoreIDString +{ + _appStoreID = [appStoreIDString integerValue]; + [[NSUserDefaults standardUserDefaults] setInteger:_appStoreID forKey:iRateAppStoreIDKey]; + [[NSUserDefaults standardUserDefaults] synchronize]; +} + +- (void)connectionSucceeded +{ + if (self.checkingForAppStoreID) + { + //no longer checking + self.checkingForPrompt = NO; + self.checkingForAppStoreID = NO; + + //open app store + [self openRatingsPageInAppStore]; + } + else if (self.checkingForPrompt) + { + //no longer checking + self.checkingForPrompt = NO; + + //confirm with delegate + if (![self.delegate iRateShouldPromptForRating]) + { + if (self.verboseLogging) + { + NSLog(@"iRate did not display the rating prompt because the iRateShouldPromptForRating delegate method returned NO"); + } + return; + } + + //prompt user + [self promptForRating]; + } +} + +- (void)connectionError:(NSError *)error +{ + if (self.checkingForPrompt || self.checkingForAppStoreID) + { + //no longer checking + self.checkingForPrompt = NO; + self.checkingForAppStoreID = NO; + + //log the error + if (error) + { + NSLog(@"iRate rating process failed because: %@", [error localizedDescription]); + } + else + { + NSLog(@"iRate rating process failed because an unknown error occured"); + } + + //could not connect + [self.delegate iRateCouldNotConnectToAppStore:error]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateCouldNotConnectToAppStore + object:error]; + } +} + +- (void)checkForConnectivityInBackground +{ + if ([NSThread isMainThread]) + { + [self performSelectorInBackground:@selector(checkForConnectivityInBackground) withObject:nil]; + return; + } + + @autoreleasepool + { + //prevent concurrent checks + static BOOL checking = NO; + if (checking) return; + checking = YES; + + //first check iTunes + NSString *iTunesServiceURL = [NSString stringWithFormat:iRateAppLookupURLFormat, self.appStoreCountry]; + if (_appStoreID) //important that we check ivar and not getter in case it has changed + { + iTunesServiceURL = [iTunesServiceURL stringByAppendingFormat:@"?id=%@", @(_appStoreID)]; + } + else + { + iTunesServiceURL = [iTunesServiceURL stringByAppendingFormat:@"?bundleId=%@", self.applicationBundleID]; + } + + if (self.verboseLogging) + { + NSLog(@"iRate is checking %@ to retrieve the App Store details...", iTunesServiceURL); + } + + NSError *error = nil; + NSURLResponse *response = nil; + NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:iTunesServiceURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:REQUEST_TIMEOUT]; + NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&error]; + NSInteger statusCode = ((NSHTTPURLResponse *)response).statusCode; + if (data && statusCode == 200) + { + //in case error is garbage... + error = nil; + + id json = nil; + if ([NSJSONSerialization class]) + { + json = [[NSJSONSerialization JSONObjectWithData:data options:(NSJSONReadingOptions)0 error:&error][@"results"] lastObject]; + } + else + { + //convert to string + json = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; + } + + if (!error) + { + //check bundle ID matches + NSString *bundleID = [self valueForKey:@"bundleId" inJSON:json]; + if (bundleID) + { + if ([bundleID isEqualToString:self.applicationBundleID]) + { + //get genre + if (self.appStoreGenreID == 0) + { + self.appStoreGenreID = [[self valueForKey:@"primaryGenreId" inJSON:json] integerValue]; + } + + //get app id + if (!_appStoreID) + { + NSString *appStoreIDString = [self valueForKey:@"trackId" inJSON:json]; + [self performSelectorOnMainThread:@selector(setAppStoreIDOnMainThread:) withObject:appStoreIDString waitUntilDone:YES]; + + if (self.verboseLogging) + { + NSLog(@"iRate found the app on iTunes. The App Store ID is %@", appStoreIDString); + } + } + + //check version + if (self.onlyPromptIfLatestVersion && !self.previewMode) + { + NSString *latestVersion = [self valueForKey:@"version" inJSON:json]; + if ([latestVersion compare:self.applicationVersion options:NSNumericSearch] == NSOrderedDescending) + { + if (self.verboseLogging) + { + NSLog(@"iRate found that the installed application version (%@) is not the latest version on the App Store, which is %@", self.applicationVersion, latestVersion); + } + + error = [NSError errorWithDomain:iRateErrorDomain code:iRateErrorApplicationIsNotLatestVersion userInfo:@{NSLocalizedDescriptionKey: @"Installed app is not the latest version available"}]; + } + } + } + else + { + if (self.verboseLogging) + { + NSLog(@"iRate found that the application bundle ID (%@) does not match the bundle ID of the app found on iTunes (%@) with the specified App Store ID (%@)", self.applicationBundleID, bundleID, @(self.appStoreID)); + } + + error = [NSError errorWithDomain:iRateErrorDomain code:iRateErrorBundleIdDoesNotMatchAppStore userInfo:@{NSLocalizedDescriptionKey: [NSString stringWithFormat:@"Application bundle ID does not match expected value of %@", bundleID]}]; + } + } + else if (_appStoreID || !self.ratingsURL) + { + if (self.verboseLogging) + { + NSLog(@"iRate could not find this application on iTunes. If your app is not intended for App Store release then you must specify a custom ratingsURL. If this is the first release of your application then it's not a problem that it cannot be found on the store yet"); + } + if (!self.previewMode) + { + error = [NSError errorWithDomain:iRateErrorDomain + code:iRateErrorApplicationNotFoundOnAppStore + userInfo:@{NSLocalizedDescriptionKey: @"The application could not be found on the App Store."}]; + } + } + else if (!_appStoreID && self.verboseLogging) + { + NSLog(@"iRate could not find your app on iTunes. If your app is not yet on the store or is not intended for App Store release then don't worry about this"); + } + } + } + else if (statusCode >= 400) + { + //http error + NSString *message = [NSString stringWithFormat:@"The server returned a %@ error", @(statusCode)]; + error = [NSError errorWithDomain:@"HTTPResponseErrorDomain" code:statusCode userInfo:@{NSLocalizedDescriptionKey: message}]; + } + + //handle errors (ignoring sandbox issues) + if (error && !(error.code == EPERM && [error.domain isEqualToString:NSPOSIXErrorDomain] && _appStoreID)) + { + [self performSelectorOnMainThread:@selector(connectionError:) withObject:error waitUntilDone:YES]; + } + else if (self.appStoreID || self.previewMode) + { + //show prompt + [self performSelectorOnMainThread:@selector(connectionSucceeded) withObject:nil waitUntilDone:YES]; + } + + //finished + checking = NO; + } +} + +- (void)promptIfNetworkAvailable +{ + if (!self.checkingForPrompt && !self.checkingForAppStoreID) + { + self.checkingForPrompt = YES; + [self checkForConnectivityInBackground]; + } +} + +- (void)promptIfAllCriteriaMet +{ + if ([self shouldPromptForRating]) + { + [self promptIfNetworkAvailable]; + } +} + +- (BOOL)showRemindButton +{ + return [self.remindButtonLabel length]; +} + +- (BOOL)showCancelButton +{ + return [self.cancelButtonLabel length]; +} + +- (void)promptForRating +{ + if (!self.visibleAlert) + { + NSString *message = self.ratedAnyVersion? self.updateMessage: self.message; + +#if TARGET_OS_IPHONE + + UIViewController *topController = [UIApplication sharedApplication].delegate.window.rootViewController; + while (topController.presentedViewController) + { + topController = topController.presentedViewController; + } + + if ([UIAlertController class] && topController && self.useUIAlertControllerIfAvailable) + { + UIAlertController *alert = [UIAlertController alertControllerWithTitle:self.messageTitle message:message preferredStyle:UIAlertControllerStyleAlert]; + + //rate action + [alert addAction:[UIAlertAction actionWithTitle:self.rateButtonLabel style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) { + [self didDismissAlert:alert withButtonAtIndex:0]; + }]]; + + //cancel action + if ([self showCancelButton]) + { + [alert addAction:[UIAlertAction actionWithTitle:self.cancelButtonLabel style:UIAlertActionStyleCancel handler:^(__unused UIAlertAction *action) { + [self didDismissAlert:alert withButtonAtIndex:1]; + }]]; + } + + //remind action + if ([self showRemindButton]) + { + [alert addAction:[UIAlertAction actionWithTitle:self.remindButtonLabel style:UIAlertActionStyleDefault handler:^(__unused UIAlertAction *action) { + [self didDismissAlert:alert withButtonAtIndex:[self showCancelButton]? 2: 1]; + }]]; + } + + self.visibleAlert = alert; + + //get current view controller and present alert + [topController presentViewController:alert animated:YES completion:NULL]; + } + else + { + UIAlertView *alert = [[UIAlertView alloc] initWithTitle:self.messageTitle + message:message + delegate:(id)self + cancelButtonTitle:nil + otherButtonTitles:self.rateButtonLabel, nil]; + if ([self showCancelButton]) + { + [alert addButtonWithTitle:self.cancelButtonLabel]; + alert.cancelButtonIndex = 1; + } + + if ([self showRemindButton]) + { + [alert addButtonWithTitle:self.remindButtonLabel]; + } + + self.visibleAlert = alert; + [self.visibleAlert show]; + } + +#else + + //only show when main window is available + if (self.onlyPromptIfMainWindowIsAvailable && ![[NSApplication sharedApplication] mainWindow]) + { + [self performSelector:@selector(promptForRating) withObject:nil afterDelay:0.5]; + return; + } + + NSAlert *alert = [[NSAlert alloc] init]; + alert.messageText = self.messageTitle; + alert.informativeText = message; + [alert addButtonWithTitle:self.rateButtonLabel]; + if ([self showCancelButton]) + { + [alert addButtonWithTitle:self.cancelButtonLabel]; + } + if ([self showRemindButton]) + { + [alert addButtonWithTitle:self.remindButtonLabel]; + } + + self.visibleAlert = alert; + +#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_9 + + if (![alert respondsToSelector:@selector(beginSheetModalForWindow:completionHandler:)]) + { + [alert beginSheetModalForWindow:[NSApplication sharedApplication].mainWindow + modalDelegate:self + didEndSelector:@selector(alertDidEnd:returnCode:contextInfo:) + contextInfo:nil]; + } + else + +#endif + + { + [alert beginSheetModalForWindow:[NSApplication sharedApplication].mainWindow completionHandler:^(NSModalResponse returnCode) { + [self didDismissAlert:alert withButtonAtIndex:returnCode - NSAlertFirstButtonReturn]; + }]; + } + +#endif + + //inform about prompt + [self.delegate iRateDidPromptForRating]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidPromptForRating + object:nil]; + } +} + +- (void)applicationLaunched +{ + //check if this is a new version + NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; + NSString *lastUsedVersion = [defaults objectForKey:iRateLastVersionUsedKey]; + if (!self.firstUsed || ![lastUsedVersion isEqualToString:self.applicationVersion]) + { + [defaults setObject:self.applicationVersion forKey:iRateLastVersionUsedKey]; + if (!self.firstUsed || [self ratedAnyVersion]) + { + //reset defaults + [defaults setObject:[NSDate date] forKey:iRateFirstUsedKey]; + [defaults setInteger:0 forKey:iRateUseCountKey]; + [defaults setInteger:0 forKey:iRateEventCountKey]; + [defaults setObject:nil forKey:iRateLastRemindedKey]; + [defaults synchronize]; + } + else if ([[NSDate date] timeIntervalSinceDate:self.firstUsed] > (self.daysUntilPrompt - 1) * SECONDS_IN_A_DAY) + { + //if was previously installed, but we haven't yet prompted for a rating + //don't reset, but make sure it won't rate for a day at least + self.firstUsed = [[NSDate date] dateByAddingTimeInterval:(self.daysUntilPrompt - 1) * -SECONDS_IN_A_DAY]; + } + + //inform about app update + [self.delegate iRateDidDetectAppUpdate]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidDetectAppUpdate + object:nil]; + } + + [self incrementUseCount]; + [self checkForConnectivityInBackground]; + if (self.promptAtLaunch) + { + [self promptIfAllCriteriaMet]; + } +} + +- (void)didDismissAlert:(__unused id)alertView withButtonAtIndex:(NSInteger)buttonIndex +{ + //get button indices + NSInteger rateButtonIndex = 0; + NSInteger cancelButtonIndex = [self showCancelButton]? 1: 0; + NSInteger remindButtonIndex = [self showRemindButton]? cancelButtonIndex + 1: 0; + + if (buttonIndex == rateButtonIndex) + { + [self rate]; + } + else if (buttonIndex == cancelButtonIndex) + { + [self declineThisVersion]; + } + else if (buttonIndex == remindButtonIndex) + { + [self remindLater]; + } + + //release alert + self.visibleAlert = nil; +} + +#if TARGET_OS_IPHONE + +- (void)applicationWillEnterForeground +{ + if ([UIApplication sharedApplication].applicationState == UIApplicationStateBackground) + { + [self incrementUseCount]; + [self checkForConnectivityInBackground]; + if (self.promptAtLaunch) + { + [self promptIfAllCriteriaMet]; + } + } +} + +- (void)openRatingsPageInAppStore +{ + if (!_ratingsURL && !self.appStoreID) + { + self.checkingForAppStoreID = YES; + if (!self.checkingForPrompt) + { + [self checkForConnectivityInBackground]; + } + return; + } + + if ([[UIApplication sharedApplication] canOpenURL:self.ratingsURL]) + { + if (self.verboseLogging) + { + NSLog(@"iRate will open the App Store ratings page using the following URL: %@", self.ratingsURL); + } + + [[UIApplication sharedApplication] openURL:self.ratingsURL]; + [self.delegate iRateDidOpenAppStore]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateDidOpenAppStore + object:nil]; + } + else + { + NSString *message = [NSString stringWithFormat:@"iRate was unable to open the specified ratings URL: %@", self.ratingsURL]; + +#if TARGET_IPHONE_SIMULATOR + + if ([[self.ratingsURL scheme] isEqualToString:iRateiOSAppStoreURLScheme]) + { + message = @"iRate could not open the ratings page because the App Store is not available on the iOS simulator"; + } + +#endif + NSLog(@"%@", message); + NSError *error = [NSError errorWithDomain:iRateErrorDomain code:iRateErrorCouldNotOpenRatingPageURL userInfo:@{NSLocalizedDescriptionKey: message}]; + [self.delegate iRateCouldNotConnectToAppStore:error]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateCouldNotConnectToAppStore + object:error]; + } +} + +- (void)alertView:(UIAlertView *)alertView didDismissWithButtonIndex:(NSInteger)buttonIndex +{ + [self didDismissAlert:alertView withButtonAtIndex:buttonIndex]; +} + +#else + +- (void)openAppPageWhenAppStoreLaunched +{ + //check if app store is running + for (NSRunningApplication *app in [[NSWorkspace sharedWorkspace] runningApplications]) + { + if ([app.bundleIdentifier isEqualToString:iRateMacAppStoreBundleID]) + { + //open app page + [[NSWorkspace sharedWorkspace] performSelector:@selector(openURL:) withObject:self.ratingsURL afterDelay:MAC_APP_STORE_REFRESH_DELAY]; + return; + } + } + + //try again + [self performSelector:@selector(openAppPageWhenAppStoreLaunched) withObject:nil afterDelay:0.0]; +} + +- (void)openRatingsPageInAppStore +{ + if (!_ratingsURL && !self.appStoreID) + { + self.checkingForAppStoreID = YES; + if (!self.checkingForPrompt) + { + [self checkForConnectivityInBackground]; + } + return; + } + + if (self.verboseLogging) + { + NSLog(@"iRate will open the App Store ratings page using the following URL: %@", self.ratingsURL); + } + + [[NSWorkspace sharedWorkspace] openURL:self.ratingsURL]; + [self openAppPageWhenAppStoreLaunched]; + [self.delegate iRateDidOpenAppStore]; +} + +- (void)alertDidEnd:(NSAlert *)alert returnCode:(NSInteger)returnCode contextInfo:(__unused void *)contextInfo +{ + [self didDismissAlert:alert withButtonAtIndex:returnCode - NSAlertFirstButtonReturn]; +} + +#endif + +- (void)logEvent:(BOOL)deferPrompt +{ + [self incrementEventCount]; + if (!deferPrompt) + { + [self promptIfAllCriteriaMet]; + } +} + +#pragma mark - User's actions + +- (void)declineThisVersion +{ + //ignore this version + self.declinedThisVersion = YES; + + //log event + [self.delegate iRateUserDidDeclineToRateApp]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidDeclineToRateApp + object:nil]; +} + +- (void)remindLater +{ + //remind later + self.lastReminded = [NSDate date]; + + //log event + [self.delegate iRateUserDidRequestReminderToRateApp]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidRequestReminderToRateApp + object:nil]; +} + +- (void)rate +{ + //mark as rated + self.ratedThisVersion = YES; + + //log event + [self.delegate iRateUserDidAttemptToRateApp]; + [[NSNotificationCenter defaultCenter] postNotificationName:iRateUserDidAttemptToRateApp + object:nil]; + + if ([self.delegate iRateShouldOpenAppStore]) + { + //launch mac app store + [self openRatingsPageInAppStore]; + } +} + +@end diff --git a/iOSStudyJsonData/blogs.json b/iOSStudyJsonData/blogs.json index 99d8a03..d89a407 100644 --- a/iOSStudyJsonData/blogs.json +++ b/iOSStudyJsonData/blogs.json @@ -1,75 +1 @@ - [ - { - "name": "破船之家", - "title": "破船之家的技术博客", - "subTitle": "去留无意,漫随天外云卷云舒", - "image": "https://avatars1.githubusercontent.com/u/3365146?v=3&s=460", - "url": "http://beyondvincent.com/", - "rssUrl": "http://beyondvincent.com/atom.xml", - "date": "2015-01-30 17:08:03" - }, - { - "name": "唐巧", - "title": "唐巧的技术博客", - "subTitle": "唐巧的技术博客记录下自己学习的点滴", - "image": "http://blog.devtang.com/images/weixin-qr.jpg", - "url": "http://blog.devtang.com", - "rssUrl": "http://blog.devtang.com/atom.xml", - "date": "2015-01-30 17:08:03" - }, - { - "name": "OneV's Den", - "title": "OneV's Den的技术博客", - "subTitle": "嗨,我是王巍 (@onevcat),一名来自中国的 iOS / Unity 开发者。现居日本,就职于 LINE。正在修行,探求创意之源。", - "image": "http://onevcat.com/content/images/2014/May/200.jpg", - "url": "http://onevcat.com/", - "rssUrl": "http://onevcat.com/rss/", - "date": "2015-01-30 17:08:03" - }, - { - "name": "Limboy", - "title": "Limboy的技术博客", - "subTitle": "对Web开发的各方面都比较熟悉,后将重心转移到iOS领域。2012年离开知乎后,与几个知乎员工一起做起了「Legend33 Studio」,在其中主要负责iOS开发,同时也参与产品/创意。首款作品「Once Touch」反响还不错,也被ifanr报道过,从此与iOS结缘。", - "image": "https://avatars2.githubusercontent.com/u/35974?v=3&s=460", - "url": "http://limboy.me/", - "rssUrl": "http://feeds.feedburner.com/lzyy", - "date": "2015-01-30 17:08:03" - }, - { - "name": "刘坤", - "title": "刘坤的技术博客", - "subTitle": "嗨,我是刘坤,一名来自中国的 IOS 开发者,现就职于杭州阿里,花名‘念纪’,沉淀技术,寻求创意", - "image": "http://blog.cnbluebox.com/images/face_liukun.jpeg", - "url": "http://blog.cnbluebox.com/", - "rssUrl": "http://blog.cnbluebox.com/atom.xml", - "date": "2015-01-30 17:08:03" - }, - { - "name": "叶孤城___", - "title": "叶孤城___", - "subTitle": "ios开发者。Vim学习中", - "image": "http://tp1.sinaimg.cn/1438670852/180/5695641016/1", - "url": "http://www.jianshu.com/users/b82d2721ba07/latest_articles", - "rssUrl": "http://www.jianshu.com/users/b82d2721ba07/latest_articles", - "date": "2015-01-30 17:08:03" - - }, - { - "name": "王轲", - "title": "王轲的技术博客", - "subTitle": "王轲, IndieBros Studio 创始人, 优秀的 iOS 开发工程师, 写的文章深入浅出, 很多问题分析透彻, 非常有条理性", - "image": "http://www.iwangke.me/img/GithubForMacIcon.png", - "url": "http://www.iwangke.me/", - "rssUrl": "http://www.iwangke.me/atom.xml", - "date": "2015-01-30 17:08:03" - }, - { - "name": "txx's blog", - "title": "txx's blog", - "subTitle": "90 后 iOS 开发者, 人称虾神, 文章内容讲解大多浅白易懂, 很值得看", - "image": "http://www.iwangke.me/img/GithubForMacIcon.png", - "url": "http://blog.txx.im/", - "rssUrl": "http://blog.txx.im/atom.xml", - "date": "2015-01-30 17:08:03" - } - ] \ No newline at end of file +{"version":"5","bloglists":[{"name":"破船之家","title":"破船之家的技术博客","subTitle":"去留无意,漫随天外云卷云舒","image":"https://avatars1.githubusercontent.com/u/3365146?v\u003d3\u0026s\u003d460","url":"http://beyondvincent.com/","rssUrl":"http://beyondvincent.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"唐巧","title":"唐巧的技术博客","subTitle":"唐巧的技术博客记录下自己学习的点滴","image":"http://blog.devtang.com/images/weixin-qr.jpg","url":"http://blog.devtang.com","rssUrl":"http://blog.devtang.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"OneV\u0027s Den","title":"OneV\u0027s Den的技术博客","subTitle":"嗨,我是王巍 (@onevcat),一名来自中国的 iOS / Unity 开发者。现居日本,就职于 LINE。正在修行,探求创意之源。","image":"http://onevcat.com/content/images/2014/May/200.jpg","url":"http://onevcat.com/","rssUrl":"http://onevcat.com/rss/","date":"2015-01-30 17:08:03"},{"name":"Limboy","title":"Limboy的技术博客","subTitle":"对Web开发的各方面都比较熟悉,后将重心转移到iOS领域。2012年离开知乎后,与几个知乎员工一起做起了「Legend33 Studio」,在其中主要负责iOS开发,同时也参与产品/创意。首款作品「Once Touch」反响还不错,也被ifanr报道过,从此与iOS结缘。","image":"https://avatars2.githubusercontent.com/u/35974?v\u003d3\u0026s\u003d460","url":"http://limboy.me/","rssUrl":"http://feeds.feedburner.com/lzyy","date":"2015-01-30 17:08:03"},{"name":"刘坤","title":"刘坤的技术博客","subTitle":"嗨,我是刘坤,一名来自中国的 IOS 开发者,现就职于杭州阿里,花名‘念纪’,沉淀技术,寻求创意","image":"http://blog.cnbluebox.com/images/face_liukun.jpeg","url":"http://blog.cnbluebox.com/","rssUrl":"http://blog.cnbluebox.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"叶孤城___","title":"叶孤城___","subTitle":"ios开发者。Vim学习中","image":"http://tp1.sinaimg.cn/1438670852/180/5695641016/1","url":"http://www.jianshu.com/users/b82d2721ba07/latest_articles","rssUrl":"http://www.jianshu.com/users/b82d2721ba07/latest_articles","date":"2015-01-30 17:08:03"},{"name":"王轲","title":"王轲的技术博客","subTitle":"王轲, IndieBros Studio 创始人, 优秀的 iOS 开发工程师, 写的文章深入浅出, 很多问题分析透彻, 非常有条理性","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://www.iwangke.me/","rssUrl":"http://www.iwangke.me/atom.xml","date":"2015-01-30 17:08:03"},{"name":"txx\u0027s blog","title":"txx\u0027s blog","subTitle":"90 后 iOS 开发者, 人称虾神, 文章内容讲解大多浅白易懂, 很值得看","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://blog.txx.im/","rssUrl":"http://blog.txx.im/atom.xml","date":"2015-01-30 17:08:03"},{"name":"岁寒","title":"岁寒","subTitle":"Web 程序员,PHP 框架 TinyLara 作者。iOS \u0026 OS X 开发者。","image":"http://lvwenhan.com/content/templates/HappyCodding/images/logo.png","url":"http://lvwenhan.com/sort/ios","rssUrl":"http://lvwenhan.com/sort/ios","date":"2015-01-30 17:08:03"},{"name":"http://itjoy.org/","title":"http://itjoy.org/","subTitle":"http://itjoy.org/","image":"http://tp2.sinaimg.cn/2663764813/180/40006387168/1","url":"http://itjoy.org/","rssUrl":"http://itjoy.org/","date":"2015-01-30 17:08:03"},{"name":"GoWhich","title":"GoWhich/","subTitle":"想你所想,做你所做,认真对待你的人生...","image":"https://avatars0.githubusercontent.com/u/1449203?v\u003d3\u0026s\u003d460","url":"http://www.gowhich.com/category/IOS","rssUrl":"http://www.gowhich.com/category/IOS","date":"2015-01-30 17:08:03"},{"name":"Kitten\u0027s 时间胶囊","title":"Kitten\u0027s 时间胶囊","subTitle":"你好,我是杨骑滔(KittenYang)。目前是一个学生,同时也是一名忠诚的iOS开发者。喜欢音乐,喜欢设计,喜欢一切让人产生美好感觉的事物。一直践行理性、自由的生活方式。","image":"http://kittenyang.com/content/images/2014/Sep/200-200-3.png","url":"http://kittenyang.com/","rssUrl":"http://kittenyang.com/rss/","date":"2015-01-30 17:08:03"},{"name":"Peter Steinberger","title":"Peter Steinberger","subTitle":"Peter Steinberger创立了个人博客,里面有丰富的上乘程序编辑素材以及程序排错资源,供开发者学习和应用。为Dropbox和EverNote等应用所用的热门iOS商用PDF文件库也是出自他之手。","image":"https://avatars0.githubusercontent.com/u/58493?v\u003d3\u0026s\u003d460","url":"http://petersteinberger.com/","rssUrl":"http://petersteinberger.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"念茜的博客","title":"念茜的博客","subTitle":"Going against the wind is more suitable for flying","image":"http://nianxi.net/favicon.png","url":"http://nianxi.net/","rssUrl":"http://nianxi.net/","date":"2015-01-30 17:08:03"},{"name":"Xcode Dev","title":"Xcode Dev","subTitle":"亮了的原创开发技术博客","image":"http://blog.xcodev.com/favicon.png","url":"http://blog.xcodev.com/","rssUrl":"http://blog.xcodev.com/atom.xml","date":"2015-01-30 17:08:03"},{"name":"Kevin Blog","title":"Kevin Blog","subTitle":"Thoughts, stories and ideas.","image":"http://blog.zhowkev.in/content/images/2015/04/image.jpg","url":"http://blog.zhowkev.in/","rssUrl":"http://blog.zhowkev.in/","date":"2015-01-30 17:08:03"},{"name":"阿毛的蛋疼地 ","title":"阿毛的蛋疼地 ","subTitle":"阿毛的蛋疼地 ","image":"http://xiangwangfeng.com/public/apple-touch-icon-precomposed.png","url":"http://xiangwangfeng.com/","rssUrl":"http://xiangwangfeng.com/","date":"2015-01-30 17:08:03"},{"name":"Nonomori - Let monkeys coding for iOS","title":"Nonomori - Let monkeys coding for iOS","subTitle":"Nonomori - Let monkeys coding for iOS","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://nonomori.farbox.com/","rssUrl":"http://nonomori.farbox.com/","date":"2015-01-30 17:08:03"},{"name":"亚庆的 Blog","title":"About life, about knowledge, about happiness!","subTitle":"About life, about knowledge, about happiness!","image":"http://www.iwangke.me/img/GithubForMacIcon.png","url":"http://billwang1990.github.io/","rssUrl":"http://billwang1990.github.io/","date":"2015-01-30 17:08:03"},{"name":"NICO","title":"喜欢技术,喜欢音乐。写过J2me、android,现在做iOS。无聊时打打游戏,听听音乐,弹弹吉他。","subTitle":"喜欢技术,喜欢音乐。写过J2me、android,现在做iOS。无聊时打打游戏,听听音乐,弹弹吉他。","image":"https://avatars2.githubusercontent.com/u/1461390?v\u003d3\u0026s\u003d460","url":"http://blog.inico.me/","rssUrl":"http://blog.inico.me/","date":"2015-01-30 17:08:03"},{"name":"Haven\u0027s Blog","title":"Haven\u0027s Blog","subTitle":"博客很好就是打开速度有点慢,关于storyboard有所讲解","image":"http://www.ifun.cc/images/profile.png","url":"http://www.ifun.cc/blog/archives/","rssUrl":"http://www.ifun.cc/blog/archives/","date":"2015-01-30 17:08:03"},{"name":"雷纯锋的技术博客","title":"雷纯锋的技术博客","subTitle":"现在主要在讲OC RunTime,非常棒的博客值得一看","image":"http://blog.leichunfeng.com/images/qrcode.jpg","url":"http://blog.leichunfeng.com/blog/archives/","rssUrl":"http://blog.leichunfeng.com/blog/archives/","date":"2015-01-30 17:08:03"}]} \ No newline at end of file diff --git a/iOSStudyJsonData/versions.json b/iOSStudyJsonData/versions.json index 925ed7b..7470d6a 100644 --- a/iOSStudyJsonData/versions.json +++ b/iOSStudyJsonData/versions.json @@ -1,2 +1 @@ -[{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/blogs.json","urlVersion":"1"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/webs.json","urlVersion":"1"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/master/iOSStudyJsonData/videos.json","urlVersion":"1"}] - +[{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/blogs.json","urlVersion":"5"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/webs.json","urlVersion":"4"},{"url":"https://raw.githubusercontent.com/chenguandong/iOSStudy/CoreDataJoin/iOSStudyJsonData/videos.json","urlVersion":"3"}] \ No newline at end of file diff --git a/iOSStudyJsonData/videos.json b/iOSStudyJsonData/videos.json index c59e8f4..2ceaa5f 100644 --- a/iOSStudyJsonData/videos.json +++ b/iOSStudyJsonData/videos.json @@ -1,2 +1 @@ -[{"videoLanguageType":"zh","title":"传智博客国内首部Swift教程(系统、全面、有深度)","subTitle":"传智博客Swift从入门到精通视频教程完整版","webImage":"http://www.itcast.cn/files/image/201406/20140611114331424.jpg","webUrl":"http://pan.baidu.com/s/1bndD3cz"},{"videoLanguageType":"zh","title":"传智博客iOS开发零基础入门教程","subTitle":"C基础 OC基础 MacOS基础 知识","webImage":"http://www.itcast.cn/files/image/201406/20140611114424706.jpg","webUrl":"http://pan.baidu.com/share/link?shareid\u003d3864330827\u0026uk\u003d3560277524"},{"videoLanguageType":"zh","title":"传智博客iOS开发进阶教程","subTitle":"一些高级和基础控件使用主要是UI的知识","webImage":"http://www.itcast.cn/files/image/201406/20140611115311661.jpg","webUrl":"http://pan.baidu.com/s/1pJDGOll"},{"videoLanguageType":"zh","title":"传智博客iOS开发快速入门教程","subTitle":"C OC基础教程","webImage":"http://www.itcast.cn/files/image/201406/20140611115327052.jpg","webUrl":"http://pan.baidu.com/share/link?shareid\u003d3691511572\u0026uk\u003d3560277524"}] - +{"version":"3","bloglists":[{"videoLanguageType":"zh","title":"传智博客国内首部Swift教程(系统、全面、有深度)","subTitle":"传智博客Swift从入门到精通视频教程完整版","webImage":"http://www.itcast.cn/files/image/201406/20140611114331424.jpg","webUrl":"http://pan.baidu.com/s/1hqB0MlY"},{"videoLanguageType":"zh","title":"传智博客iOS开发零基础入门教程","subTitle":"C基础 OC基础 MacOS基础 知识","webImage":"http://www.itcast.cn/files/image/201406/20140611114424706.jpg","webUrl":"http://pan.baidu.com/s/1dDjM9lZ"},{"videoLanguageType":"zh","title":"传智博客iOS开发进阶教程","subTitle":"一些高级和基础控件使用主要是UI的知识","webImage":"http://www.itcast.cn/files/image/201406/20140611115311661.jpg","webUrl":"http://pan.baidu.com/s/1dDAQXET"},{"videoLanguageType":"zh","title":"传智博客iOS开发快速入门教程","subTitle":"C OC基础教程","webImage":"http://www.itcast.cn/files/image/201406/20140611115327052.jpg","webUrl":"http://pan.baidu.com/s/1gdhaHWZ"},{"videoLanguageType":"zh","title":"Developing iOS 8 Apps with Swift","subTitle":"Updated for iOS 8 and Swift. Tools and APIs required to build applications for the iPhone and iPad platforms using the iOS SDK. User interface design for mobile devices and unique user interactions using multi-touch technologies. Object-oriented design using model-view-controller paradigm, memory management, Swift programming language. Other topics include: animation, mobile device power management, multi-threading, networking and performance considerations.","webImage":"http://a5.mzstatic.com/us/r30/CobaltPublic5/v4/82/13/4b/82134b13-3e4f-18be-0010-3fedbf796295/d3_100_2x.png","webUrl":"https://itunes.apple.com/cn/course/developing-ios-8-apps-swift/id961180099"},{"videoLanguageType":"zh","title":"Developing iOS 7 Apps for iPhone and iPad","subTitle":"Updated for iOS 7. Tools and APIs required to build applications for the iPhone and iPad platform using the iOS SDK. User interface designs for mobile devices and unique user interactions using multi-touch technologies. Object-oriented design using model-view-controller paradigm, memory management, Objective-C programming language. Other topics include: object-oriented database API, animation, multi-threading and performance considerations. ","webImage":"http://a2.mzstatic.com/us/r30/CobaltPublic4/v4/21/50/bb/2150bb4a-211a-f13b-cf0a-72dbb661be80/d3_100_2x.png","webUrl":"https://itunes.apple.com/cn/course/developing-ios-7-apps-for/id733644550"},{"videoLanguageType":"zh","title":"斯坦福大学公开课:iOS 8开发","subTitle":"斯坦福白胡子老爷爷的教程,入门必看","webImage":"http://img5.cache.netease.com/video/2014/1/9/201401091654243dc2a.jpg","webUrl":"http://open.163.com/special/opencourse/ios8.html"},{"videoLanguageType":"zh","title":"斯坦福大学公开课:iOS 7应用开发","subTitle":"斯坦福白胡子老爷爷的教程,入门必看","webImage":"http://img5.cache.netease.com/video/2014/1/9/201401091654243dc2a.jpg","webUrl":"http://open.163.com/special/opencourse/ios7.html"}]} \ No newline at end of file diff --git a/iOSStudyJsonData/webs.json b/iOSStudyJsonData/webs.json index 5f4499b..6fb3418 100644 --- a/iOSStudyJsonData/webs.json +++ b/iOSStudyJsonData/webs.json @@ -1,32 +1 @@ -[ - { - "title": "objc中国", - "subTitile": "为中国 Objective-C 社区带来最佳实践和先进技术", - "webImage": "http://www.objc.io/images/covers/6-small.jpg", - "webUrl": "http://objccn.io/" - }, - { - "title": "objc", - "subTitile": "A periodical about best practices and advanced techniques for iOS and OS X development.", - "webImage": "http://www.objc.io/images/covers/4-small.jpg", - "webUrl": "http://www.objc.io/" - }, - { - "title": "AppCoda", - "subTitile": "AppCoda was founded in April 2012 as a personal blog. It was a place where I shared my iOS programming experience and helped beginners to kick start iOS app development. Since then, it has grown into a community for iOS developers with hundreds of thousands readers and a bunch of contributors, as well as, a free course and two books.", - "webImage": "http://www.appcoda.com/wp-content/themes/eleven40/images/favicon.ico", - "webUrl": "http://www.appcoda.com/ios-programming-course/" - }, - { - "title": "NShipster", - "subTitile": "大神Mattt Thompson的博客你懂的", - "webImage": "http://nshipster.cn/touch-icon-ipad-retina.png", - "webUrl": "http://nshipster.cn/" - }, - { - "title": "GoWhich", - "subTitile": "想你所想,做你所做,认真对待你的人生...", - "webImage": "https://avatars0.githubusercontent.com/u/1449203?v=3&s=460", - "webUrl": "http://www.gowhich.com/category/IOS" - } -] +{"version":"4","bloglists":[{"title":"objc中国","subTitle":"为中国 Objective-C 社区带来最佳实践和先进技术","webImage":"http://www.objc.io/images/covers/6-small.jpg","webUrl":"http://objccn.io/"},{"title":"objc","subTitle":"A periodical about best practices and advanced techniques for iOS and OS X development.","webImage":"http://www.objc.io/images/covers/4-small.jpg","webUrl":"http://www.objc.io/"},{"title":"AppCoda","subTitle":"AppCoda was founded in April 2012 as a personal blog. It was a place where I shared my iOS programming experience and helped beginners to kick start iOS app development. Since then, it has grown into a community for iOS developers with hundreds of thousands readers and a bunch of contributors, as well as, a free course and two books.","webImage":"http://www.appcoda.com/wp-content/themes/eleven40/images/favicon.ico","webUrl":"http://www.appcoda.com/ios-programming-course/"},{"title":"NShipster","subTitle":"大神Mattt Thompson的博客你懂的","webImage":"http://nshipster.cn/touch-icon-ipad-retina.png","webUrl":"http://nshipster.cn/"},{"title":"Glow 技术团队博客","subTitle":"Thoughts, stories and ideas.","webImage":"http://tech.glowing.com/cn/content/images/2014/12/cover5.jpg","webUrl":"http://tech.glowing.com/cn/"},{"title":"ASCIIwwdc","subTitle":"WWDC 文字版","webImage":"http://asciiwwdc.com/images/wwdc-2014.png","webUrl":"http://asciiwwdc.com/"},{"title":"iOS App Development","subTitle":"Stories and technical tips about building apps for iOS, Apple Watch, and iPad/iPhone","webImage":"https://d262ilb51hltx0.cloudfront.net/fit/c/120/120/0*2INQIY1p2-czJerk.jpeg","webUrl":"https://medium.com/ios-os-x-development"},{"title":"Subjective-C","subTitle":"Subjective-C最近颇受追捧,该网站将热门应用中的创意模式和用户界面剖解开来,重新组合,还提供诸多值得借鉴的程序和代码库的相关实验内容。可惜作者Sam Page已决定不再更新。即便如此,旧的文章仍有参考价值。","webImage":"http://subjc.com/assets/images/icon.png","webUrl":"http://subjc.com/unread-overlay-menu/"},{"title":"cocoa","subTitle":"Cocoa上的内容虽然缺乏针对性,但对iOS开发很有参考价值,且有Tumblr的iOS开发者团队发表诸多深刻见解,值得借鉴。","webImage":"http://38.media.tumblr.com/avatar_7a8502f96043_128.png","webUrl":"http://cocoa.tumblr.com/"},{"title":"ios-goodies","subTitle":"weekly iOS newsletter curated by Rui Peres and Tiago Almeidalogo by José Torre","webImage":"http://33.media.tumblr.com/avatar_36a8f259310f_128.png","webUrl":"http://ios-goodies.com/"},{"title":"iOS Development Tips","subTitle":"iOS Development tips刚刚成立不久,博主是Rounak Jain。其中Xcode和API的使用建议比较琐碎,开发者若真有孜孜不倦的学习精神,也能发现一片广阔的天地。","webImage":"http://assets.tumblr.com/images/default_avatar/cube_open_128.png","webUrl":"http://iosdevtips.co/"},{"title":"iOS Dev Weekly","subTitle":"iOS Dev Weekly由Dave Verwer创立,发布的文章与iOS开发相关,很值得学习。该网站从2011年开始每周更新,拥有超过2万的订阅者,还能给用户推送Safari通知。","webImage":"https://d2i0sljjkrkazd.cloudfront.net/production/publication/publication_icon/1/favicon_442526aa-1e62-489a-87ac-8f09b5f0f867.png","webUrl":"http://iosdevweekly.com/"},{"title":"iOS编程指南","subTitle":"中文编程指南,包括翻译文档和原创文档。当前包含Apple官方的部分Framework编程指南,以及Dreamingwish创作的GCD由浅入深编程指南、Block深度剖析编程指南等。","webImage":"http://www.dreamingwish.com/resource/frontui/img/logo-head.png","webUrl":"http://www.dreamingwish.com/articlelist/category/toturial"},{"title":"iOS Tutorials","subTitle":"学习iOS童鞋们 这个网站大家应该都懂得. 根本停不下来!","webImage":"http://cdn3.raywenderlich.com/wp-content/uploads/2014/10/iOSApprentice-thumb.png","webUrl":"http://www.raywenderlich.com/ios-tutorials"},{"title":"iOS-Core-Animation-Advanced-Techniques","subTitle":"学习Core-Animation 请点这里,绝对不会让你失望,自己就从中受益匪浅","webImage":"https://avatars3.githubusercontent.com/u/1487627?v\u003d3\u0026s\u003d460","webUrl":"https://github.com/AttackOnDobby/iOS-Core-Animation-Advanced-Techniques"},{"title":"iOS-Core-Animation-Advanced-Techniques","subTitle":"iOS频道分享iOS和Swift开发,应用设计和推广,iOS相关的行业动态。","webImage":"http://ios.jobbole.com/wp-content/themes/jobboleblogv3/_assets/img/jobbole-logo.png","webUrl":"http://ios.jobbole.com/"},{"title":"开发技术前线","subTitle":"一个定期翻译、发布国内外iOS优质的技术、开源库、软件架构设计、测试等文章的开源项目,让我们的技术跟上国际步伐。","webImage":"https://avatars2.githubusercontent.com/u/7555256?v\u003d3\u0026s\u003d460","webUrl":"http://www.devtf.cn/?cat\u003d3"},{"title":"http://swifter.tips/","subTitle":"每周三更新,向您介绍 SWIFT 的必备 TIP","webImage":"http://swifter.tips/assets/images/favico.png","webUrl":"http://swifter.tips/"}]} \ No newline at end of file