├── DataManager.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── DataManager.xccheckout │ └── xcuserdata │ │ └── mrj.xcuserdatad │ │ ├── UserInterfaceState.xcuserstate │ │ └── WorkspaceSettings.xcsettings └── xcuserdata │ └── mrj.xcuserdatad │ ├── xcdebugger │ └── Breakpoints_v2.xcbkptlist │ └── xcschemes │ ├── DataManager.xcscheme │ └── xcschememanagement.plist ├── DataManager ├── AppDelegate.h ├── AppDelegate.m ├── Base.lproj │ └── Main.storyboard ├── Common │ ├── ApplicationContext.h │ ├── ApplicationContext.m │ ├── Category │ │ ├── AssetsLibrary+PhotoAlbum.h │ │ ├── AssetsLibrary+PhotoAlbum.m │ │ ├── NSDate+Common.h │ │ ├── NSDate+Common.m │ │ ├── NSDictionary+KVC.h │ │ ├── NSDictionary+KVC.m │ │ ├── NSObject+Common.h │ │ ├── NSObject+Common.m │ │ ├── NSString+Common.h │ │ ├── NSString+Common.m │ │ ├── NSString+Emoji.h │ │ ├── NSString+Emoji.m │ │ ├── UIDevice+Common.h │ │ ├── UIDevice+Common.m │ │ ├── UIImage+Common.h │ │ ├── UIImage+Common.m │ │ ├── UIImage+ImageEffects.h │ │ ├── UIImage+ImageEffects.m │ │ ├── UIView+Addition.h │ │ ├── UIView+Addition.m │ │ ├── UIView+AutoLayout.h │ │ ├── UIView+AutoLayout.m │ │ ├── UIView+Common.h │ │ └── UIView+Common.m │ ├── Navigation │ │ ├── UIViewController+Navigation.h │ │ ├── UIViewController+Navigation.m │ │ ├── USNavDelegateHandler.h │ │ ├── USNavDelegateHandler.m │ │ ├── USTransitionAnimator.h │ │ ├── USTransitionAnimator.m │ │ └── pub_nav_white_back@2x.png │ ├── USDataController.h │ ├── USDataController.m │ ├── USViewController.h │ ├── USViewController.m │ └── Utils │ │ ├── AuthData.h │ │ ├── AuthData.m │ │ ├── MCMenuLabel.h │ │ ├── MCMenuLabel.m │ │ ├── MCVerticalLabel.h │ │ ├── MCVerticalLabel.m │ │ ├── SoundPlayer.h │ │ ├── SoundPlayer.m │ │ ├── USHVButton.h │ │ ├── USHVButton.m │ │ ├── USMultiLineLabel.h │ │ ├── USMultiLineLabel.m │ │ ├── USTextView.h │ │ └── USTextView.m ├── DataManager-Info.plist ├── DataManager-Prefix.pch ├── DataManager │ ├── AFNetworking │ │ ├── AFHTTPSessionManager.h │ │ ├── AFHTTPSessionManager.m │ │ ├── AFNetworkReachabilityManager.h │ │ ├── AFNetworkReachabilityManager.m │ │ ├── AFNetworking.h │ │ ├── AFSecurityPolicy.h │ │ ├── AFSecurityPolicy.m │ │ ├── AFURLRequestSerialization.h │ │ ├── AFURLRequestSerialization.m │ │ ├── AFURLResponseSerialization.h │ │ ├── AFURLResponseSerialization.m │ │ ├── AFURLSessionManager.h │ │ └── AFURLSessionManager.m │ ├── CoreData │ │ ├── NLCoreData.h │ │ ├── NLCoreData.m │ │ ├── NSFetchRequest+NLCoreData.h │ │ ├── NSFetchRequest+NLCoreData.m │ │ ├── NSFetchedResultsController+NLCoreData.h │ │ ├── NSFetchedResultsController+NLCoreData.m │ │ ├── NSManagedObject+Explain.h │ │ ├── NSManagedObject+Explain.m │ │ ├── NSManagedObject+NLCoreData.h │ │ ├── NSManagedObject+NLCoreData.m │ │ ├── NSManagedObjectContext+NLCoreData.h │ │ └── NSManagedObjectContext+NLCoreData.m │ ├── DBModel │ │ ├── DBLoginUser.h │ │ ├── DBLoginUser.m │ │ ├── DBObject.h │ │ └── DBObject.m │ ├── DataManager.h │ ├── Hash │ │ ├── DataHash.h │ │ └── DataHash.m │ ├── HttpManager.h │ ├── HttpManager.m │ ├── ImageCache.h │ └── ImageCache.m ├── Images.xcassets │ ├── AppIcon.appiconset │ │ └── Contents.json │ └── LaunchImage.launchimage │ │ └── Contents.json ├── MacroToolHeader.h ├── ViewController.h ├── ViewController.m ├── default.jpg ├── en.lproj │ └── InfoPlist.strings └── main.m ├── DataManagerTests ├── DataManagerTests-Info.plist ├── DataManagerTests.m └── en.lproj │ └── InfoPlist.strings └── README.md /DataManager.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/project.xcworkspace/xcshareddata/DataManager.xccheckout: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDESourceControlProjectFavoriteDictionaryKey 6 | 7 | IDESourceControlProjectIdentifier 8 | E50A7C1B-8E84-41F1-A1EF-D851DEEED2C9 9 | IDESourceControlProjectName 10 | DataManager 11 | IDESourceControlProjectOriginsDictionary 12 | 13 | 304362E90773969B1B51783B0FBAEED6164AFA31 14 | github.com:marujun/DataManager.git 15 | 16 | IDESourceControlProjectPath 17 | DataManager.xcodeproj 18 | IDESourceControlProjectRelativeInstallPathDictionary 19 | 20 | 304362E90773969B1B51783B0FBAEED6164AFA31 21 | ../.. 22 | 23 | IDESourceControlProjectURL 24 | github.com:marujun/DataManager.git 25 | IDESourceControlProjectVersion 26 | 111 27 | IDESourceControlProjectWCCIdentifier 28 | 304362E90773969B1B51783B0FBAEED6164AFA31 29 | IDESourceControlProjectWCConfigurations 30 | 31 | 32 | IDESourceControlRepositoryExtensionIdentifierKey 33 | public.vcs.git 34 | IDESourceControlWCCIdentifierKey 35 | 304362E90773969B1B51783B0FBAEED6164AFA31 36 | IDESourceControlWCCName 37 | DataManager 38 | 39 | 40 | 41 | 42 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/project.xcworkspace/xcuserdata/mrj.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marujun/DataManager/d1caede4fd13aaed7d596164c0bb26eb105527df/DataManager.xcodeproj/project.xcworkspace/xcuserdata/mrj.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /DataManager.xcodeproj/project.xcworkspace/xcuserdata/mrj.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | HasAskedToTakeAutomaticSnapshotBeforeSignificantChanges 6 | 7 | SnapshotAutomaticallyBeforeSignificantChanges 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcuserdata/mrj.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcuserdata/mrj.xcuserdatad/xcschemes/DataManager.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 76 | 77 | 83 | 85 | 91 | 92 | 93 | 94 | 96 | 97 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /DataManager.xcodeproj/xcuserdata/mrj.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | DataManager.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 0AEAE9441891553F0055EADB 16 | 17 | primary 18 | 19 | 20 | 0AEAE9651891553F0055EADB 21 | 22 | primary 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /DataManager/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // DataManager 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /DataManager/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // DataManager 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @implementation AppDelegate 12 | 13 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 14 | { 15 | // Override point for customization after application launch. 16 | 17 | return YES; 18 | } 19 | 20 | - (void)applicationWillResignActive:(UIApplication *)application 21 | { 22 | // 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. 23 | // 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. 24 | } 25 | 26 | - (void)applicationDidEnterBackground:(UIApplication *)application 27 | { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | - (void)applicationWillEnterForeground:(UIApplication *)application 33 | { 34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 35 | } 36 | 37 | - (void)applicationDidBecomeActive:(UIApplication *)application 38 | { 39 | // 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. 40 | } 41 | 42 | - (void)applicationWillTerminate:(UIApplication *)application 43 | { 44 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 45 | } 46 | 47 | @end 48 | -------------------------------------------------------------------------------- /DataManager/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /DataManager/Common/ApplicationContext.h: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationContext.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/9/14. 6 | // Copyright (c) 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @class ApplicationContext; 12 | 13 | @interface ApplicationContext : DBObject 14 | 15 | + (instancetype)sharedContext; 16 | 17 | /*! 18 | @property 19 | @brief 是否允许横屏 20 | */ 21 | @property (nonatomic, assign) BOOL enableLandscape; 22 | 23 | /*! 24 | @property 25 | @brief 是否正在执行后台刷新 26 | */ 27 | @property (nonatomic, assign) BOOL fetchingInBackground; 28 | 29 | /*! 30 | @property 31 | @brief 是否禁止侧滑 32 | */ 33 | @property (nonatomic, assign) BOOL disableInteractiveGesture; 34 | 35 | /*! 36 | @property 37 | @brief 是否已跳转到其他应用,如微信、QQ、facebook、微博 38 | */ 39 | @property (nonatomic, assign) BOOL hasSwitchToOtherApp; 40 | 41 | @end 42 | -------------------------------------------------------------------------------- /DataManager/Common/ApplicationContext.m: -------------------------------------------------------------------------------- 1 | // 2 | // ApplicationContext.m 3 | // USEvent 4 | // 5 | // Created by marujun on 15/9/14. 6 | // Copyright (c) 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "ApplicationContext.h" 10 | #import "AppDelegate.h" 11 | 12 | @interface ApplicationContext () 13 | { 14 | UINavigationController *presentNavigationController; 15 | } 16 | 17 | @end 18 | 19 | @implementation ApplicationContext 20 | 21 | + (instancetype)sharedContext 22 | { 23 | static ApplicationContext *sharedContext = nil; 24 | static dispatch_once_t onceToken; 25 | dispatch_once(&onceToken, ^{ 26 | sharedContext = [[self alloc] init]; 27 | }); 28 | return sharedContext; 29 | } 30 | 31 | @end 32 | -------------------------------------------------------------------------------- /DataManager/Common/Category/AssetsLibrary+PhotoAlbum.h: -------------------------------------------------------------------------------- 1 | // 2 | // AssetsLibrary+PhotoAlbum.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/11/19. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | 13 | @interface PHPhotoLibrary (PhotoAlbum) 14 | 15 | /** 通过名称去查找相册,如果相册不存在则新建一个相册 */ 16 | - (void)topLevelUserCollectionWithTitle:(NSString *)title completionHandler:(void(^)(PHAssetCollection *collection, NSError *error))completionHandler; 17 | 18 | /** 通过名称去查找相册,如果相册不存在则返回nil */ 19 | - (PHAssetCollection *)existingTopLevelUserCollectionWithTitle:(NSString *)title; 20 | 21 | /** 把图片保存到相册,如果相册不存在则新建一个相册 */ 22 | - (void)saveImage:(UIImage *)image toAlbum:(NSString *)toAlbum completionHandler:(void(^)(PHAsset *asset, NSError *error))completionHandler; 23 | 24 | /** 把图片文件保存到相册(需提供文件路径),如果相册不存在则新建一个相册 */ 25 | - (void)saveImageFromFilePath:(NSString *)filePath toAlbum:(NSString *)toAlbum completionHandler:(void(^)(PHAsset *asset, NSError *error))completionHandler; 26 | 27 | @end 28 | 29 | 30 | @interface ALAssetsLibrary (PhotoAlbum) 31 | 32 | - (void)saveImage:(UIImage *)image toAlbum:(NSString *)toAlbum completionBlock:(void (^)(NSError* error))completionBlock; 33 | 34 | - (void)addAssetURL:(NSURL *)assetURL toAlbum:(NSString *)toAlbum completionBlock:(void (^)(NSError* error))completionBlock; 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /DataManager/Common/Category/AssetsLibrary+PhotoAlbum.m: -------------------------------------------------------------------------------- 1 | // 2 | // AssetsLibrary+PhotoAlbum.m 3 | // USEvent 4 | // 5 | // Created by marujun on 15/11/19. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "AssetsLibrary+PhotoAlbum.h" 10 | 11 | @implementation PHPhotoLibrary (PhotoAlbum) 12 | 13 | - (void)topLevelUserCollectionWithTitle:(NSString *)title completionHandler:(void(^)(PHAssetCollection *collection, NSError *error))completionHandler 14 | { 15 | PHAssetCollection *collection = [self existingTopLevelUserCollectionWithTitle:title]; 16 | if (collection) { 17 | completionHandler?completionHandler(collection, nil):nil; 18 | } 19 | else { 20 | //使用输入名称创建一个新的相册 21 | __block NSString *localIdentifier; 22 | [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 23 | PHAssetCollectionChangeRequest *collectonRequest = [PHAssetCollectionChangeRequest creationRequestForAssetCollectionWithTitle:title]; 24 | 25 | localIdentifier = [collectonRequest placeholderForCreatedAssetCollection].localIdentifier; 26 | 27 | } completionHandler:^(BOOL success, NSError *error) { 28 | dispatch_async(dispatch_get_main_queue(), ^{ 29 | if (!success) { 30 | completionHandler?completionHandler(nil, error):nil; 31 | } 32 | else { 33 | PHFetchResult *fetchResult = [PHAssetCollection fetchAssetCollectionsWithLocalIdentifiers:@[localIdentifier] options:nil]; 34 | completionHandler?completionHandler([fetchResult firstObject], nil):nil; 35 | } 36 | }); 37 | }]; 38 | } 39 | } 40 | 41 | - (PHAssetCollection *)existingTopLevelUserCollectionWithTitle:(NSString *)title; 42 | { 43 | PHFetchOptions *options = [[PHFetchOptions alloc] init]; 44 | options.predicate = [NSPredicate predicateWithFormat:@"localizedTitle == %@", title]; 45 | 46 | PHFetchResult *fetchResult = [PHAssetCollection fetchTopLevelUserCollectionsWithOptions:options]; 47 | if (fetchResult.count) { 48 | return fetchResult.firstObject; 49 | } 50 | 51 | return nil; 52 | } 53 | 54 | - (void)saveImage:(UIImage *)image toAlbum:(NSString *)toAlbum completionHandler:(void(^)(PHAsset *asset, NSError *error))completionHandler 55 | { 56 | [self saveImageWithObject:image toAlbum:toAlbum completionHandler:completionHandler]; 57 | } 58 | 59 | - (void)saveImageFromFilePath:(NSString *)filePath toAlbum:(NSString *)toAlbum completionHandler:(void(^)(PHAsset *asset, NSError *error))completionHandler 60 | { 61 | [self saveImageWithObject:filePath toAlbum:toAlbum completionHandler:completionHandler]; 62 | } 63 | 64 | - (void)saveImageWithObject:(id)object toAlbum:(NSString *)toAlbum completionHandler:(void(^)(PHAsset *asset, NSError *error))completionHandler 65 | { 66 | [self topLevelUserCollectionWithTitle:toAlbum completionHandler:^(PHAssetCollection *collection, NSError *error) { 67 | if (error) { 68 | completionHandler?completionHandler(nil, error):nil; 69 | return ; 70 | } 71 | 72 | //把照片写入相册 73 | __block NSString *localIdentifier; 74 | [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{ 75 | //请求创建一个Asset 76 | PHAssetChangeRequest *assetRequest = nil; 77 | if ([object isKindOfClass:[UIImage class]]) { 78 | assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImage:object]; 79 | } else if ([object isKindOfClass:[NSString class]]) { 80 | assetRequest = [PHAssetChangeRequest creationRequestForAssetFromImageAtFileURL:[NSURL fileURLWithPath:object]]; 81 | } 82 | assetRequest.creationDate = [NSDate date]; 83 | 84 | //不提供AssetCollection则默认放到CameraRoll中 85 | if(collection){ 86 | //请求编辑相册 87 | PHAssetCollectionChangeRequest *collectonRequest = [PHAssetCollectionChangeRequest changeRequestForAssetCollection:collection]; 88 | //为Asset创建一个占位符,放到相册编辑请求中 89 | PHObjectPlaceholder *placeHolder = [assetRequest placeholderForCreatedAsset]; 90 | //相册中添加照片 91 | [collectonRequest addAssets:@[placeHolder]]; 92 | } 93 | 94 | localIdentifier = [[assetRequest placeholderForCreatedAsset] localIdentifier]; 95 | 96 | } completionHandler:^(BOOL success, NSError *error) { 97 | dispatch_async(dispatch_get_main_queue(), ^{ 98 | if (!success) { 99 | completionHandler?completionHandler(nil, error):nil; 100 | } 101 | else { 102 | PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil]; 103 | completionHandler?completionHandler([fetchResult firstObject], nil):nil; 104 | } 105 | }); 106 | }]; 107 | }]; 108 | } 109 | 110 | @end 111 | 112 | @implementation ALAssetsLibrary (PhotoAlbum) 113 | 114 | - (void)saveImage:(UIImage *)image toAlbum:(NSString *)toAlbum completionBlock:(void (^)(NSError* error))completionBlock 115 | { 116 | [self writeImageToSavedPhotosAlbum:image.CGImage orientation:(ALAssetOrientation)image.imageOrientation completionBlock:^(NSURL* assetURL, NSError* error) { 117 | if (error!=nil) { 118 | if(completionBlock) { 119 | completionBlock(error); 120 | } 121 | 122 | return; 123 | } 124 | 125 | [self addAssetURL:assetURL toAlbum:toAlbum completionBlock:completionBlock]; 126 | }]; 127 | } 128 | 129 | - (void)addAssetURL:(NSURL *)assetURL toAlbum:(NSString *)toAlbum completionBlock:(void (^)(NSError* error))completionBlock 130 | { 131 | __block BOOL albumWasFound = NO; 132 | 133 | [self enumerateGroupsWithTypes:ALAssetsGroupAlbum 134 | usingBlock:^(ALAssetsGroup *group, BOOL *stop) { 135 | if ([toAlbum compare:[group valueForProperty:ALAssetsGroupPropertyName]] == NSOrderedSame) { 136 | 137 | albumWasFound = YES; 138 | [self assetForURL:assetURL 139 | resultBlock:^(ALAsset *asset) { 140 | [group addAsset:asset]; 141 | 142 | if(completionBlock) { 143 | completionBlock(nil); 144 | } 145 | } failureBlock:completionBlock]; 146 | 147 | return; 148 | } 149 | 150 | if (group==nil && albumWasFound==NO) { 151 | 152 | __weak typeof(self) wself = self; 153 | 154 | [self addAssetsGroupAlbumWithName:toAlbum 155 | resultBlock:^(ALAssetsGroup *group) { 156 | [wself assetForURL: assetURL 157 | resultBlock:^(ALAsset *asset) { 158 | [group addAsset: asset]; 159 | 160 | if(completionBlock) { 161 | completionBlock(nil); 162 | } 163 | } failureBlock:completionBlock]; 164 | } failureBlock:completionBlock]; 165 | return; 166 | } 167 | 168 | } failureBlock:completionBlock]; 169 | } 170 | 171 | @end 172 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSDate+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDate+Common.h 3 | // HLMagic 4 | // 5 | // Created by marujun on 14-1-26. 6 | // Copyright (c) 2014年 chen ying. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDate (Common) 12 | 13 | //获取天数索引 14 | - (int)dayIndexSince1970; 15 | - (int)dayIndexSinceNow; 16 | - (int)dayIndexSinceDate:(NSDate *)date; 17 | 18 | //生成timestamp 19 | - (NSString *)timestamp; 20 | + (NSDate *)dateWithTimeStamp:(double)timestamp; 21 | 22 | //返回星期的字符串 23 | - (NSString *)weekDayString; 24 | //返回简短的星期字符串 25 | - (NSString *)shortWeekDayString; 26 | //返回月份的字符串 27 | - (NSString *)monthString; 28 | //返回月份的字符串with En 29 | - (NSString *)monthStringWithEn; 30 | //获取字符串 31 | - (NSString *)string; 32 | - (NSString *)stringWithDateFormat:(NSString *)format; 33 | 34 | //格式化日期 精确到天或小时 35 | - (NSDate *)dateAccurateToDay; 36 | - (NSDate *)dateAccurateToHour; 37 | 38 | //计算年龄 39 | - (int)age; 40 | 41 | //判断2个日期是否在同一天 42 | - (BOOL)isSameDayWithDate:(NSDate *)date; 43 | //判断2个日期是否在同一个月 44 | - (BOOL)isSameMonthWithDate:(NSDate *)date; 45 | 46 | - (BOOL)isToday; 47 | 48 | //判断2个日期是否在同一年 49 | - (BOOL)isSameYearWithDate:(NSDate *)date; 50 | 51 | //忽略年月日 52 | - (NSDate *)dateRemoveYMD; 53 | 54 | - (NSDateComponents *)dateComponents; 55 | 56 | //加上时区偏移 57 | - (NSDate *)changeZone; 58 | 59 | - (NSString *)getFormatYearMonthDay; 60 | 61 | //返回day天后的日期(若day为负数,则为|day|天前的日期) 62 | - (NSDate *)dateAfterDay:(NSInteger)day; 63 | //month个月后的日期 64 | - (NSDate *)dateafterMonth:(NSInteger)month; 65 | //获取日 66 | - (NSUInteger)getDay; 67 | //获取月 68 | - (NSUInteger)getMonth; 69 | //获取年 70 | - (NSUInteger)getYear; 71 | //获取小时 72 | - (NSInteger )getHour; 73 | //获取分钟 74 | - (NSInteger)getMinute; 75 | - (NSInteger)getHour:(NSDate *)date; 76 | - (NSInteger)getMinute:(NSDate *)date; 77 | //在当前日期前几天 78 | - (NSUInteger)daysAgo; 79 | 80 | - (NSUInteger)hoursAgo; 81 | //午夜时间距今几天 82 | - (NSUInteger)daysAgoAgainstMidnight; 83 | 84 | - (NSString *)stringDaysAgo; 85 | 86 | - (NSString *)stringDaysAgoAgainstMidnight:(BOOL)flag; 87 | 88 | //返回一周的第几天(周末为第一天) 89 | - (NSUInteger)weekday; 90 | //转为NSString类型的 91 | + (NSDate *)dateFromString:(NSString *)string; 92 | 93 | + (NSDate *)dateFromString:(NSString *)string withFormat:(NSString *)format; 94 | 95 | + (NSString *)stringFromDate:(NSDate *)date withFormat:(NSString *)format; 96 | 97 | + (NSString *)stringFromDate:(NSDate *)date; 98 | 99 | + (NSString *)stringForDisplayFromDate:(NSDate *)date prefixed:(BOOL)prefixed; 100 | 101 | + (NSString *)stringForDisplayFromDate:(NSDate *)date; 102 | 103 | - (NSString *)stringWithFormat:(NSString *)format; 104 | 105 | - (NSString *)stringWithDateStyle:(NSDateFormatterStyle)dateStyle timeStyle:(NSDateFormatterStyle)timeStyle; 106 | //返回周日的的开始时间 107 | - (NSDate *)beginningOfWeek; 108 | //返回当前天的年月日. 109 | - (NSDate *)beginningOfDay; 110 | //返回该月的第一天 111 | - (NSDate *)beginningOfMonth; 112 | //该月的最后一天 113 | - (NSDate *)endOfMonth; 114 | //返回当前周的周末 115 | - (NSDate *)endOfWeek; 116 | 117 | + (NSString *)dateFormatString; 118 | 119 | + (NSString *)timeFormatString; 120 | + (NSString *)timestampFormatString; 121 | // preserving for compatibility 122 | + (NSString *)dbFormatString; 123 | @end 124 | 125 | @interface NSString (DateCommon) 126 | //获取日期 127 | - (NSDate *)date; 128 | - (NSDate *)dateWithDateFormat:(NSString *)format; 129 | @end -------------------------------------------------------------------------------- /DataManager/Common/Category/NSDictionary+KVC.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSDictionary+KVC.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/11/25. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSDictionary (KVC) 12 | 13 | /** 通过keyPath获取对应的数据,例:user.hobby[1].title */ 14 | - (id)us_valueForKeyPath:(NSString *)keyPath; 15 | 16 | /** 通过keyPath修改数据,并返回一个新的字典。例:user.hobby[1].title */ 17 | - (instancetype)dictionaryByReplaceingValue:(id)value forKeyPath:(NSString *)keyPath; 18 | 19 | /** 通过keyPath移除子节点中某个数据,并返回一个新的字典。例:user.hobby[1] */ 20 | - (instancetype)dictionaryByDeletingValueInKeyPath:(NSString *)keyPath; 21 | 22 | /** 通过模糊条件predicate查找准确的keyPath路径。例:predicate为 'list.members[].uid = 100215', 返回keyPath: list.members[2]*/ 23 | - (NSString *)keyPathForPredicate:(NSString *)predicate; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSObject+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Common.h 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-7-7. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface NSObject (Common) 12 | 13 | //去掉 json 中的多余的 null 14 | - (id)cleanNull; 15 | 16 | - (NSString *)stringValue; 17 | 18 | - (id)performSelector:(SEL)aSelector withArguments:(id)arg, ... NS_REQUIRES_NIL_TERMINATION; 19 | 20 | 21 | @end 22 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSObject+Common.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSObject+Common.m 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-7-7. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import "NSObject+Common.h" 10 | 11 | @implementation NSObject (Common) 12 | 13 | - (NSString *)stringValue 14 | { 15 | NSString *_string = [NSString stringWithFormat:@"%@", self]; 16 | if ([self isMemberOfClass:[NSString class]]) { 17 | return _string; 18 | } 19 | 20 | NSString *finalString = @""; 21 | if (_string && ![_string isEqual:[NSNull null]] && ![_string isEqualToString:@"null"] && ![_string isEqualToString:@"(null)"] && ![_string isEqualToString:@""]) { 22 | finalString = [NSString stringWithFormat:@"%@", _string]; 23 | } 24 | return finalString; 25 | } 26 | 27 | //去掉 json 中的多余的 null 28 | - (id)cleanNull 29 | { 30 | NSError *error; 31 | if (self == (id)[NSNull null]) { 32 | return [[NSObject alloc] init]; 33 | } 34 | 35 | id jsonObject; 36 | if ([self isKindOfClass:[NSData class]]) { 37 | jsonObject = [NSJSONSerialization JSONObjectWithData:(NSData *)self options:kNilOptions error:&error]; 38 | } 39 | else { 40 | jsonObject = self; 41 | } 42 | 43 | if ([jsonObject isKindOfClass:[NSArray class]]) { 44 | NSMutableArray *array = [jsonObject mutableCopy]; 45 | for (NSInteger i = array.count - 1; i >= 0; i--) { 46 | id a = array[i]; 47 | if (a == (id)[NSNull null]) { 48 | [array removeObjectAtIndex:i]; 49 | } 50 | else { 51 | array[i] = [a cleanNull]; 52 | } 53 | } 54 | return array; 55 | } 56 | else if ([jsonObject isKindOfClass:[NSDictionary class]]) { 57 | NSMutableDictionary *dictionary = [jsonObject mutableCopy]; 58 | for (NSString *key in[dictionary allKeys]) { 59 | id d = dictionary[key]; 60 | if (d == (id)[NSNull null]) { 61 | dictionary[key] = @""; 62 | } 63 | else { 64 | dictionary[key] = [d cleanNull]; 65 | } 66 | } 67 | return dictionary; 68 | } 69 | else { 70 | return jsonObject; 71 | } 72 | } 73 | 74 | 75 | - (id)performSelector:(SEL)aSelector withArguments:(id)arg, ... 76 | { 77 | NSMethodSignature *sig = [self methodSignatureForSelector:aSelector]; 78 | NSInvocation *inv = [NSInvocation invocationWithMethodSignature:sig]; 79 | [inv setTarget:self]; 80 | [inv setSelector:aSelector]; 81 | // 0被target占用,1被selector占用,故参数从2开始 82 | int index = 2; 83 | if (arg) { 84 | [inv setArgument:&arg atIndex:index]; 85 | id argVa; 86 | va_list args; 87 | va_start(args, arg); 88 | while ((argVa = va_arg(args, id))) { 89 | index ++; 90 | [inv setArgument:&argVa atIndex:index]; 91 | } 92 | va_end(args); 93 | [inv retainArguments]; 94 | } 95 | [inv invoke]; 96 | id ret = nil; 97 | [inv getReturnValue:&ret]; 98 | return ret; 99 | } 100 | 101 | @end 102 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSString+Common.h: -------------------------------------------------------------------------------- 1 | // Created by chen ying on 12-11-6. 2 | // Copyright (c) 2012年 hoolai. All rights reserved. 3 | // 4 | 5 | #import 6 | 7 | @interface NSString (Common) 8 | 9 | /** 验证邮箱 */ 10 | -(BOOL)isValidateEmail; 11 | 12 | /** 是否都为整形数字 */ 13 | - (BOOL)isPureInt; 14 | 15 | /** 验证身份证号码 */ 16 | - (BOOL)isValidateIDCard; 17 | 18 | /** 验证手机号码 */ 19 | - (BOOL)isValidateMobileNumber; 20 | 21 | /** 验证银行卡 (Luhn算法) */ 22 | - (BOOL)isValidCardNumber; 23 | 24 | /** 是否包含中文 */ 25 | - (BOOL)containsChineseCharacter; 26 | 27 | - (float)stringWidthWithFont:(UIFont *)font height:(float)height; 28 | - (float)stringHeightWithFont:(UIFont *)font width:(float)width; 29 | 30 | @end 31 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSString+Common.m: -------------------------------------------------------------------------------- 1 | // Created by chen ying on 12-11-6. 2 | 3 | #import "NSString+Common.h" 4 | 5 | 6 | @implementation NSString (Common) 7 | 8 | - (BOOL)containsString:(NSString *)str 9 | { 10 | if (str && self.length && str.length) { 11 | NSRange range = [self rangeOfString:str]; 12 | if (range.location == NSNotFound) { 13 | return NO; 14 | } 15 | return YES; 16 | } 17 | return NO; 18 | } 19 | 20 | // 验证邮箱格式 21 | -(BOOL)isValidateEmail 22 | { 23 | BOOL stricterFilter = YES; //规定是否严格判断格式 24 | NSString *stricterFilterString = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9-]+[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}"; 25 | NSString *laxString = @".+@.+\\.[A-Za-z]{2}[A-Za-z]*"; 26 | NSString *emailRegex = stricterFilter?stricterFilterString:laxString; 27 | NSPredicate *emailCheck = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex]; 28 | 29 | return [emailCheck evaluateWithObject:self]; 30 | } 31 | 32 | //是否都为整形数字 33 | - (BOOL)isPureInt 34 | { 35 | NSScanner* scan = [NSScanner scannerWithString:self]; 36 | int val; 37 | return [scan scanInt:&val] && [scan isAtEnd]; 38 | } 39 | 40 | // 验证身份证号码 41 | - (BOOL)isValidateIDCard 42 | { 43 | if (self.length != 18) { 44 | return NO; 45 | } 46 | NSArray* codeArray = [NSArray arrayWithObjects:@"7",@"9",@"10",@"5",@"8",@"4",@"2",@"1",@"6",@"3",@"7",@"9",@"10",@"5",@"8",@"4",@"2", nil]; 47 | NSDictionary* checkCodeDic = [NSDictionary dictionaryWithObjects:[NSArray arrayWithObjects:@"1",@"0",@"X",@"9",@"8",@"7",@"6",@"5",@"4",@"3",@"2", nil] forKeys:[NSArray arrayWithObjects:@"0",@"1",@"2",@"3",@"4",@"5",@"6",@"7",@"8",@"9",@"10", nil]]; 48 | NSScanner* scan = [NSScanner scannerWithString:[self substringToIndex:17]]; 49 | 50 | int val; 51 | BOOL isNum = [scan scanInt:&val] && [scan isAtEnd]; 52 | if (!isNum) { 53 | return NO; 54 | } 55 | int sumValue = 0; 56 | 57 | for (int i =0; i<17; i++) { 58 | sumValue+=[[self substringWithRange:NSMakeRange(i , 1) ] intValue]* [[codeArray objectAtIndex:i] intValue]; 59 | } 60 | 61 | NSString* strlast = [checkCodeDic objectForKey:[NSString stringWithFormat:@"%d",sumValue%11]]; 62 | 63 | if ([strlast isEqualToString: [[self substringWithRange:NSMakeRange(17, 1)]uppercaseString]]) { 64 | return YES; 65 | } 66 | return NO; 67 | } 68 | 69 | // 验证手机号码 70 | - (BOOL)isValidateMobileNumber 71 | { 72 | //手机号以13, 15,18开头,八个 \d 数字字符 (新增14、17号段) 73 | NSString *phoneRegex = @"^((13[0-9])|(14[5,7])|(15[^4,\\D])|(17[0,6-8])|(18[0-9]))\\d{8}$"; 74 | NSPredicate *phoneTest = [NSPredicate predicateWithFormat:@"SELF MATCHES %@",phoneRegex]; 75 | return [phoneTest evaluateWithObject:self]; 76 | } 77 | 78 | // 剔除卡号里的非法字符 79 | - (NSString *)getDigitsOnly 80 | { 81 | NSString *digitsOnly = @""; 82 | char c; 83 | for (int i = 0; i < self.length; i++){ 84 | c = [self characterAtIndex:i]; 85 | if (isdigit(c)){ 86 | digitsOnly =[digitsOnly stringByAppendingFormat:@"%c",c]; 87 | } 88 | } 89 | return digitsOnly; 90 | } 91 | 92 | // 验证银行卡 (Luhn算法) 93 | - (BOOL)isValidCardNumber 94 | { 95 | NSString *digitsOnly = [self getDigitsOnly]; 96 | int sum = 0, digit = 0, addend = 0; 97 | BOOL timesTwo = false; 98 | for (NSInteger i = digitsOnly.length - 1; i >= 0; i--) { 99 | digit = [digitsOnly characterAtIndex:i] - '0'; 100 | if (timesTwo) { 101 | addend = digit * 2; 102 | if (addend > 9) { 103 | addend -= 9; 104 | } 105 | } else { 106 | addend = digit; 107 | } 108 | sum += addend; 109 | timesTwo = !timesTwo; 110 | } 111 | int modulus = sum % 10; 112 | return modulus == 0; 113 | } 114 | 115 | 116 | - (float)stringWidthWithFont:(UIFont *)font height:(float)height 117 | { 118 | if (self == nil || self.length == 0) { 119 | return 0; 120 | } 121 | 122 | NSString *copyString = [NSString stringWithFormat:@"%@", self]; 123 | 124 | CGSize size = CGSizeZero; 125 | CGSize constrainedSize = CGSizeMake(CGFLOAT_MAX, height); 126 | 127 | if ([copyString respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { 128 | 129 | NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; 130 | paragraph.lineBreakMode = NSLineBreakByWordWrapping; //e.g. 131 | 132 | size = [copyString boundingRectWithSize: constrainedSize 133 | options:NSStringDrawingUsesLineFragmentOrigin 134 | attributes:@{ NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraph } 135 | context: nil].size; 136 | } else { 137 | #pragma GCC diagnostic push 138 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 139 | size = [copyString sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:NSLineBreakByWordWrapping]; 140 | #pragma GCC diagnostic pop 141 | } 142 | 143 | return ceilf(size.width); 144 | } 145 | 146 | - (float)stringHeightWithFont:(UIFont *)font width:(float)width 147 | { 148 | if (self == nil || self.length == 0) { 149 | return 0; 150 | } 151 | 152 | NSString *copyString = [NSString stringWithFormat:@"%@", self]; 153 | 154 | CGSize size = CGSizeZero; 155 | CGSize constrainedSize = CGSizeMake(width, CGFLOAT_MAX); 156 | 157 | if ([copyString respondsToSelector:@selector(boundingRectWithSize:options:attributes:context:)]) { 158 | 159 | NSMutableParagraphStyle *paragraph = [[NSMutableParagraphStyle alloc] init]; 160 | paragraph.lineBreakMode = NSLineBreakByWordWrapping; //e.g. 161 | 162 | size = [copyString boundingRectWithSize:constrainedSize 163 | options:NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading 164 | attributes:@{NSFontAttributeName:font, NSParagraphStyleAttributeName:paragraph } 165 | context:nil].size; 166 | }else{ 167 | #pragma GCC diagnostic push 168 | #pragma GCC diagnostic ignored "-Wdeprecated-declarations" 169 | size = [copyString sizeWithFont:font constrainedToSize:constrainedSize lineBreakMode:NSLineBreakByWordWrapping]; 170 | #pragma GCC diagnostic pop 171 | } 172 | 173 | return ceilf(size.height); 174 | } 175 | 176 | - (BOOL)containsChineseCharacter 177 | { 178 | BOOL isContan = NO; 179 | 180 | for(int i=0; i< [self length];i++) { 181 | NSRange range = NSMakeRange(i, 1); 182 | NSString *subString = [self substringWithRange:range]; 183 | const char *cString = [subString UTF8String]; 184 | 185 | if (cString && strlen(cString) == 3) { 186 | isContan = YES; 187 | } 188 | } 189 | 190 | return isContan; 191 | } 192 | 193 | @end 194 | -------------------------------------------------------------------------------- /DataManager/Common/Category/NSString+Emoji.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSString+Emoji.h 3 | // 4 | // 5 | // Created by Valerio Mazzeo on 24/04/13. 6 | // Copyright (c) 2013 Valerio Mazzeo. All rights reserved. 7 | // 8 | 9 | 10 | /** 11 | NSString (Emoji) extends the NSString class to provide custom functionality 12 | related to the Emoji emoticons. 13 | 14 | Through this category, it is possible to turn cheat codes from 15 | Emoji Cheat Sheet into unicode emoji characters 16 | and vice versa (useful if you need to POST a message typed by the user to a remote service). 17 | */ 18 | @interface NSString (Emoji) 19 | 20 | /** 21 | Returns a NSString in which any occurrences that match the cheat codes 22 | from Emoji Cheat Sheet are replaced by the 23 | corresponding unicode characters. 24 | 25 | Example: 26 | "This is a smiley face :smiley:" 27 | 28 | Will be replaced with: 29 | "This is a smiley face \U0001F604" 30 | */ 31 | - (NSString *)stringByReplacingEmojiCheatCodesWithUnicode; 32 | 33 | /** 34 | Returns a NSString in which any occurrences that match the unicode characters 35 | of the emoji emoticons are replaced by the corresponding cheat codes from 36 | Emoji Cheat Sheet . 37 | 38 | Example: 39 | "This is a smiley face \U0001F604" 40 | 41 | Will be replaced with: 42 | "This is a smiley face :smiley:" 43 | */ 44 | - (NSString *)stringByReplacingEmojiUnicodeWithCheatCodes; 45 | 46 | 47 | /** 是否含有系统表情 */ 48 | - (BOOL)isContainEmoji; 49 | 50 | /** 过滤表情之后的字符串 */ 51 | - (NSString *)stringByDeletingEmoji; 52 | 53 | 54 | @end -------------------------------------------------------------------------------- /DataManager/Common/Category/UIDevice+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIDevice(Common).h 3 | // UIDeviceAddition 4 | // 5 | // Created by Georg Kitz on 20.08.11. 6 | // Copyright 2011 Aurora Apps. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface UIDevice (Common) 13 | 14 | /**广告标识符 */ 15 | + (NSString *)idfa; 16 | 17 | + (NSString *)idfv; 18 | 19 | /** 是否越狱 */ 20 | + (BOOL)jailbroken; 21 | 22 | /** 是否被破解 */ 23 | + (BOOL)isCracked; 24 | 25 | + (NSString *)chinaMobileModel; 26 | + (NSString *)IPv4; 27 | + (NSString *)IPv6; 28 | + (NSString *)deviceName; 29 | + (NSString *)deviceModel; 30 | 31 | /** 已连接的wifi信息 */ 32 | + (NSDictionary *)wifiInfo; 33 | 34 | /** 是否已插入耳机 */ 35 | + (BOOL)headphonesConnected; 36 | 37 | /** 是否开启了Airplay */ 38 | + (BOOL)isAirplayActived; 39 | 40 | /** 是否已开启麦克风权限 */ 41 | + (void)recordPermission:(void (^)(BOOL granted))response; 42 | 43 | 44 | /** 剩余内存大小的格式化字符串 */ 45 | + (NSString *)freeMemory; 46 | 47 | /** 已使用内存大小的格式化字符串 */ 48 | + (NSString *)usedMemory; 49 | 50 | /** 剩余内存大小(单位:Bytes)*/ 51 | + (vm_size_t)freeMemoryInBytes; 52 | 53 | /** 已使用内存大小(单位:Bytes)*/ 54 | + (vm_size_t)usedMemoryInBytes; 55 | 56 | /** 总的磁盘空间大小的格式化字符串 */ 57 | + (NSString *)totalDiskSpace; 58 | 59 | /** 剩余磁盘空间大小的格式化字符串 */ 60 | + (NSString *)freeDiskSpace; 61 | 62 | /** 已使用磁盘空间大小的格式化字符串 */ 63 | + (NSString *)usedDiskSpace; 64 | 65 | /** 总的磁盘空间大小(单位:Bytes)*/ 66 | + (CGFloat)totalDiskSpaceInBytes; 67 | 68 | /** 剩余磁盘空间大小(单位:Bytes)*/ 69 | + (CGFloat)freeDiskSpaceInBytes; 70 | 71 | /** 已使用磁盘空间大小(单位:Bytes)*/ 72 | + (CGFloat)usedDiskSpaceInBytes; 73 | 74 | @end 75 | -------------------------------------------------------------------------------- /DataManager/Common/Category/UIImage+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIImage+Common.h 3 | // HLMagic 4 | // 5 | // Created by marujun on 13-12-8. 6 | // Copyright (c) 2013年 chen ying. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | CGFloat DegreesToRadians(CGFloat degrees); 12 | CGFloat RadiansToDegrees(CGFloat radians); 13 | 14 | @interface UIImage (Common) 15 | 16 | + (UIImage *)screenshot; 17 | + (UIImage *)imageWithColor:(UIColor *)color; 18 | + (UIImage *)imageWithColor:(UIColor *)color cornerRadius:(CGFloat)cornerRadius; 19 | + (UIImage *)imageWithView:(UIView *)view; 20 | - (UIImage *)squareImage; 21 | - (UIImage *)imageScaledToSize:(CGSize)newSize; 22 | - (UIImage *)imageClipedWithRect:(CGRect)clipRect; 23 | 24 | /** 模糊化图片 */ 25 | - (UIImage *)imageBluredByRadius:(CGFloat)radius; 26 | 27 | /** 黑白图片 */ 28 | - (UIImage*)monochromeImage; 29 | 30 | /** 灰度化图片 */ 31 | - (UIImage *)grayscaleImage; 32 | 33 | /** 修正图片的方向信息 */ 34 | - (UIImage *)fixOrientation; 35 | 36 | /** 通过弧度旋转图片 */ 37 | - (UIImage *)imageRotatedByRadians:(CGFloat)radians; 38 | 39 | /** 通过角度旋转图片 */ 40 | - (UIImage *)imageRotatedByDegrees:(CGFloat)degrees; 41 | 42 | /** 反转后的遮罩图片,效果:纯白色表示被遮罩区域将完全透明,纯黑色表示被遮罩区域将会原封不动保留下来, 43 | 灰色部分(0x000000~0xFFFFFF)表示被遮罩区域将会处理成半透明的效果 */ 44 | - (UIImage *)inverseMaskImage; 45 | 46 | @end 47 | -------------------------------------------------------------------------------- /DataManager/Common/Category/UIImage+ImageEffects.h: -------------------------------------------------------------------------------- 1 | /* 2 | File: UIImage+ImageEffects.h 3 | Abstract: This is a category of UIImage that adds methods to apply blur and tint effects to an image. This is the code you’ll want to look out to find out how to use vImage to efficiently calculate a blur. 4 | Version: 1.0 5 | 6 | Disclaimer: IMPORTANT: This Apple software is supplied to you by Apple 7 | Inc. ("Apple") in consideration of your agreement to the following 8 | terms, and your use, installation, modification or redistribution of 9 | this Apple software constitutes acceptance of these terms. If you do 10 | not agree with these terms, please do not use, install, modify or 11 | redistribute this Apple software. 12 | 13 | In consideration of your agreement to abide by the following terms, and 14 | subject to these terms, Apple grants you a personal, non-exclusive 15 | license, under Apple's copyrights in this original Apple software (the 16 | "Apple Software"), to use, reproduce, modify and redistribute the Apple 17 | Software, with or without modifications, in source and/or binary forms; 18 | provided that if you redistribute the Apple Software in its entirety and 19 | without modifications, you must retain this notice and the following 20 | text and disclaimers in all such redistributions of the Apple Software. 21 | Neither the name, trademarks, service marks or logos of Apple Inc. may 22 | be used to endorse or promote products derived from the Apple Software 23 | without specific prior written permission from Apple. Except as 24 | expressly stated in this notice, no other rights or licenses, express or 25 | implied, are granted by Apple herein, including but not limited to any 26 | patent rights that may be infringed by your derivative works or by other 27 | works in which the Apple Software may be incorporated. 28 | 29 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE 30 | MAKES NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION 31 | THE IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS 32 | FOR A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 33 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 34 | 35 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 36 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 37 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 38 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 39 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 40 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 41 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 42 | POSSIBILITY OF SUCH DAMAGE. 43 | 44 | Copyright (C) 2013 Apple Inc. All Rights Reserved. 45 | 46 | 47 | Copyright © 2013 Apple Inc. All rights reserved. 48 | WWDC 2013 License 49 | 50 | NOTE: This Apple Software was supplied by Apple as part of a WWDC 2013 51 | Session. Please refer to the applicable WWDC 2013 Session for further 52 | information. 53 | 54 | IMPORTANT: This Apple software is supplied to you by Apple Inc. 55 | ("Apple") in consideration of your agreement to the following terms, and 56 | your use, installation, modification or redistribution of this Apple 57 | software constitutes acceptance of these terms. If you do not agree with 58 | these terms, please do not use, install, modify or redistribute this 59 | Apple software. 60 | 61 | In consideration of your agreement to abide by the following terms, and 62 | subject to these terms, Apple grants you a non-exclusive license, under 63 | Apple's copyrights in this original Apple software (the "Apple 64 | Software"), to use, reproduce, modify and redistribute the Apple 65 | Software, with or without modifications, in source and/or binary forms; 66 | provided that if you redistribute the Apple Software in its entirety and 67 | without modifications, you must retain this notice and the following 68 | text and disclaimers in all such redistributions of the Apple Software. 69 | Neither the name, trademarks, service marks or logos of Apple Inc. may 70 | be used to endorse or promote products derived from the Apple Software 71 | without specific prior written permission from Apple. Except as 72 | expressly stated in this notice, no other rights or licenses, express or 73 | implied, are granted by Apple herein, including but not limited to any 74 | patent rights that may be infringed by your derivative works or by other 75 | works in which the Apple Software may be incorporated. 76 | 77 | The Apple Software is provided by Apple on an "AS IS" basis. APPLE MAKES 78 | NO WARRANTIES, EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION THE 79 | IMPLIED WARRANTIES OF NON-INFRINGEMENT, MERCHANTABILITY AND FITNESS FOR 80 | A PARTICULAR PURPOSE, REGARDING THE APPLE SOFTWARE OR ITS USE AND 81 | OPERATION ALONE OR IN COMBINATION WITH YOUR PRODUCTS. 82 | 83 | IN NO EVENT SHALL APPLE BE LIABLE FOR ANY SPECIAL, INDIRECT, INCIDENTAL 84 | OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 85 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 86 | INTERRUPTION) ARISING IN ANY WAY OUT OF THE USE, REPRODUCTION, 87 | MODIFICATION AND/OR DISTRIBUTION OF THE APPLE SOFTWARE, HOWEVER CAUSED 88 | AND WHETHER UNDER THEORY OF CONTRACT, TORT (INCLUDING NEGLIGENCE), 89 | STRICT LIABILITY OR OTHERWISE, EVEN IF APPLE HAS BEEN ADVISED OF THE 90 | POSSIBILITY OF SUCH DAMAGE. 91 | 92 | EA1002 93 | 5/3/2013 94 | */ 95 | 96 | #import 97 | 98 | @interface UIImage (ImageEffects) 99 | 100 | - (UIImage *)applyLightEffect; 101 | - (UIImage *)applyExtraLightEffect; 102 | - (UIImage *)applyDarkEffect; 103 | - (UIImage *)applyTintEffectWithColor:(UIColor *)tintColor; 104 | 105 | - (UIImage *)applyBlurWithRadius:(CGFloat)blurRadius tintColor:(UIColor *)tintColor saturationDeltaFactor:(CGFloat)saturationDeltaFactor maskImage:(UIImage *)maskImage; 106 | 107 | @end 108 | -------------------------------------------------------------------------------- /DataManager/Common/Category/UIView+Addition.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Addition.h 3 | // LepaoPlus 4 | // 5 | // Created by leslie on 4/22/14. 6 | // Copyright (c) 2014 Hoolai Game Ltd. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIView (Addition) 12 | 13 | 14 | /** 15 | * Shortcut for frame.origin.x. 16 | * 17 | * Sets frame.origin.x = left 18 | */ 19 | @property (nonatomic) CGFloat left; 20 | 21 | /** 22 | * Shortcut for frame.origin.y 23 | * 24 | * Sets frame.origin.y = top 25 | */ 26 | @property (nonatomic) CGFloat top; 27 | 28 | /** 29 | * Shortcut for frame.origin.x + frame.size.width 30 | * 31 | * Sets frame.origin.x = right - frame.size.width 32 | */ 33 | @property (nonatomic) CGFloat right; 34 | 35 | /** 36 | * Shortcut for frame.origin.y + frame.size.height 37 | * 38 | * Sets frame.origin.y = bottom - frame.size.height 39 | */ 40 | @property (nonatomic) CGFloat bottom; 41 | 42 | /** 43 | * Shortcut for frame.size.width 44 | * 45 | * Sets frame.size.width = width 46 | */ 47 | @property (nonatomic) CGFloat width; 48 | 49 | /** 50 | * Shortcut for frame.size.height 51 | * 52 | * Sets frame.size.height = height 53 | */ 54 | @property (nonatomic) CGFloat height; 55 | 56 | /** 57 | * Shortcut for center.x 58 | * 59 | * Sets center.x = centerX 60 | */ 61 | @property (nonatomic) CGFloat centerX; 62 | 63 | /** 64 | * Shortcut for center.y 65 | * 66 | * Sets center.y = centerY 67 | */ 68 | @property (nonatomic) CGFloat centerY; 69 | 70 | /** 71 | * Return the x coordinate on the screen. 72 | */ 73 | @property (nonatomic, readonly) CGFloat ttScreenX; 74 | 75 | /** 76 | * Return the y coordinate on the screen. 77 | */ 78 | @property (nonatomic, readonly) CGFloat ttScreenY; 79 | 80 | /** 81 | * Return the x coordinate on the screen, taking into account scroll views. 82 | */ 83 | @property (nonatomic, readonly) CGFloat screenViewX; 84 | 85 | /** 86 | * Return the y coordinate on the screen, taking into account scroll views. 87 | */ 88 | @property (nonatomic, readonly) CGFloat screenViewY; 89 | 90 | /** 91 | * Return the view frame on the screen, taking into account scroll views. 92 | */ 93 | @property (nonatomic, readonly) CGRect screenFrame; 94 | 95 | /** 96 | * Shortcut for frame.origin 97 | */ 98 | @property (nonatomic) CGPoint origin; 99 | 100 | /** 101 | * Shortcut for frame.size 102 | */ 103 | @property (nonatomic) CGSize size; 104 | 105 | /** 106 | * Return the width in portrait or the height in landscape. 107 | */ 108 | @property (nonatomic, readonly) CGFloat orientationWidth; 109 | 110 | /** 111 | * Return the height in portrait or the width in landscape. 112 | */ 113 | @property (nonatomic, readonly) CGFloat orientationHeight; 114 | 115 | /** 116 | * Finds the first descendant view (including this view) that is a member of a particular class. 117 | */ 118 | - (UIView*)descendantOrSelfWithClass:(Class)cls; 119 | 120 | /** 121 | * Finds the first ancestor view (including this view) that is a member of a particular class. 122 | */ 123 | - (UIView*)ancestorOrSelfWithClass:(Class)cls; 124 | 125 | /** 126 | * Removes all subviews. 127 | */ 128 | - (void)removeAllSubviews; 129 | 130 | /** 131 | * Calculates the offset of this view from another view in screen coordinates. 132 | * 133 | * otherView should be a parent view of this view. 134 | */ 135 | - (CGPoint)offsetFromView:(UIView*)otherView; 136 | 137 | 138 | - (void)setBorderColor:(UIColor *)borderColor width:(CGFloat)borderWidth cornerRadius:(CGFloat)cornerRadius; 139 | @end -------------------------------------------------------------------------------- /DataManager/Common/Category/UIView+Addition.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Addition.m 3 | // LepaoPlus 4 | // 5 | // Created by leslie on 4/22/14. 6 | // Copyright (c) 2014 Hoolai Game Ltd. All rights reserved. 7 | // 8 | 9 | #import "UIView+Addition.h" 10 | UIInterfaceOrientation CSAInterfaceOrientation() { 11 | UIInterfaceOrientation orient = [UIApplication sharedApplication].statusBarOrientation; 12 | return orient; 13 | } 14 | 15 | CGRect CSAScreenBounds() { 16 | CGRect bounds = [UIScreen mainScreen].bounds; 17 | if (UIInterfaceOrientationIsLandscape(CSAInterfaceOrientation())) { 18 | CGFloat width = bounds.size.width; 19 | bounds.size.width = bounds.size.height; 20 | bounds.size.height = width; 21 | } 22 | return bounds; 23 | } 24 | @implementation UIView (Addition) 25 | 26 | - (CGFloat)left { 27 | return self.frame.origin.x; 28 | } 29 | 30 | 31 | /////////////////////////////////////////////////////////////////////////////////////////////////// 32 | - (void)setLeft:(CGFloat)x { 33 | CGRect frame = self.frame; 34 | frame.origin.x = x; 35 | self.frame = frame; 36 | } 37 | 38 | 39 | /////////////////////////////////////////////////////////////////////////////////////////////////// 40 | - (CGFloat)top { 41 | return self.frame.origin.y; 42 | } 43 | 44 | 45 | /////////////////////////////////////////////////////////////////////////////////////////////////// 46 | - (void)setTop:(CGFloat)y { 47 | CGRect frame = self.frame; 48 | frame.origin.y = y; 49 | self.frame = frame; 50 | } 51 | 52 | 53 | /////////////////////////////////////////////////////////////////////////////////////////////////// 54 | - (CGFloat)right { 55 | return self.frame.origin.x + self.frame.size.width; 56 | } 57 | 58 | 59 | /////////////////////////////////////////////////////////////////////////////////////////////////// 60 | - (void)setRight:(CGFloat)right { 61 | CGRect frame = self.frame; 62 | frame.origin.x = right - frame.size.width; 63 | self.frame = frame; 64 | } 65 | 66 | 67 | /////////////////////////////////////////////////////////////////////////////////////////////////// 68 | - (CGFloat)bottom { 69 | return self.frame.origin.y + self.frame.size.height; 70 | } 71 | 72 | 73 | /////////////////////////////////////////////////////////////////////////////////////////////////// 74 | - (void)setBottom:(CGFloat)bottom { 75 | CGRect frame = self.frame; 76 | frame.origin.y = bottom - frame.size.height; 77 | self.frame = frame; 78 | } 79 | 80 | 81 | /////////////////////////////////////////////////////////////////////////////////////////////////// 82 | - (CGFloat)centerX { 83 | return self.center.x; 84 | } 85 | 86 | 87 | /////////////////////////////////////////////////////////////////////////////////////////////////// 88 | - (void)setCenterX:(CGFloat)centerX { 89 | self.center = CGPointMake(centerX, self.center.y); 90 | } 91 | 92 | 93 | /////////////////////////////////////////////////////////////////////////////////////////////////// 94 | - (CGFloat)centerY { 95 | return self.center.y; 96 | } 97 | 98 | 99 | /////////////////////////////////////////////////////////////////////////////////////////////////// 100 | - (void)setCenterY:(CGFloat)centerY { 101 | self.center = CGPointMake(self.center.x, centerY); 102 | } 103 | 104 | 105 | /////////////////////////////////////////////////////////////////////////////////////////////////// 106 | - (CGFloat)width { 107 | return self.frame.size.width; 108 | } 109 | 110 | 111 | /////////////////////////////////////////////////////////////////////////////////////////////////// 112 | - (void)setWidth:(CGFloat)width { 113 | CGRect frame = self.frame; 114 | frame.size.width = width; 115 | self.frame = frame; 116 | } 117 | 118 | 119 | /////////////////////////////////////////////////////////////////////////////////////////////////// 120 | - (CGFloat)height { 121 | return self.frame.size.height; 122 | } 123 | 124 | 125 | /////////////////////////////////////////////////////////////////////////////////////////////////// 126 | - (void)setHeight:(CGFloat)height { 127 | CGRect frame = self.frame; 128 | frame.size.height = height; 129 | self.frame = frame; 130 | } 131 | 132 | 133 | /////////////////////////////////////////////////////////////////////////////////////////////////// 134 | - (CGFloat)ttScreenX { 135 | CGFloat x = 0; 136 | for (UIView* view = self; view; view = view.superview) { 137 | x += view.left; 138 | } 139 | return x; 140 | } 141 | 142 | 143 | /////////////////////////////////////////////////////////////////////////////////////////////////// 144 | - (CGFloat)ttScreenY { 145 | CGFloat y = 0; 146 | for (UIView* view = self; view; view = view.superview) { 147 | y += view.top; 148 | } 149 | return y; 150 | } 151 | 152 | 153 | /////////////////////////////////////////////////////////////////////////////////////////////////// 154 | - (CGFloat)screenViewX { 155 | CGFloat x = 0; 156 | for (UIView* view = self; view; view = view.superview) { 157 | x += view.left; 158 | 159 | if ([view isKindOfClass:[UIScrollView class]]) { 160 | UIScrollView* scrollView = (UIScrollView*)view; 161 | x -= scrollView.contentOffset.x; 162 | } 163 | } 164 | 165 | return x; 166 | } 167 | 168 | 169 | /////////////////////////////////////////////////////////////////////////////////////////////////// 170 | - (CGFloat)screenViewY { 171 | CGFloat y = 0; 172 | for (UIView* view = self; view; view = view.superview) { 173 | y += view.top; 174 | 175 | if ([view isKindOfClass:[UIScrollView class]]) { 176 | UIScrollView* scrollView = (UIScrollView*)view; 177 | y -= scrollView.contentOffset.y; 178 | } 179 | } 180 | return y; 181 | } 182 | 183 | 184 | /////////////////////////////////////////////////////////////////////////////////////////////////// 185 | - (CGRect)screenFrame { 186 | return CGRectMake(self.screenViewX, self.screenViewY, self.width, self.height); 187 | } 188 | 189 | 190 | /////////////////////////////////////////////////////////////////////////////////////////////////// 191 | - (CGPoint)origin { 192 | return self.frame.origin; 193 | } 194 | 195 | 196 | /////////////////////////////////////////////////////////////////////////////////////////////////// 197 | - (void)setOrigin:(CGPoint)origin { 198 | CGRect frame = self.frame; 199 | frame.origin = origin; 200 | self.frame = frame; 201 | } 202 | 203 | 204 | /////////////////////////////////////////////////////////////////////////////////////////////////// 205 | - (CGSize)size { 206 | return self.frame.size; 207 | } 208 | 209 | 210 | /////////////////////////////////////////////////////////////////////////////////////////////////// 211 | - (void)setSize:(CGSize)size { 212 | CGRect frame = self.frame; 213 | frame.size = size; 214 | self.frame = frame; 215 | } 216 | 217 | 218 | /////////////////////////////////////////////////////////////////////////////////////////////////// 219 | - (CGFloat)orientationWidth { 220 | return UIInterfaceOrientationIsLandscape(CSAInterfaceOrientation()) 221 | ? self.height : self.width; 222 | } 223 | 224 | 225 | /////////////////////////////////////////////////////////////////////////////////////////////////// 226 | - (CGFloat)orientationHeight { 227 | return UIInterfaceOrientationIsLandscape(CSAInterfaceOrientation()) 228 | ? self.width : self.height; 229 | } 230 | 231 | 232 | /////////////////////////////////////////////////////////////////////////////////////////////////// 233 | - (UIView*)descendantOrSelfWithClass:(Class)cls { 234 | if ([self isKindOfClass:cls]) 235 | return self; 236 | 237 | for (UIView* child in self.subviews) { 238 | UIView* it = [child descendantOrSelfWithClass:cls]; 239 | if (it) 240 | return it; 241 | } 242 | 243 | return nil; 244 | } 245 | 246 | 247 | /////////////////////////////////////////////////////////////////////////////////////////////////// 248 | - (UIView*)ancestorOrSelfWithClass:(Class)cls { 249 | if ([self isKindOfClass:cls]) { 250 | return self; 251 | 252 | } else if (self.superview) { 253 | return [self.superview ancestorOrSelfWithClass:cls]; 254 | 255 | } else { 256 | 257 | return nil; 258 | 259 | } 260 | } 261 | 262 | 263 | /////////////////////////////////////////////////////////////////////////////////////////////////// 264 | - (void)removeAllSubviews { 265 | while (self.subviews.count) { 266 | UIView* child = self.subviews.lastObject; 267 | [child removeFromSuperview]; 268 | } 269 | } 270 | 271 | /////////////////////////////////////////////////////////////////////////////////////////////////// 272 | - (CGPoint)offsetFromView:(UIView*)otherView { 273 | CGFloat x = 0, y = 0; 274 | for (UIView* view = self; view && view != otherView; view = view.superview) { 275 | x += view.left; 276 | y += view.top; 277 | } 278 | return CGPointMake(x, y); 279 | } 280 | 281 | - (void)setBorderColor:(UIColor *)borderColor width:(CGFloat)borderWidth cornerRadius:(CGFloat)cornerRadius 282 | { 283 | self.layer.borderColor = borderColor.CGColor; 284 | self.layer.cornerRadius = cornerRadius; 285 | self.layer.borderWidth = borderWidth; 286 | } 287 | @end 288 | -------------------------------------------------------------------------------- /DataManager/Common/Category/UIView+Common.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIView+Common.h 3 | // HLMagic 4 | // 5 | // Created by marujun on 13-12-8. 6 | // Copyright (c) 2013年 chen ying. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #define KeyboardAnimationCurve 7 << 16 12 | #define KeyboardAnimationDuration 0.25 13 | 14 | @interface BlurView : UIView 15 | 16 | // Use the following property to set the tintColor. Set it to nil to reset. 17 | @property (nonatomic, strong) UIColor *blurTintColor; 18 | 19 | @end 20 | 21 | @interface UIView (Common) 22 | 23 | - (UIView *)findFirstResponder; 24 | 25 | - (void)setBlurColor:(UIColor *)blurColor; 26 | 27 | - (UIViewController *)nearsetViewController; 28 | 29 | /** Set the anchorPoint of view without changing is perceived position. */ 30 | - (void)setAnchorPointMotionlessly:(CGPoint)anchorPoint xConstraint:(NSLayoutConstraint *)xConstraint yConstraint:(NSLayoutConstraint *)yConstraint; 31 | 32 | //添加动画遮罩 并在duration秒之后移除 33 | - (void)addMaskViewWithDuration:(float)duration; 34 | 35 | //标题View(是否loadingView) 36 | + (UIView *)titileViewWithTitle:(NSString *)title activity:(BOOL)activity; 37 | 38 | //标题View(带图片) 39 | + (UIView *)titileViewWithTitle:(NSString *)title image:(UIImage *)image; 40 | 41 | //注意: 必须使用weakSelf : __weak typeof(self) weakSelf = self; 42 | - (void)setTapActionWithBlock:(void (^)(void))block; 43 | 44 | - (void)setPanActionWithBlock:(void (^)(void))block; 45 | 46 | - (void) sizeLayoutToFit; 47 | 48 | @end 49 | -------------------------------------------------------------------------------- /DataManager/Common/Navigation/UIViewController+Navigation.h: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Navigation.h 3 | // HLSNS 4 | // 5 | // Created by 刘波 on 12-12-4. 6 | // Copyright (c) 2012年 hoolai. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface UIViewController (Navigation) 12 | 13 | // 设置回退按钮 14 | - (void)setNavigationBackButton:(UIButton *)button; 15 | - (void)setNavBackButtonWithTitle:(NSString *)title; 16 | 17 | - (void)navigationBackButtonAction:(UIButton *)sender; 18 | 19 | // 设置默认回退按钮 20 | - (void)setNavigationBackButtonDefault; 21 | 22 | // 为navigationbar设置左视图 23 | - (void)setNavigationLeftView:(UIView *)view; 24 | 25 | // 为navigationbar设置右视图 26 | -(void)setNavigationRightView:(UIView *)view; 27 | 28 | // 为navigationbar设置右视图集 29 | - (void)setNavigationRightViews:(NSArray *)views; 30 | 31 | // 为navigationbar设置标题视图 32 | - (void)setNavigationTitleView:(UIView *)view; 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /DataManager/Common/Navigation/UIViewController+Navigation.m: -------------------------------------------------------------------------------- 1 | // 2 | // UIViewController+Navigation.m 3 | // HLSNS 4 | // 5 | // Created by 刘波 on 12-12-4. 6 | // Copyright (c) 2012年 hoolai. All rights reserved. 7 | // 8 | 9 | #import "UIViewController+Navigation.h" 10 | #import "USViewController.h" 11 | 12 | @implementation UIViewController (Navigation) 13 | 14 | - (void)setNavigationBackButtonDefault 15 | { 16 | NSString *title = nil; 17 | NSArray *array = self.navigationController.viewControllers; 18 | if (array && array.count >= 2) { 19 | title = [array[array.count-2] title]; 20 | } 21 | 22 | [self setNavBackButtonWithTitle:title]; 23 | } 24 | 25 | - (void)setNavBackButtonWithTitle:(NSString *)title 26 | { 27 | UIButton *backButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 46, 44)]; 28 | [backButton setTitleColor:RGBCOLOR(255, 255, 255) forState:UIControlStateNormal]; 29 | backButton.titleLabel.font = [UIFont systemFontOfSize:16]; 30 | [backButton setTitleEdgeInsets:UIEdgeInsetsMake(0, 4, 0, 0)]; 31 | 32 | [backButton setImage:[UIImage imageNamed:(@"pub_nav_white_back.png")] forState:UIControlStateNormal]; 33 | [backButton setTitleColor:RGBCOLOR(136, 136, 136) forState:UIControlStateHighlighted]; 34 | if (!title || !title.length) title = @""; 35 | [backButton setTitle:title forState:UIControlStateNormal]; 36 | 37 | float width = [title stringWidthWithFont:backButton.titleLabel.font height:44]; 38 | backButton.frame = CGRectMake(0, 0, MAX(MIN(width, 60)+20, 44), 44); 39 | 40 | [self setNavigationBackButton:backButton]; 41 | [backButton setExclusiveTouch:YES]; 42 | } 43 | 44 | - (void)setNavigationBackButton:(UIButton *)button 45 | { 46 | [button addTarget:self action:@selector(navigationBackButtonAction:) forControlEvents:UIControlEventTouchUpInside]; 47 | [self setNavigationLeftView:button]; 48 | } 49 | 50 | - (void)navigationBackButtonAction:(UIButton *)sender 51 | { 52 | if (self.navigationController) { 53 | [self.navigationController popViewControllerAnimated:YES]; 54 | } 55 | else { 56 | [self dismissViewControllerAnimated:YES completion:nil]; 57 | } 58 | } 59 | 60 | - (void)setNavigationLeftView:(UIView *)view 61 | { 62 | if ([view isKindOfClass:[UIButton class]]) { 63 | [(UIButton *)view setContentHorizontalAlignment:UIControlContentHorizontalAlignmentLeft]; 64 | } 65 | 66 | UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:view]; 67 | 68 | // 调整 leftBarButtonItem 在 iOS6 下面的位置 69 | UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; 70 | if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){ 71 | negativeSpacer.width = 5; //向右移动5个像素 72 | }else{ 73 | negativeSpacer.width = -6; //向左移动6个像素 74 | } 75 | 76 | //不是双语按钮的情况 77 | if (![view.accessibilityLabel isEqual:@"bilingual"]) { 78 | //在us.上统一再向右移10个像素 79 | negativeSpacer.width += 10; 80 | } 81 | 82 | if ([self respondsToSelector:@selector(myNavigationItem)] && ((USViewController *)self).myNavigationItem) { 83 | ((USViewController *)self).myNavigationItem.leftBarButtonItems = @[negativeSpacer, buttonItem]; 84 | }else{ 85 | self.navigationItem.leftBarButtonItems = @[negativeSpacer, buttonItem]; 86 | } 87 | } 88 | 89 | - (void)setNavigationRightView:(UIView *)view 90 | { 91 | if ([view isKindOfClass:[UIButton class]]) { 92 | [(UIButton *)view setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight]; 93 | } 94 | UIBarButtonItem *buttonItem = [[UIBarButtonItem alloc] initWithCustomView:view]; 95 | 96 | // 调整 rightBarButtonItem 在 iOS6 下面的位置 97 | UIBarButtonItem *negativeSpacer = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFixedSpace target:nil action:nil]; 98 | if(floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_6_1){ 99 | negativeSpacer.width = 5; //向左移动5个像素 100 | }else{ 101 | negativeSpacer.width = -5; //向右移动5个像素 102 | } 103 | 104 | //在us.上统一再向左移10个像素 105 | negativeSpacer.width += 10; 106 | 107 | if ([self respondsToSelector:@selector(myNavigationItem)] && ((USViewController *)self).myNavigationItem) { 108 | ((USViewController *)self).myNavigationItem.rightBarButtonItems = @[negativeSpacer, buttonItem]; 109 | }else{ 110 | self.navigationItem.rightBarButtonItems = @[negativeSpacer, buttonItem]; 111 | } 112 | } 113 | 114 | - (void)setNavigationRightViews:(NSArray *)views 115 | { 116 | UIView *parentView = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 100, 44)]; 117 | parentView.backgroundColor = [UIColor clearColor]; 118 | parentView.clipsToBounds = YES; 119 | 120 | [self setNavigationRightView:parentView]; 121 | 122 | UIView *view1 = [views objectAtIndex:0]; 123 | UIView *view2 = [views objectAtIndex:1]; 124 | [parentView addSubview:view1]; 125 | [parentView addSubview:view2]; 126 | 127 | CGRect parentFrame = parentView.frame; 128 | CGRect view1Frame = view1.frame; 129 | CGRect view2Frame = view1.frame; 130 | 131 | view2Frame.origin.x = parentFrame.size.width-view2Frame.size.width; 132 | view2Frame.origin.y = (parentFrame.size.height-view2Frame.size.height)/2; 133 | view1Frame.origin.x = view2Frame.origin.x-view1Frame.size.width; 134 | view1Frame.origin.y = view2Frame.origin.y; 135 | 136 | view1.frame = view1Frame; 137 | view2.frame = view2Frame; 138 | } 139 | 140 | - (void)setNavigationTitleView:(UIView *)view 141 | { 142 | if ([self respondsToSelector:@selector(myNavigationItem)] && ((USViewController *)self).myNavigationItem) { 143 | ((USViewController *)self).myNavigationItem.titleView = view; 144 | }else{ 145 | self.navigationItem.titleView = view; 146 | } 147 | } 148 | 149 | @end 150 | -------------------------------------------------------------------------------- /DataManager/Common/Navigation/USNavDelegateHandler.h: -------------------------------------------------------------------------------- 1 | // 2 | // USNavDelegateHandler.h 3 | // USNavAnimation 4 | // 5 | // Created by marujun on 15/12/26. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface USNavDelegateHandler : UIView 12 | 13 | @property (strong, nonatomic) UINavigationController *navigationController; 14 | 15 | @end 16 | -------------------------------------------------------------------------------- /DataManager/Common/Navigation/USNavDelegateHandler.m: -------------------------------------------------------------------------------- 1 | // 2 | // USNavDelegateHandler.m 3 | // USNavAnimation 4 | // 5 | // Created by marujun on 15/12/26. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "USNavDelegateHandler.h" 10 | #import "USTransitionAnimator.h" 11 | #import "USViewController.h" 12 | 13 | @interface USNavDelegateHandler () 14 | 15 | @property (strong, nonatomic) USSysTransitionAnimator *sysTransition; 16 | @property (strong, nonatomic) USFlipTransitionAnimator *flipTransition; 17 | @property (strong, nonatomic) USFadeTransitionAnimator *fadeTransition; 18 | @property (strong, nonatomic) USScaleTransitionAnimator *scaleTransition; 19 | @property (strong, nonatomic) USPresentTransitionAnimator *presentTransition; 20 | 21 | @property (strong, nonatomic) UIPanGestureRecognizer *panGestureRecognizer; 22 | @property (strong, nonatomic) UIPercentDrivenInteractiveTransition *interactiveTransition; 23 | 24 | @end 25 | 26 | 27 | @implementation USNavDelegateHandler 28 | 29 | - (instancetype)init 30 | { 31 | self = [super init]; 32 | if (self) { 33 | // init your code 34 | self.hidden = YES; 35 | _panGestureRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(panGestureHandler:)]; 36 | _panGestureRecognizer.delegate = self; 37 | 38 | _sysTransition = [USSysTransitionAnimator new]; 39 | _flipTransition = [USFlipTransitionAnimator new]; 40 | _fadeTransition = [USFadeTransitionAnimator new]; 41 | _scaleTransition = [USScaleTransitionAnimator new]; 42 | _presentTransition = [USPresentTransitionAnimator new]; 43 | } 44 | return self; 45 | } 46 | 47 | - (void)setNavigationController:(UINavigationController *)navigationController 48 | { 49 | _navigationController = navigationController; 50 | 51 | [_navigationController.view insertSubview:self atIndex:0]; 52 | [_navigationController.view addGestureRecognizer:_panGestureRecognizer]; 53 | } 54 | 55 | - (void)panGestureHandler:(UIPanGestureRecognizer*)recognizer 56 | { 57 | // Calculate how far the user has dragged across the view 58 | UIView *view = _navigationController.view; 59 | CGPoint translation = [recognizer translationInView:view]; 60 | CGFloat progress = translation.x / CGRectGetWidth(view.bounds); 61 | progress = MIN(1.0, MAX(0.0, fabs(progress))); 62 | 63 | if (recognizer.state == UIGestureRecognizerStateBegan) { 64 | CGPoint location = [recognizer locationInView:view]; 65 | CGPoint velocity = [recognizer velocityInView:view]; 66 | NSInteger count = _navigationController.viewControllers.count; 67 | 68 | if (location.x < CGRectGetMidX(view.bounds) && velocity.x > 0 && count > 1) { // left half went right 69 | // Create a interactive transition and pop the view controller 70 | _interactiveTransition = [UIPercentDrivenInteractiveTransition new]; 71 | [_navigationController popViewControllerAnimated:YES]; 72 | } 73 | else if (location.x > CGRectGetMidX(view.bounds) && velocity.x < 0) { // right half went left 74 | //Need topViewController implementation selector 75 | USViewController *topViewController = (id)_navigationController.topViewController; 76 | if ([topViewController respondsToSelector:@selector(viewControllerWillPushForLeftDirectionPan)]) { 77 | UIViewController *viewController = [topViewController viewControllerWillPushForLeftDirectionPan]; 78 | if (viewController) { 79 | // Create a interactive transition and push the view controller 80 | _interactiveTransition = [UIPercentDrivenInteractiveTransition new]; 81 | [_navigationController pushViewController:viewController animated:YES]; 82 | } 83 | } 84 | } 85 | } 86 | else if (recognizer.state == UIGestureRecognizerStateChanged) { 87 | // Update the interactive transition's progress 88 | [_interactiveTransition updateInteractiveTransition:progress]; 89 | } 90 | else if (recognizer.state == UIGestureRecognizerStateEnded || 91 | recognizer.state == UIGestureRecognizerStateCancelled) { 92 | // Finish or cancel the interactive transition 93 | if (progress < 0.4 || recognizer.state == UIGestureRecognizerStateCancelled) { 94 | [_interactiveTransition cancelInteractiveTransition]; 95 | } else { 96 | [_interactiveTransition finishInteractiveTransition]; 97 | } 98 | _interactiveTransition = nil; 99 | } 100 | } 101 | 102 | - (id)navigationController:(UINavigationController *)navigationController animationControllerForOperation:(UINavigationControllerOperation)operation fromViewController:(UIViewController *)fromVC toViewController:(UIViewController *)toVC 103 | { 104 | USTransitionAnimator *transition = nil; 105 | 106 | BOOL reversed = operation==UINavigationControllerOperationPop; 107 | USViewController *targetVC = (USViewController *)(reversed?fromVC:toVC); 108 | 109 | if ([targetVC respondsToSelector:@selector(transitionOption)]) { 110 | switch (targetVC.transitionOption) { 111 | case USNavigationTransitionOptionFade: 112 | transition = _fadeTransition; 113 | break; 114 | case USNavigationTransitionOptionSystem: 115 | transition = _sysTransition; 116 | break; 117 | case USNavigationTransitionOptionFlip: 118 | transition = _interactiveTransition?_sysTransition:_flipTransition; 119 | break; 120 | case USNavigationTransitionOptionScale: 121 | if ([targetVC conformsToProtocol:@protocol(USScaleTransitionAnimatorDataSource)]) { 122 | _scaleTransition.dataSource = (id)targetVC; 123 | transition = _scaleTransition; 124 | } else { 125 | targetVC.transitionOption = USNavigationTransitionOptionNone; 126 | } 127 | break; 128 | 129 | case USNavigationTransitionOptionFromRight: 130 | case USNavigationTransitionOptionFromLeft: 131 | case USNavigationTransitionOptionFromTop: 132 | case USNavigationTransitionOptionFromBottom: 133 | transition = _presentTransition; 134 | _presentTransition.option = targetVC.transitionOption; 135 | break; 136 | 137 | default: 138 | break; 139 | } 140 | } 141 | transition.reversed = reversed; 142 | transition.interactive = _interactiveTransition?YES:NO; 143 | 144 | return transition; 145 | } 146 | 147 | - (id)navigationController:(UINavigationController *)navigationController interactionControllerForAnimationController:(id)animationController 148 | { 149 | if ([animationController isKindOfClass:[USTransitionAnimator class]]) { 150 | _panGestureRecognizer.enabled = YES; 151 | return _interactiveTransition; 152 | } 153 | 154 | _panGestureRecognizer.enabled = NO; 155 | return nil; 156 | } 157 | 158 | #pragma mark - UINavigationControllerDelegate 159 | - (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated 160 | { 161 | 162 | } 163 | 164 | - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(USViewController *)viewController animated:(BOOL)animated 165 | { 166 | if ([viewController respondsToSelector:@selector(transitionOption)] && 167 | viewController.transitionOption != USNavigationTransitionOptionNone) { 168 | _panGestureRecognizer.enabled = YES; 169 | } 170 | else { 171 | _panGestureRecognizer.enabled = NO; 172 | } 173 | } 174 | 175 | #pragma mark - UIGestureRecognizerDelegate 176 | - (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer 177 | { 178 | if (_applicationContext.disableInteractiveGesture) { 179 | return NO; 180 | } 181 | 182 | if (_navigationController.viewControllers.count == 1) { 183 | return NO; 184 | } 185 | 186 | USViewController *topVC = (id)_navigationController.topViewController; 187 | if ([topVC respondsToSelector:@selector(enableScreenEdgePanGesture)]) { 188 | return [topVC enableScreenEdgePanGesture]; 189 | } 190 | 191 | return YES; 192 | } 193 | 194 | @end 195 | -------------------------------------------------------------------------------- /DataManager/Common/Navigation/USTransitionAnimator.h: -------------------------------------------------------------------------------- 1 | // 2 | // USTransitionAnimator.h 3 | // USNavAnimation 4 | // 5 | // Created by marujun on 15/12/26. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef NS_ENUM(NSUInteger, USNavigationTransitionOption) { 12 | USNavigationTransitionOptionNone = 0, //系统默认动画 13 | USNavigationTransitionOptionFade, //渐隐渐现动画 14 | USNavigationTransitionOptionFlip, //3D翻转动画 15 | USNavigationTransitionOptionScale, //类似相册的缩放动画 16 | USNavigationTransitionOptionSystem, //模拟系统动画 17 | 18 | USNavigationTransitionOptionFromRight, //从右边弹出动画 19 | USNavigationTransitionOptionFromLeft, //从左边弹出动画 20 | USNavigationTransitionOptionFromTop, //从顶部弹出动画 21 | USNavigationTransitionOptionFromBottom, //从底部弹出动画 22 | }; 23 | 24 | @interface USTransitionAnimator : NSObject 25 | { 26 | BOOL _reversed; 27 | BOOL _interactive; 28 | } 29 | 30 | @property (nonatomic, assign) BOOL reversed; 31 | @property (nonatomic, assign) BOOL interactive; 32 | 33 | @end 34 | 35 | @interface USFadeTransitionAnimator : USTransitionAnimator 36 | 37 | @end 38 | 39 | @interface USFlipTransitionAnimator : USTransitionAnimator 40 | 41 | @end 42 | 43 | @class USScaleTransitionAnimator; 44 | @protocol USScaleTransitionAnimatorDataSource 45 | @required 46 | - (CGRect)beginRectWithScaleAnimator:(USScaleTransitionAnimator *)animator; 47 | - (CGRect)endRectWithScaleAnimator:(USScaleTransitionAnimator *)animator; 48 | - (NSArray *)fadeViewsWithScaleAnimator:(USScaleTransitionAnimator *)animator; 49 | - (UIView *)snapshotViewWithScaleAnimator:(USScaleTransitionAnimator *)animator; 50 | 51 | @optional 52 | - (void)snapshotViewDidPresented:(USScaleTransitionAnimator *)animator; 53 | - (void)snapshotViewDidDismiss:(USScaleTransitionAnimator *)animator; 54 | 55 | @end 56 | 57 | @interface USScaleTransitionAnimator : USTransitionAnimator 58 | 59 | @property (nonatomic, assign) BOOL cancel; 60 | @property (nonatomic, weak) id dataSource; 61 | 62 | @end 63 | 64 | @interface USSysTransitionAnimator : USTransitionAnimator 65 | 66 | @end 67 | 68 | @interface USPresentTransitionAnimator : USTransitionAnimator 69 | 70 | @property (nonatomic, assign) USNavigationTransitionOption option; 71 | 72 | @end -------------------------------------------------------------------------------- /DataManager/Common/Navigation/pub_nav_white_back@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marujun/DataManager/d1caede4fd13aaed7d596164c0bb26eb105527df/DataManager/Common/Navigation/pub_nav_white_back@2x.png -------------------------------------------------------------------------------- /DataManager/Common/USDataController.h: -------------------------------------------------------------------------------- 1 | // 2 | // USDataController.h 3 | // USEvent 4 | // 5 | // Created by marujun on 16/1/7. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef void (^USRequestCompletionBlock)(BOOL success); 12 | 13 | @interface USDataController : NSObject 14 | { 15 | BOOL _isFirstRequest; 16 | NSMutableArray *_dataSource; 17 | } 18 | 19 | @property (nonatomic, assign) BOOL isFirstRequest; 20 | @property (nonatomic, strong, readonly) NSMutableArray *dataSource; 21 | 22 | - (void)requestDataWithCompletionBlock:(USRequestCompletionBlock)completionBlock; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /DataManager/Common/USDataController.m: -------------------------------------------------------------------------------- 1 | // 2 | // USDataController.m 3 | // USEvent 4 | // 5 | // Created by marujun on 16/1/7. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "USDataController.h" 10 | 11 | @implementation USDataController 12 | 13 | - (instancetype)init 14 | { 15 | self = [super init]; 16 | if (self) { 17 | [self fInit]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)fInit 23 | { 24 | FLOG(@"init 创建类 %@", NSStringFromClass([self class])); 25 | } 26 | 27 | - (void)requestDataWithCompletionBlock:(USRequestCompletionBlock)completionBlock 28 | { 29 | 30 | } 31 | 32 | - (void)dealloc 33 | { 34 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 35 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 36 | 37 | FLOG(@"dealloc 释放类 %@", NSStringFromClass([self class])); 38 | } 39 | 40 | @end 41 | -------------------------------------------------------------------------------- /DataManager/Common/USViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // USViewController.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/9/8. 6 | // Copyright (c) 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "USTransitionAnimator.h" 11 | 12 | @interface USViewController : UIViewController 13 | { 14 | float _topInset; 15 | 16 | USNavigationTransitionOption _transitionOption; 17 | } 18 | 19 | @property(nonatomic, assign) float topInset; 20 | 21 | @property(nonatomic, strong) UILabel *navigationLine; 22 | @property(nonatomic, strong) UINavigationBar *navigationBar; 23 | @property(nonatomic, strong) UINavigationItem *myNavigationItem; 24 | 25 | @property (nonatomic, assign) USNavigationTransitionOption transitionOption; 26 | 27 | /** 是否允许屏幕边缘侧滑手势 */ 28 | @property (nonatomic, assign) BOOL enableScreenEdgePanGesture; 29 | 30 | 31 | - (void)updateDisplay; 32 | 33 | + (instancetype)viewController; 34 | 35 | - (UIViewController *)viewControllerWillPushForLeftDirectionPan; 36 | 37 | @end 38 | -------------------------------------------------------------------------------- /DataManager/Common/USViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // USViewController.m 3 | // USEvent 4 | // 5 | // Created by marujun on 15/9/8. 6 | // Copyright (c) 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "USViewController.h" 10 | 11 | @interface USViewController () 12 | 13 | @end 14 | 15 | 16 | @implementation USViewController 17 | 18 | - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil 19 | { 20 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]; 21 | if (self) { 22 | [self fInit]; 23 | } 24 | return self; 25 | } 26 | 27 | - (void)viewDidLoad 28 | { 29 | [super viewDidLoad]; 30 | 31 | self.view.clipsToBounds = YES; 32 | 33 | self.automaticallyAdjustsScrollViewInsets = NO; 34 | 35 | NSShadow *shadow = [NSShadow new]; 36 | NSDictionary *dict = @{NSShadowAttributeName:shadow}; 37 | 38 | self.navigationBar.clipsToBounds = YES; 39 | self.navigationBar.translucent = NO; 40 | self.navigationBar.titleTextAttributes = dict; 41 | self.navigationBar.barTintColor = [UIColor whiteColor]; 42 | 43 | if (self.navigationController) { 44 | self.navigationController.navigationBar.clipsToBounds = YES; 45 | self.navigationController.navigationBar.translucent = NO; 46 | self.navigationController.navigationBar.titleTextAttributes = dict; 47 | self.navigationController.navigationBar.barTintColor = [UIColor whiteColor]; 48 | [self.navigationController.navigationBar setTitleVerticalPositionAdjustment:-2 forBarMetrics:UIBarMetricsDefault]; 49 | } 50 | 51 | [self.view addSubview:self.navigationBar]; 52 | [self.navigationBar pushNavigationItem:self.myNavigationItem animated:NO]; 53 | [self.navigationBar autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsMake(0, -1, 0, 0) excludingEdge:ALEdgeBottom]; 54 | } 55 | 56 | - (void)setTitle:(NSString *)title 57 | { 58 | self.myNavigationItem.title = title; 59 | 60 | [super setTitle:title]; 61 | } 62 | 63 | - (void)fInit 64 | { 65 | _topInset = 64; 66 | _enableScreenEdgePanGesture = YES; 67 | self.navigationBar = [[UINavigationBar alloc] initForAutoLayout]; 68 | [self.navigationBar autoSetDimension:ALDimensionHeight toSize:_topInset]; 69 | 70 | self.myNavigationItem = [[UINavigationItem alloc] initWithTitle:@""]; 71 | [self.navigationBar setTitleVerticalPositionAdjustment:-2.f forBarMetrics:UIBarMetricsDefault]; 72 | 73 | FLOG(@"init 创建类 %@", NSStringFromClass([self class])); 74 | } 75 | 76 | - (void)updateDisplay 77 | { 78 | 79 | } 80 | 81 | - (UIViewController *)viewControllerWillPushForLeftDirectionPan 82 | { 83 | return nil; 84 | } 85 | 86 | + (instancetype)viewController 87 | { 88 | return [[self alloc] initWithNibName:NSStringFromClass([self class]) bundle:nil]; 89 | } 90 | 91 | - (void)viewWillAppear:(BOOL)animated 92 | { 93 | [super viewWillAppear:animated]; 94 | 95 | if ([self UMStatisticPage]) { 96 | // [MobClick beginLogPageView:[self UMStatisticPage]]; 97 | } 98 | 99 | [[ImageCacheManager defaultManager] bringIdentifyToFront:NSStringFromClass([self class])]; 100 | } 101 | 102 | - (void)viewWillDisappear:(BOOL)animated 103 | { 104 | [super viewWillDisappear:animated]; 105 | 106 | if ([self UMStatisticPage]) { 107 | // [MobClick endLogPageView:[self UMStatisticPage]]; 108 | } 109 | } 110 | 111 | 112 | 113 | //友盟页面统计 114 | - (NSString *)UMStatisticPage 115 | { 116 | #ifdef DEBUG 117 | return nil; 118 | #else 119 | NSString *className = NSStringFromClass([self class]); 120 | 121 | if ([className isEqualToString:@"USHomeViewController"]) { 122 | return @"首页"; 123 | } 124 | 125 | return nil; 126 | #endif 127 | } 128 | 129 | - (void)dealloc 130 | { 131 | [NSObject cancelPreviousPerformRequestsWithTarget:self]; 132 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 133 | 134 | FLOG(@"dealloc 释放类 %@", NSStringFromClass([self class])); 135 | } 136 | 137 | @end 138 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/AuthData.h: -------------------------------------------------------------------------------- 1 | // 2 | // AuthData.h 3 | // HLMagic 4 | // 5 | // Created by marujun on 14-1-8. 6 | // Copyright (c) 2014年 chen ying. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "DBLoginUser.h" 11 | 12 | @interface AuthData : NSData 13 | 14 | + (DBLoginUser *)loginUser; 15 | 16 | + (void)removeLoginUser; 17 | 18 | + (void)synchronize; 19 | + (void)loginSuccess:(NSDictionary *)info; 20 | 21 | //操作当前用户在UserDefault中对应的字典 22 | + (id)objectForKey:(NSString *)aKey; 23 | + (void)setObject:(id)anObject forKey:(NSString *)aKey; 24 | + (void)removeObjectForKey:(NSString *)aKey; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/AuthData.m: -------------------------------------------------------------------------------- 1 | // 2 | // AuthData.m 3 | // HLMagic 4 | // 5 | // Created by marujun on 14-1-8. 6 | // Copyright (c) 2014年 chen ying. All rights reserved. 7 | // 8 | 9 | #import "AuthData.h" 10 | 11 | static DBLoginUser *loginUser; 12 | 13 | @implementation AuthData 14 | 15 | + (DBLoginUser *)loginUser 16 | { 17 | if (!loginUser) { 18 | NSDictionary *info = [userDefaults objectForKey:@"LoginUser"]; 19 | if (info) { 20 | loginUser = [[DBLoginUser alloc] initWithObject:info]; 21 | } 22 | } 23 | return loginUser; 24 | } 25 | 26 | + (void)removeLoginUser 27 | { 28 | loginUser = nil; 29 | [self synchronize]; 30 | } 31 | 32 | + (void)loginSuccess:(NSDictionary *)info 33 | { 34 | loginUser = [[DBLoginUser alloc] initWithObject:info]; 35 | [self synchronize]; 36 | 37 | //通知其他页面刷新数据 38 | [[NSNotificationCenter defaultCenter] postNotificationName:@"LoginSuccess" object:nil]; 39 | } 40 | 41 | + (void)synchronize 42 | { 43 | if (loginUser) { 44 | [userDefaults setObject:[loginUser dictionary] forKey:@"LoginUser"]; 45 | } else { 46 | [userDefaults removeObjectForKey:@"LoginUser"]; 47 | } 48 | 49 | [userDefaults synchronize]; 50 | } 51 | 52 | + (NSDictionary *)authData 53 | { 54 | NSMutableDictionary *allAuthData = [[userDefaults objectForKey:@"AllAuthData"] mutableCopy]; 55 | if (allAuthData) { 56 | NSString *userId = @"0"; 57 | if (loginUser) { 58 | userId = [loginUser uid]; 59 | } 60 | NSMutableDictionary *userAuthData = [[allAuthData objectForKey:userId] mutableCopy]; 61 | return userAuthData.copy; 62 | } 63 | return nil; 64 | } 65 | 66 | + (id)objectForKey:(NSString *)aKey 67 | { 68 | id value = nil; 69 | @try { 70 | NSMutableDictionary *userAuthData = [[AuthData authData] mutableCopy]; 71 | if(userAuthData){ 72 | value = [userAuthData objectForKey:aKey]; 73 | } 74 | value = [self defaultValue:value key:aKey]; 75 | } 76 | @catch (NSException *exception) { 77 | NSLog(@"%s [Line %d] exception:\n%@",__PRETTY_FUNCTION__, __LINE__,exception); 78 | } 79 | return value; 80 | } 81 | 82 | + (id)defaultValue:(id)value key:(NSString *)key 83 | { 84 | if (value == nil) { 85 | 86 | } 87 | return value; 88 | } 89 | 90 | + (void)setObject:(id)anObject forKey:(NSString *)aKey 91 | { 92 | @try { 93 | [AuthData operateUserData:^(NSMutableDictionary *userData) { 94 | [userData setValue:anObject forKey:aKey]; 95 | }]; 96 | } 97 | @catch (NSException *exception) { 98 | NSLog(@"%s [Line %d] exception:\n%@",__PRETTY_FUNCTION__, __LINE__,exception); 99 | } 100 | } 101 | 102 | + (void)removeObjectForKey:(NSString *)aKey 103 | { 104 | @try { 105 | [AuthData operateUserData:^(NSMutableDictionary *userData) { 106 | [userData removeObjectForKey:aKey]; 107 | }]; 108 | } 109 | @catch (NSException *exception) { 110 | NSLog(@"%s [Line %d] exception:\n%@",__PRETTY_FUNCTION__, __LINE__,exception); 111 | } 112 | } 113 | 114 | + (void)operateUserData:(void (^)(NSMutableDictionary *userData))callback 115 | { 116 | NSMutableDictionary *allAuthData = [[userDefaults objectForKey:@"AllAuthData"] mutableCopy]; 117 | if (!allAuthData) { 118 | allAuthData = [[NSMutableDictionary alloc] init]; 119 | } 120 | NSString *userId = @"0"; 121 | if (loginUser) { 122 | userId = [loginUser uid]; 123 | } 124 | NSMutableDictionary *userAuthData = [[allAuthData objectForKey:userId] mutableCopy]; 125 | if(!userAuthData){ 126 | userAuthData = [[NSMutableDictionary alloc] init]; 127 | } 128 | 129 | //执行回调 130 | callback ? callback(userAuthData) : nil; 131 | 132 | [allAuthData setValue:userAuthData forKey:userId]; 133 | 134 | [userDefaults setValue:allAuthData forKey:@"AllAuthData"]; 135 | [userDefaults synchronize]; 136 | } 137 | 138 | @end 139 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/MCMenuLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCMenuLabel.h 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-6-11. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface MCMenuLabel : UILabel 12 | 13 | @property (nonatomic, assign) BOOL copyingEnabled; // Defaults to YES 14 | 15 | // You may want to add longPressGestureRecognizer to a container view 16 | @property (nonatomic, strong, readonly) UILongPressGestureRecognizer *longPressGestureRecognizer; 17 | 18 | @end 19 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/MCMenuLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCMenuLabel.m 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-6-11. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import "MCMenuLabel.h" 10 | 11 | @implementation MCMenuLabel 12 | 13 | - (id)initWithFrame:(CGRect)frame 14 | { 15 | if (self = [super initWithFrame:frame]) 16 | { 17 | [self setup]; 18 | } 19 | return self; 20 | } 21 | 22 | - (void)awakeFromNib 23 | { 24 | [self setup]; 25 | } 26 | 27 | - (void)setup 28 | { 29 | self.userInteractionEnabled = YES; 30 | _copyingEnabled = YES; 31 | 32 | _longPressGestureRecognizer = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(longPress:)]; 33 | [self addGestureRecognizer:_longPressGestureRecognizer]; 34 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(willHideEditMenu:) name:UIMenuControllerDidHideMenuNotification object:nil]; 35 | } 36 | 37 | - (void)dealloc 38 | { 39 | [[NSNotificationCenter defaultCenter] removeObserver:self]; 40 | } 41 | 42 | #pragma mark - Public 43 | 44 | - (void)setCopyingEnabled:(BOOL)copyingEnabled 45 | { 46 | if (_copyingEnabled != copyingEnabled) 47 | { 48 | _copyingEnabled = copyingEnabled; 49 | 50 | self.userInteractionEnabled = copyingEnabled; 51 | _longPressGestureRecognizer.enabled = copyingEnabled; 52 | } 53 | } 54 | 55 | #pragma mark - Callbacks 56 | 57 | - (void)willHideEditMenu:(NSNotification *)note 58 | { 59 | [UIView animateWithDuration:.3 animations:^{ 60 | self.backgroundColor = [UIColor clearColor]; 61 | }]; 62 | } 63 | 64 | - (void)longPress:(UILongPressGestureRecognizer *)recognizer 65 | { 66 | if (recognizer.state == UIGestureRecognizerStateBegan) { 67 | [recognizer.view becomeFirstResponder]; 68 | 69 | UIMenuController *copyMenu = [UIMenuController sharedMenuController]; 70 | UIMenuItem *copyItem = [[UIMenuItem alloc] initWithTitle:@"复制"action:@selector(copyAction:)]; 71 | [copyMenu setMenuItems:[NSArray arrayWithObjects:copyItem, nil]]; 72 | [copyMenu setTargetRect:recognizer.view.bounds inView:recognizer.view]; 73 | [copyMenu setMenuVisible:YES animated:YES]; 74 | 75 | [UIView animateWithDuration:.3 animations:^{ 76 | self.backgroundColor = HexColor(0xe8e8e8); 77 | }]; 78 | } 79 | } 80 | 81 | #pragma mark - UIResponder 82 | 83 | - (BOOL)canBecomeFirstResponder 84 | { 85 | return true; 86 | } 87 | 88 | - (BOOL)canPerformAction:(SEL)action withSender:(id)sender 89 | { 90 | if (action == @selector(copyAction:)){ 91 | return YES; 92 | } 93 | return NO; 94 | } 95 | 96 | - (void)copyAction:(id)sender 97 | { 98 | [[UIPasteboard generalPasteboard] setString:self.text]; 99 | } 100 | 101 | 102 | @end 103 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/MCVerticalLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // MCVerticalLabel.h 3 | // MCFriends 4 | // 5 | // Created by marujun on 15/2/2. 6 | // Copyright (c) 2015年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | typedef enum 12 | { 13 | VerticalAlignmentTop = 0, // default 14 | VerticalAlignmentMiddle, 15 | VerticalAlignmentBottom, 16 | } VerticalAlignment; 17 | 18 | @interface MCVerticalLabel : UILabel 19 | { 20 | @private 21 | VerticalAlignment _verticalAlignment; 22 | } 23 | 24 | @property (nonatomic) VerticalAlignment verticalAlignment; 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/MCVerticalLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // MCVerticalLabel.m 3 | // MCFriends 4 | // 5 | // Created by marujun on 15/2/2. 6 | // Copyright (c) 2015年 marujun. All rights reserved. 7 | // 8 | 9 | #import "MCVerticalLabel.h" 10 | 11 | @implementation MCVerticalLabel 12 | @synthesize verticalAlignment = verticalAlignment_; 13 | 14 | //code 15 | - (id)initWithFrame:(CGRect)frame 16 | { 17 | if (self = [super initWithFrame:frame]) { 18 | self.verticalAlignment = VerticalAlignmentMiddle; 19 | } 20 | return self; 21 | } 22 | 23 | //XIB 24 | - (id)initWithCoder:(NSCoder *)aDecoder 25 | { 26 | self = [super initWithCoder:aDecoder]; 27 | if (self) { 28 | self.verticalAlignment = VerticalAlignmentMiddle; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)setVerticalAlignment:(VerticalAlignment)verticalAlignment 34 | { 35 | verticalAlignment_ = verticalAlignment; 36 | 37 | [self setNeedsDisplay]; 38 | } 39 | 40 | - (CGRect)textRectForBounds:(CGRect)bounds limitedToNumberOfLines:(NSInteger)numberOfLines 41 | { 42 | CGRect textRect = [super textRectForBounds:bounds limitedToNumberOfLines:numberOfLines]; 43 | 44 | switch (self.verticalAlignment) { 45 | case VerticalAlignmentTop: 46 | textRect.origin.y = bounds.origin.y; 47 | break; 48 | case VerticalAlignmentBottom: 49 | textRect.origin.y = bounds.origin.y + bounds.size.height - textRect.size.height; 50 | break; 51 | case VerticalAlignmentMiddle: 52 | // Fall through. 53 | default: 54 | textRect.origin.y = bounds.origin.y + (bounds.size.height - textRect.size.height) / 2.0; 55 | } 56 | return textRect; 57 | } 58 | 59 | - (void)drawTextInRect:(CGRect)requestedRect 60 | { 61 | CGRect actualRect = [self textRectForBounds:requestedRect limitedToNumberOfLines:self.numberOfLines]; 62 | 63 | [super drawTextInRect:actualRect]; 64 | } 65 | 66 | 67 | @end 68 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/SoundPlayer.h: -------------------------------------------------------------------------------- 1 | // 2 | // SoundPlayer.h 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-4-25. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface SoundPlayer : NSObject 13 | 14 | 15 | @property (nonatomic, assign) SystemSoundID soundID; 16 | @property (nonatomic, assign) BOOL isPlaying; 17 | 18 | 19 | /** 20 | * @brief 为播放震动效果初始化 21 | * 22 | * @return self 23 | */ 24 | + (instancetype)initVibratePlayer; 25 | 26 | /** 27 | * @brief 为播放系统音效初始化(无需提供音频文件) 28 | * 29 | * SoundID 类型 http://iphonedevwiki.net/index.php/AudioService 30 | * 31 | * @param fileName 系统音效名称 32 | * 33 | * @return self 34 | */ 35 | + (instancetype)initSystemPlayerWithFileName:(NSString *)fileName; 36 | 37 | /** 38 | * @brief 为播放特定的音频文件初始化(需提供音频文件) 39 | * 40 | * @param fileName 音频文件名(加在工程中) 41 | * 42 | * @return self 43 | */ 44 | + (instancetype)initPlayerWithFileName:(NSString *)fileName; 45 | 46 | /** 47 | * @brief 播放音效 48 | */ 49 | - (void)play; 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/SoundPlayer.m: -------------------------------------------------------------------------------- 1 | // 2 | // SoundPlayer.m 3 | // MCFriends 4 | // 5 | // Created by marujun on 14-4-25. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import "SoundPlayer.h" 10 | 11 | @implementation SoundPlayer 12 | 13 | /** 14 | * @brief 为播放震动效果初始化 15 | */ 16 | + (instancetype)initVibratePlayer 17 | { 18 | SoundPlayer *player = [[SoundPlayer alloc] init]; 19 | player.soundID = kSystemSoundID_Vibrate; 20 | return player; 21 | } 22 | 23 | 24 | /** 25 | * @brief 为播放系统音效初始化(无需提供音频文件) 26 | */ 27 | + (instancetype)initSystemPlayerWithFileName:(NSString *)fileName 28 | { 29 | SoundPlayer *player = [[SoundPlayer alloc] init]; 30 | NSString *path = [NSString stringWithFormat:@"/System/Library/Audio/UISounds/%@",fileName]; 31 | if (path) { 32 | SystemSoundID theSoundID; 33 | OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)[NSURL fileURLWithPath:path],&theSoundID); 34 | 35 | if (error == kAudioServicesNoError) { 36 | player.soundID = theSoundID; 37 | }else { 38 | NSLog(@"Failed to create sound "); 39 | } 40 | } 41 | return player; 42 | } 43 | 44 | /** 45 | * @brief 为播放特定的音频文件初始化(需提供音频文件) 46 | */ 47 | + (instancetype)initPlayerWithFileName:(NSString *)fileName 48 | { 49 | SoundPlayer *player = [[SoundPlayer alloc] init]; 50 | NSURL *fileURL = [[NSBundle mainBundle] URLForResource:fileName withExtension:nil]; 51 | if (fileURL != nil) 52 | { 53 | SystemSoundID theSoundID; 54 | OSStatus error = AudioServicesCreateSystemSoundID((__bridge CFURLRef)fileURL, &theSoundID); 55 | if (error == kAudioServicesNoError){ 56 | player.soundID = theSoundID; 57 | }else { 58 | NSLog(@"Failed to create sound "); 59 | } 60 | } 61 | return player; 62 | } 63 | 64 | /** 65 | * @brief 播放音效 66 | */ 67 | - (void)play 68 | { 69 | if (_soundID == kSystemSoundID_Vibrate) { 70 | AudioServicesPlayAlertSound(kSystemSoundID_Vibrate); 71 | }else{ 72 | if (_isPlaying) { 73 | return; 74 | } 75 | // 根据ID播放自定义系统声音 76 | AudioServicesPlaySystemSound(_soundID); 77 | _isPlaying = true; 78 | 79 | AudioServicesAddSystemSoundCompletion(_soundID, NULL, NULL, &playFinished, (__bridge void *)(self)); 80 | } 81 | } 82 | 83 | 84 | /** 85 | *参数说明: 86 | * 1、刚刚播放完成自定义系统声音的ID 87 | * 2、回调函数(playFinished)执行的run Loop,NULL表示main run loop 88 | * 3、回调函数执行所在run loop的模式,NULL表示默认的run loop mode 89 | * 4、需要回调的函数 90 | * 5、传入的参数, 此参数会被传入回调函数里 91 | */ 92 | void playFinished(SystemSoundID soundId, void* clientData) 93 | { 94 | SystemSoundID ID = soundId; // soundId 不能直接作为参数打印出来,需要中转一次 95 | 96 | NSLog(@"播放完成-传入ID为: %@, 传入的参数为%@", @(ID), clientData); 97 | 98 | ((__bridge SoundPlayer *)clientData).isPlaying = false; 99 | 100 | // 移除完成后执行的函数 101 | AudioServicesRemoveSystemSoundCompletion(ID); 102 | } 103 | 104 | -(void)dealloc 105 | { 106 | // 根据ID释放自定义系统声音 107 | AudioServicesDisposeSystemSoundID(_soundID); 108 | } 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/USHVButton.h: -------------------------------------------------------------------------------- 1 | // 2 | // USHVButton.h 3 | // HappyIn 4 | // 5 | // Created by marujun on 16/3/2. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface USHVButton : UIButton 12 | 13 | /*! 14 | @property 15 | @brief 图片和文字之间的垂直间距,默认为0 16 | */ 17 | @property (assign, nonatomic) CGFloat space; 18 | 19 | /*! 20 | @property 21 | @brief 重置图片的尺寸,默认取图片原有的尺寸 22 | */ 23 | @property (assign, nonatomic) CGSize image_size; 24 | 25 | @end 26 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/USHVButton.m: -------------------------------------------------------------------------------- 1 | // 2 | // USHVButton.m 3 | // HappyIn 4 | // 5 | // Created by marujun on 16/3/2. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "USHVButton.h" 10 | 11 | @implementation USHVButton 12 | 13 | //code 14 | - (id)initWithFrame:(CGRect)frame 15 | { 16 | self = [super initWithFrame:frame]; 17 | if (self) { 18 | [self makeEdgeHighlighted:self.highlighted]; 19 | } 20 | return self; 21 | } 22 | 23 | //XIB 24 | - (id)initWithCoder:(NSCoder *)aDecoder 25 | { 26 | self = [super initWithCoder:aDecoder]; 27 | if (self) { 28 | [self makeEdgeHighlighted:self.highlighted]; 29 | } 30 | return self; 31 | } 32 | 33 | - (void)setSpace:(CGFloat)space 34 | { 35 | _space = space; 36 | 37 | [self makeEdgeHighlighted:self.highlighted]; 38 | } 39 | 40 | - (void)setImage_size:(CGSize)image_size 41 | { 42 | _image_size = image_size; 43 | 44 | [self setImageSize:_image_size forState:UIControlStateNormal]; 45 | [self setImageSize:_image_size forState:UIControlStateHighlighted]; 46 | [self setImageSize:_image_size forState:UIControlStateSelected]; 47 | } 48 | 49 | - (void)setImageSize:(CGSize)size forState:(UIControlState)state 50 | { 51 | UIImage *oldImage = [self imageForState:state]; 52 | 53 | if (oldImage && !CGSizeEqualToSize(oldImage.size, size)) { 54 | [self setImage:[oldImage imageScaledToSize:size] forState:state]; 55 | } 56 | } 57 | 58 | - (void)setImage:(UIImage *)image forState:(UIControlState)state 59 | { 60 | UIImage *oldImage = [self imageForState:state]; 61 | 62 | [super setImage:image forState:state]; 63 | 64 | if (!oldImage || !CGSizeEqualToSize(oldImage.size, image.size)) { 65 | [self makeEdgeHighlighted:self.highlighted]; 66 | } 67 | } 68 | 69 | - (void)setTitle:(NSString *)title forState:(UIControlState)state 70 | { 71 | [super setTitle:title forState:state]; 72 | 73 | [self makeEdgeHighlighted:self.highlighted]; 74 | } 75 | 76 | - (void)setFrame:(CGRect)frame 77 | { 78 | [super setFrame:frame]; 79 | 80 | [self makeEdgeHighlighted:self.highlighted]; 81 | } 82 | 83 | - (void)setHighlighted:(BOOL)highlighted 84 | { 85 | [super setHighlighted:highlighted]; 86 | 87 | [self makeEdgeHighlighted:highlighted]; 88 | } 89 | 90 | - (void)setSelected:(BOOL)selected 91 | { 92 | [super setSelected:selected]; 93 | 94 | [self makeEdgeHighlighted:self.highlighted]; 95 | } 96 | 97 | - (void)makeEdgeHighlighted:(BOOL)highlighted 98 | { 99 | [self setTitleEdgeInsets:UIEdgeInsetsZero]; 100 | [self setImageEdgeInsets:UIEdgeInsetsZero]; 101 | 102 | NSString *_text; 103 | UIImage *_image; 104 | 105 | if (highlighted) { 106 | _text = [self titleForState:UIControlStateHighlighted]; 107 | _image = [self imageForState:UIControlStateHighlighted]; 108 | } 109 | else if (self.selected){ 110 | _text = [self titleForState:UIControlStateSelected]; 111 | _image = [self imageForState:UIControlStateSelected]; 112 | } 113 | else{ 114 | _text = [self titleForState:UIControlStateNormal]; 115 | _image = [self imageForState:UIControlStateNormal]; 116 | } 117 | 118 | self.contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; 119 | self.contentVerticalAlignment = UIControlContentVerticalAlignmentTop; 120 | 121 | CGFloat btnWidth = self.bounds.size.width; 122 | CGFloat btnHeight = self.bounds.size.height; 123 | 124 | CGFloat imgHeight = _image.size.height; 125 | 126 | CGFloat imgCenterX = self.imageView.center.x; 127 | 128 | CGFloat textHeight = self.titleLabel.bounds.size.height; 129 | CGSize size = [self sizeWithFont:self.titleLabel.font 130 | constrainedToSize:CGSizeMake(CGFLOAT_MAX, textHeight) 131 | text:_text]; 132 | 133 | CGFloat textCenterX = size.width/2 + self.titleLabel.frame.origin.x; 134 | 135 | CGFloat top = (btnHeight - (imgHeight + self.space + textHeight)) / 2; 136 | 137 | [self setImageEdgeInsets:UIEdgeInsetsMake(top, (btnWidth / 2 - imgCenterX), 0, 0)]; 138 | [self setTitleEdgeInsets:UIEdgeInsetsMake(imgHeight + self.space + top, (btnWidth / 2 - textCenterX), 0, 0)]; 139 | } 140 | 141 | - (CGSize)sizeWithFont:(UIFont*)tFont constrainedToSize:(CGSize)consize text:(NSString *)text 142 | { 143 | if (!(text.length > 0)) { 144 | text = @""; 145 | } 146 | 147 | NSAttributedString *attrStr = [[NSAttributedString alloc] initWithString:text 148 | attributes:@{NSFontAttributeName:tFont}]; 149 | return [attrStr boundingRectWithSize:consize 150 | options:NSStringDrawingUsesLineFragmentOrigin 151 | context:nil].size; 152 | } 153 | 154 | 155 | @end 156 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/USMultiLineLabel.h: -------------------------------------------------------------------------------- 1 | // 2 | // USMultiLineLabel.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/11/30. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface USMultiLineLabel : UILabel 12 | { 13 | @private 14 | long characterSpacing_; //字间距 15 | CGFloat linesSpacing_; //行间距 16 | } 17 | 18 | @property(nonatomic, assign) long characterSpacing; 19 | @property(nonatomic, assign) CGFloat linesSpacing; 20 | 21 | /** 绘制前获取label高度和最小宽度 */ 22 | - (CGSize)sizeWithAttributedStringWidth:(CGFloat)width; 23 | 24 | @end 25 | -------------------------------------------------------------------------------- /DataManager/Common/Utils/USMultiLineLabel.m: -------------------------------------------------------------------------------- 1 | // 2 | // USMultiLineLabel.m 3 | // USEvent 4 | // 5 | // Created by marujun on 15/11/30. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "USMultiLineLabel.h" 10 | #import 11 | 12 | @interface USMultiLineLabel() 13 | { 14 | @private 15 | NSMutableAttributedString *attributedString; 16 | } 17 | - (void) initAttributedString; 18 | @end 19 | 20 | 21 | @implementation USMultiLineLabel 22 | 23 | @synthesize characterSpacing = characterSpacing_; 24 | @synthesize linesSpacing = linesSpacing_; 25 | 26 | - (id)initWithFrame:(CGRect)frame 27 | { 28 | //初始化字间距、行间距 29 | self = [super initWithFrame:frame]; 30 | if (self) { 31 | self.characterSpacing = 1.0f; 32 | self.linesSpacing = 4.4f; 33 | } 34 | return self; 35 | } 36 | 37 | //外部调用设置字间距 38 | - (void)setCharacterSpacing:(long)characterSpacing 39 | { 40 | characterSpacing_ = characterSpacing; 41 | [self setNeedsDisplay]; 42 | } 43 | 44 | //外部调用设置行间距 45 | - (void)setLinesSpacing:(CGFloat)linesSpacing 46 | { 47 | linesSpacing_ = linesSpacing; 48 | [self setNeedsDisplay]; 49 | } 50 | 51 | /* 52 | * 初始化AttributedString并进行相应设置 53 | */ 54 | - (void)initAttributedString 55 | { 56 | if(!attributedString || ![attributedString.string isEqualToString:self.text]){ 57 | //去掉空行 58 | NSString *labelString = self.text; 59 | NSString *myString = [labelString stringByReplacingOccurrencesOfString:@"\r\n" withString:@"\n"]; 60 | 61 | //创建AttributeString 62 | attributedString = [[NSMutableAttributedString alloc] initWithString:myString]; 63 | 64 | //设置字体及大小 65 | CTFontRef helveticaBold = CTFontCreateWithName((CFStringRef)self.font.fontName, self.font.pointSize, NULL); 66 | [attributedString addAttribute:(id)kCTFontAttributeName value:(__bridge id)helveticaBold range:NSMakeRange(0,[attributedString length])]; 67 | 68 | //设置字间距 69 | long number = self.characterSpacing; 70 | 71 | CFNumberRef num = CFNumberCreate(kCFAllocatorDefault,kCFNumberSInt8Type,&number); 72 | [attributedString addAttribute:(id)kCTKernAttributeName value:(__bridge id)num range:NSMakeRange(0,[attributedString length])]; 73 | CFRelease(num); 74 | 75 | //设置字体颜色 76 | [attributedString addAttribute:(id)kCTForegroundColorAttributeName value:(id)(self.textColor.CGColor) range:NSMakeRange(0,[attributedString length])]; 77 | 78 | //创建文本对齐方式 79 | CTTextAlignment alignment = kCTLeftTextAlignment; 80 | if(self.textAlignment == NSTextAlignmentCenter) 81 | { 82 | alignment = kCTCenterTextAlignment; 83 | } 84 | if(self.textAlignment == NSTextAlignmentRight) 85 | { 86 | alignment = kCTRightTextAlignment; 87 | } 88 | 89 | CTParagraphStyleSetting alignmentStyle; 90 | 91 | alignmentStyle.spec = kCTParagraphStyleSpecifierAlignment; 92 | 93 | alignmentStyle.valueSize = sizeof(alignment); 94 | 95 | alignmentStyle.value = &alignment; 96 | 97 | //设置文本行间距 98 | CGFloat lineSpace = self.linesSpacing; 99 | 100 | CTParagraphStyleSetting lineSpaceStyle; 101 | lineSpaceStyle.spec = kCTParagraphStyleSpecifierLineSpacingAdjustment; 102 | lineSpaceStyle.valueSize = sizeof(lineSpace); 103 | lineSpaceStyle.value =&lineSpace; 104 | 105 | //设置文本段间距 106 | CGFloat paragraphSpacing = 15.0; 107 | CTParagraphStyleSetting paragraphSpaceStyle; 108 | paragraphSpaceStyle.spec = kCTParagraphStyleSpecifierParagraphSpacing; 109 | paragraphSpaceStyle.valueSize = sizeof(CGFloat); 110 | paragraphSpaceStyle.value = ¶graphSpacing; 111 | 112 | //创建设置数组 113 | CTParagraphStyleSetting settings[ ] ={alignmentStyle,lineSpaceStyle,paragraphSpaceStyle}; 114 | CTParagraphStyleRef style = CTParagraphStyleCreate(settings ,3); 115 | 116 | //给文本添加设置 117 | [attributedString addAttribute:(id)kCTParagraphStyleAttributeName value:(__bridge id)style range:NSMakeRange(0 , [attributedString length])]; 118 | CFRelease(helveticaBold); 119 | } 120 | } 121 | 122 | 123 | /* 124 | * 覆写setText方法 125 | */ 126 | - (void) setText:(NSString *)text 127 | { 128 | [super setText:text]; 129 | [self initAttributedString]; 130 | } 131 | 132 | /* 133 | * 开始绘制 134 | */ 135 | - (void) drawTextInRect:(CGRect)requestedRect 136 | { 137 | [self initAttributedString]; 138 | 139 | //排版 140 | 141 | CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); 142 | 143 | CGMutablePathRef leftColumnPath = CGPathCreateMutable(); 144 | 145 | CGPathAddRect(leftColumnPath, NULL ,CGRectMake(0 , 0 ,self.bounds.size.width , self.bounds.size.height)); 146 | 147 | CTFrameRef leftFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0, 0), leftColumnPath , NULL); 148 | 149 | //翻转坐标系统(文本原来是倒的要翻转下) 150 | 151 | CGContextRef context = UIGraphicsGetCurrentContext(); 152 | 153 | CGContextSetTextMatrix(context , CGAffineTransformIdentity); 154 | 155 | CGContextTranslateCTM(context , 0 ,self.bounds.size.height); 156 | 157 | CGContextScaleCTM(context, 1.0 ,-1.0); 158 | 159 | //画出文本 160 | 161 | CTFrameDraw(leftFrame,context); 162 | 163 | //释放 164 | 165 | CGPathRelease(leftColumnPath); 166 | 167 | CFRelease(framesetter); 168 | 169 | UIGraphicsPushContext(context); 170 | } 171 | 172 | 173 | /* 174 | * 绘制前获取label高度和最小宽度 175 | */ 176 | - (CGSize)sizeWithAttributedStringWidth:(CGFloat)width 177 | { 178 | [self initAttributedString]; 179 | 180 | CGFloat min_width = 0; 181 | int total_height = 0; 182 | 183 | CTFramesetterRef framesetter = CTFramesetterCreateWithAttributedString((CFAttributedStringRef)attributedString); //string 为要计算高度的NSAttributedString 184 | CGRect drawingRect = CGRectMake(0, 0, width, 100000); //这里的高要设置足够大 185 | CGMutablePathRef path = CGPathCreateMutable(); 186 | CGPathAddRect(path, NULL, drawingRect); 187 | CTFrameRef textFrame = CTFramesetterCreateFrame(framesetter,CFRangeMake(0,0), path, NULL); 188 | CGPathRelease(path); 189 | CFRelease(framesetter); 190 | 191 | NSArray *lines = (NSArray *) CTFrameGetLines(textFrame); 192 | 193 | if (lines.count) { 194 | if(lines.count > 1){ 195 | min_width = self.width; 196 | } else { 197 | CTLineRef line = (__bridge CTLineRef)lines[0]; 198 | min_width = CTLineGetTypographicBounds(line, nil, nil, nil); 199 | } 200 | 201 | CGPoint origins[[lines count]]; 202 | CTFrameGetLineOrigins(textFrame, CFRangeMake(0, 0), origins); 203 | 204 | int line_y = (int) origins[[lines count] -1].y; //最后一行line的原点y坐标 205 | 206 | CGFloat ascent; 207 | CGFloat descent; 208 | CGFloat leading; 209 | 210 | CTLineRef line = (__bridge CTLineRef) [lines objectAtIndex:[lines count]-1]; 211 | CTLineGetTypographicBounds(line, &ascent, &descent, &leading); 212 | 213 | total_height = 100000 - line_y + (int) descent +1;//+1为了纠正descent转换成int小数点后舍去的值 214 | } 215 | 216 | CFRelease(textFrame); 217 | 218 | return CGSizeMake(min_width, total_height); 219 | } 220 | 221 | @end -------------------------------------------------------------------------------- /DataManager/Common/Utils/USTextView.h: -------------------------------------------------------------------------------- 1 | // 2 | // USTextView.h 3 | // USEvent 4 | // 5 | // Created by marujun on 15/12/15. 6 | // Copyright © 2015年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | IB_DESIGNABLE 12 | 13 | @interface USTextView : UITextView 14 | 15 | @property (copy, nonatomic) IBInspectable NSString *placeholder; 16 | @property (nonatomic) IBInspectable double fadeTime; 17 | @property (copy, nonatomic) NSAttributedString *attributedPlaceholder; 18 | @property (retain, nonatomic) UIColor *placeholderTextColor UI_APPEARANCE_SELECTOR; 19 | 20 | @end 21 | -------------------------------------------------------------------------------- /DataManager/DataManager-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleDisplayName 8 | ${PRODUCT_NAME} 9 | CFBundleExecutable 10 | ${EXECUTABLE_NAME} 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1.0 25 | LSRequiresIPhoneOS 26 | 27 | UIMainStoryboardFile 28 | Main 29 | NSAppTransportSecurity 30 | 31 | NSAllowsArbitraryLoads 32 | 33 | 34 | UIRequiredDeviceCapabilities 35 | 36 | armv7 37 | 38 | UISupportedInterfaceOrientations 39 | 40 | UIInterfaceOrientationPortrait 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /DataManager/DataManager-Prefix.pch: -------------------------------------------------------------------------------- 1 | // 2 | // Prefix header 3 | // 4 | // The contents of this file are implicitly included at the beginning of every source file. 5 | // 6 | 7 | #import 8 | 9 | #ifndef __IPHONE_5_0 10 | #warning "This project uses features only available in iOS SDK 5.0 and later." 11 | #endif 12 | 13 | #ifdef __OBJC__ 14 | #import 15 | #import 16 | #import "DataManager.h" 17 | #endif 18 | 19 | 20 | -------------------------------------------------------------------------------- /DataManager/DataManager/AFNetworking/AFNetworkReachabilityManager.h: -------------------------------------------------------------------------------- 1 | // AFNetworkReachabilityManager.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | 24 | #if !TARGET_OS_WATCH 25 | #import 26 | 27 | typedef NS_ENUM(NSInteger, AFNetworkReachabilityStatus) { 28 | AFNetworkReachabilityStatusUnknown = -1, 29 | AFNetworkReachabilityStatusNotReachable = 0, 30 | AFNetworkReachabilityStatusReachableViaWWAN = 1, 31 | AFNetworkReachabilityStatusReachableViaWiFi = 2, 32 | }; 33 | 34 | NS_ASSUME_NONNULL_BEGIN 35 | 36 | /** 37 | `AFNetworkReachabilityManager` monitors the reachability of domains, and addresses for both WWAN and WiFi network interfaces. 38 | 39 | Reachability can be used to determine background information about why a network operation failed, or to trigger a network operation retrying when a connection is established. It should not be used to prevent a user from initiating a network request, as it's possible that an initial request may be required to establish reachability. 40 | 41 | See Apple's Reachability Sample Code ( https://developer.apple.com/library/ios/samplecode/reachability/ ) 42 | 43 | @warning Instances of `AFNetworkReachabilityManager` must be started with `-startMonitoring` before reachability status can be determined. 44 | */ 45 | @interface AFNetworkReachabilityManager : NSObject 46 | 47 | /** 48 | The current network reachability status. 49 | */ 50 | @property (readonly, nonatomic, assign) AFNetworkReachabilityStatus networkReachabilityStatus; 51 | 52 | /** 53 | Whether or not the network is currently reachable. 54 | */ 55 | @property (readonly, nonatomic, assign, getter = isReachable) BOOL reachable; 56 | 57 | /** 58 | Whether or not the network is currently reachable via WWAN. 59 | */ 60 | @property (readonly, nonatomic, assign, getter = isReachableViaWWAN) BOOL reachableViaWWAN; 61 | 62 | /** 63 | Whether or not the network is currently reachable via WiFi. 64 | */ 65 | @property (readonly, nonatomic, assign, getter = isReachableViaWiFi) BOOL reachableViaWiFi; 66 | 67 | ///--------------------- 68 | /// @name Initialization 69 | ///--------------------- 70 | 71 | /** 72 | Returns the shared network reachability manager. 73 | */ 74 | + (instancetype)sharedManager; 75 | 76 | /** 77 | Creates and returns a network reachability manager with the default socket address. 78 | 79 | @return An initialized network reachability manager, actively monitoring the default socket address. 80 | */ 81 | + (instancetype)manager; 82 | 83 | /** 84 | Creates and returns a network reachability manager for the specified domain. 85 | 86 | @param domain The domain used to evaluate network reachability. 87 | 88 | @return An initialized network reachability manager, actively monitoring the specified domain. 89 | */ 90 | + (instancetype)managerForDomain:(NSString *)domain; 91 | 92 | /** 93 | Creates and returns a network reachability manager for the socket address. 94 | 95 | @param address The socket address (`sockaddr_in6`) used to evaluate network reachability. 96 | 97 | @return An initialized network reachability manager, actively monitoring the specified socket address. 98 | */ 99 | + (instancetype)managerForAddress:(const void *)address; 100 | 101 | /** 102 | Initializes an instance of a network reachability manager from the specified reachability object. 103 | 104 | @param reachability The reachability object to monitor. 105 | 106 | @return An initialized network reachability manager, actively monitoring the specified reachability. 107 | */ 108 | - (instancetype)initWithReachability:(SCNetworkReachabilityRef)reachability NS_DESIGNATED_INITIALIZER; 109 | 110 | ///-------------------------------------------------- 111 | /// @name Starting & Stopping Reachability Monitoring 112 | ///-------------------------------------------------- 113 | 114 | /** 115 | Starts monitoring for changes in network reachability status. 116 | */ 117 | - (void)startMonitoring; 118 | 119 | /** 120 | Stops monitoring for changes in network reachability status. 121 | */ 122 | - (void)stopMonitoring; 123 | 124 | ///------------------------------------------------- 125 | /// @name Getting Localized Reachability Description 126 | ///------------------------------------------------- 127 | 128 | /** 129 | Returns a localized string representation of the current network reachability status. 130 | */ 131 | - (NSString *)localizedNetworkReachabilityStatusString; 132 | 133 | ///--------------------------------------------------- 134 | /// @name Setting Network Reachability Change Callback 135 | ///--------------------------------------------------- 136 | 137 | /** 138 | Sets a callback to be executed when the network availability of the `baseURL` host changes. 139 | 140 | @param block A block object to be executed when the network availability of the `baseURL` host changes.. This block has no return value and takes a single argument which represents the various reachability states from the device to the `baseURL`. 141 | */ 142 | - (void)setReachabilityStatusChangeBlock:(nullable void (^)(AFNetworkReachabilityStatus status))block; 143 | 144 | @end 145 | 146 | ///---------------- 147 | /// @name Constants 148 | ///---------------- 149 | 150 | /** 151 | ## Network Reachability 152 | 153 | The following constants are provided by `AFNetworkReachabilityManager` as possible network reachability statuses. 154 | 155 | enum { 156 | AFNetworkReachabilityStatusUnknown, 157 | AFNetworkReachabilityStatusNotReachable, 158 | AFNetworkReachabilityStatusReachableViaWWAN, 159 | AFNetworkReachabilityStatusReachableViaWiFi, 160 | } 161 | 162 | `AFNetworkReachabilityStatusUnknown` 163 | The `baseURL` host reachability is not known. 164 | 165 | `AFNetworkReachabilityStatusNotReachable` 166 | The `baseURL` host cannot be reached. 167 | 168 | `AFNetworkReachabilityStatusReachableViaWWAN` 169 | The `baseURL` host can be reached via a cellular connection, such as EDGE or GPRS. 170 | 171 | `AFNetworkReachabilityStatusReachableViaWiFi` 172 | The `baseURL` host can be reached via a Wi-Fi connection. 173 | 174 | ### Keys for Notification UserInfo Dictionary 175 | 176 | Strings that are used as keys in a `userInfo` dictionary in a network reachability status change notification. 177 | 178 | `AFNetworkingReachabilityNotificationStatusItem` 179 | A key in the userInfo dictionary in a `AFNetworkingReachabilityDidChangeNotification` notification. 180 | The corresponding value is an `NSNumber` object representing the `AFNetworkReachabilityStatus` value for the current reachability status. 181 | */ 182 | 183 | ///-------------------- 184 | /// @name Notifications 185 | ///-------------------- 186 | 187 | /** 188 | Posted when network reachability changes. 189 | This notification assigns no notification object. The `userInfo` dictionary contains an `NSNumber` object under the `AFNetworkingReachabilityNotificationStatusItem` key, representing the `AFNetworkReachabilityStatus` value for the current network reachability. 190 | 191 | @warning In order for network reachability to be monitored, include the `SystemConfiguration` framework in the active target's "Link Binary With Library" build phase, and add `#import ` to the header prefix of the project (`Prefix.pch`). 192 | */ 193 | FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityDidChangeNotification; 194 | FOUNDATION_EXPORT NSString * const AFNetworkingReachabilityNotificationStatusItem; 195 | 196 | ///-------------------- 197 | /// @name Functions 198 | ///-------------------- 199 | 200 | /** 201 | Returns a localized string representation of an `AFNetworkReachabilityStatus` value. 202 | */ 203 | FOUNDATION_EXPORT NSString * AFStringFromNetworkReachabilityStatus(AFNetworkReachabilityStatus status); 204 | 205 | NS_ASSUME_NONNULL_END 206 | #endif 207 | -------------------------------------------------------------------------------- /DataManager/DataManager/AFNetworking/AFNetworking.h: -------------------------------------------------------------------------------- 1 | // AFNetworking.h 2 | // 3 | // Copyright (c) 2013 AFNetworking (http://afnetworking.com/) 4 | // 5 | // Permission is hereby granted, free of charge, to any person obtaining a copy 6 | // of this software and associated documentation files (the "Software"), to deal 7 | // in the Software without restriction, including without limitation the rights 8 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | // copies of the Software, and to permit persons to whom the Software is 10 | // furnished to do so, subject to the following conditions: 11 | // 12 | // The above copyright notice and this permission notice shall be included in 13 | // all copies or substantial portions of the Software. 14 | // 15 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | // THE SOFTWARE. 22 | 23 | #import 24 | #import 25 | #import 26 | 27 | #ifndef _AFNETWORKING_ 28 | #define _AFNETWORKING_ 29 | 30 | #import "AFURLRequestSerialization.h" 31 | #import "AFURLResponseSerialization.h" 32 | #import "AFSecurityPolicy.h" 33 | 34 | #if !TARGET_OS_WATCH 35 | #import "AFNetworkReachabilityManager.h" 36 | #endif 37 | 38 | #import "AFURLSessionManager.h" 39 | #import "AFHTTPSessionManager.h" 40 | 41 | #endif /* _AFNETWORKING_ */ 42 | -------------------------------------------------------------------------------- /DataManager/DataManager/AFNetworking/AFSecurityPolicy.h: -------------------------------------------------------------------------------- 1 | // AFSecurityPolicy.h 2 | // Copyright (c) 2011–2016 Alamofire Software Foundation ( http://alamofire.org/ ) 3 | // 4 | // Permission is hereby granted, free of charge, to any person obtaining a copy 5 | // of this software and associated documentation files (the "Software"), to deal 6 | // in the Software without restriction, including without limitation the rights 7 | // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | // copies of the Software, and to permit persons to whom the Software is 9 | // furnished to do so, subject to the following conditions: 10 | // 11 | // The above copyright notice and this permission notice shall be included in 12 | // all copies or substantial portions of the Software. 13 | // 14 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 19 | // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 20 | // THE SOFTWARE. 21 | 22 | #import 23 | #import 24 | 25 | typedef NS_ENUM(NSUInteger, AFSSLPinningMode) { 26 | AFSSLPinningModeNone, 27 | AFSSLPinningModePublicKey, 28 | AFSSLPinningModeCertificate, 29 | }; 30 | 31 | /** 32 | `AFSecurityPolicy` evaluates server trust against pinned X.509 certificates and public keys over secure connections. 33 | 34 | Adding pinned SSL certificates to your app helps prevent man-in-the-middle attacks and other vulnerabilities. Applications dealing with sensitive customer data or financial information are strongly encouraged to route all communication over an HTTPS connection with SSL pinning configured and enabled. 35 | */ 36 | 37 | NS_ASSUME_NONNULL_BEGIN 38 | 39 | @interface AFSecurityPolicy : NSObject 40 | 41 | /** 42 | The criteria by which server trust should be evaluated against the pinned SSL certificates. Defaults to `AFSSLPinningModeNone`. 43 | */ 44 | @property (readonly, nonatomic, assign) AFSSLPinningMode SSLPinningMode; 45 | 46 | /** 47 | The certificates used to evaluate server trust according to the SSL pinning mode. 48 | 49 | By default, this property is set to any (`.cer`) certificates included in the target compiling AFNetworking. Note that if you are using AFNetworking as embedded framework, no certificates will be pinned by default. Use `certificatesInBundle` to load certificates from your target, and then create a new policy by calling `policyWithPinningMode:withPinnedCertificates`. 50 | 51 | Note that if pinning is enabled, `evaluateServerTrust:forDomain:` will return true if any pinned certificate matches. 52 | */ 53 | @property (nonatomic, strong, nullable) NSSet *pinnedCertificates; 54 | 55 | /** 56 | Whether or not to trust servers with an invalid or expired SSL certificates. Defaults to `NO`. 57 | */ 58 | @property (nonatomic, assign) BOOL allowInvalidCertificates; 59 | 60 | /** 61 | Whether or not to validate the domain name in the certificate's CN field. Defaults to `YES`. 62 | */ 63 | @property (nonatomic, assign) BOOL validatesDomainName; 64 | 65 | ///----------------------------------------- 66 | /// @name Getting Certificates from the Bundle 67 | ///----------------------------------------- 68 | 69 | /** 70 | Returns any certificates included in the bundle. If you are using AFNetworking as an embedded framework, you must use this method to find the certificates you have included in your app bundle, and use them when creating your security policy by calling `policyWithPinningMode:withPinnedCertificates`. 71 | 72 | @return The certificates included in the given bundle. 73 | */ 74 | + (NSSet *)certificatesInBundle:(NSBundle *)bundle; 75 | 76 | ///----------------------------------------- 77 | /// @name Getting Specific Security Policies 78 | ///----------------------------------------- 79 | 80 | /** 81 | Returns the shared default security policy, which does not allow invalid certificates, validates domain name, and does not validate against pinned certificates or public keys. 82 | 83 | @return The default security policy. 84 | */ 85 | + (instancetype)defaultPolicy; 86 | 87 | ///--------------------- 88 | /// @name Initialization 89 | ///--------------------- 90 | 91 | /** 92 | Creates and returns a security policy with the specified pinning mode. 93 | 94 | @param pinningMode The SSL pinning mode. 95 | 96 | @return A new security policy. 97 | */ 98 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode; 99 | 100 | /** 101 | Creates and returns a security policy with the specified pinning mode. 102 | 103 | @param pinningMode The SSL pinning mode. 104 | @param pinnedCertificates The certificates to pin against. 105 | 106 | @return A new security policy. 107 | */ 108 | + (instancetype)policyWithPinningMode:(AFSSLPinningMode)pinningMode withPinnedCertificates:(NSSet *)pinnedCertificates; 109 | 110 | ///------------------------------ 111 | /// @name Evaluating Server Trust 112 | ///------------------------------ 113 | 114 | /** 115 | Whether or not the specified server trust should be accepted, based on the security policy. 116 | 117 | This method should be used when responding to an authentication challenge from a server. 118 | 119 | @param serverTrust The X.509 certificate trust of the server. 120 | @param domain The domain of serverTrust. If `nil`, the domain will not be validated. 121 | 122 | @return Whether or not to trust the server. 123 | */ 124 | - (BOOL)evaluateServerTrust:(SecTrustRef)serverTrust 125 | forDomain:(nullable NSString *)domain; 126 | 127 | @end 128 | 129 | NS_ASSUME_NONNULL_END 130 | 131 | ///---------------- 132 | /// @name Constants 133 | ///---------------- 134 | 135 | /** 136 | ## SSL Pinning Modes 137 | 138 | The following constants are provided by `AFSSLPinningMode` as possible SSL pinning modes. 139 | 140 | enum { 141 | AFSSLPinningModeNone, 142 | AFSSLPinningModePublicKey, 143 | AFSSLPinningModeCertificate, 144 | } 145 | 146 | `AFSSLPinningModeNone` 147 | Do not used pinned certificates to validate servers. 148 | 149 | `AFSSLPinningModePublicKey` 150 | Validate host certificates against public keys of pinned certificates. 151 | 152 | `AFSSLPinningModeCertificate` 153 | Validate host certificates against pinned certificates. 154 | */ 155 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NLCoreData.h: -------------------------------------------------------------------------------- 1 | // 2 | // NLCoreData.h 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | /** 26 | If an error occurs during a core data operation and DEBUG is defined, an exception is usually raised. 27 | Make sure not to define DEBUG in production. 28 | */ 29 | 30 | #import 31 | 32 | #import "NSManagedObject+NLCoreData.h" 33 | #import "NSManagedObjectContext+NLCoreData.h" 34 | #import "NSFetchRequest+NLCoreData.h" 35 | #import "NSFetchedResultsController+NLCoreData.h" 36 | #import "NSManagedObject+Explain.h" 37 | 38 | #ifdef DEBUG 39 | #define SET_PREDICATE_WITH_VARIADIC_ARGS \ 40 | NSPredicate* predicate = nil; \ 41 | if ([predicateOrString isKindOfClass:[NSString class]]) { \ 42 | va_list args; \ 43 | va_start(args, predicateOrString); \ 44 | predicate = [NSPredicate predicateWithFormat:predicateOrString arguments:args]; \ 45 | va_end(args); \ 46 | } \ 47 | else if ([predicateOrString isKindOfClass:[NSPredicate class]]) \ 48 | predicate = predicateOrString; \ 49 | else if (predicateOrString) \ 50 | [NSException raise:NLCoreDataExceptions.predicate format:@"invalid predicate: %@", predicateOrString]; 51 | #else 52 | #define SET_PREDICATE_WITH_VARIADIC_ARGS \ 53 | NSPredicate* predicate = nil; \ 54 | if ([predicateOrString isKindOfClass:[NSString class]]) { \ 55 | va_list args; \ 56 | va_start(args, predicateOrString); \ 57 | predicate = [NSPredicate predicateWithFormat:predicateOrString arguments:args]; \ 58 | va_end(args); \ 59 | } \ 60 | else if ([predicateOrString isKindOfClass:[NSPredicate class]]) \ 61 | predicate = predicateOrString; 62 | #endif 63 | 64 | extern const struct NLCoreDataExceptionsStruct 65 | { 66 | __unsafe_unretained NSString* predicate; 67 | __unsafe_unretained NSString* count; 68 | __unsafe_unretained NSString* parameter; 69 | __unsafe_unretained NSString* merge; 70 | __unsafe_unretained NSString* fileExist; 71 | __unsafe_unretained NSString* fileCopy; 72 | __unsafe_unretained NSString* encryption; 73 | __unsafe_unretained NSString* persistentStore; 74 | __unsafe_unretained NSString* permanentID; 75 | } NLCoreDataExceptions; 76 | 77 | 78 | @class 79 | NSManagedObjectModel, 80 | NSPersistentStoreCoordinator, 81 | NSManagedObjectContext; 82 | 83 | #pragma mark - 84 | @interface NLCoreData : NSObject 85 | 86 | /** 87 | Model name. Set this before use, typically in application:didFinishLaunchingWithOptions: 88 | If your data model is named MyDataModel.xcdatamodeld, set modelName to @"MyDataModel". 89 | This is optional. If not explicitly set, NLCoreData uses CFBundleName for the main bundle. 90 | E.g., if the app is named "MyApp", the model should be named "MyApp". 91 | */ 92 | @property (strong, nonatomic) NSString* modelName; 93 | 94 | /** 95 | Whether or not the store exists. This is likely NO before it's used the first time only. 96 | Use it to check if the store needs to be seeded. 97 | */ 98 | @property (assign, nonatomic, readonly) BOOL storeExists; 99 | 100 | /** 101 | Whether or not the store is encrypted. 102 | */ 103 | @property (assign, nonatomic, getter=isStoreEncrypted) BOOL storeEncrypted; 104 | 105 | /** 106 | Options for the persistent store. Set to automigrate by default. 107 | */ 108 | @property (strong, nonatomic) NSDictionary* persistentStoreOptions; 109 | 110 | /** 111 | Type for the persistent store. Set to NSSQLiteStoreType 112 | */ 113 | @property (copy, nonatomic) NSString* persistentStoreType; 114 | 115 | /** 116 | The persistent store coordinator. 117 | */ 118 | @property (strong, nonatomic) NSPersistentStoreCoordinator* storeCoordinator; 119 | 120 | /** 121 | The managed object model. 122 | */ 123 | @property (strong, nonatomic) NSManagedObjectModel* managedObjectModel; 124 | 125 | /** 126 | @name Path 127 | Filesystem path to the store as NSString and NSURL. 128 | */ 129 | - (NSString *)storePath; 130 | - (NSURL *)storeURL; 131 | 132 | #pragma mark - Lifecycle 133 | 134 | /** 135 | @name Lifecycle 136 | The shared instance. Use this, not alloc/init. 137 | */ 138 | + (NLCoreData *)shared; 139 | 140 | /** 141 | @name Lifecycle 142 | Copies a preseeded database file to be used as your Core Data store. 143 | The filetype should be sqlite and it should conform to your model. 144 | @param filePath Path to the preseeded file. 145 | @warning This should be called before using Core Data on first run. 146 | */ 147 | - (void)useDatabaseFile:(NSString *)filePath; 148 | 149 | /** 150 | @name Lifecycle 151 | @return A boolean on whether or not the operation succeeded. 152 | Resets the database (deletes all content). 153 | @warning If you use this, be sure to drop all references to managed objects beforehand. 154 | */ 155 | - (BOOL)resetDatabase; 156 | 157 | @end 158 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSFetchRequest+NLCoreData.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFetchRequest+NLCoreData.h 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | @interface NSFetchRequest (NLCoreData) 28 | 29 | /** 30 | @name Lifecycle 31 | A fetch request. 32 | @param entity The NSManagedObject subclass of the entity. 33 | @param context The context in which to execute the fetch request. 34 | @return The NSFetchRequest. 35 | */ 36 | + (instancetype)fetchRequestWithEntity:(Class)entity context:(NSManagedObjectContext *)context; 37 | 38 | /** 39 | @name Sorting 40 | Adds a sort descriptor to the fetch request. First added is primary, second added is secondary, etc. 41 | @param key The keypath to use when performing a comparison. 42 | @param ascending YES if the receiver specifies sorting in ascending order, otherwise NO. 43 | */ 44 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending; 45 | 46 | /** 47 | @name Sorting 48 | Adds a sort descriptor to the fetch request. First added is primary, second added is secondary, etc. 49 | @param key The keypath to use when performing a comparison. 50 | @param ascending YES if the receiver specifies sorting in ascending order, otherwise NO. 51 | @param selector The selector to use when performing a comparison. 52 | */ 53 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending selector:(SEL)selector; 54 | 55 | /** 56 | @name Predicate 57 | Sets predicate inline. 58 | @param predicateOrString A predicate or a predicate format string. 59 | */ 60 | - (void)setPredicateOrString:(id)predicateOrString, ...; 61 | 62 | /** 63 | @name Configuration 64 | A default value for the includesSubentities setting of NSFetchRequests. Default is NO. 65 | @param includeSubentities 66 | @note Default is NO for historical reasons. Expect this to change in the next major version. 67 | */ 68 | + (void)setIncludesSubentitiesByDefault:(BOOL)includesSubentities; 69 | + (BOOL)includesSubentitiesByDefault; 70 | 71 | @end 72 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSFetchRequest+NLCoreData.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFetchRequest+NLCoreData.m 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import "NSFetchRequest+NLCoreData.h" 26 | #import "NLCoreData.h" 27 | 28 | static BOOL _NLCoreDataNSFetchRequestIncludesSubentities = NO; 29 | 30 | @implementation NSFetchRequest (NLCoreData) 31 | 32 | + (instancetype)fetchRequestWithEntity:(Class)entity context:(NSManagedObjectContext *)context 33 | { 34 | NSFetchRequest* request = [[NSFetchRequest alloc] init]; 35 | 36 | [request setEntity:[NSEntityDescription entityForName:[entity entityName] inManagedObjectContext:context]]; 37 | [request setIncludesSubentities:_NLCoreDataNSFetchRequestIncludesSubentities]; 38 | 39 | return request; 40 | } 41 | 42 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending 43 | { 44 | [self sortByKey:key ascending:ascending selector:nil]; 45 | } 46 | 47 | - (void)sortByKey:(NSString *)key ascending:(BOOL)ascending selector:(SEL)selector 48 | { 49 | NSSortDescriptor* sortDescriptor = [NSSortDescriptor sortDescriptorWithKey:key ascending:ascending selector:selector]; 50 | NSMutableArray* descriptors = [NSMutableArray arrayWithArray:[self sortDescriptors]]; 51 | 52 | [descriptors addObject:sortDescriptor]; 53 | [self setSortDescriptors:descriptors]; 54 | } 55 | 56 | - (void)setPredicateOrString:(id)predicateOrString, ... 57 | { 58 | SET_PREDICATE_WITH_VARIADIC_ARGS 59 | [self setPredicate:predicate]; 60 | } 61 | 62 | + (void)setIncludesSubentitiesByDefault:(BOOL)includesSubentities 63 | { 64 | _NLCoreDataNSFetchRequestIncludesSubentities = includesSubentities; 65 | } 66 | 67 | + (BOOL)includesSubentitiesByDefault 68 | { 69 | return _NLCoreDataNSFetchRequestIncludesSubentities; 70 | } 71 | 72 | @end 73 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSFetchedResultsController+NLCoreData.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSFetchedResultsController+NLCoreData.h 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | @interface NSFetchedResultsController (NLCoreData) 28 | 29 | /** 30 | @name Lifecycle 31 | 32 | */ 33 | + (instancetype)controllerWithRequest:(NSFetchRequest *)request; 34 | + (instancetype)controllerWithRequest:(NSFetchRequest *)request sectionNameKeyPath:(NSString *)keyPath cacheName:(NSString *)cacheName; 35 | 36 | - (NSInteger)numberOfObjectsInSection:(NSInteger)section; 37 | 38 | @end 39 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSFetchedResultsController+NLCoreData.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSFetchedResultsController+NLCoreData.m 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import "NSFetchedResultsController+NLCoreData.h" 26 | #import "NLCoreData.h" 27 | 28 | @implementation NSFetchedResultsController (NLCoreData) 29 | 30 | + (instancetype)controllerWithRequest:(NSFetchRequest *)request 31 | { 32 | return [self controllerWithRequest:request sectionNameKeyPath:nil cacheName:nil]; 33 | } 34 | 35 | + (instancetype)controllerWithRequest:(NSFetchRequest *)request sectionNameKeyPath:(NSString *)keyPath cacheName:(NSString *)cacheName 36 | { 37 | return [[self alloc] initWithFetchRequest:request managedObjectContext:[NSManagedObjectContext mainContext] sectionNameKeyPath:keyPath cacheName:cacheName]; 38 | } 39 | 40 | - (NSInteger)numberOfObjectsInSection:(NSInteger)section 41 | { 42 | return [(id)[self sections][section] numberOfObjects]; 43 | } 44 | 45 | @end 46 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSManagedObject+Explain.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObject+Explain.h 3 | // CoreDataUtil 4 | // 5 | // Created by marujun on 14-1-13. 6 | // Copyright (c) 2014年 jizhi. All rights reserved. 7 | // 8 | 9 | /*导入所有通过model生成的SubClass*/ 10 | 11 | typedef void(^NLCoreDataFetchCompleteBlock)(NSArray *objects); 12 | 13 | @interface NSManagedObject (Explain) 14 | 15 | - (NSDictionary *)dictionary; 16 | 17 | - (void)saveAndWait; 18 | - (void)deleteAndWait; 19 | - (void)saveWithComplete:(NLCoreDataSaveCompleteBlock)complete; 20 | 21 | - (instancetype)objectInBgContext; 22 | - (instancetype)objectInMainContext; 23 | - (instancetype)objectInContext:(NSManagedObjectContext *)context; 24 | 25 | /** 保存BackgroundContext里的数据变化,主线程执行完成回调 */ 26 | + (void)saveWithComplete:(NLCoreDataSaveCompleteBlock)complete; 27 | 28 | /** 在BackgroundContext里操作数据,主线程执行完成回调 */ 29 | + (void)performBlock:(void (^)(NSManagedObjectContext *context))block complete:(NLCoreDataSaveCompleteBlock)complete; 30 | 31 | /** 创建一个private queue context,然后在该context中保存。一般情况下不要使用这个方法!!! */ 32 | + (void)saveInPrivateQueueWithBlock:(void(^)(NSManagedObjectContext *localContext))block complete:(NLCoreDataSaveCompleteBlock)complete; 33 | 34 | //TODO:异步执行任务 35 | + (void)insertObjectsAsync:(NSArray *)array complete:(NLCoreDataFetchCompleteBlock)complete; 36 | + (void)deleteObjectsAsync:(NSArray *)array complete:(NLCoreDataSaveCompleteBlock)complete; 37 | + (void)deleteAsyncWithPredicate:(id)predicateOrString complete:(NLCoreDataSaveCompleteBlock)complete; 38 | + (void)updateAsyncWithPredicate:(id)predicateOrString properties:(NSDictionary *)properties complete:(NLCoreDataSaveCompleteBlock)complete; 39 | + (void)fetchAllAsyncWithComplete:(NLCoreDataFetchCompleteBlock)complete; 40 | + (void)fetchAsyncWithPredicate:(id)predicateOrString complete:(NLCoreDataFetchCompleteBlock)complete; 41 | + (void)fetchAsyncWithPredicate:(id)predicateOrString sortDescriptors:(NSArray *)sortDescriptors complete:(NLCoreDataFetchCompleteBlock)complete; 42 | 43 | //TODO:在主线程中操作 44 | + (NSUInteger)countInMainWithPredicate:(id)predicateOrString, ...; 45 | + (instancetype)fetchSingleInMainWithPredicate:(id)predicateOrString, ...; 46 | + (instancetype)fetchOrInsertSingleInMainWithPredicate:(id)predicateOrString, ...; 47 | + (NSArray *)fetchInMainWithPredicate:(id)predicateOrString, ...; 48 | + (NSArray *)fetchInMainWithRequest:(void (^)(NSFetchRequest* request))block; 49 | 50 | //TODO:在子线程中操作 51 | + (NSUInteger)countInBgWithPredicate:(id)predicateOrString, ...; 52 | + (instancetype)fetchSingleInBgWithPredicate:(id)predicateOrString, ...; 53 | + (instancetype)fetchOrInsertSingleInBgWithPredicate:(id)predicateOrString, ...; 54 | + (NSArray *)fetchInBgWithPredicate:(id)predicateOrString, ...; 55 | + (NSArray *)fetchInBgWithRequest:(void (^)(NSFetchRequest* request))block; 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSManagedObject+Explain.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObject+Explain.m 3 | // CoreDataUtil 4 | // 5 | // Created by marujun on 14-1-13. 6 | // Copyright (c) 2014年 jizhi. All rights reserved. 7 | // 8 | 9 | #import "NSManagedObject+Explain.h" 10 | #import "NLCoreData.h" 11 | 12 | 13 | @implementation NSManagedObject (Explain) 14 | 15 | - (NSDictionary *)dictionary 16 | { 17 | NSArray *keys = [[[self entity] attributesByName] allKeys]; 18 | return [[self dictionaryWithValuesForKeys:keys] mutableCopy]; 19 | } 20 | 21 | - (void)saveAndWait 22 | { 23 | [_backgroundContext performBlockAndWait:^{ 24 | [_backgroundContext saveNested]; 25 | }]; 26 | } 27 | 28 | - (void)deleteAndWait 29 | { 30 | [_backgroundContext performBlockAndWait:^{ 31 | [[[self class] fetchWithObjectID:self.objectID context:_backgroundContext] delete]; 32 | [_backgroundContext saveNested]; 33 | }]; 34 | } 35 | 36 | - (void)saveWithComplete:(NLCoreDataSaveCompleteBlock)complete 37 | { 38 | [[self class] saveWithComplete:complete]; 39 | } 40 | 41 | - (instancetype)objectInBgContext 42 | { 43 | return [self objectInContext:_backgroundContext]; 44 | } 45 | 46 | - (instancetype)objectInMainContext 47 | { 48 | return [self objectInContext:_mainContext]; 49 | } 50 | 51 | - (instancetype)objectInContext:(NSManagedObjectContext *)context 52 | { 53 | if ([[self objectID] isTemporaryID]) { 54 | if (![self obtainPermanentID]) return nil; 55 | } 56 | 57 | return [[self class] fetchWithObjectID:[self objectID] context:context]; 58 | } 59 | 60 | + (void)saveWithComplete:(NLCoreDataSaveCompleteBlock)complete 61 | { 62 | [self performBlock:nil complete:complete]; 63 | } 64 | 65 | + (void)performBlock:(void (^)(NSManagedObjectContext *context))block complete:(NLCoreDataSaveCompleteBlock)complete 66 | { 67 | [_backgroundContext performBlock:^{ 68 | if (block) block(_backgroundContext); 69 | 70 | [_backgroundContext saveNestedAsynchronousWithCallback:^(BOOL success) { 71 | dispatch_async(dispatch_get_main_queue(), ^{ 72 | if (complete) complete(success); 73 | }); 74 | }]; 75 | }]; 76 | } 77 | 78 | + (void)saveInPrivateQueueWithBlock:(void(^)(NSManagedObjectContext *context))block complete:(NLCoreDataSaveCompleteBlock)complete 79 | { 80 | NSManagedObjectContext *localContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 81 | [localContext setParentContext:_mainContext]; 82 | [localContext setDisplay_name:NSStringFromSelector(_cmd)]; 83 | 84 | [localContext performBlock:^{ 85 | if (block) block(localContext); 86 | 87 | [localContext saveNestedAsynchronousWithCallback:^(BOOL success) { 88 | dispatch_async(dispatch_get_main_queue(), ^{ 89 | if (complete) complete(success); 90 | }); 91 | }]; 92 | }]; 93 | } 94 | 95 | 96 | //TODO:异步执行任务 97 | + (void)insertObjectsAsync:(NSArray *)array complete:(NLCoreDataFetchCompleteBlock)complete 98 | { 99 | NSManagedObjectContext *context = [NSManagedObjectContext backgroundContext]; 100 | [context performBlock:^{ 101 | NSMutableArray *objects = [NSMutableArray array]; 102 | NSManagedObject *object = nil; 103 | for (NSDictionary *item in array) { 104 | object = [self insertInContext:context]; 105 | [object populateWithDictionary:item]; 106 | [objects addObject:object]; 107 | } 108 | [context saveNestedAsynchronousWithCallback:^(BOOL success) { 109 | dispatch_async(dispatch_get_main_queue(), ^{ 110 | if (complete) complete(objects); 111 | }); 112 | }]; 113 | }]; 114 | } 115 | 116 | + (void)deleteObjectsAsync:(NSArray *)array complete:(NLCoreDataSaveCompleteBlock)complete 117 | { 118 | NSManagedObjectContext *context = [NSManagedObjectContext backgroundContext]; 119 | [context performBlock:^{ 120 | for (NSManagedObject *object in array){ 121 | [[self fetchWithObjectID:object.objectID context:context] delete]; 122 | } 123 | [context saveNestedAsynchronousWithCallback:^(BOOL success) { 124 | dispatch_async(dispatch_get_main_queue(), ^{ 125 | if (complete) complete(success); 126 | }); 127 | }]; 128 | }]; 129 | } 130 | 131 | + (void)deleteAsyncWithPredicate:(id)predicateOrString complete:(NLCoreDataSaveCompleteBlock)complete 132 | { 133 | NSManagedObjectContext *bgContext = [NSManagedObjectContext backgroundContext]; 134 | NSPredicate *predicate = predicateOrString; 135 | if (predicateOrString && [predicateOrString isKindOfClass:[NSString class]]) { 136 | predicate = [NSPredicate predicateWithFormat:predicateOrString]; 137 | } 138 | 139 | [bgContext performBlock:^{ 140 | if ([self deleteInContext:bgContext predicate:predicate]) { 141 | [bgContext saveNestedAsynchronousWithCallback:^(BOOL success) { 142 | dispatch_async(dispatch_get_main_queue(), ^{ 143 | if (complete) complete(success); 144 | }); 145 | }]; 146 | } 147 | else { 148 | dispatch_async(dispatch_get_main_queue(), ^{ 149 | if (complete) complete(NO); 150 | }); 151 | } 152 | }]; 153 | 154 | } 155 | 156 | + (void)updateAsyncWithPredicate:(id)predicateOrString properties:(NSDictionary *)properties complete:(NLCoreDataSaveCompleteBlock)complete 157 | { 158 | NSManagedObjectContext *bgContext = [NSManagedObjectContext backgroundContext]; 159 | NSPredicate *predicate = predicateOrString; 160 | if (predicateOrString && [predicateOrString isKindOfClass:[NSString class]]) { 161 | predicate = [NSPredicate predicateWithFormat:predicateOrString]; 162 | } 163 | 164 | [bgContext performBlock:^{ 165 | if ([self updateInContext:bgContext properties:properties predicate:predicate]) { 166 | [bgContext saveNestedAsynchronousWithCallback:^(BOOL success) { 167 | dispatch_async(dispatch_get_main_queue(), ^{ 168 | if (complete) complete(success); 169 | }); 170 | }]; 171 | } 172 | else { 173 | dispatch_async(dispatch_get_main_queue(), ^{ 174 | if (complete) complete(NO); 175 | }); 176 | } 177 | }]; 178 | } 179 | 180 | + (void)fetchAllAsyncWithComplete:(NLCoreDataFetchCompleteBlock)complete 181 | { 182 | [self fetchAsyncWithPredicate:nil sortDescriptors:nil complete:complete]; 183 | } 184 | 185 | + (void)fetchAsyncWithPredicate:(id)predicateOrString complete:(NLCoreDataFetchCompleteBlock)complete 186 | { 187 | [self fetchAsyncWithPredicate:predicateOrString sortDescriptors:nil complete:complete]; 188 | } 189 | 190 | + (void)fetchAsyncWithPredicate:(id)predicateOrString sortDescriptors:(NSArray *)sortDescriptors complete:(NLCoreDataFetchCompleteBlock)complete 191 | { 192 | [self fetchAsyncToMainContextWithRequest:^(NSFetchRequest *request) { 193 | NSPredicate *predicate = predicateOrString; 194 | if ([predicateOrString isKindOfClass:[NSString class]]) { 195 | predicate = [NSPredicate predicateWithFormat:predicateOrString]; 196 | } 197 | [request setPredicate:predicate]; 198 | [request setSortDescriptors:sortDescriptors]; 199 | 200 | } completion:^(NSArray *objects) { 201 | if (complete) complete(objects); 202 | }]; 203 | } 204 | 205 | 206 | 207 | 208 | //TODO:在主线程中操作 209 | + (NSUInteger)countInMainWithPredicate:(id)predicateOrString, ... 210 | { 211 | SET_PREDICATE_WITH_VARIADIC_ARGS 212 | return [self countInContext:[NSManagedObjectContext mainContext] predicate:predicate]; 213 | } 214 | 215 | + (instancetype)fetchSingleInMainWithPredicate:(id)predicateOrString, ... 216 | { 217 | SET_PREDICATE_WITH_VARIADIC_ARGS 218 | return [self fetchSingleInContext:[NSManagedObjectContext mainContext] predicate:predicate]; 219 | } 220 | 221 | + (instancetype)fetchOrInsertSingleInMainWithPredicate:(id)predicateOrString, ... 222 | { 223 | SET_PREDICATE_WITH_VARIADIC_ARGS 224 | return [self fetchOrInsertSingleInContext:[NSManagedObjectContext mainContext] predicate:predicate]; 225 | } 226 | 227 | + (NSArray *)fetchInMainWithPredicate:(id)predicateOrString, ... 228 | { 229 | SET_PREDICATE_WITH_VARIADIC_ARGS 230 | return [self fetchInContext:[NSManagedObjectContext mainContext] predicate:predicate]; 231 | } 232 | 233 | + (NSArray *)fetchInMainWithRequest:(void (^)(NSFetchRequest* request))block 234 | { 235 | return [self fetchWithRequest:block context:[NSManagedObjectContext mainContext]]; 236 | } 237 | 238 | 239 | //TODO:在子线程中操作 240 | + (NSUInteger)countInBgWithPredicate:(id)predicateOrString, ... 241 | { 242 | SET_PREDICATE_WITH_VARIADIC_ARGS 243 | return [self countInContext:[NSManagedObjectContext backgroundContext] predicate:predicate]; 244 | } 245 | 246 | + (instancetype)fetchSingleInBgWithPredicate:(id)predicateOrString, ... 247 | { 248 | SET_PREDICATE_WITH_VARIADIC_ARGS 249 | return [self fetchSingleInContext:[NSManagedObjectContext backgroundContext] predicate:predicate]; 250 | } 251 | 252 | + (instancetype)fetchOrInsertSingleInBgWithPredicate:(id)predicateOrString, ... 253 | { 254 | SET_PREDICATE_WITH_VARIADIC_ARGS 255 | return [self fetchOrInsertSingleInContext:[NSManagedObjectContext backgroundContext] predicate:predicate]; 256 | } 257 | 258 | 259 | + (NSArray *)fetchInBgWithPredicate:(id)predicateOrString, ... 260 | { 261 | SET_PREDICATE_WITH_VARIADIC_ARGS 262 | return [self fetchInContext:[NSManagedObjectContext backgroundContext] predicate:predicate]; 263 | } 264 | 265 | + (NSArray *)fetchInBgWithRequest:(void (^)(NSFetchRequest* request))block 266 | { 267 | return [self fetchWithRequest:block context:[NSManagedObjectContext backgroundContext]]; 268 | } 269 | 270 | @end 271 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSManagedObject+NLCoreData.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObject+NLCoreData.h 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | @interface NSManagedObject (NLCoreData) 28 | 29 | #pragma mark - Lifecycle 30 | 31 | /** 32 | @name Lifecycle 33 | The default implementation returns the class name as a string. 34 | Override in your NSManagedObject subclass if your class name does not match your entity name. 35 | */ 36 | + (NSString *)entityName; 37 | 38 | #pragma mark - Inserting 39 | 40 | /** 41 | @name Inserting 42 | 43 | */ 44 | + (instancetype)insertInContext:(NSManagedObjectContext *)context; 45 | 46 | #pragma mark - Deleting 47 | 48 | /** 49 | @name Deleting 50 | 51 | */ 52 | - (void)delete; 53 | 54 | /** 55 | @name Deleting 56 | 57 | */ 58 | + (BOOL)deleteWithRequest:(void (^)(NSFetchRequest* request))block context:(NSManagedObjectContext *)context; 59 | 60 | /** 61 | @name Deleting 62 | 63 | */ 64 | + (BOOL)deleteInContext:(NSManagedObjectContext *)context predicate:(id)predicateOrString, ...; 65 | 66 | /** 67 | @name Deleting 68 | WARNING: NSBatchDeleteRequest(iOS9)是直接操作数据库,所以并不会引起NSManagedObjectContext的同步更新。并且不会运行有效性验证(主要是一些关系的约束),慎重使用!!! 69 | 70 | */ 71 | + (BOOL)deleteInContext:(NSManagedObjectContext *)context batch:(BOOL)batch predicate:(id)predicateOrString, ...; 72 | 73 | /** 74 | @name Deleting 75 | WARNING: NSBatchDeleteRequest(iOS9)是直接操作数据库,所以并不会引起NSManagedObjectContext的同步更新。并且不会运行有效性验证(主要是一些关系的约束),慎重使用!!! 76 | 77 | */ 78 | + (BOOL)deleteWithRequest:(void (^)(NSFetchRequest* request))block batch:(BOOL)batch context:(NSManagedObjectContext *)context; 79 | 80 | /** 81 | @name Updating 82 | 83 | */ 84 | + (BOOL)updateInContext:(NSManagedObjectContext *)context properties:(NSDictionary *)properties predicate:(id)predicateOrString, ...; 85 | 86 | /** 87 | @name Updating 88 | WARNING: NSBatchUpdateRequest(iOS8)并不会先将数据存入内存,而是直接操作数据库,所以并不会引起NSManagedObjectContext的同步更新。慎重使用!!! 89 | 90 | */ 91 | + (BOOL)updateInContext:(NSManagedObjectContext *)context batch:(BOOL)batch properties:(NSDictionary *)properties predicate:(id)predicateOrString, ...; 92 | 93 | #pragma mark - Counting 94 | 95 | /** 96 | @name Counting 97 | 98 | */ 99 | + (NSUInteger)countInContext:(NSManagedObjectContext *)context predicate:(id)predicateOrString, ...; 100 | 101 | /** 102 | @name Counting 103 | 104 | */ 105 | + (NSUInteger)countWithRequest:(void (^)(NSFetchRequest* request))block context:(NSManagedObjectContext *)context; 106 | 107 | #pragma mark - Fetching 108 | 109 | /** 110 | @name Fetching 111 | 112 | */ 113 | + (instancetype)fetchWithObjectID:(NSManagedObjectID *)objectID context:(NSManagedObjectContext *)context; 114 | 115 | /** 116 | @name Fetching 117 | 118 | */ 119 | + (NSArray *)fetchWithRequest:(void (^)(NSFetchRequest* request))block context:(NSManagedObjectContext *)context; 120 | 121 | /** 122 | @name Fetching 123 | 124 | */ 125 | + (NSArray *)fetchInContext:(NSManagedObjectContext *)context predicate:(id)predicateOrString, ...; 126 | 127 | /** 128 | @name Fetching 129 | 130 | */ 131 | + (instancetype)fetchSingleInContext:(NSManagedObjectContext *)context predicate:(id)predicateOrString, ...; 132 | 133 | /** 134 | @name Fetching 135 | 136 | */ 137 | + (instancetype)fetchSingleInContext:(NSManagedObjectContext *)context sortByKey:(NSString *)key ascending:(BOOL)ascending predicate:(id)predicateOrString, ...; 138 | 139 | /** 140 | @name Fetching 141 | */ 142 | + (instancetype)fetchOrInsertSingleInContext:(NSManagedObjectContext *)context predicate:(id)predicateOrString, ...; 143 | 144 | /** 145 | @name Fetching 146 | Performs a complex fetch in the background context and passes the object id's to the main context for a faster fetch. 147 | @param block 148 | @param completion 149 | */ 150 | + (void)fetchAsyncToMainContextWithRequest:(void (^)(NSFetchRequest* request))block completion:(void (^)(NSArray* objects))completion; 151 | 152 | /** 153 | @name Population 154 | @param dictionary NSDictionary with data to populate object 155 | */ 156 | - (void)populateWithDictionary:(NSDictionary *)dictionary; 157 | 158 | /** 159 | @name Population 160 | @param dictionary NSDictionary with data to populate object 161 | @param matchTypes Check for data type match before setting value 162 | A class can optionally implement +(NSDictionary *)translatePopulationDictionary:(NSMutableDictionary *)dictionary to modify the dictionary before it's sent to this method (e.g., if the server sends "user_id" and your model has a userId, use this to modify the dictionary). 163 | */ 164 | - (void)populateWithDictionary:(NSDictionary *)dictionary matchTypes:(BOOL)matchTypes; 165 | 166 | #pragma mark - Miscellaneous 167 | 168 | /** 169 | @name Miscellaneous 170 | */ 171 | - (BOOL)isPersisted; 172 | 173 | /** 174 | @name Miscellaneous 175 | */ 176 | - (BOOL)obtainPermanentID; 177 | 178 | /** 179 | @name Miscellaneous 180 | Prints a description of the object. 181 | */ 182 | - (NSString *)usefulDescription; 183 | 184 | /** 185 | @name Miscellaneous 186 | Returns the Object ID in NSString format. 187 | */ 188 | - (NSString *)objectIDString; 189 | 190 | @end 191 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSManagedObjectContext+NLCoreData.h: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObjectContext+NLCoreData.h 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import 26 | 27 | typedef void(^NLCoreDataSaveCompleteBlock)(BOOL success); 28 | 29 | #define _mainContext [NSManagedObjectContext mainContext] 30 | #define _storeContext [NSManagedObjectContext storeContext] 31 | #define _backgroundContext [NSManagedObjectContext backgroundContext] 32 | 33 | #pragma mark - 34 | @interface NSManagedObjectContext (NLCoreData) 35 | 36 | #pragma mark - Lifecycle 37 | 38 | /** 39 | @name Lifecycle 40 | Saves the context. 41 | */ 42 | - (BOOL)save; 43 | 44 | /** 45 | @name Lifecycle 46 | Saves the context and all parent contexts asynchronously. 47 | */ 48 | - (void)saveNestedAsynchronous; 49 | 50 | /** 51 | @name Lifecycle 52 | Saves the context and all parent contexts asynchronously. 53 | @param block Calback for when save is complete 54 | */ 55 | - (void)saveNestedAsynchronousWithCallback:(NLCoreDataSaveCompleteBlock)block; 56 | 57 | /** 58 | @name Lifecycle 59 | Saves the context and all parent contexts synchronously. 60 | */ 61 | - (BOOL)saveNested; 62 | 63 | /** 64 | @name Lifecycle 65 | Rebuilds all contexts (the background context, the store context and the main context). 66 | @warning You probably don't want to call this manually. 67 | */ 68 | + (void)rebuildAllContexts; 69 | 70 | /** 71 | @name Lifecycle 72 | @return The main thread context. Lazily loaded if non-existant. 73 | */ 74 | + (NSManagedObjectContext *)mainContext; 75 | 76 | /** 77 | @name Lifecycle 78 | @return The context tied to the persistent store. Lazily loaded if non-existant. 79 | */ 80 | + (NSManagedObjectContext *)storeContext; 81 | 82 | /** 83 | @name Lifecycle 84 | @return The background thread context. Lazily loaded if non-existant. 85 | */ 86 | + (NSManagedObjectContext *)backgroundContext; 87 | 88 | #pragma mark - Properties 89 | 90 | /** 91 | @name Undo 92 | Enables/disables or checks if an NSUndoManager is present for the context. 93 | */ 94 | @property (assign, nonatomic, getter=isUndoEnabled) BOOL undoEnabled; 95 | 96 | /** 97 | @name Debugging 98 | Set a name to a managed object context to aid in debugging. 99 | */ 100 | @property (nonatomic, copy) NSString *display_name; 101 | 102 | /** Provides a string to log from a validation error given by core data. 103 | 104 | @param error The error given by Core Data 105 | 106 | @return A human readable string of what's gone wrong. 107 | */ 108 | - (NSString *)detailedDescriptionFromValidationError:(NSError *)error; 109 | 110 | @end 111 | -------------------------------------------------------------------------------- /DataManager/DataManager/CoreData/NSManagedObjectContext+NLCoreData.m: -------------------------------------------------------------------------------- 1 | // 2 | // NSManagedObjectContext+NLCoreData.m 3 | // 4 | // Created by Jesper Skrufve 5 | // 6 | // Permission is hereby granted, free of charge, to any person obtaining a copy 7 | // of this software and associated documentation files (the "Software"), to 8 | // deal in the Software without restriction, including without limitation the 9 | // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 10 | // sell copies of the Software, and to permit persons to whom the Software is 11 | // furnished to do so, subject to the following conditions: 12 | // 13 | // The above copyright notice and this permission notice shall be included in 14 | // all copies or substantial portions of the Software. 15 | // 16 | // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 21 | // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 22 | // IN THE SOFTWARE. 23 | // 24 | 25 | #import "NSManagedObjectContext+NLCoreData.h" 26 | #import "NLCoreData.h" 27 | 28 | static dispatch_once_t* _storeContextTokenRef; 29 | static dispatch_once_t* _mainContextTokenRef; 30 | static dispatch_once_t* _backgroundContextTokenRef; 31 | static NSManagedObjectContext* _storeObjectContext; 32 | static NSManagedObjectContext* _mainObjectContext; 33 | static NSManagedObjectContext* _backgroundObjectContext; 34 | 35 | @implementation NSManagedObjectContext (NLCoreData) 36 | 37 | @dynamic 38 | undoEnabled; 39 | 40 | #pragma mark - Lifecycle 41 | 42 | - (BOOL)save 43 | { 44 | if (![self hasChanges]) return YES; 45 | 46 | BOOL saveResult = NO; 47 | NSError* error = nil; 48 | 49 | @try { 50 | saveResult = [self save:&error]; 51 | } 52 | @catch(NSException *exception) { 53 | #ifdef DEBUG 54 | NSLog(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]); 55 | #endif 56 | } 57 | @finally { 58 | #ifdef DEBUG 59 | if (error) NSLog(@"%@", [self detailedDescriptionFromValidationError:error]); 60 | #endif 61 | return saveResult; 62 | } 63 | } 64 | 65 | - (BOOL)saveNested 66 | { 67 | if ([self save]) { 68 | 69 | NSManagedObjectContext* context = [self parentContext]; 70 | 71 | if (!context) 72 | return YES; 73 | 74 | __block BOOL save = NO; 75 | 76 | if (context) 77 | [context performBlockAndWait:^{ 78 | 79 | save = [context saveNested]; 80 | }]; 81 | 82 | return save; 83 | } 84 | 85 | return NO; 86 | } 87 | 88 | - (void)saveNestedAsynchronous 89 | { 90 | [self saveNestedAsynchronousWithCallback:nil]; 91 | } 92 | 93 | - (void)saveNestedAsynchronousWithCallback:(NLCoreDataSaveCompleteBlock)block 94 | { 95 | if ([self save]) { 96 | 97 | NSManagedObjectContext* context = [self parentContext]; 98 | 99 | if (context) 100 | [context performBlock:^{ 101 | 102 | [context saveNestedAsynchronousWithCallback:block]; 103 | }]; 104 | else if (block) 105 | block(YES); 106 | } 107 | else if (block) 108 | block(NO); 109 | } 110 | 111 | + (void)rebuildAllContexts 112 | { 113 | if (_mainContextTokenRef) 114 | *_mainContextTokenRef = 0; 115 | 116 | if (_storeContextTokenRef) 117 | *_storeContextTokenRef = 0; 118 | 119 | if (_backgroundContextTokenRef) 120 | *_backgroundContextTokenRef = 0; 121 | 122 | _mainObjectContext = nil; 123 | _storeObjectContext = nil; 124 | _backgroundObjectContext = nil; 125 | } 126 | 127 | + (NSManagedObjectContext *)mainContext 128 | { 129 | static dispatch_once_t token = 0; 130 | _mainContextTokenRef = &token; 131 | 132 | dispatch_once(&token, ^{ 133 | 134 | _mainObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 135 | [_mainObjectContext setParentContext:[self storeContext]]; 136 | [_mainObjectContext setDisplay_name:@"MainContext"]; 137 | }); 138 | 139 | return _mainObjectContext; 140 | } 141 | 142 | + (NSManagedObjectContext *)storeContext 143 | { 144 | static dispatch_once_t token = 0; 145 | _storeContextTokenRef = &token; 146 | 147 | dispatch_once(&token, ^{ 148 | 149 | _storeObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 150 | [_storeObjectContext performBlockAndWait:^{ 151 | [_storeObjectContext setPersistentStoreCoordinator:[[NLCoreData shared] storeCoordinator]]; 152 | [_storeObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy]; 153 | }]; 154 | [_storeObjectContext setDisplay_name:@"StoreContext"]; 155 | }); 156 | 157 | return _storeObjectContext; 158 | } 159 | 160 | + (NSManagedObjectContext *)backgroundContext 161 | { 162 | static dispatch_once_t token = 0; 163 | _backgroundContextTokenRef = &token; 164 | 165 | dispatch_once(&token, ^{ 166 | 167 | _backgroundObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 168 | [_backgroundObjectContext setParentContext:[self mainContext]]; 169 | [_backgroundObjectContext setDisplay_name:@"BackgroundContext"]; 170 | }); 171 | 172 | return _backgroundObjectContext; 173 | } 174 | 175 | #pragma mark - Properties 176 | 177 | - (void)setUndoEnabled:(BOOL)undoEnabled 178 | { 179 | if (undoEnabled && ![self isUndoEnabled]) 180 | [self setUndoManager:[[NSUndoManager alloc] init]]; 181 | else if (!undoEnabled) 182 | [self setUndoManager:nil]; 183 | } 184 | 185 | - (BOOL)isUndoEnabled 186 | { 187 | return !![self undoManager]; 188 | } 189 | 190 | - (void)setDisplay_name:(NSString *)name 191 | { 192 | objc_setAssociatedObject(self, @selector(display_name), name, OBJC_ASSOCIATION_COPY_NONATOMIC); 193 | } 194 | 195 | - (NSString *)display_name 196 | { 197 | return objc_getAssociatedObject(self, _cmd); 198 | } 199 | 200 | - (NSString *)detailedDescriptionFromValidationError:(NSError *)anError 201 | { 202 | if (![[anError domain] isEqualToString:@"NSCocoaErrorDomain"]) return nil; 203 | 204 | NSArray *errors = nil; 205 | 206 | if ([anError code] == NSValidationMultipleErrorsError) 207 | errors = [[anError userInfo] objectForKey:NSDetailedErrorsKey]; 208 | else 209 | errors = [NSArray arrayWithObject:anError]; 210 | 211 | if ([errors count] == 0) return nil; 212 | 213 | NSMutableString *messages = [[NSMutableString alloc] initWithFormat:@"NSManagedObjectContext with name %@ failed to save with the following reason%@:", 214 | self.display_name, 215 | (([errors count] > 1)?@"s":@"")]; 216 | 217 | for (NSError *error in errors) { 218 | 219 | NSString *entityName = [[[[error userInfo] objectForKey:@"NSValidationErrorObject"] entity] name]; 220 | NSString *attributeName = [[error userInfo] objectForKey:@"NSValidationErrorKey"]; 221 | 222 | NSString *message = nil; 223 | 224 | switch ([error code]) { 225 | case NSManagedObjectValidationError: 226 | message = @"Generic validation error."; 227 | break; 228 | case NSValidationMissingMandatoryPropertyError: 229 | message = [NSString stringWithFormat:@"The attribute '%@' must not be empty.", attributeName]; 230 | break; 231 | case NSValidationRelationshipLacksMinimumCountError: 232 | message = [NSString stringWithFormat:@"The relationship '%@' doesn't have enough entries.", attributeName]; 233 | break; 234 | case NSValidationRelationshipExceedsMaximumCountError: 235 | message = [NSString stringWithFormat:@"The relationship '%@' has too many entries.", attributeName]; 236 | break; 237 | case NSValidationRelationshipDeniedDeleteError: 238 | message = [NSString stringWithFormat:@"To delete, the relationship '%@' must be empty.", attributeName]; 239 | break; 240 | case NSValidationNumberTooLargeError: 241 | message = [NSString stringWithFormat:@"The number of the attribute '%@' is too large.", attributeName]; 242 | break; 243 | case NSValidationNumberTooSmallError: 244 | message = [NSString stringWithFormat:@"The number of the attribute '%@' is too small.", attributeName]; 245 | break; 246 | case NSValidationDateTooLateError: 247 | message = [NSString stringWithFormat:@"The date of the attribute '%@' is too late.", attributeName]; 248 | break; 249 | case NSValidationDateTooSoonError: 250 | message = [NSString stringWithFormat:@"The date of the attribute '%@' is too soon.", attributeName]; 251 | break; 252 | case NSValidationInvalidDateError: 253 | message = [NSString stringWithFormat:@"The date of the attribute '%@' is invalid.", attributeName]; 254 | break; 255 | case NSValidationStringTooLongError: 256 | message = [NSString stringWithFormat:@"The text of the attribute '%@' is too long.", attributeName]; 257 | break; 258 | case NSValidationStringTooShortError: 259 | message = [NSString stringWithFormat:@"The text of the attribute '%@' is too short.", attributeName]; 260 | break; 261 | case NSValidationStringPatternMatchingError: 262 | message = [NSString stringWithFormat:@"The text of the attribute '%@' doesn't match the required pattern.", attributeName]; 263 | break; 264 | default: 265 | message = [NSString stringWithFormat:@"Unknown error (code %@).", @([error code])]; 266 | break; 267 | } 268 | 269 | #pragma clang diagnostic push 270 | #pragma clang diagnostic ignored "-Wgnu-conditional-omitted-operand" 271 | [messages appendFormat:@"\n %@%@%@%@%@", (entityName?:@""), (attributeName?@".":@""), (attributeName?:@""), (entityName?@": ":@""), message]; 272 | #pragma clang diagnostic pop 273 | } 274 | 275 | return messages; 276 | } 277 | 278 | @end 279 | -------------------------------------------------------------------------------- /DataManager/DataManager/DBModel/DBLoginUser.h: -------------------------------------------------------------------------------- 1 | // 2 | // DBLoginUser.h 3 | // MCFriends 4 | // 5 | // Created by 马汝军 on 15/7/19. 6 | // Copyright (c) 2015年 marujun. All rights reserved. 7 | // 8 | 9 | typedef enum { 10 | GENDER_WOMEN = 0, 11 | GENDER_MAN, 12 | GENDER_NONE 13 | } GENDER; 14 | 15 | @interface DBLoginUser : DBObject 16 | 17 | @property (nonatomic, retain) NSString * avatar; 18 | @property (nonatomic, retain) NSString * birthday; 19 | @property (nonatomic, retain) NSMutableDictionary * extra; 20 | @property (nonatomic, retain) NSString * nickname; 21 | @property (nonatomic, assign) GENDER gender; 22 | @property (nonatomic, retain) NSString * uid; 23 | 24 | @property (nonatomic, retain) NSString * location; 25 | @property (nonatomic, retain, readonly) NSString * session_key; 26 | 27 | - (void)synchronize; 28 | 29 | @end 30 | -------------------------------------------------------------------------------- /DataManager/DataManager/DBModel/DBLoginUser.m: -------------------------------------------------------------------------------- 1 | // 2 | // DBLoginUser.m 3 | // MCFriends 4 | // 5 | // Created by 马汝军 on 15/7/19. 6 | // Copyright (c) 2015年 marujun. All rights reserved. 7 | // 8 | 9 | #import "DBLoginUser.h" 10 | #import "AuthData.h" 11 | 12 | @implementation DBLoginUser 13 | 14 | - (void)synchronize 15 | { 16 | [AuthData synchronize]; 17 | } 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /DataManager/DataManager/DBModel/DBObject.h: -------------------------------------------------------------------------------- 1 | // 2 | // DBObject.h 3 | // MCFriends 4 | // 5 | // Created by marujun on 15/7/18. 6 | // Copyright (c) 2015年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface DBObject : NSObject 13 | 14 | - (NSArray *)properties; 15 | 16 | - (NSDictionary *)dictionary; 17 | 18 | - (instancetype)initWithObject:(id)object; 19 | 20 | + (instancetype)modelWithObject:(id)object; 21 | 22 | + (NSMutableArray *)modelListWithArray:(NSArray *)array; 23 | 24 | - (void)populateValue:(id)value forKey:(NSString *)key; 25 | 26 | - (void)populateWithObject:(id)object; 27 | 28 | /** 29 | Custom property mapper. 30 | 31 | @discussion If the key in JSON/Dictionary does not match to the model's property name, 32 | implements this method and returns the additional mapper. 33 | 34 | Example: 35 | 36 | json: 37 | { 38 | "n":"Harry Pottery", 39 | "p": 256, 40 | "ext" : { 41 | "desc" : "A book written by J.K.Rowling." 42 | }, 43 | "ID" : 100010 44 | } 45 | 46 | model: 47 | @interface DBBook : NSObject 48 | @property NSString *name; 49 | @property NSInteger page; 50 | @property NSString *desc; 51 | @property NSString *bookID; 52 | @end 53 | 54 | @implementation DBBook 55 | + (NSDictionary *)propertyMapper { 56 | return @{@"name" : @"n", 57 | @"page" : @"p", 58 | @"desc" : @"ext.desc", 59 | @"bookID": @[@"id", @"ID", @"book_id"]}; 60 | } 61 | @end 62 | 63 | @return A custom mapper for properties. 64 | */ 65 | + (NSDictionary *)propertyMapper; 66 | 67 | /** 68 | The generic class mapper for container properties. 69 | 70 | @discussion If the property is a container object, such as NSArray/NSSet/NSDictionary, 71 | implements this method and returns a property->class mapper, tells which kind of 72 | object will be add to the array/set/dictionary. 73 | 74 | Example: 75 | @class DBShadow, DBBorder, DBAttachment; 76 | 77 | @interface DBAttributes 78 | @property NSString *name; 79 | @property NSArray *shadows; 80 | @property NSSet *borders; 81 | @property NSDictionary *attachments; 82 | @end 83 | 84 | @implementation DBAttributes 85 | + (NSDictionary *) propertyGenericClass { 86 | return @{@"shadows" : [DBShadow class], 87 | @"borders" : DBBorder.class, 88 | @"attachments" : @"DBAttachment" }; 89 | } 90 | @end 91 | 92 | @return A class mapper. 93 | */ 94 | + (NSDictionary *)propertyGenericClass; 95 | 96 | @end 97 | 98 | @interface DMObject : DBObject 99 | { 100 | NSManagedObjectID *_objectID; 101 | } 102 | 103 | @property (nonatomic, readonly, strong) NSManagedObjectID *objectID; 104 | 105 | @end 106 | -------------------------------------------------------------------------------- /DataManager/DataManager/DataManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataManager.h 3 | // CoreDataUtil 4 | // 5 | // Created by 马汝军 on 14-1-17. 6 | // Copyright (c) 2014年 马汝军. All rights reserved. 7 | // 8 | 9 | #import "DBObject.h" 10 | #import "DataHash.h" 11 | #import "NLCoreData.h" 12 | #import "MacroToolHeader.h" 13 | 14 | #import "NSObject+Common.h" 15 | #import "NSDate+Common.h" 16 | #import "NSString+Common.h" 17 | #import "NSString+Emoji.h" 18 | #import "UIDevice+Common.h" 19 | #import "UIImage+Common.h" 20 | #import "UIView+Common.h" 21 | #import "UIView+AutoLayout.h" 22 | #import "UIImage+ImageEffects.h" 23 | #import "UIView+Addition.h" 24 | #import "NSDictionary+KVC.h" 25 | #import "AssetsLibrary+PhotoAlbum.h" 26 | 27 | #import "HttpManager.h" 28 | #import "ImageCache.h" 29 | #import "USViewController.h" 30 | -------------------------------------------------------------------------------- /DataManager/DataManager/Hash/DataHash.h: -------------------------------------------------------------------------------- 1 | // 2 | // DataHash.h 3 | // HappyIn 4 | // 5 | // Created by marujun on 16/3/10. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | 12 | @interface NSData (DataHash) 13 | 14 | - (NSString *)md5; 15 | 16 | - (NSString *)sha1; 17 | 18 | - (NSString *)sha512; 19 | 20 | - (NSString *)crc32; 21 | 22 | @end 23 | 24 | @interface NSString (DataHash) 25 | 26 | - (NSString *)md5; 27 | 28 | - (NSString *)sha1; 29 | 30 | - (NSString *)sha512; 31 | 32 | - (NSString *)crc32; 33 | 34 | @end 35 | 36 | @interface NSFileManager (DataHash) 37 | 38 | + (NSString *)fileMD5AtPath:(NSString *)filePath; 39 | 40 | + (NSString *)fileSHA1AtPath:(NSString *)filePath; 41 | 42 | + (NSString *)fileSHA512AtPath:(NSString *)filePath; 43 | 44 | + (NSString *)fileCRC32AtPath:(NSString *)filePath; 45 | 46 | @end 47 | 48 | @interface ALAssetRepresentation (DataHash) 49 | 50 | - (NSString *)md5; 51 | 52 | - (NSString *)sha1; 53 | 54 | - (NSString *)sha512; 55 | 56 | - (NSString *)crc32; 57 | 58 | @end 59 | -------------------------------------------------------------------------------- /DataManager/DataManager/HttpManager.h: -------------------------------------------------------------------------------- 1 | // 2 | // HttpManager.h 3 | // HLMagic 4 | // 5 | // Created by marujun on 14-1-17. 6 | // Copyright (c) 2014年 jizhi. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import "AFNetworking.h" 12 | 13 | @interface NSString (HttpManager) 14 | - (NSString *)encode; 15 | - (NSString *)decode; 16 | - (id)object; 17 | @end 18 | 19 | @interface NSObject (HttpManager) 20 | - (NSString *)json; 21 | @end 22 | 23 | @interface NSURL (HttpManager) 24 | /*! 25 | @brief 返回URL的接口名称,会去除掉URL中的参数 26 | */ 27 | - (NSString *)interface; 28 | @end 29 | 30 | @interface HttpResponse : DBObject 31 | 32 | @property (nonatomic, assign) BOOL is_cache; //是否是缓存数据 33 | 34 | @property (nonatomic, strong) NSURL *request_url; //请求的链接 35 | @property (nonatomic, strong) NSDictionary *request_params; //请求的参数 36 | 37 | @property (nonatomic, strong) id payload; //返回的结果 38 | @property (nonatomic, strong) NSString *hint; //提示语 39 | @property (nonatomic, strong) NSError *error; //错误信息 40 | @property (nonatomic, strong) NSDate *date; //返回结果的时间 41 | 42 | @property (nonatomic, strong) id extra; //用户自定义的额外信息 43 | 44 | @end 45 | 46 | @interface HttpManager : NSObject 47 | 48 | /*! 49 | @property 50 | @brief 所有请求操作的管理器 51 | */ 52 | @property(nonatomic, strong, readonly) AFHTTPSessionManager *sessionManager; 53 | 54 | + (instancetype)defaultManager; 55 | 56 | /* -------判断当前的网络类型---------- 57 | 1、NotReachable - 没有网络连接 58 | 2、ReachableViaWWAN - 移动网络(2G、3G) 59 | 3、ReachableViaWiFi - WIFI网络 60 | */ 61 | - (AFNetworkReachabilityStatus)networkStatus; 62 | 63 | + (NSMutableDictionary *)getRequestBodyWithParams:(NSDictionary *)params; 64 | 65 | //AFHTTPRequestOperation可以暂停、重新开启、取消 [operation pause]、[operation resume]、[operation cancel]; 66 | 67 | /** GET 请求 */ 68 | - (NSURLSessionDataTask *)getRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, HttpResponse *response))complete; 69 | 70 | /** 读取本地缓存数据 */ 71 | - (void)localCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, HttpResponse *response))complete; 72 | 73 | /** 通过keypath更新本地缓存数据,删除某个节点数据value赋值为nil;例:user.hobby[1].title */ 74 | - (void)updateLocalCacheToUrl:(NSString *)url params:(NSDictionary *)params keyPath:(NSString *)keyPath value:(id)value; 75 | 76 | /** GET 请求并添加到缓存,未联网时使用缓存数据 */ 77 | - (NSURLSessionDataTask *)getCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, HttpResponse *response))complete; 78 | 79 | /** POST 请求 */ 80 | - (NSURLSessionDataTask *)postRequestToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, HttpResponse *response))complete; 81 | 82 | /** POST 请求并添加到缓存,未联网时使用缓存数据 */ 83 | - (NSURLSessionDataTask *)postCacheToUrl:(NSString *)url params:(NSDictionary *)params complete:(void (^)(BOOL successed, HttpResponse *response))complete; 84 | 85 | /* 86 | files : 需要上传的文件数组,数组里为多个字典 87 | 字典里的key: 88 | 1、name: 文件名称(如:demo.jpg) 89 | 2、file: 文件 (支持四种数据类型:NSData、UIImage、NSURL、NSString)NSURL、NSString为文件路径 90 | 3、key : 文件对应字段的key(默认:file) 91 | 4、type: 文件类型(默认:image/jpeg) 92 | 示例: @[@{@"file":_headImg.currentBackgroundImage,@"name":@"head.jpg"}]; 93 | */ 94 | - (NSURLSessionUploadTask *)uploadToUrl:(NSString *)url 95 | params:(NSDictionary *)params 96 | files:(NSArray *)files 97 | complete:(void (^)(BOOL successed, HttpResponse *response))complete; 98 | 99 | 100 | //可以查看进度 process_block 101 | - (NSURLSessionUploadTask *)uploadToUrl:(NSString *)url 102 | params:(NSDictionary *)params 103 | files:(NSArray *)files 104 | process:(void (^)(int64_t writedBytes, int64_t totalBytes))process 105 | complete:(void (^)(BOOL successed, HttpResponse *response))complete; 106 | /** 107 | filePath : 下载文件的存储路径 108 | response : 接口返回的不是文件而是json数据 109 | process : 进度 110 | */ 111 | - (NSURLSessionDownloadTask *)downloadFromUrl:(NSString *)url 112 | filePath:(NSString *)filePath 113 | complete:(void (^)(BOOL successed, HttpResponse *response))complete; 114 | 115 | - (NSURLSessionDownloadTask *)downloadFromUrl:(NSString *)url 116 | params:(NSDictionary *)params 117 | filePath:(NSString *)filePath 118 | process:(void (^)(int64_t readBytes, int64_t totalBytes))process 119 | complete:(void (^)(BOOL successed, HttpResponse *response))complete; 120 | 121 | @end 122 | -------------------------------------------------------------------------------- /DataManager/DataManager/ImageCache.h: -------------------------------------------------------------------------------- 1 | // 2 | // ImageCache.h 3 | // CoreDataUtil 4 | // 5 | // Created by marujun on 14-1-18. 6 | // Copyright (c) 2014年 jizhi. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #include 12 | #include 13 | 14 | #define ADD_DYNAMIC_PROPERTY(PROPERTY_TYPE,PROPERTY_NAME,SETTER_NAME) \ 15 | @dynamic PROPERTY_NAME ; \ 16 | static char kProperty##PROPERTY_NAME; \ 17 | - ( PROPERTY_TYPE ) PROPERTY_NAME{ \ 18 | return ( PROPERTY_TYPE ) objc_getAssociatedObject(self, &(kProperty##PROPERTY_NAME ) ); \ 19 | } \ 20 | - (void) SETTER_NAME :( PROPERTY_TYPE ) PROPERTY_NAME{ \ 21 | objc_setAssociatedObject(self, &kProperty##PROPERTY_NAME , PROPERTY_NAME , OBJC_ASSOCIATION_RETAIN_NONATOMIC); \ 22 | } \ 23 | 24 | #define dispatch_main_sync_safe(block)\ 25 | if ([NSThread isMainThread]) {\ 26 | block();\ 27 | } else {\ 28 | dispatch_sync(dispatch_get_main_queue(), block);\ 29 | } 30 | 31 | #define dispatch_main_async_safe(block)\ 32 | if ([NSThread isMainThread]) {\ 33 | block();\ 34 | } else {\ 35 | dispatch_async(dispatch_get_main_queue(), block);\ 36 | } 37 | 38 | #define dispatch_main_after(delayInSeconds,block)\ 39 | dispatch_after(dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC), dispatch_get_main_queue(),block); 40 | 41 | #define ImageCacheIdentifyDefault @"identify_default" 42 | #define ImageCacheIdentifyImprove @"identify_improve" 43 | 44 | @interface NSData (ImageCache) 45 | @property(nonatomic, strong) NSNumber *disk_exist; 46 | 47 | /* ********************----------***************************** 48 | 1、NSData 的扩展方法,用于缓存文件;如果文件已下载则使用本地文件 49 | 2、下载完成之后会执行回调,并可查看下载进度 50 | ********************----------******************************/ 51 | 52 | + (void)dataWithURL:(NSString *)url completed:(void(^)(NSData *data))completed; 53 | 54 | + (void)dataWithURL:(NSString *)url 55 | identify:(NSString *)identify 56 | completed:(void(^)(NSData *data))completed; 57 | 58 | + (void)dataWithURL:(NSString *)url 59 | identify:(NSString *)identify 60 | process:(void (^)(int64_t readBytes, int64_t totalBytes))process 61 | completed:(void(^)(NSData *data))completed; 62 | 63 | /** 通过URL获取缓存文件在本地对应的路径 */ 64 | + (NSString *)diskCachePathWithURL:(NSString *)url; 65 | 66 | /** 缓存文件对应的文件夹 */ 67 | + (NSString *)diskCacheDirectory; 68 | 69 | /** 获取图片的类型 */ 70 | + (NSString *)contentTypeForImageData:(NSData *)data; 71 | 72 | @end 73 | 74 | @interface UIImage (ImageCache) 75 | @property(nonatomic, strong) NSString *cache_url; 76 | @property(nonatomic, strong) NSNumber *disk_exist; 77 | 78 | /* ********************----------***************************** 79 | 1、UIImage 的扩展方法,用于缓存图片;如果图片已下载则使用本地图片 80 | 2、下载完成之后会执行回调,并可查看下载进度 81 | ********************----------******************************/ 82 | 83 | + (void)imageWithURL:(NSString *)url completed:(void(^)(UIImage *image))completed; 84 | 85 | + (void)imageWithURL:(NSString *)url 86 | identify:(NSString *)identify 87 | completed:(void(^)(UIImage *image))completed; 88 | 89 | + (void)imageWithURL:(NSString *)url 90 | identify:(NSString *)identify 91 | process:(void (^)(int64_t readBytes, int64_t totalBytes))process 92 | completed:(void(^)(UIImage *image))completed; 93 | 94 | /** 通过URL获取缓存图片在本地对应的路径 */ 95 | + (NSString *)diskCachePathWithURL:(NSString *)url; 96 | 97 | /** 缓存图片对应的文件夹 */ 98 | + (NSString *)diskCacheDirectory; 99 | 100 | /** 把图片保存到缓存文件夹 */ 101 | + (void)storeImage:(UIImage *)image forUrl:(NSString *)url; 102 | 103 | @end 104 | 105 | @interface UIImageView (ImageCache) 106 | @property(nonatomic, strong) NSString *cache_url; 107 | @property(nonatomic, strong) NSString *cache_identify; 108 | 109 | /** 设置UIImageView的图片的URL,下载失败设置图片为空 */ 110 | - (void)setImageWithURL:(NSString *)url; 111 | 112 | /** 设置UIImageView的图片的URL,下载失败则使用默认图片设置 */ 113 | - (void)setImageWithURL:(NSString *)url placeholderImage:(UIImage *)placeholder; 114 | 115 | /** 设置UIImageView的图片的URL,下载完成之后先设置图片然后执行回调函数 */ 116 | - (void)setImageWithURL:(NSString *)url completed:(void(^)(UIImage *image))completed; 117 | 118 | /** 设置UIImageView的图片的URL,下载完成之后先设置图片然后执行回调函数,可指定该视图对应ViewController ID */ 119 | - (void)setImageWithURL:(NSString *)url identify:(NSString *)identify completed:(void(^)(UIImage *image))completed; 120 | 121 | @end 122 | 123 | @interface UIButton (ImageCache) 124 | @property(nonatomic, strong) NSString *cache_url; 125 | @property(nonatomic, strong) NSString *cache_identify; 126 | 127 | /** 设置按钮的图片的URL,下载失败设置图片为空 */ 128 | - (void)setImageWithURL:(NSString *)url forState:(UIControlState)state; 129 | 130 | /** 设置按钮的图片的URL,下载失败则使用默认图片设置 */ 131 | - (void)setImageWithURL:(NSString *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; 132 | 133 | /** 设置按钮的图片的URL,下载完成之后先设置图片然后执行回调函数 */ 134 | - (void)setImageWithURL:(NSString *)url forState:(UIControlState)state completed:(void(^)(UIImage *image))completed; 135 | 136 | /** 设置按钮的图片的URL,下载完成之后先设置图片然后执行回调函数,可指定该视图对应ViewController ID */ 137 | - (void)setImageWithURL:(NSString *)url forState:(UIControlState)state identify:(NSString *)identify completed:(void(^)(UIImage *image))completed; 138 | 139 | /** 设置按钮的背景图片的URL,下载失败设置图片为空 */ 140 | - (void)setBackgroundImageWithURL:(NSString *)url forState:(UIControlState)state; 141 | 142 | /** 设置按钮的背景图片的URL,下载失败则使用默认图片设置 */ 143 | - (void)setBackgroundImageWithURL:(NSString *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder; 144 | 145 | /** 设置按钮的背景图片的URL,下载完成之后先设置图片然后执行回调函数 */ 146 | - (void)setBackgroundImageWithURL:(NSString *)url forState:(UIControlState)state completed:(void(^)(UIImage *image))completed; 147 | 148 | /** 设置按钮的背景图片的URL,下载完成之后先设置图片然后执行回调函数,可指定该视图对应ViewController ID */ 149 | - (void)setBackgroundImageWithURL:(NSString *)url forState:(UIControlState)state identify:(NSString *)identify completed:(void(^)(UIImage *image))completed; 150 | 151 | @end 152 | 153 | @interface NSFileManager (ImageCache) 154 | 155 | /** 单个文件的大小 */ 156 | + (long long)fileSizeAtPath:(NSString*)filePath; 157 | 158 | /** 遍历文件夹获得文件夹大小,返回多少M */ 159 | + (CGFloat)folderSizeAtPath:(NSString*)folderPath; 160 | 161 | @end 162 | 163 | @class AFHTTPRequestOperation; 164 | 165 | @interface ImageCacheManager : NSObject 166 | 167 | @property (strong, nonatomic, readonly) NSString *downloadingUrl; 168 | @property (strong, nonatomic, readonly) NSURLSessionDownloadTask *requestOperation; 169 | @property (strong, nonatomic, readonly) NSCache *imageMemoryCache; 170 | 171 | + (instancetype)defaultManager; 172 | 173 | /** 获取一个view对应的identify */ 174 | + (NSString *)identifyOfView:(UIView *)view; 175 | 176 | /** 通过URL提高下载任务的优先级 */ 177 | - (void)bringURLToFront:(NSString *)url; 178 | 179 | /** 通过给定的URL数组提高下载任务的优先级 */ 180 | - (void)bringURLArrayToFront:(NSArray *)urlArray; 181 | 182 | /** 通过URL取消正在下载的任务 */ 183 | - (void)cancelLoadingURL:(NSString *)url; 184 | 185 | /** 提高整个identify对应下载任务的优先级 */ 186 | - (void)bringIdentifyToFront:(NSString *)identify; 187 | 188 | @end 189 | -------------------------------------------------------------------------------- /DataManager/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /DataManager/Images.xcassets/LaunchImage.launchimage/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "orientation" : "portrait", 5 | "idiom" : "iphone", 6 | "extent" : "full-screen", 7 | "minimum-system-version" : "7.0", 8 | "scale" : "2x" 9 | }, 10 | { 11 | "orientation" : "portrait", 12 | "idiom" : "iphone", 13 | "subtype" : "retina4", 14 | "extent" : "full-screen", 15 | "minimum-system-version" : "7.0", 16 | "scale" : "2x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } -------------------------------------------------------------------------------- /DataManager/MacroToolHeader.h: -------------------------------------------------------------------------------- 1 | // 2 | // MacroToolHeader.h 3 | // HappyIn 4 | // 5 | // Created by marujun on 16/3/2. 6 | // Copyright © 2016年 MaRuJun. All rights reserved. 7 | // 8 | 9 | #import "AuthData.h" 10 | #import "ApplicationContext.h" 11 | 12 | #ifndef MacroToolHeader_h 13 | #define MacroToolHeader_h 14 | 15 | #define IS_IPAD (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPad) 16 | #define IS_IPHONE (UI_USER_INTERFACE_IDIOM() == UIUserInterfaceIdiomPhone) 17 | #define IS_RETINA ([[UIScreen mainScreen] scale] >= 2.0) 18 | 19 | #define SCREEN_WIDTH [[UIScreen mainScreen] bounds].size.width 20 | #define SCREEN_HEIGHT [[UIScreen mainScreen] bounds].size.height 21 | #define SCREEN_MAX_LENGTH (MAX(SCREEN_WIDTH, SCREEN_HEIGHT)) 22 | #define SCREEN_MIN_LENGTH (MIN(SCREEN_WIDTH, SCREEN_HEIGHT)) 23 | 24 | 25 | #define IS_IPHONE_4 (IS_IPHONE && SCREEN_MAX_LENGTH < 568.0) 26 | #define IS_IPHONE_5 (IS_IPHONE && SCREEN_MAX_LENGTH == 568.0) 27 | #define IS_IPHONE_6 (IS_IPHONE && SCREEN_MAX_LENGTH == 667.0) 28 | #define IS_IPHONE_6P (IS_IPHONE && SCREEN_MAX_LENGTH == 736.0) 29 | 30 | 31 | #define userDefaults [NSUserDefaults standardUserDefaults] 32 | #define KeyWindow [[[UIApplication sharedApplication] delegate] window] 33 | #define WindowZoomScale (SCREEN_WIDTH/320.f) 34 | #define UniversalZoomScale (MIN(1.8, WindowZoomScale)) //适配iPad 35 | 36 | #define DocumentPath [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) firstObject] //获取Document文件夹的路径 37 | #define ResourcePath [[NSBundle mainBundle] resourcePath] //获取自定义文件的bundle路径 38 | #define ImageNamed(name) [UIImage imageWithContentsOfFile:[ResourcePath stringByAppendingPathComponent:name]] 39 | #define RGBCOLOR(r,g,b) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:1] //RGB进制颜色值 40 | #define RGBACOLOR(r,g,b,a) [UIColor colorWithRed:(r)/255.0f green:(g)/255.0f blue:(b)/255.0f alpha:(a)] //RGBA进制颜色值 41 | #define HexColor(hexValue) [UIColor colorWithRed:((float)(((hexValue) & 0xFF0000) >> 16))/255.0 green:((float)(((hexValue) & 0xFF00) >> 8))/255.0 blue:((float)((hexValue) & 0xFF))/255.0 alpha:1] //16进制颜色值,如:#000000 , 注意:在使用的时候hexValue写成:0x000000 42 | 43 | #define XcodeBundleVersion [[[NSBundle mainBundle] infoDictionary] objectForKey:@"CFBundleVersion"] 44 | 45 | 46 | #define _loginUser [AuthData loginUser] 47 | #define _applicationContext [ApplicationContext sharedContext] 48 | 49 | #ifdef DEBUG 50 | #define USTakeTimeCountBegin NSDate *takeTimeCountDate = [NSDate date]; 51 | #define USTakeTimeCountEnd(flag) DLOG(@"%@耗时 %.4f 秒",flag,[[NSDate date] timeIntervalSinceDate:takeTimeCountDate]); 52 | #else 53 | #define USTakeTimeCountBegin ((void)0); 54 | #define USTakeTimeCountEnd(flag) ((void)0); 55 | #endif 56 | 57 | #ifdef DEBUG 58 | #define FLOG(fmt,...) NSLog((@"[%@][%d] " fmt),[[NSString stringWithUTF8String:__FILE__] lastPathComponent], __LINE__,##__VA_ARGS__) 59 | #else 60 | #define FLOG(str, args...) ((void)0) 61 | #endif 62 | 63 | 64 | //获取随机数 65 | #define Random(from, to) (int)(from + (arc4random() % (to - from + 1))); //+1,result is [from to]; else is [from, to)!!!!!!! 66 | #define ARC4RANDOM_MAX (0x100000000 * 20) 67 | 68 | 69 | /** 70 | Synthsize a weak or strong reference. 71 | 72 | Example: 73 | @weakify(self) 74 | [self doSomething^{ 75 | @strongify(self) 76 | if (!self) return; 77 | ... 78 | }]; 79 | 80 | */ 81 | #ifndef weakify 82 | #if DEBUG 83 | #if __has_feature(objc_arc) 84 | #define weakify(object) autoreleasepool{} __weak __typeof__(object) weak##_##object = object; 85 | #else 86 | #define weakify(object) autoreleasepool{} __block __typeof__(object) block##_##object = object; 87 | #endif 88 | #else 89 | #if __has_feature(objc_arc) 90 | #define weakify(object) try{} @finally{} {} __weak __typeof__(object) weak##_##object = object; 91 | #else 92 | #define weakify(object) try{} @finally{} {} __block __typeof__(object) block##_##object = object; 93 | #endif 94 | #endif 95 | #endif 96 | 97 | #ifndef strongify 98 | #if DEBUG 99 | #if __has_feature(objc_arc) 100 | #define strongify(object) autoreleasepool{} __typeof__(object) object = weak##_##object; 101 | #else 102 | #define strongify(object) autoreleasepool{} __typeof__(object) object = block##_##object; 103 | #endif 104 | #else 105 | #if __has_feature(objc_arc) 106 | #define strongify(object) try{} @finally{} __typeof__(object) object = weak##_##object; 107 | #else 108 | #define strongify(object) try{} @finally{} __typeof__(object) object = block##_##object; 109 | #endif 110 | #endif 111 | #endif 112 | 113 | 114 | 115 | #endif /* MacroToolHeader_h */ 116 | -------------------------------------------------------------------------------- /DataManager/ViewController.h: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.h 3 | // DataManager 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface ViewController : USViewController 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /DataManager/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // DataManager 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | 11 | @interface ViewController () 12 | 13 | @end 14 | 15 | @implementation ViewController 16 | 17 | - (void)viewDidLoad 18 | { 19 | [super viewDidLoad]; 20 | // Do any additional setup after loading the view, typically from a nib. 21 | 22 | [self downloadImage]; 23 | } 24 | 25 | - (void)downloadImage 26 | { 27 | /* 使用示例 */ 28 | NSString *url = @"http://image.tianjimedia.com/uploadImages/2013/309/43U9QN353KB7.jpg"; 29 | 30 | //缓存图片 31 | // [UIImage imageWithURL:url process:^(int64_t readBytes, int64_t totalBytes) { 32 | // NSLog(@"下载进度 : %.0f%%",100*readBytes/totalBytes); 33 | // } callback:^(UIImage *image) { 34 | // NSLog(@"图片下载完成!"); 35 | // }]; 36 | 37 | //设置UIImageView的图片,下载失败则使用默认图片 38 | // UIImageView *imageView = [[UIImageView alloc] initWithFrame:self.view.bounds]; 39 | // [imageView setImageURL:url defaultImage:[UIImage imageNamed:@"default.jpg"]]; 40 | // imageView.contentMode = UIViewContentModeScaleAspectFit; 41 | // [self.view addSubview:imageView]; 42 | 43 | //设置UIButton的图片,下载失败则使用默认图片 44 | UIButton *button = [[UIButton alloc] initWithFrame:self.view.bounds]; 45 | [button setImageWithURL:url forState:UIControlStateNormal placeholderImage:[UIImage imageNamed:@"default.jpg"]]; 46 | [self.view addSubview:button]; 47 | } 48 | 49 | - (void)didReceiveMemoryWarning 50 | { 51 | [super didReceiveMemoryWarning]; 52 | // Dispose of any resources that can be recreated. 53 | } 54 | 55 | @end 56 | -------------------------------------------------------------------------------- /DataManager/default.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/marujun/DataManager/d1caede4fd13aaed7d596164c0bb26eb105527df/DataManager/default.jpg -------------------------------------------------------------------------------- /DataManager/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /DataManager/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // DataManager 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | #import "AppDelegate.h" 12 | 13 | int main(int argc, char * argv[]) 14 | { 15 | @autoreleasepool { 16 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /DataManagerTests/DataManagerTests-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundlePackageType 14 | BNDL 15 | CFBundleShortVersionString 16 | 1.0 17 | CFBundleSignature 18 | ???? 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /DataManagerTests/DataManagerTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // DataManagerTests.m 3 | // DataManagerTests 4 | // 5 | // Created by 马汝军 on 14-1-23. 6 | // Copyright (c) 2014年 marujun. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface DataManagerTests : XCTestCase 12 | 13 | @end 14 | 15 | @implementation DataManagerTests 16 | 17 | - (void)setUp 18 | { 19 | [super setUp]; 20 | // Put setup code here. This method is called before the invocation of each test method in the class. 21 | } 22 | 23 | - (void)tearDown 24 | { 25 | // Put teardown code here. This method is called after the invocation of each test method in the class. 26 | [super tearDown]; 27 | } 28 | 29 | - (void)testExample 30 | { 31 | XCTFail(@"No implementation for \"%s\"", __PRETTY_FUNCTION__); 32 | } 33 | 34 | @end 35 | -------------------------------------------------------------------------------- /DataManagerTests/en.lproj/InfoPlist.strings: -------------------------------------------------------------------------------- 1 | /* Localized versions of Info.plist keys */ 2 | 3 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | DataManager 2 | =========== 3 | --------------------------------------------------------------------------------