├── 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 |
--------------------------------------------------------------------------------