├── .DS_Store
├── README.md
├── _config.yml
├── iOS_APIParser.xcodeproj
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ ├── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
│ └── xcuserdata
│ │ ├── dhruvikrao.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
│ │ └── dro.xcuserdatad
│ │ └── UserInterfaceState.xcuserstate
└── xcuserdata
│ ├── dhruvikrao.xcuserdatad
│ ├── xcdebugger
│ │ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ │ ├── iOS_APIParser.xcscheme
│ │ └── xcschememanagement.plist
│ └── dro.xcuserdatad
│ ├── xcdebugger
│ └── Breakpoints_v2.xcbkptlist
│ └── xcschemes
│ ├── iOS_APIParser.xcscheme
│ └── xcschememanagement.plist
├── iOS_APIParser
├── AppControllers
│ ├── FeedVC.h
│ └── FeedVC.m
├── AppDelegate.h
├── AppDelegate.m
├── AppModelClasses
│ ├── FeedObject.h
│ └── FeedObject.m
├── ApplicationAPI
│ ├── APIConstants.h
│ ├── APILogger
│ │ ├── Controller
│ │ │ ├── APILogDetailVC.h
│ │ │ ├── APILogDetailVC.m
│ │ │ ├── APILogsVC.h
│ │ │ ├── APILogsVC.m
│ │ │ ├── InternetConnectionStatusVC.h
│ │ │ └── InternetConnectionStatusVC.m
│ │ ├── Model
│ │ │ ├── APIInfoObject.h
│ │ │ ├── APIInfoObject.m
│ │ │ ├── AppCacheManagement.h
│ │ │ └── AppCacheManagement.m
│ │ └── View
│ │ │ ├── DeveloperInsights.storyboard
│ │ │ └── InternetConnection.storyboard
│ ├── APIParser+User.h
│ ├── APIParser+User.m
│ ├── APIParser.h
│ ├── APIParser.m
│ ├── AppMacros.h
│ └── Reachability
│ │ ├── Reachability.h
│ │ └── Reachability.m
├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ ├── Contents.json
│ └── internet_reachability.imageset
│ │ ├── Contents.json
│ │ └── no-internet-connection-sign-of-phone-interface.png
├── Base.lproj
│ ├── LaunchScreen.storyboard
│ └── Main.storyboard
├── CategoryClasses
│ └── NSString+ContainString.m
├── CustomCell
│ ├── OrderSummaryCell.h
│ ├── OrderSummaryCell.m
│ ├── OrderSummaryVC.h
│ └── OrderSummaryVC.m
├── Helper
│ ├── UIViewController+Helper.h
│ └── UIViewController+Helper.m
├── Info.plist
├── Objects
│ ├── RechargePlanCommonObject.h
│ ├── RechargePlanCommonObject.m
│ ├── RechargePlansMainObject.h
│ ├── RechargePlansMainObject.m
│ ├── RechargeTurboObject.h
│ └── RechargeTurboObject.m
├── iOS_APIParser-Prefix.pch
└── main.m
├── iOS_APIParserTests
├── Info.plist
└── iOS_APIParserTests.m
└── iOS_APIParserUITests
├── Info.plist
└── iOS_APIParserUITests.m
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhruvik13/iOS-Webservice/1b5d2f0a8152760e9f0b67be17cc8bcf81ef8648/.DS_Store
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # iOS-WebService
2 |
3 | This will helps you to integrate API (web service) communication architecture within your project, without any third party tool required. Easy to implement in project.
4 |
5 | ## Usage
6 |
7 | Here is a example of how to use this architecture to communicate with API server.
8 |
9 | ```objc
10 | APIParser *service = [APIParser sharedMediaServer]; //set your shared Instanse for calling an API
11 |
12 | [service URLRequestWithType:APIGetComments //specify your current calling API name
13 | parameters:@"" //pass request parameter as POST param orr GET param as per requirement
14 | cookieValue:nil //pass any cookie if required by the specific request
15 | customeobject:nil //pass any custom object as parameter if service required
16 | withRequestType:APIRequestMethodGET //define you request method
17 | withRequestHeaders:nil //pass anny additional header parameters if required by the server or request
18 | block:^(NSError *error, id objects, NSString *responseString, NSString *nextUrl, NSMutableArray *responseArray, NSURLResponse *URLResponseObject) {
19 |
20 | if (error) {
21 |
22 | //Handle Error
23 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[error domain] message:[NSString stringWithFormat:@"%@", error.localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
24 |
25 | UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
26 | [alertController addAction:ok];
27 |
28 | [self presentViewController:alertController animated:YES completion:nil];
29 | }
30 | else {
31 |
32 | if (responseArray.count > 0) {
33 |
34 | //Handle Response Array
35 | if (self.commentArrayCount == nil) {
36 | self.commentArrayCount = [NSMutableArray new];
37 | self.commentArrayCount = [responseArray mutableCopy];
38 | } else {
39 | [self.commentArrayCount addObjectsFromArray:[responseArray copy]];
40 | }
41 |
42 | [self.tableView reloadData];
43 | }
44 | else {
45 |
46 | //Handle null response array
47 | }
48 | }
49 | }];
50 |
51 |
52 | - Added support for NSINvocation
53 | - Enhancement for CacheManagement
54 | - Reachabilty support improved
55 | - Debug logs for API calling
56 | - Connection Lost UI added (Image source Google)
57 | - Call API from where connection lost (maintained with parameters)
58 |
59 |
60 | To enanble API Logs
61 | [[AppCacheManagement sharedCacheManager] setAPILoggingEnabled:true];
62 |
63 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-cayman
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/project.xcworkspace/xcuserdata/dhruvikrao.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhruvik13/iOS-Webservice/1b5d2f0a8152760e9f0b67be17cc8bcf81ef8648/iOS_APIParser.xcodeproj/project.xcworkspace/xcuserdata/dhruvikrao.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/project.xcworkspace/xcuserdata/dro.xcuserdatad/UserInterfaceState.xcuserstate:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhruvik13/iOS-Webservice/1b5d2f0a8152760e9f0b67be17cc8bcf81ef8648/iOS_APIParser.xcodeproj/project.xcworkspace/xcuserdata/dro.xcuserdatad/UserInterfaceState.xcuserstate
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dhruvikrao.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dhruvikrao.xcuserdatad/xcschemes/iOS_APIParser.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dhruvikrao.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | iOS_APIParser.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 19428EA41BFA0B3300C135C8
16 |
17 | primary
18 |
19 |
20 | 19428EBD1BFA0B3500C135C8
21 |
22 | primary
23 |
24 |
25 | 19428EC81BFA0B3500C135C8
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dro.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dro.xcuserdatad/xcschemes/iOS_APIParser.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
43 |
49 |
50 |
51 |
52 |
53 |
59 |
60 |
61 |
62 |
63 |
64 |
74 |
76 |
82 |
83 |
84 |
85 |
86 |
87 |
93 |
95 |
101 |
102 |
103 |
104 |
106 |
107 |
110 |
111 |
112 |
--------------------------------------------------------------------------------
/iOS_APIParser.xcodeproj/xcuserdata/dro.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | iOS_APIParser.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | 19428EA41BFA0B3300C135C8
16 |
17 | primary
18 |
19 |
20 | 19428EBD1BFA0B3500C135C8
21 |
22 | primary
23 |
24 |
25 | 19428EC81BFA0B3500C135C8
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppControllers/FeedVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // FeedVC.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FeedVC : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppControllers/FeedVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // FeedVC.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "FeedVC.h"
10 | #import "APIParser+User.h"
11 | #import "APILogsVC.h"
12 | #include
13 |
14 | @interface CommentCell : UITableViewCell
15 |
16 | @property (weak , nonatomic) IBOutlet UIImageView *imgProfileImage;
17 | @property (weak , nonatomic) IBOutlet UILabel *lblName;
18 | @property (weak , nonatomic) IBOutlet UILabel *lblEmail;
19 | @property (weak , nonatomic) IBOutlet UILabel *lblCommentDesc;
20 |
21 | @end
22 |
23 | @implementation CommentCell
24 |
25 | @synthesize imgProfileImage, lblName, lblEmail, lblCommentDesc;
26 |
27 | @end
28 |
29 |
30 | @interface FeedVC ()
31 |
32 | @property (nonatomic, strong) NSMutableArray *commentArrayCount;
33 |
34 | @end
35 |
36 | @implementation FeedVC
37 |
38 | - (void)viewDidLoad {
39 |
40 | [super viewDidLoad];
41 | [self getPostForUser:nil];
42 | }
43 |
44 | - (void)didReceiveMemoryWarning {
45 | [super didReceiveMemoryWarning];
46 | // Dispose of any resources that can be recreated.
47 | }
48 |
49 | #pragma mark - Sample web service calling
50 |
51 | - (IBAction) getPostForUser :(id)sender {
52 | if (sender) { // To check API method stack
53 | [self getposts];
54 | [self getposts];
55 | [self getposts];
56 | } else {
57 | [self getposts];
58 | }
59 | }
60 |
61 |
62 | //Sample API
63 | - (void)getposts {
64 | APIParser *service = [APIParser sharedMediaServer];
65 |
66 | [service URLRequestWithType:APIGetComments
67 | parameters:nil
68 | cookieValue:nil
69 | customeobject:nil
70 | withRequestType:APIRequestMethodGET
71 | withRequestHeaders:nil
72 | block:^(NSError *error, id objects, NSString *responseString, NSString *nextUrl, NSMutableArray *responseArray, NSURLResponse *URLResponseObject) {
73 |
74 | if (error) {
75 |
76 | //Handle Error
77 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:[error domain] message:[NSString stringWithFormat:@"%@", error.localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
78 |
79 | UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
80 | [alertController addAction:ok];
81 |
82 | [self presentViewController:alertController animated:YES completion:nil];
83 | }
84 | else {
85 |
86 | if (responseArray.count > 0) {
87 |
88 | //Handle Response Array
89 | if (self.commentArrayCount == nil) {
90 | self.commentArrayCount = [NSMutableArray new];
91 | self.commentArrayCount = [responseArray mutableCopy];
92 | } else {
93 | [self.commentArrayCount addObjectsFromArray:[responseArray copy]];
94 | }
95 |
96 | [self.tableView reloadData];
97 | }
98 | else {
99 |
100 | //Handle null response array
101 | }
102 | }
103 | }];
104 | }
105 |
106 | #pragma mark - Login API
107 | //Sample API
108 | -(IBAction)loginUser:(id)sender {
109 |
110 | APIParser *service = [APIParser sharedMediaServer];
111 |
112 | NSDictionary *params = @{
113 | @"uname":@"xyz@abc.com",
114 | @"password":[self MD5HashFor:@"654321"]
115 | };
116 |
117 | NSString *urlWithQuerystring = [service serializeParams:params];
118 |
119 | [service URLRequestWithType:APIUserLogIn
120 | parameters:urlWithQuerystring
121 | cookieValue:nil
122 | customeobject:nil
123 | withRequestType:APIRequestMethodPOST
124 | withRequestHeaders:nil
125 | block:^(NSError *error, id objects, NSString *responseString, NSString *nextUrl, NSMutableArray *responseArray, NSURLResponse *URLResponseObject) {
126 |
127 | if (error) {
128 |
129 | //Handle Error
130 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Failure!" message:[NSString stringWithFormat:@"%@", error.localizedDescription] preferredStyle:UIAlertControllerStyleAlert];
131 |
132 | UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
133 | [alertController addAction:ok];
134 |
135 | [self presentViewController:alertController animated:YES completion:nil];
136 | }
137 | else {
138 |
139 | UIAlertController *alertController = [UIAlertController alertControllerWithTitle:@"Success! Login Response" message:[NSString stringWithFormat:@"%@", objects] preferredStyle:UIAlertControllerStyleAlert];
140 |
141 | UIAlertAction* ok = [UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil];
142 | [alertController addAction:ok];
143 |
144 | [self presentViewController:alertController animated:YES completion:nil];
145 | }
146 | }];
147 | }
148 |
149 | #pragma mark - Table view data source
150 |
151 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
152 | return 1;
153 | }
154 |
155 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
156 | return self.commentArrayCount.count;
157 | }
158 |
159 |
160 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
161 | CommentCell *cell = (CommentCell *) [tableView dequeueReusableCellWithIdentifier:@"commentcell" forIndexPath:indexPath];
162 |
163 | cell.lblName.text = [(NSDictionary *)self.commentArrayCount[indexPath.row] valueForKey:@"name"];
164 | cell.lblEmail.text = [[(NSDictionary *)self.commentArrayCount[indexPath.row] valueForKey:@"email"] length] >= 20 ? [[(NSDictionary *)self.commentArrayCount[indexPath.row] valueForKey:@"email"] substringWithRange:NSMakeRange(0, 20)] : [(NSDictionary *)self.commentArrayCount[indexPath.row] valueForKey:@"email"];
165 | cell.lblCommentDesc.text = [(NSDictionary *)self.commentArrayCount[indexPath.row] valueForKey:@"body"];
166 |
167 | return cell;
168 | }
169 |
170 |
171 | -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
172 | return 40;
173 | }
174 |
175 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
176 | return UITableViewAutomaticDimension;
177 | }
178 |
179 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
180 | [self.tableView deselectRowAtIndexPath:indexPath animated:YES];
181 | }
182 |
183 |
184 | #pragma mark - Navigate to API logs
185 |
186 | - (IBAction)navigateAPILog:(id)sender {
187 | APILogsVC *apiDetailVC = loadViewController(@"DeveloperInsights", @"idAPILogsVC");
188 | [self.navigationController pushViewController:apiDetailVC animated:YES];
189 | }
190 |
191 | - (NSString *) MD5HashFor:(NSString *)pass
192 | {
193 | const char *cStr = [pass UTF8String];
194 | unsigned char result[CC_MD5_DIGEST_LENGTH];
195 | CC_MD5( cStr, (int)strlen(cStr), result );
196 | return [NSString stringWithFormat:
197 | @"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
198 | result[0], result[1], result[2], result[3],
199 | result[4], result[5], result[6], result[7],
200 | result[8], result[9], result[10], result[11],
201 | result[12], result[13], result[14], result[15]
202 | ];
203 | }
204 |
205 | @end
206 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Reachability.h"
11 |
12 | @interface AppDelegate : UIResponder
13 |
14 | @property (strong, nonatomic) UIWindow *window;
15 |
16 | #pragma mark - Check Host Reachability
17 | - (NetworkStatus) checkHostReachability;
18 |
19 | @property (nonatomic, strong) Reachability *hostReachability;
20 |
21 | @property (nonatomic, strong) UINavigationController *appNavigationController;
22 |
23 | - (UIViewController*) topMostController;
24 |
25 | @end
26 |
27 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import "AppCacheManagement.h"
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 |
19 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
20 | // Override point for customization after application launch.
21 |
22 | //Start Logging API request / response
23 | [[AppCacheManagement sharedCacheManager] setAPILoggingEnabled:true];
24 |
25 | return YES;
26 | }
27 |
28 | - (void)applicationWillResignActive:(UIApplication *)application {
29 | // 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.
30 | // 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.
31 | }
32 |
33 | - (void)applicationDidEnterBackground:(UIApplication *)application {
34 | // 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.
35 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
36 | }
37 |
38 | - (void)applicationWillEnterForeground:(UIApplication *)application {
39 | // 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.
40 | }
41 |
42 | - (void)applicationDidBecomeActive:(UIApplication *)application {
43 | // 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.
44 | }
45 |
46 | - (void)applicationWillTerminate:(UIApplication *)application {
47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
48 | }
49 |
50 | #pragma mark - Check Host Reachability
51 |
52 | - (NetworkStatus) checkHostReachability {
53 | self.hostReachability = [Reachability reachabilityForInternetConnection];
54 | return self.hostReachability.currentReachabilityStatus;
55 | }
56 |
57 | - (UIViewController*) topMostController
58 | {
59 | UIViewController *topController = [UIApplication sharedApplication].keyWindow.rootViewController;
60 |
61 | while (topController.presentedViewController) {
62 | topController = topController.presentedViewController;
63 | }
64 |
65 | return topController;
66 | }
67 |
68 | @end
69 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppModelClasses/FeedObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // FeedObject.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface FeedObject : NSObject
12 |
13 | @property (nonatomic, strong) NSString *email;
14 | @property (nonatomic, assign) double internalBaseClassIdentifier;
15 | @property (nonatomic, assign) double postId;
16 | @property (nonatomic, strong) NSString *body;
17 | @property (nonatomic, strong) NSString *name;
18 |
19 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
20 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
21 | - (NSDictionary *)dictionaryRepresentation;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/iOS_APIParser/AppModelClasses/FeedObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // FeedObject.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "FeedObject.h"
10 |
11 | NSString *const kBaseClassEmail = @"email";
12 | NSString *const kBaseClassId = @"id";
13 | NSString *const kBaseClassPostId = @"postId";
14 | NSString *const kBaseClassBody = @"body";
15 | NSString *const kBaseClassName = @"name";
16 |
17 | @interface FeedObject ()
18 |
19 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
20 |
21 | @end
22 |
23 | @implementation FeedObject
24 |
25 | @synthesize email = _email;
26 | @synthesize internalBaseClassIdentifier = _internalBaseClassIdentifier;
27 | @synthesize postId = _postId;
28 | @synthesize body = _body;
29 | @synthesize name = _name;
30 |
31 |
32 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict {
33 | return [[self alloc] initWithDictionary:dict];
34 | }
35 |
36 | - (instancetype)initWithDictionary:(NSDictionary *)dict {
37 | self = [super init];
38 |
39 | // This check serves to make sure that a non-NSDictionary object
40 | // passed into the model class doesn't break the parsing.
41 | if (self && [dict isKindOfClass:[NSDictionary class]]) {
42 | self.email = [self objectOrNilForKey:kBaseClassEmail fromDictionary:dict];
43 | self.internalBaseClassIdentifier = [[self objectOrNilForKey:kBaseClassId fromDictionary:dict] doubleValue];
44 | self.postId = [[self objectOrNilForKey:kBaseClassPostId fromDictionary:dict] doubleValue];
45 | self.body = [self objectOrNilForKey:kBaseClassBody fromDictionary:dict];
46 | self.name = [self objectOrNilForKey:kBaseClassName fromDictionary:dict];
47 | }
48 |
49 | return self;
50 |
51 | }
52 |
53 | - (NSDictionary *)dictionaryRepresentation {
54 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
55 | [mutableDict setValue:self.email forKey:kBaseClassEmail];
56 | [mutableDict setValue:[NSNumber numberWithDouble:self.internalBaseClassIdentifier] forKey:kBaseClassId];
57 | [mutableDict setValue:[NSNumber numberWithDouble:self.postId] forKey:kBaseClassPostId];
58 | [mutableDict setValue:self.body forKey:kBaseClassBody];
59 | [mutableDict setValue:self.name forKey:kBaseClassName];
60 |
61 | return [NSDictionary dictionaryWithDictionary:mutableDict];
62 | }
63 |
64 | - (NSString *)description {
65 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
66 | }
67 |
68 | #pragma mark - Helper Method
69 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict {
70 | id object = [dict objectForKey:aKey];
71 | return [object isEqual:[NSNull null]] ? nil : object;
72 | }
73 |
74 |
75 | #pragma mark - NSCoding Methods
76 |
77 | - (id)initWithCoder:(NSCoder *)aDecoder {
78 | self = [super init];
79 |
80 | self.email = [aDecoder decodeObjectForKey:kBaseClassEmail];
81 | self.internalBaseClassIdentifier = [aDecoder decodeDoubleForKey:kBaseClassId];
82 | self.postId = [aDecoder decodeDoubleForKey:kBaseClassPostId];
83 | self.body = [aDecoder decodeObjectForKey:kBaseClassBody];
84 | self.name = [aDecoder decodeObjectForKey:kBaseClassName];
85 | return self;
86 | }
87 |
88 | - (void)encodeWithCoder:(NSCoder *)aCoder
89 | {
90 | [aCoder encodeObject:_email forKey:kBaseClassEmail];
91 | [aCoder encodeDouble:_internalBaseClassIdentifier forKey:kBaseClassId];
92 | [aCoder encodeDouble:_postId forKey:kBaseClassPostId];
93 | [aCoder encodeObject:_body forKey:kBaseClassBody];
94 | [aCoder encodeObject:_name forKey:kBaseClassName];
95 | }
96 |
97 | - (id)copyWithZone:(NSZone *)zone {
98 | FeedObject *copy = [[FeedObject alloc] init];
99 |
100 | if (copy) {
101 |
102 | copy.email = [self.email copyWithZone:zone];
103 | copy.internalBaseClassIdentifier = self.internalBaseClassIdentifier;
104 | copy.postId = self.postId;
105 | copy.body = [self.body copyWithZone:zone];
106 | copy.name = [self.name copyWithZone:zone];
107 | }
108 |
109 | return copy;
110 | }
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APIConstants.h:
--------------------------------------------------------------------------------
1 | //
2 | // APIConstants.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #ifndef iOS_APIParser_APIConstants_h
10 | #define iOS_APIParser_APIConstants_h
11 |
12 | #define DEFAULT_TIMEOUT 120000.0f
13 |
14 | #define ServerPath "https://jsonplaceholder.typicode.com"
15 |
16 | #pragma mark - Test
17 |
18 | #if __IPHONE_OS_VERSION_MIN_REQUIRED >= 80000
19 |
20 | #define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIApplication sharedApplication].keyWindow bounds].size.width : [[UIApplication sharedApplication].keyWindow bounds].size.height)
21 |
22 | #define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIApplication sharedApplication].keyWindow bounds].size.height : [[UIApplication sharedApplication].keyWindow bounds].size.width)
23 |
24 | #else
25 |
26 | #define SCREEN_WIDTH ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.width : [[UIScreen mainScreen] bounds].size.height)
27 |
28 | #define SCREEN_HEIGHT ((([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortrait) || ([UIApplication sharedApplication].statusBarOrientation == UIInterfaceOrientationPortraitUpsideDown)) ? [[UIScreen mainScreen] bounds].size.height : [[UIScreen mainScreen] bounds].size.width)
29 |
30 | #endif
31 |
32 | #endif
33 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/APILogDetailVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // APILogDetailVC.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "APIInfoObject.h"
11 |
12 | @interface APILogDetailVC : UITableViewController
13 |
14 | @property (nonatomic, strong) APIInfoObject *selectedAPIForDetail;
15 |
16 | @end
17 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/APILogDetailVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // APILogDetailVC.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APILogDetailVC.h"
10 |
11 | @interface APILogDetailVC ()
12 | {
13 | __weak IBOutlet UILabel *lblRequestURL;
14 | __weak IBOutlet UILabel *lblRequestParameters;
15 | __weak IBOutlet UILabel *lblRequestHeaders;
16 |
17 | __weak IBOutlet UITextView *txtURLResponse;
18 | __weak IBOutlet UILabel *lblResponseHeader;
19 |
20 | __weak IBOutlet UISegmentedControl *responseDisplaySegmentControl;
21 | }
22 | @end
23 |
24 | @implementation APILogDetailVC
25 |
26 | - (void)viewDidLoad {
27 | [super viewDidLoad];
28 |
29 | self.title = [NSString stringWithFormat:@"%@ : Status (%ld) ",self.selectedAPIForDetail.APITitle, (long)((NSHTTPURLResponse *)self.selectedAPIForDetail.APIResponce).statusCode];
30 |
31 | lblRequestURL.text = self.selectedAPIForDetail.APIRequest.URL.absoluteString;
32 | lblRequestHeaders.text = [NSString stringWithFormat:@"%@",self.selectedAPIForDetail.APIRequest.allHTTPHeaderFields];
33 | lblRequestParameters.text = [[[NSString alloc] initWithData:[self.selectedAPIForDetail.APIRequest HTTPBody] encoding:NSUTF8StringEncoding] stringByReplacingOccurrencesOfString:@"&" withString:@"\n"];
34 |
35 | txtURLResponse.scrollEnabled = NO;
36 |
37 | // txtURLResponse.text = (self.selectedAPIForDetail.responseDictionary) ? [NSString stringWithFormat:@"%@", self.selectedAPIForDetail.responseDictionary] : (self.selectedAPIForDetail.responseString.length>0) ? self.selectedAPIForDetail.responseString : @"";
38 |
39 | txtURLResponse.text = self.selectedAPIForDetail.responseString;
40 |
41 | [txtURLResponse layoutSubviews];
42 |
43 | [txtURLResponse resignFirstResponder];
44 | [txtURLResponse becomeFirstResponder];
45 |
46 | [self.tableView reloadData];
47 |
48 | [self.tableView beginUpdates];
49 | [self.tableView endUpdates];
50 |
51 | [responseDisplaySegmentControl addTarget:self
52 | action:@selector(responseDisplaySegmentChanged:)
53 | forControlEvents:UIControlEventValueChanged];
54 | }
55 |
56 | - (void)didReceiveMemoryWarning {
57 | [super didReceiveMemoryWarning];
58 | }
59 |
60 | #pragma mark - Table view data source
61 |
62 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
63 | return 2;
64 | }
65 |
66 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
67 | return (section ==0) ? 3: 1;
68 | }
69 |
70 | -(CGFloat)tableView:(UITableView *)tableView estimatedHeightForRowAtIndexPath:(NSIndexPath *)indexPath{
71 | return 46;
72 | }
73 |
74 | -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
75 | return UITableViewAutomaticDimension;
76 | }
77 |
78 | #pragma mark - Response Display Segment changed
79 |
80 | - (void)responseDisplaySegmentChanged:(id)sender {
81 | switch (responseDisplaySegmentControl.selectedSegmentIndex) {
82 | case 0: //RAW Response
83 | {
84 | txtURLResponse.text = self.selectedAPIForDetail.responseString;
85 | }
86 | break;
87 | case 1: //FORMATTED Response
88 | {
89 | txtURLResponse.text = [NSString stringWithFormat:@"%@", self.selectedAPIForDetail.responseDictionary];
90 | }
91 | break;
92 | default:
93 | break;
94 | }
95 | [self.tableView reloadData];
96 | }
97 |
98 | @end
99 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/APILogsVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // APILogsVC.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface APIDetailCell : UITableViewCell
12 |
13 | @property (weak, nonatomic) IBOutlet UILabel *lblStatusIndicator;
14 | @property (weak, nonatomic) IBOutlet UILabel *lblAPITitle;
15 | @property (weak, nonatomic) IBOutlet UILabel *lblAPIURL;
16 | @property (weak, nonatomic) IBOutlet UIButton *btnStatusCode;
17 |
18 | @end
19 |
20 | @interface APILogsVC : UITableViewController
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/APILogsVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // APILogsVC.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APILogsVC.h"
10 | #import "AppCacheManagement.h"
11 | #import "APIInfoObject.h"
12 | #import "APILogDetailVC.h"
13 | #import "APIParser.h"
14 |
15 | @implementation APIDetailCell
16 |
17 | @end
18 |
19 |
20 | @interface APILogsVC ()
21 |
22 | @property (nonatomic, strong) NSMutableArray *APIDetailArray;
23 |
24 | @end
25 |
26 | @implementation APILogsVC
27 |
28 | - (void)viewDidLoad {
29 | [super viewDidLoad];
30 |
31 | self.tableView.showsVerticalScrollIndicator = false;
32 |
33 | self.title = @"API Logs";
34 |
35 | [[AppCacheManagement sharedCacheManager] getcachedataArrayFor_:kDeveloperDebugAPILog myMethod:^(BOOL status, NSMutableArray *retrivedArray) {
36 |
37 | if (retrivedArray != nil) {
38 |
39 | _APIDetailArray = [[[retrivedArray reverseObjectEnumerator] allObjects] mutableCopy];
40 |
41 | [self.tableView reloadData];
42 |
43 | [self.tableView beginUpdates];
44 | [self.tableView endUpdates];
45 | }
46 | }];
47 | }
48 |
49 | - (void)didReceiveMemoryWarning {
50 | [super didReceiveMemoryWarning];
51 | }
52 |
53 | #pragma mark - Table view data source
54 |
55 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
56 | return 1;
57 | }
58 |
59 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
60 | return _APIDetailArray.count;
61 | }
62 |
63 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
64 | APIDetailCell *cell = [tableView dequeueReusableCellWithIdentifier:@"APICell" forIndexPath:indexPath];
65 |
66 | APIInfoObject *apiDetail = (APIInfoObject *) [_APIDetailArray objectAtIndex:indexPath.row];
67 |
68 | if (((NSHTTPURLResponse *)apiDetail.APIResponce).statusCode == 200) {
69 | cell.lblStatusIndicator.backgroundColor = RGBCOLOR(10, 168, 50, 1.0);
70 | } else {
71 | cell.lblStatusIndicator.backgroundColor = RGBCOLOR(255, 0, 28, 1.0);
72 | }
73 |
74 | [cell.btnStatusCode setTitle:[NSString stringWithFormat:@"%ld", (long)((NSHTTPURLResponse *)apiDetail.APIResponce).statusCode] forState:UIControlStateNormal];
75 |
76 | cell.lblAPITitle.text = apiDetail.APITitle;
77 |
78 | cell.lblAPIURL.text = apiDetail.APIRequest.URL.absoluteString;
79 |
80 | return cell;
81 | }
82 |
83 | -(void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
84 | {
85 | [tableView deselectRowAtIndexPath:indexPath animated:YES];
86 |
87 | APILogDetailVC *APIDetail = loadViewController(@"DeveloperInsights", @"idAPILogDetailVC");
88 | APIDetail.selectedAPIForDetail = (APIInfoObject *) [_APIDetailArray objectAtIndex:indexPath.row];
89 | [self.navigationController pushViewController:APIDetail animated:YES];
90 | }
91 |
92 |
93 | @end
94 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/InternetConnectionStatusVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // InternetConnectionStatusVC.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface InternetConnectionStatusVC : UIViewController
12 |
13 | typedef void (^NetworkCompletion)(InternetConnectionStatusVC *);
14 |
15 | @property (nonatomic, readwrite) NSString *headerMessage;
16 | @property (nonatomic, readwrite) NSString *descriptionMessage;
17 |
18 | //Parent View Controller
19 | @property (nonatomic, strong) UIViewController *parentVC;
20 |
21 | //Completion block
22 | @property (nonatomic,copy) NetworkCompletion completionBlock;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Controller/InternetConnectionStatusVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // InternetConnectionStatusVC.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "InternetConnectionStatusVC.h"
10 | #import "UIViewController+Helper.h"
11 |
12 | @interface InternetConnectionStatusVC ()
13 | {
14 | IBOutlet UILabel *lblInternetStatusHeader;
15 | IBOutlet UILabel *lblInternetStatusDescription;
16 | IBOutlet UIImageView *imgInternetStatus;
17 | IBOutlet UIButton *btnTryAgain;
18 | }
19 | @end
20 |
21 | @implementation InternetConnectionStatusVC
22 |
23 | - (void)viewDidLoad {
24 | [super viewDidLoad];
25 |
26 | self.title = @"Newtwork Issue!";
27 |
28 | [self.navigationController.navigationBar setTitleTextAttributes:@{
29 | NSForegroundColorAttributeName : RGBCOLOR(49, 146, 181, 1.0),
30 | NSFontAttributeName : [UIFont systemFontOfSize:20.0]
31 | }];
32 |
33 | //Add Right bar button
34 | UIButton *btnRight = [UIButton buttonWithType:UIButtonTypeSystem];
35 | [btnRight setFrame:CGRectMake(0, 0, 40, 40)];
36 | [btnRight setTintColor:[UIColor whiteColor]];
37 | [btnRight setImage:[UIImage imageNamed:@"close_navigationbar"] forState:UIControlStateNormal];
38 | [btnRight addTarget:self action:@selector(closeConnectivityView:) forControlEvents:UIControlEventTouchUpInside];
39 |
40 | [btnRight setContentHorizontalAlignment:UIControlContentHorizontalAlignmentRight];
41 |
42 | btnRight.imageView.contentMode = UIViewContentModeScaleAspectFit;
43 | btnRight.contentHorizontalAlignment = UIControlContentHorizontalAlignmentRight;
44 | btnRight.contentVerticalAlignment = UIControlContentVerticalAlignmentCenter;
45 |
46 | UIBarButtonItem *rightBarButton = [[UIBarButtonItem alloc] initWithCustomView:btnRight];
47 | [rightBarButton setTintColor:[UIColor whiteColor]];
48 | // self.navigationItem.rightBarButtonItem = rightBarButton;
49 | }
50 |
51 | - (void) viewWillAppear:(BOOL)animated
52 | {
53 | [super viewWillAppear:animated];
54 | }
55 |
56 | -(UIBarPosition)positionForBar:(id)bar {
57 | return UIBarPositionTopAttached;
58 | }
59 |
60 | - (void)didReceiveMemoryWarning {
61 | [super didReceiveMemoryWarning];
62 | // Dispose of any resources that can be recreated.
63 | }
64 |
65 | #pragma mark - Close presented View
66 |
67 | - (IBAction)closeConnectivityView:(id)sender {
68 |
69 | [self dismissViewControllerAnimated:YES completion:^{
70 |
71 | }];
72 | }
73 |
74 | #pragma mark - Try Again Click
75 |
76 | - (IBAction)retryClicked:(id)sender {
77 |
78 | UIButton *btnSender = (UIButton *)sender;
79 |
80 | UIActivityIndicatorView *indicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite];
81 | indicator.tag = 200;
82 | indicator.tintColor = [UIColor whiteColor];
83 | CGFloat halfButtonHeight = btnSender.bounds.size.height / 2;
84 | CGFloat buttonWidth = btnSender.bounds.size.width;
85 | indicator.center = CGPointMake(buttonWidth - halfButtonHeight , halfButtonHeight);
86 | indicator.hidesWhenStopped = YES;
87 | [btnSender addSubview:indicator];
88 | [indicator startAnimating];
89 |
90 | [btnTryAgain setEnabled:NO];
91 |
92 | [self checkHostReachabilityWithIndicator:indicator];
93 | }
94 |
95 |
96 | - (void) checkHostReachabilityWithIndicator :(UIActivityIndicatorView*)indicator {
97 |
98 | NetworkStatus currentStatus = [APP_CONTEXT checkHostReachability];
99 |
100 | switch (currentStatus) {
101 | case NotReachable:
102 | {
103 | __weak UIActivityIndicatorView *weakindicator = indicator;
104 |
105 | [self _shake:7 direction:1 currentTimes:0 withDelta:2 speed:0.06 shakeDirection:ShakeDirectionHorizontal forView:btnTryAgain completion:^{
106 |
107 | [weakindicator stopAnimating];
108 | [weakindicator removeFromSuperview];
109 |
110 | [btnTryAgain setEnabled:YES];
111 | }];
112 | }
113 | break;
114 | case ReachableViaWiFi:
115 | case ReachableViaWWAN:
116 | {
117 | [self dismissViewControllerAnimated:YES completion:^{
118 |
119 | if (self.completionBlock) {
120 | self.completionBlock(self);
121 | }
122 | }];
123 |
124 | }
125 | }
126 | }
127 |
128 | @end
129 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Model/APIInfoObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // APIInfoObject.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface APIInfoObject : NSObject
12 |
13 | @property (nonatomic, strong) NSString *APITitle;
14 |
15 | @property (nonatomic, strong) NSURLRequest *APIRequest;
16 |
17 | @property (nonatomic, strong) NSURLResponse *APIResponce;
18 |
19 | @property (nonatomic, strong) NSDictionary *responseDictionary;
20 |
21 | @property (nonatomic, strong) NSString *responseString;
22 |
23 | + (instancetype)modelObjectWithDetails:(NSString *)apiTitle request:(NSURLRequest *)apiRequest response:(NSURLResponse *)apiResponse responseDictionary:(NSDictionary *)responseDict responseString:(NSString *)responseString;
24 |
25 | @end
26 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Model/APIInfoObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // APIInfoObject.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APIInfoObject.h"
10 |
11 | @implementation APIInfoObject
12 |
13 | + (instancetype)modelObjectWithDetails:(NSString *)apiTitle request:(NSURLRequest *)apiRequest response:(NSURLResponse *)apiResponse responseDictionary:(NSDictionary *)responseDict responseString:(NSString *)responseString
14 | {
15 | return [[self alloc] initWithDetail:apiTitle request:apiRequest response:apiResponse responseDictionary:responseDict responseString:responseString];
16 | }
17 |
18 | - (instancetype)initWithDetail:(NSString *)apiTitle request:(NSURLRequest *)apiRequest response:(NSURLResponse *)apiResponse responseDictionary:(NSDictionary *)responseDict responseString:(NSString *)responseString
19 | {
20 | self = [super init];
21 |
22 | self.APITitle = apiTitle;
23 | self.APIRequest = apiRequest;
24 | self.APIResponce = apiResponse;
25 | self.responseDictionary = responseDict;
26 | self.responseString = responseString;
27 |
28 | return self;
29 | }
30 |
31 | #pragma mark - NSCoding Methods
32 |
33 | - (id)initWithCoder:(NSCoder *)aDecoder
34 | {
35 | self = [super init];
36 |
37 | self.APITitle = [aDecoder decodeObjectForKey:@"Title"];
38 | self.APIRequest = [aDecoder decodeObjectForKey:@"Request"];
39 | self.APIResponce = [aDecoder decodeObjectForKey:@"Response"];
40 | self.responseDictionary = [aDecoder decodeObjectForKey:@"ResponseDictionary"];
41 | self.responseString = [aDecoder decodeObjectForKey:@"ResponseString"];
42 |
43 | return self;
44 | }
45 |
46 | - (void)encodeWithCoder:(NSCoder *)aCoder
47 | {
48 | [aCoder encodeObject:_APITitle forKey:@"Title"];
49 | [aCoder encodeObject:_APIRequest forKey:@"Request"];
50 | [aCoder encodeObject:_APIResponce forKey:@"Response"];
51 | [aCoder encodeObject:_responseDictionary forKey:@"ResponseDictionary"];
52 | [aCoder encodeObject:_responseString forKey:@"ResponseString"];
53 | }
54 |
55 | - (id)copyWithZone:(NSZone *)zone
56 | {
57 | APIInfoObject *copy = [[APIInfoObject alloc] init];
58 |
59 | if (copy) {
60 |
61 | copy.APITitle = [self.APITitle copyWithZone:zone];
62 | copy.APIRequest = [self.APIRequest copyWithZone:zone];
63 | copy.APIResponce = [self.APIResponce copyWithZone:zone];
64 | copy.responseDictionary = [self.responseDictionary copyWithZone:zone];
65 | copy.responseString = [self.responseString copyWithZone:zone];
66 | }
67 |
68 | return copy;
69 | }
70 |
71 |
72 | @end
73 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Model/AppCacheManagement.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppCacheManagement.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | static NSString* kDeveloperDebugAPILog = @"DeveloperDebugAPILog";
12 |
13 | static int kConstMaxDebugAPICount = 50;
14 |
15 | typedef void(^cacheArrayGetCompletion)(BOOL status, NSMutableArray* retrivedArray);
16 |
17 | typedef void(^cacheObjectGetCompletion)(BOOL status, id obj);
18 |
19 | @interface AppCacheManagement : NSObject
20 |
21 |
22 | + (id)sharedCacheManager;
23 |
24 | #pragma mark - Enable / Disable API Logger
25 |
26 | - (BOOL)APILoggingEnabled;
27 | - (void)setAPILoggingEnabled:(BOOL)value;
28 |
29 |
30 | #pragma mark - Cache Saving mechanisam
31 | - (void)setCacheToUserDefaults:(NSMutableArray *)resPonseArrayList ForKey:(NSString *)strKey ;
32 | - (void)getcachedataArrayFor_:(NSString *)strKey myMethod:(cacheArrayGetCompletion) compblock ;
33 | - (void)removeCacheForKey:(NSString *)objectKey ;
34 |
35 |
36 | #pragma mark - Object
37 | - (void)setObjectCacheToUserDefaults:(id)resPonseObject ForKey:(NSString *)strKey ;
38 | - (void)getObjectCachedataFor_:(NSString *)strKey myMethod:(cacheObjectGetCompletion) compblock;
39 |
40 |
41 | #pragma mark - Remove all cache fro Current User
42 | - (void) removeAllAPICachedObjects ;
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/Model/AppCacheManagement.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppCacheManagement.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "AppCacheManagement.h"
10 |
11 | static BOOL APILoggingEnabled;
12 |
13 | @implementation AppCacheManagement
14 |
15 | #pragma mark Singleton Methods
16 |
17 | + (id)sharedCacheManager {
18 | static AppCacheManagement *sharedCacheManager = nil;
19 | static dispatch_once_t onceToken;
20 | dispatch_once(&onceToken, ^{
21 | sharedCacheManager = [[self alloc] init];
22 | });
23 | return sharedCacheManager;
24 | }
25 |
26 |
27 | #pragma mark - Enable / Disable API Logger
28 |
29 | - (BOOL)APILoggingEnabled {
30 | return APILoggingEnabled;
31 | }
32 |
33 | - (void)setAPILoggingEnabled:(BOOL)value {
34 | APILoggingEnabled = value;
35 | }
36 |
37 | #pragma mark - Cache Saving mechanisam
38 |
39 | - (void)setCacheToUserDefaults:(NSMutableArray *)resPonseArrayList ForKey:(NSString *)strKey
40 | {
41 | @autoreleasepool
42 | {
43 | [self setCustomObject:resPonseArrayList forKey:strKey];
44 | resPonseArrayList = nil;
45 | }
46 | }
47 |
48 | - (void)getcachedataArrayFor_:(NSString *)strKey
49 | myMethod:(cacheArrayGetCompletion) compblock
50 | {
51 | @autoreleasepool
52 | {
53 | NSMutableArray *retrivedCacheData = [[NSMutableArray alloc] init];
54 | [retrivedCacheData addObjectsFromArray:[self customObjectForKey:strKey]];
55 |
56 | compblock(YES, retrivedCacheData);
57 | }
58 | }
59 |
60 | #pragma mark - object
61 | - (void)setObjectCacheToUserDefaults:(id)resPonseObject ForKey:(NSString *)strKey
62 | {
63 | @autoreleasepool
64 | {
65 | [self setCustomObject:resPonseObject forKey:strKey];
66 | resPonseObject = nil;
67 | }
68 | }
69 |
70 | - (void) getObjectCachedataFor_:(NSString *)strKey
71 | myMethod:(cacheObjectGetCompletion) compblock
72 | {
73 | @autoreleasepool
74 | {
75 | id retrivedObject;
76 | retrivedObject = [self customObjectForKey:strKey];
77 |
78 | compblock(YES, retrivedObject);
79 | }
80 | }
81 |
82 | #pragma mark - Remove key
83 |
84 | - (void)removeCacheForKey:(NSString *)objectKey
85 | {
86 | @autoreleasepool
87 | {
88 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:objectKey];
89 | [[NSUserDefaults standardUserDefaults] synchronize];
90 | }
91 | }
92 |
93 | #pragma mark - Remove all cache fro Current User
94 | - (void) removeAllAPICachedObjects
95 | {
96 | [[NSUserDefaults standardUserDefaults] removeObjectForKey:kDeveloperDebugAPILog];
97 | [[NSUserDefaults standardUserDefaults] synchronize];
98 | }
99 |
100 | #pragma mark - Encode Array of objects or object
101 |
102 | - (id)customObjectForKey:(NSString *)key {
103 |
104 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
105 | NSData *encodedObject = [defaults objectForKey:key];
106 | id obj = [NSKeyedUnarchiver unarchiveObjectWithData:encodedObject];
107 | return obj;
108 | }
109 |
110 | - (void)setCustomObject:(id)obj forKey:(NSString *)key {
111 | if ([obj respondsToSelector:@selector(encodeWithCoder:)] == NO) {
112 | return;
113 | }
114 | NSData *encodedObject = [NSKeyedArchiver archivedDataWithRootObject:obj];
115 | NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
116 | [defaults setObject:encodedObject forKey:key];
117 | [defaults synchronize];
118 | }
119 |
120 |
121 | @end
122 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/View/DeveloperInsights.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 | SourceSansPro-Black
15 |
16 |
17 | SourceSansPro-Light
18 |
19 |
20 | SourceSansPro-Semibold
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
51 |
57 |
66 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 |
151 |
152 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
180 |
189 |
190 |
191 |
192 |
193 |
194 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
214 |
223 |
224 |
225 |
226 |
227 |
228 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
247 |
248 |
249 |
250 |
251 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APILogger/View/InternetConnection.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | SourceSansPro-Regular
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
39 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
77 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APIParser+User.h:
--------------------------------------------------------------------------------
1 | //
2 | // APIParser+User.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 17/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APIParser.h"
10 |
11 | @interface APIParser (User)
12 |
13 | typedef enum
14 | {
15 | APIUserLogIn,
16 | APIGetComments
17 | } APIType;
18 |
19 | - (void)URLRequestWithType:(APIType)serviceName
20 | parameters:(NSString *)parameters
21 | cookieValue:(NSMutableArray *)cookies
22 | customeobject:(id)object
23 | withRequestType:(APIRequestType) requestType
24 | withRequestHeaders:(NSDictionary *) headerDictionaries
25 | block:(ResponseBlock)block;
26 |
27 | @end
28 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APIParser+User.m:
--------------------------------------------------------------------------------
1 | //
2 | // APIParser+User.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 17/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APIParser+User.h"
10 | #import "FeedObject.h"
11 |
12 | @implementation APIParser (User)
13 |
14 | - (void)URLRequestWithType:(APIType)serviceName
15 | parameters:(NSString *)parameters
16 | cookieValue:(NSMutableArray *)cookies
17 | customeobject:(id)object
18 | withRequestType:(APIRequestType) requestType
19 | withRequestHeaders:(NSDictionary *) headerDictionaries
20 | block:(ResponseBlock)block
21 | {
22 | //Check Internet Connectivity
23 | NetworkStatus currentStatus = [APP_CONTEXT checkHostReachability];
24 |
25 | switch (currentStatus) {
26 | case ReachableViaWiFi:
27 | case ReachableViaWWAN:
28 | {
29 | NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
30 |
31 | NSString *URLString;
32 | NSData *jsonData;
33 | NSString *nextStartRecord;
34 |
35 | NSURLSessionConfiguration *defaultConfigObject = [NSURLSessionConfiguration defaultSessionConfiguration];
36 | NSURLSession *defaultSession = [NSURLSession sessionWithConfiguration: defaultConfigObject];
37 | NSURLSessionDataTask * dataTask;
38 |
39 | switch (serviceName)
40 | {
41 | case APIUserLogIn:
42 | {
43 | URLString = @"";
44 | }
45 | break;
46 | case APIGetComments:
47 | {
48 | URLString = [NSString stringWithFormat:@"%s/posts/1/comments", ServerPath];
49 | }
50 | break;
51 | default:
52 | break;
53 | }
54 |
55 | NSMutableURLRequest *request;
56 |
57 | if (object == nil) {
58 |
59 | jsonData = [parameters dataUsingEncoding:NSASCIIStringEncoding allowLossyConversion:YES];
60 | request = [self urlRequestForURL:[NSURL URLWithString:URLString] withObjects:jsonData withReqCookies:cookies isObject:NO withParameters:parameters reqType:requestType reqHeaders:headerDictionaries];
61 | }
62 | else {
63 |
64 | jsonData = [self dictionaryWithPropertiesOfObject:object];
65 | request = [self urlRequestForURL:[NSURL URLWithString:URLString] withObjects:jsonData withReqCookies:cookies isObject:YES withParameters:parameters reqType:requestType reqHeaders:headerDictionaries];
66 | }
67 |
68 | __block id Responceobjects = nil;
69 |
70 | runOnMainQueueWithoutDeadlocking(^{
71 | ShowNetworkIndicator(1);
72 | });
73 |
74 | dataTask = [defaultSession dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
75 | {
76 | if (((NSHTTPURLResponse *)response).statusCode == 401) {
77 |
78 | error = [NSError errorWithDomain:@"Session time out" code:401 userInfo:nil];
79 |
80 | runOnMainQueueWithoutDeadlocking(^{
81 | //Show Alert for Session Time Out.
82 | });
83 |
84 | NSString *responseString;
85 |
86 | NSDictionary *jsonDict;
87 |
88 | if (data) {
89 | responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
90 |
91 | jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
92 | }
93 |
94 | NSMutableArray *responceDataArray;
95 |
96 | //API cache Logger
97 | [self saveAPIDetailsToCacheForRequestTitle:[[NSURL URLWithString:URLString] lastPathComponent]
98 | andResponse:response
99 | andRequest:request
100 | responseDictionary:(jsonDict) ? : nil
101 | responseString:(responseString) ? : @""];
102 |
103 |
104 | dispatch_async(dispatch_get_main_queue(), ^(){
105 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{
106 | if ( error )
107 | {
108 | ShowNetworkIndicator(0);
109 | block(error,Responceobjects,responseString, nil, responceDataArray, response);
110 | }
111 | else
112 | {
113 | ShowNetworkIndicator(0);
114 | block(error,Responceobjects,responseString, nextStartRecord, responceDataArray, response);
115 | }
116 | }];
117 | });
118 | }
119 | else if(error != nil)
120 | {
121 | NSString *responseString;
122 |
123 | NSDictionary *jsonDict;
124 |
125 | if (data) {
126 | responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
127 |
128 | jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
129 | }
130 |
131 |
132 |
133 | NSMutableArray *responceDataArray;
134 |
135 | runOnMainQueueWithoutDeadlocking(^{
136 | //Show Alert for Request Failed.
137 | });
138 |
139 | //API cache Logger
140 | [self saveAPIDetailsToCacheForRequestTitle:[[NSURL URLWithString:URLString] lastPathComponent]
141 | andResponse:response
142 | andRequest:request
143 | responseDictionary:(jsonDict) ? : nil
144 | responseString:(responseString) ? : @""];
145 |
146 | dispatch_async(dispatch_get_main_queue(), ^(){
147 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{
148 | if ( error )
149 | {
150 | ShowNetworkIndicator(0);
151 | block(error,Responceobjects,responseString, nil, responceDataArray, response);
152 | }
153 | else
154 | {
155 | ShowNetworkIndicator(0);
156 | block(error,Responceobjects,responseString, nextStartRecord, responceDataArray, response);
157 | }
158 | }];
159 | });
160 | }
161 | else if(error == nil)
162 | {
163 |
164 | NSString *responseString = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
165 |
166 | NSDictionary *jsonDict = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
167 |
168 | //API cache Logger
169 | [self saveAPIDetailsToCacheForRequestTitle:[[NSURL URLWithString:URLString] lastPathComponent]
170 | andResponse:response
171 | andRequest:request
172 | responseDictionary:jsonDict
173 | responseString:responseString];
174 |
175 | NSMutableArray *responceDataArray;
176 |
177 | if (data.length>0)
178 | {
179 | Responceobjects = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
180 | responceDataArray = [NSMutableArray array];
181 |
182 | NSLog(@"ResponseString :: %@", responseString);
183 |
184 | switch (serviceName)
185 | {
186 | case APIUserLogIn:
187 | {
188 | /*
189 | If Any status has been passed from Server then first check SUCCESS / FAILURE status
190 | Then Parse your response within condition
191 | */
192 | if ([[[(NSDictionary *)Responceobjects valueForKey:@"STATUS"] stringValue] isEqualToString:Success])
193 | {
194 | Responceobjects = [(NSDictionary *)Responceobjects valueForKey:@"DATA"];
195 | }
196 | else if ([[[(NSDictionary *)Responceobjects valueForKey:@"STATUS"] stringValue] isEqualToString:Failure])
197 | {
198 | NSDictionary *errorDict = [[NSDictionary alloc]initWithObjectsAndKeys:[(NSDictionary *)Responceobjects valueForKey:@"MESSAGE"], @"msg", nil];
199 | error = [NSError errorWithDomain:@"Internal Error" code:2 userInfo:errorDict];
200 | }
201 | else if ([[[(NSDictionary *)Responceobjects valueForKey:@"STATUS"] stringValue] isEqualToString:InvalidResponce])
202 | {
203 | NSDictionary *errorDict = [[NSDictionary alloc]initWithObjectsAndKeys:[(NSDictionary *)Responceobjects valueForKey:@"MESSAGE"], @"msg", nil];
204 | error = [NSError errorWithDomain:@"Internal Error" code:2 userInfo:errorDict];
205 | }
206 | }
207 | break;
208 | case APIGetComments :
209 | {
210 | // responceDataArray = (NSMutableArray *)Responceobjects;
211 | for (NSDictionary *dictionary in Responceobjects) {
212 | FeedObject *feedObj = [FeedObject modelObjectWithDictionary:dictionary];
213 | [responceDataArray addObject:feedObj];
214 | }
215 | break;
216 | }
217 | default:
218 | break;
219 | }
220 | }
221 | else if(error != nil)
222 | {
223 | runOnMainQueueWithoutDeadlocking(^{
224 | //Handle Error as per your requirement
225 | });
226 | }
227 | else if(data.length == 0)
228 | {
229 | runOnMainQueueWithoutDeadlocking(^{
230 | //No response Received
231 | });
232 | }
233 |
234 | dispatch_async(dispatch_get_main_queue(), ^(){
235 | [[NSOperationQueue mainQueue] addOperationWithBlock:^{
236 | if ( error )
237 | {
238 | ShowNetworkIndicator(0);
239 | block(error,Responceobjects,responseString, nil, responceDataArray, response);
240 | }
241 | else
242 | {
243 | ShowNetworkIndicator(0);
244 | block(error,Responceobjects,responseString, nextStartRecord, responceDataArray,response);
245 | }
246 | }];
247 | });
248 | }
249 | }
250 | }];
251 |
252 | [dataTask resume];
253 | }];
254 |
255 | [operation setQueuePriority:NSOperationQueuePriorityVeryHigh];
256 | [self.WSoperationQueue addOperation:operation];
257 | }
258 | break;
259 | case NotReachable:
260 | {
261 | if (!self.APIRequestsArray) {
262 | self.APIRequestsArray = [NSMutableArray new];
263 | }
264 | //Get current selector
265 | SEL aSelector = @selector(URLRequestWithType:
266 | parameters:
267 | cookieValue:
268 | customeobject:
269 | withRequestType:
270 | withRequestHeaders:
271 | block:);
272 | NSMethodSignature *signature = [self methodSignatureForSelector:aSelector];
273 |
274 | //Set arguments in Invocation
275 | NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:signature];
276 | [invocation setTarget:self];
277 | [invocation setSelector:aSelector];
278 | [invocation setArgument:&serviceName atIndex:2];
279 | [invocation setArgument:¶meters atIndex:3];
280 | [invocation setArgument:&cookies atIndex:4];
281 | [invocation setArgument:&object atIndex:5];
282 | [invocation setArgument:&requestType atIndex:6];
283 | [invocation setArgument:&headerDictionaries atIndex:7];
284 | [invocation setArgument:&block atIndex:8];
285 |
286 | //Retaining the arguments to invoke method later on
287 | [invocation retainArguments];
288 |
289 | [self.APIRequestsArray addObject:invocation];
290 |
291 |
292 | if (!self.isnetworkStatusVCPresented) {
293 |
294 | InternetConnectionStatusVC *networkStatus = loadViewController(@"InternetConnection", @"idInternetConnectionStatusVC");
295 |
296 | //Set specific message for network connectivity
297 | networkStatus.headerMessage = @"";
298 | networkStatus.descriptionMessage = @"";
299 |
300 | networkStatus.completionBlock = ^(InternetConnectionStatusVC *controller)
301 | {
302 |
303 | //Network connected, call previous WS
304 | for (NSInvocation *WSInvocationCall in self.APIRequestsArray) {
305 | //Invoke (call) stored WS functions
306 | [WSInvocationCall performSelector:@selector(invoke) withObject:nil afterDelay:0.0];
307 | }
308 | self.APIRequestsArray = nil;
309 |
310 | self.isnetworkStatusVCPresented = NO;
311 | };
312 |
313 | self.isnetworkStatusVCPresented = YES;
314 |
315 | UIViewController *vc = APP_CONTEXT.window.rootViewController;
316 |
317 | if (!APP_CONTEXT.appNavigationController) {
318 | APP_CONTEXT.appNavigationController = [[UINavigationController alloc] init];
319 | }
320 |
321 | UINavigationController *navigationController = [[UINavigationController alloc] initWithRootViewController:networkStatus];
322 |
323 | [vc presentViewController:navigationController animated:YES
324 | completion:^{
325 |
326 | }];
327 | }
328 | }
329 | break;
330 | default:
331 | break;
332 | }
333 | }
334 |
335 |
336 |
337 | @end
338 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APIParser.h:
--------------------------------------------------------------------------------
1 | //
2 | // APIParser.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "Reachability.h"
11 | #import "APIConstants.h"
12 | #import "objc/runtime.h"
13 | #import "InternetConnectionStatusVC.h"
14 |
15 |
16 | typedef enum
17 | {
18 | APIRequestMethodGET,
19 | APIRequestMethodPOST,
20 | APIRequestMethodDELETE,
21 | APIRequestMethodPUT
22 | } APIRequestType;
23 |
24 | typedef void (^ResponseBlock) (NSError *error, id objects, NSString *responseString,NSString *nextUrl, NSMutableArray *responseArray, NSURLResponse *URLResponseObject);
25 |
26 | enum RESPONCESTATUTS
27 | {
28 | NORESPONCE=0,
29 | VALID = 1,
30 | INVALID = 2
31 | };
32 |
33 | #define Success @"1"
34 | #define InvalidResponce @"2"
35 | #define Failure @"3"
36 |
37 | @interface APIParser : NSObject
38 | {
39 | Reachability *reachability;
40 | }
41 |
42 | @property (nonatomic, assign) APIRequestType requestType;
43 |
44 | @property (strong) NSOperationQueue *WSoperationQueue;
45 |
46 | @property (nonatomic, assign) BOOL isnetworkStatusVCPresented;
47 |
48 | @property (nonatomic, strong) NSMutableArray *APIRequestsArray;
49 |
50 | + (id)sharedMediaServer;
51 |
52 | - (NSData *)dictionaryWithPropertiesOfObject:(id)obj;
53 | - (NSData *)dictionaryWithmembersOfObject:(id)obj formembers:(NSArray *)members;
54 | - (NSData *)dictionaryToJSONData:(NSDictionary *)dict;
55 |
56 | - (NSMutableURLRequest *)urlRequestForURL:(NSURL *)url withObjects:(NSData *)objData
57 | withReqCookies:(NSMutableArray *)arrCookies
58 | isObject:(bool)customObj
59 | withParameters :(NSString *) params
60 | reqType :(APIRequestType) requestType
61 | reqHeaders:(NSDictionary *) requestHeaders;
62 |
63 | #pragma mark - Cancel all API request with operation
64 | - (void)cancelALLCurrentlyExecutingRequest;
65 |
66 | #pragma mark - Dictionary to QueryString
67 | -(NSString *)serializeParams:(NSDictionary *)params;
68 |
69 | #pragma mark - DEVELOPER API DEBUG LOGS
70 | - (void) saveAPIDetailsToCacheForRequestTitle:(NSString *)apiName //Title of API
71 | andResponse:(NSURLResponse *)response //Response object
72 | andRequest:(NSURLRequest *)request //Request object
73 | responseDictionary:(NSDictionary *)responseDict //Formatted response
74 | responseString:(NSString *)responseString; //Raw response
75 |
76 | #pragma mark - Run On Main Thread
77 | void runOnMainQueueWithoutDeadlocking(void (^block)(void));
78 |
79 | @end
80 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/APIParser.m:
--------------------------------------------------------------------------------
1 | //
2 | // APIParser.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "APIParser.h"
10 | #import "APIInfoObject.h"
11 | #import "AppCacheManagement.h"
12 |
13 | @implementation APIParser
14 |
15 | #pragma mark - Properties
16 |
17 | @synthesize WSoperationQueue = WSoperationQueue;
18 |
19 | #pragma mark - Init NSObject
20 |
21 | - (id)init
22 | {
23 | if ( ( self = [super init] ) )
24 | {
25 | // The maxConcurrentOperationCount should reflect the number of open
26 | // connections the server can handle. Right now, limit it to two for
27 | // the sake of this example.
28 | WSoperationQueue = [[NSOperationQueue alloc] init];
29 | WSoperationQueue.maxConcurrentOperationCount = 16;
30 |
31 | if (IOS_NEWER_OR_EQUAL_TO_X(8.0)) {
32 |
33 | WSoperationQueue.qualityOfService = NSQualityOfServiceBackground;
34 | }
35 |
36 | // Allocate a reachability object
37 | Reachability* reach = [Reachability reachabilityWithHostname:@ServerPath];
38 |
39 | // Set the blocks
40 | reach.reachableBlock = ^(Reachability*reach)
41 | {
42 | ////TRC_DBG(@"%s REACHABLE!",ServerPath);
43 | };
44 |
45 | reach.unreachableBlock = ^(Reachability*reach)
46 | {
47 | ////TRC_DBG(@"%s UNREACHABLE!",ServerPath);
48 | };
49 |
50 | // Start the notifier, which will cause the reachability object to retain itself!
51 | [reach startNotifier];
52 |
53 | [WSoperationQueue addObserver:self forKeyPath:@"operations" options:0 context:NULL];
54 | }
55 | return self;
56 | }
57 |
58 | - (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object
59 | change:(NSDictionary *)change context:(void *)context
60 | {
61 | APIParser *parser =[APIParser sharedMediaServer];
62 |
63 | if (object == parser.WSoperationQueue && [keyPath isEqualToString:@"operations"])
64 | {
65 | if ([parser.WSoperationQueue.operations count] == 0)
66 | {
67 | runOnMainQueueWithoutDeadlocking(^{
68 | ShowNetworkIndicator(0);
69 | });
70 | }
71 | }
72 | else {
73 | [super observeValueForKeyPath:keyPath ofObject:object
74 | change:change context:context];
75 | }
76 | }
77 |
78 | #pragma mark - Cancel all API request with operation
79 |
80 | - (void)cancelALLCurrentlyExecutingRequest {
81 | [WSoperationQueue cancelAllOperations];
82 | ShowNetworkIndicator(0);
83 | }
84 |
85 | #pragma mark - API
86 |
87 | + (id)sharedMediaServer;
88 | {
89 | static dispatch_once_t onceToken;
90 | static id sharedMediaServer = nil;
91 |
92 | dispatch_once( &onceToken, ^{
93 | sharedMediaServer = [[[self class] alloc] init];
94 | });
95 |
96 | return sharedMediaServer;
97 | }
98 |
99 | - (NSData *) dictionaryWithPropertiesOfObject:(id)obj
100 | {
101 | NSError *jsonError = nil;
102 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithDictionary:(NSMutableDictionary *)obj] options:0 error:&jsonError];
103 |
104 | if (jsonError!=nil)
105 | {
106 | return nil;
107 | }
108 | return jsonData;
109 | }
110 |
111 | - (NSData *)dictionaryToJSONData:(NSDictionary *)dict
112 | {
113 | NSError *jsonError = nil;
114 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithDictionary:dict] options:0 error:&jsonError];
115 |
116 | if (jsonError!=nil)
117 | {
118 | return nil;
119 | }
120 | return jsonData;
121 | }
122 |
123 | - (NSData *)dictionaryWithmembersOfObject:(id)obj formembers:(NSArray *)members
124 | {
125 | NSMutableDictionary *dict = [NSMutableDictionary dictionary];
126 | for (NSString *memberkey in members)
127 | {
128 | if(memberkey.length>0)
129 | {
130 | if ([obj valueForKey:memberkey] != nil)
131 | {
132 | [dict setObject:[obj valueForKey:memberkey] forKey:memberkey];
133 | }
134 | }
135 | }
136 |
137 | NSError *jsonError = nil;
138 | NSData *jsonData = [NSJSONSerialization dataWithJSONObject:[NSDictionary dictionaryWithDictionary:dict] options:0 error:&jsonError];
139 |
140 | if (jsonError!=nil)
141 | {
142 | return nil;
143 | }
144 | return jsonData;
145 | }
146 |
147 | #pragma mark - Create Request
148 |
149 | - (NSMutableURLRequest *)urlRequestForURL:(NSURL *)url withObjects:(NSData *)objData
150 | withReqCookies:(NSMutableArray *)arrCookies
151 | isObject:(bool)customObj
152 | withParameters :(NSString *) params
153 | reqType :(APIRequestType) requestType
154 | reqHeaders:(NSDictionary *) requestHeaders
155 | {
156 |
157 | NSMutableURLRequest *request = [NSMutableURLRequest
158 | requestWithURL:url
159 | cachePolicy:NSURLRequestUseProtocolCachePolicy
160 | timeoutInterval:DEFAULT_TIMEOUT];
161 |
162 | if (customObj) {
163 | [request addValue:@"application/json" forHTTPHeaderField:@"Content-Type"];
164 | [request setValue:@"application/json;charset=UTF-8" forHTTPHeaderField:@"content-type"];
165 | }
166 | else {
167 | [request addValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
168 | }
169 |
170 | [request addValue:[NSString stringWithFormat:@"%lu", (unsigned long)[objData length]] forHTTPHeaderField:@"Content-Length"];
171 | [request addValue:@"application/json" forHTTPHeaderField:@"Accept"];
172 | [request setHTTPMethod:StringFromAPIRequestMethod(requestType)];
173 | [request setHTTPShouldHandleCookies:YES];
174 |
175 |
176 | //Add custom Headers
177 | for (NSString *key in [requestHeaders allKeys]) {
178 | [request setValue:[requestHeaders valueForKey:key] forHTTPHeaderField:key];
179 | }
180 |
181 | //Some Universal Request Headers for all request
182 | [request setValue:@"Pass_Your_Access_Token" forHTTPHeaderField:@"AuthorizationTemp"];
183 | [request setValue:@"Pass_YourSession_ID" forHTTPHeaderField:@"SessionIdTemp"];
184 |
185 | //Set Cookie
186 | NSMutableArray *allCookies = [NSMutableArray array];
187 |
188 | NSHTTPCookieStorage *storage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
189 |
190 | for (NSHTTPCookie *cookie in [storage cookies]) {
191 | [allCookies addObject:cookie];
192 | }
193 |
194 | if ([allCookies count] > 0) {
195 |
196 | NSDictionary *headers = [NSHTTPCookie requestHeaderFieldsWithCookies:allCookies];
197 | [request setAllHTTPHeaderFields:headers];
198 | }
199 |
200 | [request setHTTPBody:objData];
201 |
202 | return request;
203 | }
204 |
205 | #pragma mark - Dictionary to QueryString
206 |
207 | -(NSString *)serializeParams:(NSDictionary *)params {
208 |
209 | /*
210 |
211 | Convert an NSDictionary to a query string
212 |
213 | */
214 |
215 | NSMutableArray* pairs = [NSMutableArray array];
216 | for (NSString* key in [params keyEnumerator]) {
217 | id value = [params objectForKey:key];
218 | if ([value isKindOfClass:[NSDictionary class]]) {
219 | for (NSString *subKey in value) {
220 | NSString* escaped_value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
221 | (CFStringRef)[value objectForKey:subKey],
222 | NULL,
223 | (CFStringRef)@"!*'();:@&=+$,/?%#[]",
224 | kCFStringEncodingUTF8));
225 | [pairs addObject:[NSString stringWithFormat:@"%@[%@]=%@", key, subKey, escaped_value]];
226 | }
227 | } else if ([value isKindOfClass:[NSArray class]]) {
228 | for (NSString *subValue in value) {
229 | NSString* escaped_value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
230 | (CFStringRef)subValue,
231 | NULL,
232 | (CFStringRef)@"!*'();:@&=+$,/?%#[]",
233 | kCFStringEncodingUTF8));
234 | [pairs addObject:[NSString stringWithFormat:@"%@[]=%@", key, escaped_value]];
235 | }
236 | } else {
237 | NSString* escaped_value = (NSString *)CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(NULL,
238 | (CFStringRef)[params objectForKey:key],
239 | NULL,
240 | (CFStringRef)@"!*'();:@&=+$,/?%#[]",
241 | kCFStringEncodingUTF8));
242 | [pairs addObject:[NSString stringWithFormat:@"%@=%@", key, escaped_value]];
243 | // [escaped_value release];
244 | }
245 | }
246 | return [pairs componentsJoinedByString:@"&"];
247 | }
248 |
249 | #pragma mark - DEVELOPER API DEBUG LOGS
250 |
251 | - (void)saveAPIDetailsToCacheForRequestTitle:(NSString *)apiName //Title of API
252 | andResponse:(NSURLResponse *)response //Response object
253 | andRequest:(NSURLRequest *)request //Request object
254 | responseDictionary:(NSDictionary *)responseDict //Formatted response
255 | responseString:(NSString *)responseString //Raw response
256 | {
257 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
258 |
259 | if (![[AppCacheManagement sharedCacheManager] APILoggingEnabled])
260 | return;
261 |
262 | APIInfoObject *debugDetail = [APIInfoObject modelObjectWithDetails:apiName request:request response:response responseDictionary:responseDict responseString:responseString];
263 |
264 | __block NSMutableArray *debugCachedArray;
265 | [[AppCacheManagement sharedCacheManager] getcachedataArrayFor_:kDeveloperDebugAPILog myMethod:^(BOOL status, NSMutableArray *retrivedArray) {
266 | if (retrivedArray != nil) {
267 | debugCachedArray = retrivedArray;
268 | }
269 | }];
270 | if (debugCachedArray.count == kConstMaxDebugAPICount) {
271 |
272 | [debugCachedArray removeObjectAtIndex:0];
273 | }
274 |
275 | [debugCachedArray addObject:debugDetail];
276 |
277 | [[AppCacheManagement sharedCacheManager] setCacheToUserDefaults:debugCachedArray ForKey:kDeveloperDebugAPILog];
278 | });
279 | }
280 |
281 | #pragma mark - Run On Main Thread
282 |
283 | void runOnMainQueueWithoutDeadlocking(void (^block)(void))
284 | {
285 | if ([NSThread isMainThread])
286 | {
287 | block();
288 | }
289 | else
290 | {
291 | dispatch_async(dispatch_get_main_queue(), block);
292 | }
293 | }
294 |
295 | #pragma mark - String Request enum
296 |
297 | NSString *StringFromAPIRequestMethod(APIRequestType apiType)
298 | {
299 | switch (apiType) {
300 | case APIRequestMethodGET: return @"GET";
301 | case APIRequestMethodPOST: return @"POST";
302 | case APIRequestMethodPUT: return @"PUT";
303 | case APIRequestMethodDELETE: return @"DELETE";
304 | default: break;
305 | }
306 | return nil;
307 | }
308 |
309 | @end
310 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/AppMacros.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppMacros.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #ifndef AppMacros_h
12 | #define AppMacros_h
13 |
14 | #pragma mark -
15 | #pragma mark - App Delegate
16 |
17 | #define APP_CONTEXT ((AppDelegate*)[[UIApplication sharedApplication] delegate])
18 |
19 | #define IOS_NEWER_OR_EQUAL_TO_X(XX) ( [ [ [ UIDevice currentDevice ] systemVersion ] floatValue ] >= XX )
20 |
21 | #pragma mark -
22 | #pragma mark - Network Indicator
23 |
24 | #define ShowNetworkIndicator(BOOL) [UIApplication sharedApplication].networkActivityIndicatorVisible = BOOL
25 |
26 | #pragma mark -
27 | #pragma mark - View
28 |
29 | #define getStoryboard(StoryboardWithName) [UIStoryboard storyboardWithName:[NSString stringWithFormat:@"%@", StoryboardWithName] bundle:NULL]
30 | #define loadViewController(StoryBoardName, VCIdentifer) [getStoryboard(StoryBoardName)instantiateViewControllerWithIdentifier:VCIdentifer]
31 |
32 | #define RGBCOLOR(r, g, b, alp) [UIColor colorWithRed:r/255.0f green:g/255.0f blue:b/255.0f alpha:alp]
33 |
34 | #define Screen_Height [UIScreen mainScreen].bounds.size.height
35 | #define Screen_Width [UIScreen mainScreen].bounds.size.width
36 |
37 | #endif /* AppMacros_h */
38 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/Reachability/Reachability.h:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, Tony Million.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 | POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #import
29 | #import
30 |
31 | #import
32 | #import
33 | #import
34 | #import
35 | #import
36 | #import
37 |
38 | /**
39 | * Does ARC support GCD objects?
40 | * It does if the minimum deployment target is iOS 6+ or Mac OS X 8+
41 | *
42 | * @see http://opensource.apple.com/source/libdispatch/libdispatch-228.18/os/object.h
43 | **/
44 | #if OS_OBJECT_USE_OBJC
45 | #define NEEDS_DISPATCH_RETAIN_RELEASE 0
46 | #else
47 | #define NEEDS_DISPATCH_RETAIN_RELEASE 1
48 | #endif
49 |
50 | /**
51 | * Create NS_ENUM macro if it does not exist on the targeted version of iOS or OS X.
52 | *
53 | * @see http://nshipster.com/ns_enum-ns_options/
54 | **/
55 | #ifndef NS_ENUM
56 | #define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
57 | #endif
58 |
59 | extern NSString *const kReachabilityChangedNotification;
60 |
61 | typedef NS_ENUM(NSInteger, NetworkStatus) {
62 | // Apple NetworkStatus Compatible Names.
63 | NotReachable = 0,
64 | ReachableViaWiFi = 2,
65 | ReachableViaWWAN = 1
66 | };
67 |
68 | @class Reachability;
69 |
70 | typedef void (^NetworkReachable)(Reachability * reachability);
71 | typedef void (^NetworkUnreachable)(Reachability * reachability);
72 |
73 | @interface Reachability : NSObject
74 |
75 | @property (nonatomic, copy) NetworkReachable reachableBlock;
76 | @property (nonatomic, copy) NetworkUnreachable unreachableBlock;
77 |
78 |
79 | @property (nonatomic, assign) BOOL reachableOnWWAN;
80 |
81 | +(Reachability*)reachabilityWithHostname:(NSString*)hostname;
82 | // This is identical to the function above, but is here to maintain
83 | //compatibility with Apples original code. (see .m)
84 | +(Reachability*)reachabilityWithHostName:(NSString*)hostname;
85 | +(Reachability*)reachabilityForInternetConnection;
86 | +(Reachability*)reachabilityWithAddress:(const struct sockaddr_in*)hostAddress;
87 | +(Reachability*)reachabilityForLocalWiFi;
88 |
89 | -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref;
90 |
91 | -(BOOL)startNotifier;
92 | -(void)stopNotifier;
93 |
94 | -(BOOL)isReachable;
95 | -(BOOL)isReachableViaWWAN;
96 | -(BOOL)isReachableViaWiFi;
97 |
98 | // WWAN may be available, but not active until a connection has been established.
99 | // WiFi may require a connection for VPN on Demand.
100 | -(BOOL)isConnectionRequired; // Identical DDG variant.
101 | -(BOOL)connectionRequired; // Apple's routine.
102 | // Dynamic, on demand connection?
103 | -(BOOL)isConnectionOnDemand;
104 | // Is user intervention required?
105 | -(BOOL)isInterventionRequired;
106 |
107 | -(NetworkStatus)currentReachabilityStatus;
108 | -(SCNetworkReachabilityFlags)reachabilityFlags;
109 | -(NSString*)currentReachabilityString;
110 | -(NSString*)currentReachabilityFlags;
111 |
112 | @end
113 |
--------------------------------------------------------------------------------
/iOS_APIParser/ApplicationAPI/Reachability/Reachability.m:
--------------------------------------------------------------------------------
1 | /*
2 | Copyright (c) 2011, Tony Million.
3 | All rights reserved.
4 |
5 | Redistribution and use in source and binary forms, with or without
6 | modification, are permitted provided that the following conditions are met:
7 |
8 | 1. Redistributions of source code must retain the above copyright notice, this
9 | list of conditions and the following disclaimer.
10 |
11 | 2. Redistributions in binary form must reproduce the above copyright notice,
12 | this list of conditions and the following disclaimer in the documentation
13 | and/or other materials provided with the distribution.
14 |
15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 | ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
19 | LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 | CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 | SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 | INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 | ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 | POSSIBILITY OF SUCH DAMAGE.
26 | */
27 |
28 | #import "Reachability.h"
29 |
30 |
31 | NSString *const kReachabilityChangedNotification = @"kReachabilityChangedNotification";
32 |
33 | @interface Reachability ()
34 |
35 | @property (nonatomic, assign) SCNetworkReachabilityRef reachabilityRef;
36 |
37 |
38 | #if NEEDS_DISPATCH_RETAIN_RELEASE
39 | @property (nonatomic, assign) dispatch_queue_t reachabilitySerialQueue;
40 | #else
41 | @property (nonatomic, strong) dispatch_queue_t reachabilitySerialQueue;
42 | #endif
43 |
44 |
45 | @property (nonatomic, strong) id reachabilityObject;
46 |
47 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags;
48 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags;
49 |
50 | @end
51 |
52 | static NSString *reachabilityFlags(SCNetworkReachabilityFlags flags)
53 | {
54 | return [NSString stringWithFormat:@"%c%c %c%c%c%c%c%c%c",
55 | #if TARGET_OS_IPHONE
56 | (flags & kSCNetworkReachabilityFlagsIsWWAN) ? 'W' : '-',
57 | #else
58 | 'X',
59 | #endif
60 | (flags & kSCNetworkReachabilityFlagsReachable) ? 'R' : '-',
61 | (flags & kSCNetworkReachabilityFlagsConnectionRequired) ? 'c' : '-',
62 | (flags & kSCNetworkReachabilityFlagsTransientConnection) ? 't' : '-',
63 | (flags & kSCNetworkReachabilityFlagsInterventionRequired) ? 'i' : '-',
64 | (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) ? 'C' : '-',
65 | (flags & kSCNetworkReachabilityFlagsConnectionOnDemand) ? 'D' : '-',
66 | (flags & kSCNetworkReachabilityFlagsIsLocalAddress) ? 'l' : '-',
67 | (flags & kSCNetworkReachabilityFlagsIsDirect) ? 'd' : '-'];
68 | }
69 |
70 | // Start listening for reachability notifications on the current run loop
71 | static void TMReachabilityCallback(SCNetworkReachabilityRef target, SCNetworkReachabilityFlags flags, void* info)
72 | {
73 | #pragma unused (target)
74 | #if __has_feature(objc_arc)
75 | Reachability *reachability = ((__bridge Reachability*)info);
76 | #else
77 | Reachability *reachability = ((Reachability*)info);
78 | #endif
79 |
80 | // We probably don't need an autoreleasepool here, as GCD docs state each queue has its own autorelease pool,
81 | // but what the heck eh?
82 | @autoreleasepool
83 | {
84 | [reachability reachabilityChanged:flags];
85 | }
86 | }
87 |
88 |
89 | @implementation Reachability
90 |
91 | @synthesize reachabilityRef;
92 | @synthesize reachabilitySerialQueue;
93 |
94 | @synthesize reachableOnWWAN;
95 |
96 | @synthesize reachableBlock;
97 | @synthesize unreachableBlock;
98 |
99 | @synthesize reachabilityObject;
100 |
101 | #pragma mark - Class Constructor Methods
102 |
103 | +(Reachability*)reachabilityWithHostName:(NSString*)hostname
104 | {
105 | return [Reachability reachabilityWithHostname:hostname];
106 | }
107 |
108 | +(Reachability*)reachabilityWithHostname:(NSString*)hostname
109 | {
110 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithName(NULL, [hostname UTF8String]);
111 | if (ref)
112 | {
113 | id reachability = [[self alloc] initWithReachabilityRef:ref];
114 |
115 | #if __has_feature(objc_arc)
116 | return reachability;
117 | #else
118 | return [reachability autorelease];
119 | #endif
120 |
121 | }
122 |
123 | return nil;
124 | }
125 |
126 | +(Reachability *)reachabilityWithAddress:(const struct sockaddr_in *)hostAddress
127 | {
128 | SCNetworkReachabilityRef ref = SCNetworkReachabilityCreateWithAddress(kCFAllocatorDefault, (const struct sockaddr*)hostAddress);
129 | if (ref)
130 | {
131 | id reachability = [[self alloc] initWithReachabilityRef:ref];
132 |
133 | #if __has_feature(objc_arc)
134 | return reachability;
135 | #else
136 | return [reachability autorelease];
137 | #endif
138 | }
139 |
140 | return nil;
141 | }
142 |
143 | +(Reachability *)reachabilityForInternetConnection
144 | {
145 | struct sockaddr_in zeroAddress;
146 | bzero(&zeroAddress, sizeof(zeroAddress));
147 | zeroAddress.sin_len = sizeof(zeroAddress);
148 | zeroAddress.sin_family = AF_INET;
149 |
150 | return [self reachabilityWithAddress:&zeroAddress];
151 | }
152 |
153 | +(Reachability*)reachabilityForLocalWiFi
154 | {
155 | struct sockaddr_in localWifiAddress;
156 | bzero(&localWifiAddress, sizeof(localWifiAddress));
157 | localWifiAddress.sin_len = sizeof(localWifiAddress);
158 | localWifiAddress.sin_family = AF_INET;
159 | // IN_LINKLOCALNETNUM is defined in as 169.254.0.0
160 | localWifiAddress.sin_addr.s_addr = htonl(IN_LINKLOCALNETNUM);
161 |
162 | return [self reachabilityWithAddress:&localWifiAddress];
163 | }
164 |
165 |
166 | // Initialization methods
167 |
168 | -(Reachability *)initWithReachabilityRef:(SCNetworkReachabilityRef)ref
169 | {
170 | self = [super init];
171 | if (self != nil)
172 | {
173 | self.reachableOnWWAN = YES;
174 | self.reachabilityRef = ref;
175 | }
176 |
177 | return self;
178 | }
179 |
180 | -(void)dealloc
181 | {
182 | [self stopNotifier];
183 |
184 | if(self.reachabilityRef)
185 | {
186 | CFRelease(self.reachabilityRef);
187 | self.reachabilityRef = nil;
188 | }
189 |
190 | self.reachableBlock = nil;
191 | self.unreachableBlock = nil;
192 |
193 | #if !(__has_feature(objc_arc))
194 | [super dealloc];
195 | #endif
196 |
197 |
198 | }
199 |
200 | #pragma mark - Notifier Methods
201 |
202 | // Notifier
203 | // NOTE: This uses GCD to trigger the blocks - they *WILL NOT* be called on THE MAIN THREAD
204 | // - In other words DO NOT DO ANY UI UPDATES IN THE BLOCKS.
205 | // INSTEAD USE dispatch_async(dispatch_get_main_queue(), ^{UISTUFF}) (or dispatch_sync if you want)
206 |
207 | -(BOOL)startNotifier
208 | {
209 | SCNetworkReachabilityContext context = { 0, NULL, NULL, NULL, NULL };
210 |
211 | // this should do a retain on ourself, so as long as we're in notifier mode we shouldn't disappear out from under ourselves
212 | // woah
213 | self.reachabilityObject = self;
214 |
215 |
216 |
217 | // First, we need to create a serial queue.
218 | // We allocate this once for the lifetime of the notifier.
219 | self.reachabilitySerialQueue = dispatch_queue_create("com.tonymillion.reachability", NULL);
220 | if(!self.reachabilitySerialQueue)
221 | {
222 | return NO;
223 | }
224 |
225 | #if __has_feature(objc_arc)
226 | context.info = (__bridge void *)self;
227 | #else
228 | context.info = (void *)self;
229 | #endif
230 |
231 | if (!SCNetworkReachabilitySetCallback(self.reachabilityRef, TMReachabilityCallback, &context))
232 | {
233 | #ifdef DEBUG
234 | //////NSLog(@"SCNetworkReachabilitySetCallback() failed: %s", SCErrorString(SCError()));
235 | #endif
236 |
237 | // Clear out the dispatch queue
238 | if(self.reachabilitySerialQueue)
239 | {
240 | #if NEEDS_DISPATCH_RETAIN_RELEASE
241 | dispatch_release(self.reachabilitySerialQueue);
242 | #endif
243 | self.reachabilitySerialQueue = nil;
244 | }
245 |
246 | self.reachabilityObject = nil;
247 |
248 | return NO;
249 | }
250 |
251 | // Set it as our reachability queue, which will retain the queue
252 | if(!SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, self.reachabilitySerialQueue))
253 | {
254 | #ifdef DEBUG
255 | //////NSLog(@"SCNetworkReachabilitySetDispatchQueue() failed: %s", SCErrorString(SCError()));
256 | #endif
257 |
258 | // UH OH - FAILURE!
259 |
260 | // First stop, any callbacks!
261 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
262 |
263 | // Then clear out the dispatch queue.
264 | if(self.reachabilitySerialQueue)
265 | {
266 | #if NEEDS_DISPATCH_RETAIN_RELEASE
267 | dispatch_release(self.reachabilitySerialQueue);
268 | #endif
269 | self.reachabilitySerialQueue = nil;
270 | }
271 |
272 | self.reachabilityObject = nil;
273 |
274 | return NO;
275 | }
276 |
277 | return YES;
278 | }
279 |
280 | -(void)stopNotifier
281 | {
282 | // First stop, any callbacks!
283 | SCNetworkReachabilitySetCallback(self.reachabilityRef, NULL, NULL);
284 |
285 | // Unregister target from the GCD serial dispatch queue.
286 | SCNetworkReachabilitySetDispatchQueue(self.reachabilityRef, NULL);
287 |
288 | if(self.reachabilitySerialQueue)
289 | {
290 | #if NEEDS_DISPATCH_RETAIN_RELEASE
291 | dispatch_release(self.reachabilitySerialQueue);
292 | #endif
293 | self.reachabilitySerialQueue = nil;
294 | }
295 |
296 | self.reachabilityObject = nil;
297 | }
298 |
299 | #pragma mark - reachability tests
300 |
301 | // This is for the case where you flick the airplane mode;
302 | // you end up getting something like this:
303 | //Reachability: WR ct-----
304 | //Reachability: -- -------
305 | //Reachability: WR ct-----
306 | //Reachability: -- -------
307 | // We treat this as 4 UNREACHABLE triggers - really apple should do better than this
308 |
309 | #define testcase (kSCNetworkReachabilityFlagsConnectionRequired | kSCNetworkReachabilityFlagsTransientConnection)
310 |
311 | -(BOOL)isReachableWithFlags:(SCNetworkReachabilityFlags)flags
312 | {
313 | BOOL connectionUP = YES;
314 |
315 | if(!(flags & kSCNetworkReachabilityFlagsReachable))
316 | connectionUP = NO;
317 |
318 | if( (flags & testcase) == testcase )
319 | connectionUP = NO;
320 |
321 | #if TARGET_OS_IPHONE
322 | if(flags & kSCNetworkReachabilityFlagsIsWWAN)
323 | {
324 | // We're on 3G.
325 | if(!self.reachableOnWWAN)
326 | {
327 | // We don't want to connect when on 3G.
328 | connectionUP = NO;
329 | }
330 | }
331 | #endif
332 |
333 | return connectionUP;
334 | }
335 |
336 | -(BOOL)isReachable
337 | {
338 | SCNetworkReachabilityFlags flags;
339 |
340 | if(!SCNetworkReachabilityGetFlags(self.reachabilityRef, &flags))
341 | return NO;
342 |
343 | return [self isReachableWithFlags:flags];
344 | }
345 |
346 | -(BOOL)isReachableViaWWAN
347 | {
348 | #if TARGET_OS_IPHONE
349 |
350 | SCNetworkReachabilityFlags flags = 0;
351 |
352 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
353 | {
354 | // Check we're REACHABLE
355 | if(flags & kSCNetworkReachabilityFlagsReachable)
356 | {
357 | // Now, check we're on WWAN
358 | if(flags & kSCNetworkReachabilityFlagsIsWWAN)
359 | {
360 | return YES;
361 | }
362 | }
363 | }
364 | #endif
365 |
366 | return NO;
367 | }
368 |
369 | -(BOOL)isReachableViaWiFi
370 | {
371 | SCNetworkReachabilityFlags flags = 0;
372 |
373 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
374 | {
375 | // Check we're reachable
376 | if((flags & kSCNetworkReachabilityFlagsReachable))
377 | {
378 | #if TARGET_OS_IPHONE
379 | // Check we're NOT on WWAN
380 | if((flags & kSCNetworkReachabilityFlagsIsWWAN))
381 | {
382 | return NO;
383 | }
384 | #endif
385 | return YES;
386 | }
387 | }
388 |
389 | return NO;
390 | }
391 |
392 |
393 | // WWAN may be available, but not active until a connection has been established.
394 | // WiFi may require a connection for VPN on Demand.
395 | -(BOOL)isConnectionRequired
396 | {
397 | return [self connectionRequired];
398 | }
399 |
400 | -(BOOL)connectionRequired
401 | {
402 | SCNetworkReachabilityFlags flags;
403 |
404 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
405 | {
406 | return (flags & kSCNetworkReachabilityFlagsConnectionRequired);
407 | }
408 |
409 | return NO;
410 | }
411 |
412 | // Dynamic, on demand connection?
413 | -(BOOL)isConnectionOnDemand
414 | {
415 | SCNetworkReachabilityFlags flags;
416 |
417 | if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
418 | {
419 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
420 | (flags & (kSCNetworkReachabilityFlagsConnectionOnTraffic | kSCNetworkReachabilityFlagsConnectionOnDemand)));
421 | }
422 |
423 | return NO;
424 | }
425 |
426 | // Is user intervention required?
427 | -(BOOL)isInterventionRequired
428 | {
429 | SCNetworkReachabilityFlags flags;
430 |
431 | if (SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
432 | {
433 | return ((flags & kSCNetworkReachabilityFlagsConnectionRequired) &&
434 | (flags & kSCNetworkReachabilityFlagsInterventionRequired));
435 | }
436 |
437 | return NO;
438 | }
439 |
440 |
441 | #pragma mark - reachability status stuff
442 |
443 | -(NetworkStatus)currentReachabilityStatus
444 | {
445 | if([self isReachable])
446 | {
447 | if([self isReachableViaWiFi])
448 | return ReachableViaWiFi;
449 |
450 | #if TARGET_OS_IPHONE
451 | return ReachableViaWWAN;
452 | #endif
453 | }
454 |
455 | return NotReachable;
456 | }
457 |
458 | -(SCNetworkReachabilityFlags)reachabilityFlags
459 | {
460 | SCNetworkReachabilityFlags flags = 0;
461 |
462 | if(SCNetworkReachabilityGetFlags(reachabilityRef, &flags))
463 | {
464 | return flags;
465 | }
466 |
467 | return 0;
468 | }
469 |
470 | -(NSString*)currentReachabilityString
471 | {
472 | NetworkStatus temp = [self currentReachabilityStatus];
473 |
474 | if(temp == reachableOnWWAN)
475 | {
476 | // Updated for the fact that we have CDMA phones now!
477 | return NSLocalizedString(@"Cellular", @"");
478 | }
479 | if (temp == ReachableViaWiFi)
480 | {
481 | return NSLocalizedString(@"WiFi", @"");
482 | }
483 |
484 | return NSLocalizedString(@"No Connection", @"");
485 | }
486 |
487 | -(NSString*)currentReachabilityFlags
488 | {
489 | return reachabilityFlags([self reachabilityFlags]);
490 | }
491 |
492 | #pragma mark - Callback function calls this method
493 |
494 | -(void)reachabilityChanged:(SCNetworkReachabilityFlags)flags
495 | {
496 | if([self isReachableWithFlags:flags])
497 | {
498 | if(self.reachableBlock)
499 | {
500 | self.reachableBlock(self);
501 | }
502 | }
503 | else
504 | {
505 | if(self.unreachableBlock)
506 | {
507 | self.unreachableBlock(self);
508 | }
509 | }
510 |
511 | // this makes sure the change notification happens on the MAIN THREAD
512 | dispatch_async(dispatch_get_main_queue(), ^{
513 | [[NSNotificationCenter defaultCenter] postNotificationName:kReachabilityChangedNotification
514 | object:self];
515 | });
516 | }
517 |
518 | #pragma mark - Debug Description
519 |
520 | - (NSString *) description
521 | {
522 | NSString *description = [NSString stringWithFormat:@"<%@: %#x>",
523 | NSStringFromClass([self class]), (unsigned int) self];
524 | return description;
525 | }
526 |
527 | @end
528 |
--------------------------------------------------------------------------------
/iOS_APIParser/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
--------------------------------------------------------------------------------
/iOS_APIParser/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/iOS_APIParser/Assets.xcassets/internet_reachability.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "scale" : "1x"
6 | },
7 | {
8 | "idiom" : "universal",
9 | "filename" : "no-internet-connection-sign-of-phone-interface.png",
10 | "scale" : "2x"
11 | },
12 | {
13 | "idiom" : "universal",
14 | "scale" : "3x"
15 | }
16 | ],
17 | "info" : {
18 | "version" : 1,
19 | "author" : "xcode"
20 | }
21 | }
--------------------------------------------------------------------------------
/iOS_APIParser/Assets.xcassets/internet_reachability.imageset/no-internet-connection-sign-of-phone-interface.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dhruvik13/iOS-Webservice/1b5d2f0a8152760e9f0b67be17cc8bcf81ef8648/iOS_APIParser/Assets.xcassets/internet_reachability.imageset/no-internet-connection-sign-of-phone-interface.png
--------------------------------------------------------------------------------
/iOS_APIParser/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/iOS_APIParser/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 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
68 |
77 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
140 |
--------------------------------------------------------------------------------
/iOS_APIParser/CategoryClasses/NSString+ContainString.m:
--------------------------------------------------------------------------------
1 | //
2 | // NSString+ContainString.m
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 17/10/15.
6 | // Copyright © 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 |
10 | #import
11 |
12 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
13 |
14 | @interface NSString (PSPDFModernizer)
15 |
16 | // Added in iOS 8, retrofitted for iOS 7
17 | - (BOOL)containsString:(NSString *)aString;
18 |
19 | @end
20 |
21 | #endif
22 |
23 | #import
24 |
25 | #if __IPHONE_OS_VERSION_MIN_REQUIRED < 80000
26 |
27 | @implementation NSString (PSPDFModernizerCreator)
28 |
29 | + (void)load {
30 | @autoreleasepool {
31 | [self pspdf_modernizeSelector:NSSelectorFromString(@"containsString:") withSelector:@selector(pspdf_containsString:)];
32 | }
33 | }
34 |
35 | + (void)pspdf_modernizeSelector:(SEL)originalSelector withSelector:(SEL)newSelector {
36 | if (![NSString instancesRespondToSelector:originalSelector]) {
37 | Method newMethod = class_getInstanceMethod(self, newSelector);
38 | class_addMethod(self, originalSelector, method_getImplementation(newMethod), method_getTypeEncoding(newMethod));
39 | }
40 | }
41 |
42 | // containsString: has been added in iOS 8. We dynamically add this if we run on iOS 7.
43 | - (BOOL)pspdf_containsString:(NSString *)aString {
44 | return [self rangeOfString:aString].location != NSNotFound;
45 | }
46 |
47 | @end
48 |
49 | #endif
--------------------------------------------------------------------------------
/iOS_APIParser/CustomCell/OrderSummaryCell.h:
--------------------------------------------------------------------------------
1 | //
2 | // OrderSummaryCell.h
3 | // FastTicket
4 | //
5 | // Created by Manan Sheth on 9/9/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface OrderSummaryCell : UITableViewCell
12 |
13 | @property (strong, nonatomic) UILabel *lblKey;
14 | @property (strong, nonatomic) UILabel *lblValue;
15 |
16 | - (id)initWithStyle:(UITableViewCellStyle)style
17 | reuseIdentifier:(NSString *)reuseIdentifier
18 | forCurrentObjectKey:(NSString*) key
19 | forCurrentObjectValue:(NSString*) value
20 | forParentFrame : (CGRect) frame ;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/iOS_APIParser/CustomCell/OrderSummaryCell.m:
--------------------------------------------------------------------------------
1 | //
2 | // OrderSummaryCell.m
3 | // FastTicket
4 | //
5 | // Created by Manan Sheth on 9/9/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import "OrderSummaryCell.h"
10 |
11 | @implementation OrderSummaryCell
12 |
13 | @synthesize lblKey;
14 | @synthesize lblValue;
15 |
16 |
17 | - (id)initWithStyle:(UITableViewCellStyle)style
18 | reuseIdentifier:(NSString *)reuseIdentifier
19 | forCurrentObjectKey:(NSString*) key
20 | forCurrentObjectValue:(NSString*) value
21 | forParentFrame : (CGRect) frame
22 | {
23 | self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
24 | if (self) {
25 |
26 | int ParentWidth = CGRectGetWidth(frame);
27 |
28 | //Key
29 | lblKey = [UILabel new];
30 | lblKey.frame = CGRectMake(10, 8, (ParentWidth / 2) - 20, 20);
31 |
32 | CGRect textRectKey = [key boundingRectWithSize:CGSizeMake((ParentWidth / 2) - 20, 9999)
33 | options:NSStringDrawingUsesLineFragmentOrigin
34 | attributes:@{NSFontAttributeName:THEME_FONT_REGULAR(14.0)}
35 | context:nil];
36 | lblKey.frame = CGRectMake(10, 8, (ParentWidth / 2) - 20, textRectKey.size.height);
37 |
38 | lblKey.textColor = RGBCOLOR(131, 131, 131, 1);
39 | lblKey.textAlignment = NSTextAlignmentLeft;
40 | lblKey.font = THEME_FONT_REGULAR(14.0);
41 | lblKey.numberOfLines = 0;
42 | lblKey.text = key;
43 | [lblKey setBackgroundColor:[UIColor clearColor]];
44 | [self addSubview:lblKey];
45 |
46 | //Seperator
47 | UILabel *lblColumn = [UILabel new];
48 | lblColumn.frame = CGRectMake(CGRectGetMaxX(lblKey.frame) , lblKey.frame.origin.y - 4, 7, 24);
49 | [lblColumn setText:@" : "];
50 | lblColumn.numberOfLines = 0;
51 | lblColumn.font = THEME_FONT_REGULAR(14.0);
52 | lblColumn.textColor = RGBCOLOR(131, 131, 131, 1);
53 | lblColumn.textAlignment = NSTextAlignmentLeft;
54 | lblColumn.numberOfLines = 0;
55 | [lblColumn setBackgroundColor:[UIColor clearColor]];
56 | [self addSubview:lblColumn];
57 |
58 | //Value
59 | lblValue = [UILabel new];
60 | lblValue.frame = CGRectMake(CGRectGetMaxX(lblColumn.frame) + 4 , 8, ParentWidth - (CGRectGetMaxX(lblColumn.frame) + 10), 24);
61 |
62 | CGRect textRectValue = [value boundingRectWithSize:CGSizeMake(ParentWidth - (CGRectGetMaxX(lblColumn.frame) + 10), 9999)
63 | options:NSStringDrawingUsesLineFragmentOrigin
64 | attributes:@{NSFontAttributeName:THEME_FONT_REGULAR(14.0)}
65 | context:nil];
66 |
67 | lblValue.frame = CGRectMake(CGRectGetMaxX(lblColumn.frame) + 4 , 8, (ParentWidth - (CGRectGetMaxX(lblColumn.frame) + 10)), textRectValue.size.height);
68 |
69 | lblValue.textColor = RGBCOLOR(131, 131, 131, 1);
70 | lblValue.textAlignment = NSTextAlignmentLeft;
71 | lblValue.font = THEME_FONT_REGULAR(14.0);
72 | lblValue.numberOfLines = 0;
73 | lblValue.text = value;
74 | [lblValue setBackgroundColor:[UIColor clearColor]];
75 | [self addSubview:lblValue];
76 |
77 | self.backgroundColor = [UIColor whiteColor];
78 | }
79 |
80 | return self;
81 | }
82 |
83 | @end
84 |
--------------------------------------------------------------------------------
/iOS_APIParser/CustomCell/OrderSummaryVC.h:
--------------------------------------------------------------------------------
1 | //
2 | // OrderSummaryVC.h
3 | // FastTicket
4 | //
5 | // Created by Manan Sheth on 9/9/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @protocol OrderSummaryViewDelegate
12 |
13 | @optional
14 |
15 | - (void)clickForDismissView;
16 |
17 | @end
18 |
19 | @interface OrderSummaryVC : UIViewController
20 |
21 | @property (strong, nonatomic) id orderSummaryDelegate;
22 |
23 | @end
--------------------------------------------------------------------------------
/iOS_APIParser/CustomCell/OrderSummaryVC.m:
--------------------------------------------------------------------------------
1 | //
2 | // OrderSummaryVC.m
3 | // FastTicket
4 | //
5 | // Created by Manan Sheth on 9/9/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import "OrderSummaryVC.h"
10 | #import "OrderSummaryCell.h"
11 |
12 | @interface OrderSummaryVC ()
13 | {
14 | __weak IBOutlet UITableView *tblOrder;
15 |
16 | IBOutlet UILabel *lblHeader;
17 | IBOutlet UIButton *btnClose;
18 | }
19 |
20 | - (IBAction)clickToClose:(id)sender;
21 |
22 | @end
23 |
24 | @implementation OrderSummaryVC
25 |
26 | #pragma mark - Class Methods
27 |
28 | - (void)viewDidLoad {
29 |
30 | [super viewDidLoad];
31 |
32 | [lblHeader setFont:THEME_FONT_BOLD(15.0)];
33 | btnClose.titleLabel.font =THEME_FONT_BOLD(15.0);
34 |
35 | if (iPadDevice)
36 | [self.view setFrame:CGRectMake(100, 140, SCREEN_WIDTH - 200, SCREEN_HEIGHT - 280)];
37 | // else
38 | // [self.view setFrame:CGRectMake(10, 40, SCREEN_WIDTH - 20, SCREEN_HEIGHT - 80)];
39 |
40 | [tblOrder setSeparatorStyle:UITableViewCellSeparatorStyleNone];
41 |
42 | tblOrder.tableFooterView = [[UIView alloc] initWithFrame:CGRectZero];
43 |
44 | [tblOrder setBackgroundColor:[UIColor whiteColor]];
45 |
46 | [tblOrder reloadData];
47 | }
48 |
49 | - (void)didReceiveMemoryWarning {
50 |
51 | [super didReceiveMemoryWarning];
52 | }
53 |
54 | #pragma mark - Table view data source
55 |
56 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
57 | {
58 | return 1;
59 | }
60 |
61 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
62 | {
63 | return 10;
64 | }
65 |
66 | - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
67 | {
68 | return [self getHeightForTransactionCellCellAtIndexPath:indexPath];
69 | }
70 |
71 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
72 | {
73 | return [self getOrderSummaryCellForRowAtIndexPath:indexPath];
74 | }
75 |
76 | - (CGFloat)getHeightForTransactionCellCellAtIndexPath:(NSIndexPath *)indexPath
77 | {
78 | return ((UITableViewCell*)[self getOrderSummaryCellForRowAtIndexPath:indexPath]).contentView.frame.size.height;
79 | }
80 |
81 | - (UITableViewCell*)getOrderSummaryCellForRowAtIndexPath:(NSIndexPath*)indexPath
82 | {
83 | OrderSummaryCell *cell;
84 |
85 | NSString *reuseID = [NSString stringWithFormat:@"OrderSummaryCell%d", (int) indexPath.row];
86 |
87 | if (!cell)
88 | {
89 | cell = [[OrderSummaryCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseID forCurrentObjectKey:[[PaymentSession currentPaymentSession].summaryDetailKeyArray objectAtIndex:indexPath.row] forCurrentObjectValue:[[PaymentSession currentPaymentSession].summaryDetailValueArray objectAtIndex:indexPath.row] forParentFrame:tblOrder.frame];
90 |
91 | float height = ((CGRectGetMaxY(cell.lblKey.frame) > CGRectGetMaxY(cell.lblValue.frame)) ? CGRectGetMaxY(cell.lblKey.frame) + 16 : CGRectGetMaxY(cell.lblValue.frame) + 16);
92 |
93 | cell.contentView.frame = CGRectMake(0, 0, SCREEN_WIDTH - 20, height);
94 |
95 | [cell setSelectionStyle:UITableViewCellSelectionStyleNone];
96 | }
97 |
98 | return cell;
99 | }
100 |
101 | #pragma mark - Close View
102 |
103 | - (IBAction)clickToClose:(id)sender
104 | {
105 | [_orderSummaryDelegate clickForDismissView];
106 | }
107 |
108 | @end
109 |
--------------------------------------------------------------------------------
/iOS_APIParser/Helper/UIViewController+Helper.h:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+Helper.h
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef NS_ENUM(NSInteger, ShakeDirection) {
12 | /** Shake left and right */
13 | ShakeDirectionHorizontal,
14 | /** Shake up and down */
15 | ShakeDirectionVertical
16 | };
17 |
18 | @interface UIViewController (Helper)
19 |
20 | //Shake Animation
21 | - (void)_shake:(int)times direction:(int)direction currentTimes:(int)current withDelta:(CGFloat)delta speed:(NSTimeInterval)interval shakeDirection:(ShakeDirection)shakeDirection forView:(UIView*)view completion:(void (^)(void))completionHandler ;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/iOS_APIParser/Helper/UIViewController+Helper.m:
--------------------------------------------------------------------------------
1 | //
2 | // UIViewController+Helper.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 9/7/18.
6 | // Copyright © 2018 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import "UIViewController+Helper.h"
10 |
11 | @implementation UIViewController (Helper)
12 |
13 | #pragma mark - Shake Animation
14 |
15 | - (void)_shake:(int)times direction:(int)direction currentTimes:(int)current withDelta:(CGFloat)delta speed:(NSTimeInterval)interval shakeDirection:(ShakeDirection)shakeDirection forView:(UIView*)view completion:(void (^)(void))completionHandler {
16 |
17 | __weak UIViewController *weakSelf = self;
18 |
19 | [UIView animateWithDuration:interval animations:^{
20 | view.layer.affineTransform = (shakeDirection == ShakeDirectionHorizontal) ? CGAffineTransformMakeTranslation(delta * direction, 0) : CGAffineTransformMakeTranslation(0, delta * direction);
21 | } completion:^(BOOL finished) {
22 | if(current >= times) {
23 | [UIView animateWithDuration:interval animations:^{
24 | view.layer.affineTransform = CGAffineTransformIdentity;
25 | } completion:^(BOOL finished){
26 | if (completionHandler != nil) {
27 | completionHandler();
28 | }
29 | }];
30 | return;
31 | }
32 | [weakSelf _shake:(times - 1)
33 | direction:direction * -1
34 | currentTimes:current + 1
35 | withDelta:delta
36 | speed:interval
37 | shakeDirection:shakeDirection
38 | forView:view
39 | completion:completionHandler];
40 | }];
41 | }
42 |
43 | @end
44 |
--------------------------------------------------------------------------------
/iOS_APIParser/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 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | NSAppTransportSecurity
34 |
35 | NSAllowsArbitraryLoads
36 |
37 | NSExceptionDomains
38 |
39 | akamaihd.net
40 |
41 | NSIncludesSubdomains
42 |
43 | NSThirdPartyExceptionRequiresForwardSecrecy
44 |
45 |
46 | facebook.com
47 |
48 | NSIncludesSubdomains
49 |
50 | NSThirdPartyExceptionRequiresForwardSecrecy
51 |
52 |
53 | fbcdn.net
54 |
55 | NSIncludesSubdomains
56 |
57 | NSThirdPartyExceptionRequiresForwardSecrecy
58 |
59 |
60 |
61 |
62 | UISupportedInterfaceOrientations
63 |
64 | UIInterfaceOrientationPortrait
65 | UIInterfaceOrientationLandscapeLeft
66 | UIInterfaceOrientationLandscapeRight
67 |
68 | UISupportedInterfaceOrientations~ipad
69 |
70 | UIInterfaceOrientationPortrait
71 | UIInterfaceOrientationPortraitUpsideDown
72 | UIInterfaceOrientationLandscapeLeft
73 | UIInterfaceOrientationLandscapeRight
74 |
75 |
76 |
77 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargePlanCommonObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // RechargePlanCommonObject.h
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 05/06/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RechargePlanCommonObject : NSObject
12 |
13 | @property (nonatomic, assign) double talktime;
14 | @property (nonatomic, strong) NSString *detail;
15 | @property (nonatomic, strong) NSString *validity;
16 | @property (nonatomic, assign) double price;
17 |
18 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
19 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
20 | - (NSDictionary *)dictionaryRepresentation;
21 |
22 | @end
23 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargePlanCommonObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // RechargePlanCommonObject.m
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 05/06/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import "RechargePlanCommonObject.h"
10 |
11 | NSString *const kRechargeCommonTalktime = @"talktime";
12 | NSString *const kRechargeCommonDetail = @"detail";
13 | NSString *const kRechargeCommonValidity = @"validity";
14 | NSString *const kRechargeCommonPrice = @"price";
15 |
16 | @interface RechargePlanCommonObject ()
17 |
18 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
19 |
20 | @end
21 |
22 | @implementation RechargePlanCommonObject
23 |
24 | @synthesize talktime = _talktime;
25 | @synthesize detail = _detail;
26 | @synthesize validity = _validity;
27 | @synthesize price = _price;
28 |
29 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
30 | {
31 | return [[self alloc] initWithDictionary:dict];
32 | }
33 |
34 | - (instancetype)initWithDictionary:(NSDictionary *)dict
35 | {
36 | self = [super init];
37 |
38 | // This check serves to make sure that a non-NSDictionary object
39 | // passed into the model class doesn't break the parsing.
40 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
41 | self.talktime = [[self objectOrNilForKey:kRechargeCommonTalktime fromDictionary:dict] doubleValue];
42 | self.detail = [self objectOrNilForKey:kRechargeCommonDetail fromDictionary:dict];
43 | self.validity = [self objectOrNilForKey:kRechargeCommonValidity fromDictionary:dict];
44 | self.price = [[self objectOrNilForKey:kRechargeCommonPrice fromDictionary:dict] doubleValue];
45 | }
46 |
47 | return self;
48 | }
49 |
50 | - (NSDictionary *)dictionaryRepresentation
51 | {
52 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
53 | [mutableDict setValue:[NSNumber numberWithDouble:self.talktime] forKey:kRechargeCommonTalktime];
54 | [mutableDict setValue:self.detail forKey:kRechargeCommonDetail];
55 | [mutableDict setValue:self.validity forKey:kRechargeCommonValidity];
56 | [mutableDict setValue:[NSNumber numberWithDouble:self.price] forKey:kRechargeCommonPrice];
57 |
58 | return [NSDictionary dictionaryWithDictionary:mutableDict];
59 | }
60 |
61 | - (NSString *)description
62 | {
63 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
64 | }
65 |
66 | #pragma mark - Helper Method
67 |
68 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
69 | {
70 | id object = [dict objectForKey:aKey];
71 | return [object isEqual:[NSNull null]] ? nil : object;
72 | }
73 |
74 | #pragma mark - NSCoding Methods
75 |
76 | - (id)initWithCoder:(NSCoder *)aDecoder
77 | {
78 | self = [super init];
79 |
80 | self.talktime = [aDecoder decodeDoubleForKey:kRechargeCommonTalktime];
81 | self.detail = [aDecoder decodeObjectForKey:kRechargeCommonDetail];
82 | self.validity = [aDecoder decodeObjectForKey:kRechargeCommonValidity];
83 | self.price = [aDecoder decodeDoubleForKey:kRechargeCommonPrice];
84 | return self;
85 | }
86 |
87 | - (void)encodeWithCoder:(NSCoder *)aCoder
88 | {
89 | [aCoder encodeDouble:_talktime forKey:kRechargeCommonTalktime];
90 | [aCoder encodeObject:_detail forKey:kRechargeCommonDetail];
91 | [aCoder encodeObject:_validity forKey:kRechargeCommonValidity];
92 | [aCoder encodeDouble:_price forKey:kRechargeCommonPrice];
93 | }
94 |
95 | - (id)copyWithZone:(NSZone *)zone
96 | {
97 | RechargePlanCommonObject *copy = [[RechargePlanCommonObject alloc] init];
98 |
99 | if (copy) {
100 |
101 | copy.talktime = self.talktime;
102 | copy.detail = [self.detail copyWithZone:zone];
103 | copy.validity = [self.validity copyWithZone:zone];
104 | copy.price = self.price;
105 | }
106 |
107 | return copy;
108 | }
109 |
110 | @end
111 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargePlansMainObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // RechargePlansMainObject.h
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 29/05/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface RechargePlansMainObject : NSObject
12 |
13 | @property (nonatomic, strong) NSString *imageUrl;
14 | @property (nonatomic, strong) NSString *service;
15 | @property (nonatomic, strong) NSString *circle;
16 |
17 | @property (nonatomic, strong) NSString *rechargePlanTypeName;
18 | @property (nonatomic, strong) NSArray *planObjects;
19 |
20 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
21 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
22 | - (NSDictionary *)dictionaryRepresentation;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargePlansMainObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // RechargePlansMainObject.m
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 29/05/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import "RechargePlansMainObject.h"
10 |
11 | NSString *const kDATAPlan = @"plan";
12 | NSString *const kDATAImageUrl = @"imageUrl";
13 | NSString *const kDATAService = @"service";
14 | NSString *const kDATACircle = @"circle";
15 |
16 | NSString *const kDATARechargePlanTypeName = @"planname";
17 | NSString *const kDATAPlanObjects = @"planobjects";
18 |
19 |
20 | @interface RechargePlansMainObject ()
21 |
22 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
23 |
24 | @end
25 |
26 | @implementation RechargePlansMainObject
27 |
28 | @synthesize imageUrl = _imageUrl;
29 | @synthesize service = _service;
30 | @synthesize circle = _circle;
31 |
32 |
33 | @synthesize rechargePlanTypeName = _rechargePlanTypeName;
34 | @synthesize planObjects = _planObjects;
35 |
36 |
37 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
38 | {
39 | return [[self alloc] initWithDictionary:dict];
40 | }
41 |
42 | - (instancetype)initWithDictionary:(NSDictionary *)dict
43 | {
44 | self = [super init];
45 |
46 | // This check serves to make sure that a non-NSDictionary object
47 | // passed into the model class doesn't break the parsing.
48 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
49 | self.imageUrl = [self objectOrNilForKey:kDATAImageUrl fromDictionary:dict];
50 | self.service = [self objectOrNilForKey:kDATAService fromDictionary:dict];
51 | self.circle = [self objectOrNilForKey:kDATACircle fromDictionary:dict];
52 | }
53 |
54 | return self;
55 | }
56 |
57 | - (NSDictionary *)dictionaryRepresentation
58 | {
59 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
60 | [mutableDict setValue:self.imageUrl forKey:kDATAImageUrl];
61 | [mutableDict setValue:self.service forKey:kDATAService];
62 | [mutableDict setValue:self.circle forKey:kDATACircle];
63 | [mutableDict setValue:self.rechargePlanTypeName forKey:kDATARechargePlanTypeName];
64 | [mutableDict setValue:self.planObjects forKey:kDATAPlanObjects];
65 |
66 | return [NSDictionary dictionaryWithDictionary:mutableDict];
67 | }
68 |
69 | - (NSString *)description
70 | {
71 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
72 | }
73 |
74 | #pragma mark - Helper Method
75 |
76 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
77 | {
78 | id object = [dict objectForKey:aKey];
79 | return [object isEqual:[NSNull null]] ? nil : object;
80 | }
81 |
82 | #pragma mark - NSCoding Methods
83 |
84 | - (id)initWithCoder:(NSCoder *)aDecoder
85 | {
86 | self = [super init];
87 |
88 | self.imageUrl = [aDecoder decodeObjectForKey:kDATAImageUrl];
89 | self.service = [aDecoder decodeObjectForKey:kDATAService];
90 | self.circle = [aDecoder decodeObjectForKey:kDATACircle];
91 | self.rechargePlanTypeName = [aDecoder decodeObjectForKey:kDATARechargePlanTypeName];
92 | self.planObjects = [aDecoder decodeObjectForKey:kDATAPlanObjects];
93 |
94 | return self;
95 | }
96 |
97 | - (void)encodeWithCoder:(NSCoder *)aCoder
98 | {
99 | [aCoder encodeObject:_imageUrl forKey:kDATAImageUrl];
100 | [aCoder encodeObject:_service forKey:kDATAService];
101 | [aCoder encodeObject:_circle forKey:kDATACircle];
102 |
103 | [aCoder encodeObject:_rechargePlanTypeName forKey:kDATARechargePlanTypeName];
104 |
105 | [aCoder encodeObject:_planObjects forKey:kDATAPlanObjects];
106 | }
107 |
108 | - (id)copyWithZone:(NSZone *)zone
109 | {
110 | RechargePlansMainObject *copy = [[RechargePlansMainObject alloc] init];
111 |
112 | if (copy) {
113 |
114 | copy.imageUrl = [self.imageUrl copyWithZone:zone];
115 | copy.service = [self.service copyWithZone:zone];
116 | copy.circle = [self.circle copyWithZone:zone];
117 | copy.rechargePlanTypeName = [self.rechargePlanTypeName copyWithZone:zone];
118 | copy.planObjects = [self.planObjects copyWithZone:zone];
119 | }
120 |
121 | return copy;
122 | }
123 |
124 | @end
125 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargeTurboObject.h:
--------------------------------------------------------------------------------
1 | //
2 | // RechargeTurboObject.h
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 07/08/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "CircleObject.h"
11 |
12 | //Service
13 | @interface Service : NSObject
14 |
15 | @property (nonatomic, assign) double serviceIdentifier;
16 | @property (nonatomic, strong) NSString *name;
17 |
18 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
19 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
20 | - (NSDictionary *)dictionaryRepresentation;
21 |
22 | @end
23 |
24 |
25 |
26 | //Recharge
27 | @interface Recharge : NSObject
28 |
29 | @property (nonatomic, assign) double rechargeIdentifier;
30 | @property (nonatomic, assign) double amount;
31 | @property (nonatomic, assign) BOOL topUp;
32 |
33 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
34 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
35 | - (NSDictionary *)dictionaryRepresentation;
36 |
37 | @end
38 |
39 |
40 |
41 | //Company
42 | @interface Company : NSObject
43 |
44 | @property (nonatomic, strong) Service *service;
45 | @property (nonatomic, assign) double companyIdentifier;
46 | @property (nonatomic, strong) NSString *imageUrl;
47 | @property (nonatomic, strong) NSString *smsCode;
48 | @property (nonatomic, assign) BOOL rechargeTypeRequired;
49 | @property (nonatomic, strong) NSString *label;
50 | @property (nonatomic, strong) NSString *updatedOn;
51 | @property (nonatomic, strong) NSString *name;
52 | @property (nonatomic, assign) BOOL showRechargeType;
53 |
54 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
55 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
56 | - (NSDictionary *)dictionaryRepresentation;
57 |
58 | @end
59 |
60 |
61 |
62 |
63 | //Turbo Main Object
64 |
65 | @interface RechargeTurboObject : NSObject
66 |
67 | @property (nonatomic, strong) NSString *mobile;
68 | @property (nonatomic, assign) double userId;
69 | @property (nonatomic, strong) CircleObject *circle;
70 | @property (nonatomic, strong) NSArray *recharge;
71 | @property (nonatomic, strong) Company *company;
72 | @property (nonatomic, strong) NSString *circleId;
73 | @property (nonatomic, strong) NSString *companyId;
74 |
75 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict;
76 | - (instancetype)initWithDictionary:(NSDictionary *)dict;
77 | - (NSDictionary *)dictionaryRepresentation;
78 |
79 |
80 | @end
81 |
--------------------------------------------------------------------------------
/iOS_APIParser/Objects/RechargeTurboObject.m:
--------------------------------------------------------------------------------
1 | //
2 | // RechargeTurboObject.m
3 | // FastTicket
4 | //
5 | // Created by Dhruvik Rao on 07/08/15.
6 | // Copyright (c) 2015 Sujav Group. All rights reserved.
7 | //
8 |
9 | #import "RechargeTurboObject.h"
10 |
11 |
12 | //Service
13 | NSString *const kServiceId = @"id";
14 | NSString *const kServiceName = @"name";
15 |
16 |
17 | @interface Service ()
18 |
19 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
20 |
21 | @end
22 |
23 | @implementation Service
24 |
25 | @synthesize serviceIdentifier = _serviceIdentifier;
26 | @synthesize name = _name;
27 |
28 |
29 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
30 | {
31 | return [[self alloc] initWithDictionary:dict];
32 | }
33 |
34 | - (instancetype)initWithDictionary:(NSDictionary *)dict
35 | {
36 | self = [super init];
37 |
38 | // This check serves to make sure that a non-NSDictionary object
39 | // passed into the model class doesn't break the parsing.
40 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
41 | self.serviceIdentifier = [[self objectOrNilForKey:kServiceId fromDictionary:dict] doubleValue];
42 | self.name = [self objectOrNilForKey:kServiceName fromDictionary:dict];
43 | }
44 |
45 | return self;
46 | }
47 |
48 | - (NSDictionary *)dictionaryRepresentation
49 | {
50 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
51 | [mutableDict setValue:[NSNumber numberWithDouble:self.serviceIdentifier] forKey:kServiceId];
52 | [mutableDict setValue:self.name forKey:kServiceName];
53 |
54 | return [NSDictionary dictionaryWithDictionary:mutableDict];
55 | }
56 |
57 | - (NSString *)description
58 | {
59 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
60 | }
61 |
62 | #pragma mark - Helper Method
63 |
64 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
65 | {
66 | id object = [dict objectForKey:aKey];
67 | return [object isEqual:[NSNull null]] ? nil : object;
68 | }
69 |
70 | #pragma mark - NSCoding Methods
71 |
72 | - (id)initWithCoder:(NSCoder *)aDecoder
73 | {
74 | self = [super init];
75 |
76 | self.serviceIdentifier = [aDecoder decodeDoubleForKey:kServiceId];
77 | self.name = [aDecoder decodeObjectForKey:kServiceName];
78 | return self;
79 | }
80 |
81 | - (void)encodeWithCoder:(NSCoder *)aCoder
82 | {
83 |
84 | [aCoder encodeDouble:_serviceIdentifier forKey:kServiceId];
85 | [aCoder encodeObject:_name forKey:kServiceName];
86 | }
87 |
88 | - (id)copyWithZone:(NSZone *)zone
89 | {
90 | Service *copy = [[Service alloc] init];
91 |
92 | if (copy) {
93 |
94 | copy.serviceIdentifier = self.serviceIdentifier;
95 | copy.name = [self.name copyWithZone:zone];
96 | }
97 |
98 | return copy;
99 | }
100 |
101 |
102 | @end
103 |
104 |
105 |
106 | //Company
107 | NSString *const kCompanyService = @"service";
108 | NSString *const kCompanyId = @"id";
109 | NSString *const kCompanyImageUrl = @"imageUrl";
110 | NSString *const kCompanySmsCode = @"smsCode";
111 | NSString *const kCompanyRechargeTypeRequired = @"rechargeTypeRequired";
112 | NSString *const kCompanyLabel = @"label";
113 | NSString *const kCompanyUpdatedOn = @"updatedOn";
114 | NSString *const kCompanyName = @"name";
115 | NSString *const kShowRechargeType = @"showRechargeType";
116 |
117 | @interface Company ()
118 |
119 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
120 |
121 | @end
122 |
123 | @implementation Company
124 |
125 | @synthesize service = _service;
126 | @synthesize companyIdentifier = _companyIdentifier;
127 | @synthesize imageUrl = _imageUrl;
128 | @synthesize smsCode = _smsCode;
129 | @synthesize rechargeTypeRequired = _rechargeTypeRequired;
130 | @synthesize label = _label;
131 | @synthesize updatedOn = _updatedOn;
132 | @synthesize name = _name;
133 | @synthesize showRechargeType = _showRechargeType;
134 |
135 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
136 | {
137 | return [[self alloc] initWithDictionary:dict];
138 | }
139 |
140 | - (instancetype)initWithDictionary:(NSDictionary *)dict
141 | {
142 | self = [super init];
143 |
144 | // This check serves to make sure that a non-NSDictionary object
145 | // passed into the model class doesn't break the parsing.
146 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
147 | self.service = [Service modelObjectWithDictionary:[dict objectForKey:kCompanyService]];
148 | self.companyIdentifier = [[self objectOrNilForKey:kCompanyId fromDictionary:dict] doubleValue];
149 | self.imageUrl = [self objectOrNilForKey:kCompanyImageUrl fromDictionary:dict];
150 | self.smsCode = [self objectOrNilForKey:kCompanySmsCode fromDictionary:dict];
151 | self.rechargeTypeRequired = [[self objectOrNilForKey:kCompanyRechargeTypeRequired fromDictionary:dict] boolValue];
152 | self.showRechargeType = [[self objectOrNilForKey:kShowRechargeType fromDictionary:dict] boolValue];
153 | self.label = [self objectOrNilForKey:kCompanyLabel fromDictionary:dict];
154 | self.updatedOn = [self objectOrNilForKey:kCompanyUpdatedOn fromDictionary:dict];
155 | self.name = [self objectOrNilForKey:kCompanyName fromDictionary:dict];
156 | }
157 |
158 | return self;
159 | }
160 |
161 | - (NSDictionary *)dictionaryRepresentation
162 | {
163 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
164 | [mutableDict setValue:[self.service dictionaryRepresentation] forKey:kCompanyService];
165 | [mutableDict setValue:[NSNumber numberWithDouble:self.companyIdentifier] forKey:kCompanyId];
166 | [mutableDict setValue:self.imageUrl forKey:kCompanyImageUrl];
167 | [mutableDict setValue:self.smsCode forKey:kCompanySmsCode];
168 | [mutableDict setValue:[NSNumber numberWithBool:self.rechargeTypeRequired] forKey:kCompanyRechargeTypeRequired];
169 | [mutableDict setValue:[NSNumber numberWithBool:self.showRechargeType] forKey:kShowRechargeType];
170 | [mutableDict setValue:self.label forKey:kCompanyLabel];
171 | [mutableDict setValue:self.updatedOn forKey:kCompanyUpdatedOn];
172 | [mutableDict setValue:self.name forKey:kCompanyName];
173 |
174 | return [NSDictionary dictionaryWithDictionary:mutableDict];
175 | }
176 |
177 | - (NSString *)description
178 | {
179 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
180 | }
181 |
182 | #pragma mark - Helper Method
183 |
184 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
185 | {
186 | id object = [dict objectForKey:aKey];
187 | return [object isEqual:[NSNull null]] ? nil : object;
188 | }
189 |
190 | #pragma mark - NSCoding Methods
191 |
192 | - (id)initWithCoder:(NSCoder *)aDecoder
193 | {
194 | self = [super init];
195 |
196 | self.service = [aDecoder decodeObjectForKey:kCompanyService];
197 | self.companyIdentifier = [aDecoder decodeDoubleForKey:kCompanyId];
198 | self.imageUrl = [aDecoder decodeObjectForKey:kCompanyImageUrl];
199 | self.smsCode = [aDecoder decodeObjectForKey:kCompanySmsCode];
200 | self.rechargeTypeRequired = [aDecoder decodeBoolForKey:kCompanyRechargeTypeRequired];
201 | self.showRechargeType = [aDecoder decodeBoolForKey:kShowRechargeType];
202 | self.label = [aDecoder decodeObjectForKey:kCompanyLabel];
203 | self.updatedOn = [aDecoder decodeObjectForKey:kCompanyUpdatedOn];
204 | self.name = [aDecoder decodeObjectForKey:kCompanyName];
205 | return self;
206 | }
207 |
208 | - (void)encodeWithCoder:(NSCoder *)aCoder
209 | {
210 | [aCoder encodeObject:_service forKey:kCompanyService];
211 | [aCoder encodeDouble:_companyIdentifier forKey:kCompanyId];
212 | [aCoder encodeObject:_imageUrl forKey:kCompanyImageUrl];
213 | [aCoder encodeObject:_smsCode forKey:kCompanySmsCode];
214 | [aCoder encodeBool:_rechargeTypeRequired forKey:kCompanyRechargeTypeRequired];
215 | [aCoder encodeBool:_showRechargeType forKey:kShowRechargeType];
216 | [aCoder encodeObject:_label forKey:kCompanyLabel];
217 | [aCoder encodeObject:_updatedOn forKey:kCompanyUpdatedOn];
218 | [aCoder encodeObject:_name forKey:kCompanyName];
219 | }
220 |
221 | - (id)copyWithZone:(NSZone *)zone
222 | {
223 | Company *copy = [[Company alloc] init];
224 |
225 | if (copy) {
226 |
227 | copy.service = [self.service copyWithZone:zone];
228 | copy.companyIdentifier = self.companyIdentifier;
229 | copy.imageUrl = [self.imageUrl copyWithZone:zone];
230 | copy.smsCode = [self.smsCode copyWithZone:zone];
231 | copy.rechargeTypeRequired = self.rechargeTypeRequired;
232 | copy.showRechargeType = self.showRechargeType;
233 | copy.label = [self.label copyWithZone:zone];
234 | copy.updatedOn = [self.updatedOn copyWithZone:zone];
235 | copy.name = [self.name copyWithZone:zone];
236 | }
237 |
238 | return copy;
239 | }
240 |
241 |
242 | @end
243 |
244 |
245 |
246 | //Recharge
247 |
248 | NSString *const kRechargeId = @"id";
249 | NSString *const kRechargeAmount = @"amount";
250 | NSString *const kRechargeTopUp = @"topUp";
251 |
252 |
253 | @interface Recharge ()
254 |
255 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
256 |
257 | @end
258 |
259 | @implementation Recharge
260 |
261 | @synthesize rechargeIdentifier = _rechargeIdentifier;
262 | @synthesize amount = _amount;
263 | @synthesize topUp = _topUp;
264 |
265 |
266 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
267 | {
268 | return [[self alloc] initWithDictionary:dict];
269 | }
270 |
271 | - (instancetype)initWithDictionary:(NSDictionary *)dict
272 | {
273 | self = [super init];
274 |
275 | // This check serves to make sure that a non-NSDictionary object
276 | // passed into the model class doesn't break the parsing.
277 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
278 | self.rechargeIdentifier = [[self objectOrNilForKey:kRechargeId fromDictionary:dict] doubleValue];
279 | self.amount = [[self objectOrNilForKey:kRechargeAmount fromDictionary:dict] doubleValue];
280 | self.topUp = [[self objectOrNilForKey:kRechargeTopUp fromDictionary:dict] boolValue];
281 | }
282 |
283 | return self;
284 | }
285 |
286 | - (NSDictionary *)dictionaryRepresentation
287 | {
288 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
289 | [mutableDict setValue:[NSNumber numberWithDouble:self.rechargeIdentifier] forKey:kRechargeId];
290 | [mutableDict setValue:[NSNumber numberWithDouble:self.amount] forKey:kRechargeAmount];
291 | [mutableDict setValue:[NSNumber numberWithBool:self.topUp] forKey:kRechargeTopUp];
292 |
293 | return [NSDictionary dictionaryWithDictionary:mutableDict];
294 | }
295 |
296 | - (NSString *)description
297 | {
298 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
299 | }
300 |
301 | #pragma mark - Helper Method
302 |
303 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
304 | {
305 | id object = [dict objectForKey:aKey];
306 | return [object isEqual:[NSNull null]] ? nil : object;
307 | }
308 |
309 | #pragma mark - NSCoding Methods
310 |
311 | - (id)initWithCoder:(NSCoder *)aDecoder
312 | {
313 | self = [super init];
314 |
315 | self.rechargeIdentifier = [aDecoder decodeDoubleForKey:kRechargeId];
316 | self.amount = [aDecoder decodeDoubleForKey:kRechargeAmount];
317 | self.topUp = [aDecoder decodeBoolForKey:kRechargeTopUp];
318 | return self;
319 | }
320 |
321 | - (void)encodeWithCoder:(NSCoder *)aCoder
322 | {
323 |
324 | [aCoder encodeDouble:_rechargeIdentifier forKey:kRechargeId];
325 | [aCoder encodeDouble:_amount forKey:kRechargeAmount];
326 | [aCoder encodeBool:_topUp forKey:kRechargeTopUp];
327 | }
328 |
329 | - (id)copyWithZone:(NSZone *)zone
330 | {
331 | Recharge *copy = [[Recharge alloc] init];
332 |
333 | if (copy) {
334 |
335 | copy.rechargeIdentifier = self.rechargeIdentifier;
336 | copy.amount = self.amount;
337 | copy.topUp = self.topUp;
338 | }
339 |
340 | return copy;
341 | }
342 |
343 |
344 | @end
345 |
346 |
347 |
348 | //RechargeTurbo Main Object
349 |
350 | NSString *const kRechargeTurboMobile = @"mobile";
351 | NSString *const kRechargeTurboUserId = @"userId";
352 | NSString *const kRechargeTurboCircle = @"circle";
353 | NSString *const kRechargeTurboRecharge = @"recharge";
354 | NSString *const kRechargeTurboCompany = @"company";
355 | NSString *const kRechargeTurboCircleId = @"circleId";
356 | NSString *const kRechargeTurboCompanyId = @"companyId";
357 |
358 | @interface RechargeTurboObject ()
359 |
360 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict;
361 |
362 | @end
363 |
364 | @implementation RechargeTurboObject
365 |
366 |
367 | @synthesize mobile = _mobile;
368 | @synthesize userId = _userId;
369 | @synthesize circle = _circle;
370 | @synthesize recharge = _recharge;
371 | @synthesize company = _company;
372 | @synthesize circleId = _circleId;
373 | @synthesize companyId = _companyId;
374 |
375 |
376 | + (instancetype)modelObjectWithDictionary:(NSDictionary *)dict
377 | {
378 | return [[self alloc] initWithDictionary:dict];
379 | }
380 |
381 | - (instancetype)initWithDictionary:(NSDictionary *)dict
382 | {
383 | self = [super init];
384 |
385 | // This check serves to make sure that a non-NSDictionary object
386 | // passed into the model class doesn't break the parsing.
387 | if(self && [dict isKindOfClass:[NSDictionary class]]) {
388 | self.mobile = [self objectOrNilForKey:kRechargeTurboMobile fromDictionary:dict];
389 | self.userId = [[self objectOrNilForKey:kRechargeTurboUserId fromDictionary:dict] doubleValue];
390 | self.circle = [CircleObject modelObjectWithDictionary:[dict objectForKey:kRechargeTurboCircle]];
391 |
392 | NSObject *receivedRecharge = [dict objectForKey:kRechargeTurboRecharge];
393 | NSMutableArray *parsedRecharge = [NSMutableArray array];
394 | if ([receivedRecharge isKindOfClass:[NSArray class]]) {
395 | for (NSDictionary *item in (NSArray *)receivedRecharge) {
396 | if ([item isKindOfClass:[NSDictionary class]]) {
397 | [parsedRecharge addObject:[Recharge modelObjectWithDictionary:item]];
398 | }
399 | }
400 | } else if ([receivedRecharge isKindOfClass:[NSDictionary class]]) {
401 | [parsedRecharge addObject:[Recharge modelObjectWithDictionary:(NSDictionary *)receivedRecharge]];
402 | }
403 |
404 | self.recharge = [NSArray arrayWithArray:parsedRecharge];
405 | self.company = [Company modelObjectWithDictionary:[dict objectForKey:kRechargeTurboCompany]];
406 | self.circleId = [self objectOrNilForKey:kRechargeTurboCircleId fromDictionary:dict];
407 | self.companyId = [self objectOrNilForKey:kRechargeTurboCompanyId fromDictionary:dict];
408 | }
409 |
410 | return self;
411 | }
412 |
413 | - (NSDictionary *)dictionaryRepresentation
414 | {
415 | NSMutableDictionary *mutableDict = [NSMutableDictionary dictionary];
416 | [mutableDict setValue:self.mobile forKey:kRechargeTurboMobile];
417 | [mutableDict setValue:[NSNumber numberWithDouble:self.userId] forKey:kRechargeTurboUserId];
418 | [mutableDict setValue:[self.circle dictionaryRepresentation] forKey:kRechargeTurboCircle];
419 |
420 | NSMutableArray *tempArrayForRecharge = [NSMutableArray array];
421 | for (NSObject *subArrayObject in self.recharge) {
422 | if([subArrayObject respondsToSelector:@selector(dictionaryRepresentation)]) {
423 | // This class is a model object
424 | [tempArrayForRecharge addObject:[subArrayObject performSelector:@selector(dictionaryRepresentation)]];
425 | } else {
426 | // Generic object
427 | [tempArrayForRecharge addObject:subArrayObject];
428 | }
429 | }
430 | [mutableDict setValue:[NSArray arrayWithArray:tempArrayForRecharge] forKey:kRechargeTurboRecharge];
431 | [mutableDict setValue:[self.company dictionaryRepresentation] forKey:kRechargeTurboCompany];
432 | [mutableDict setValue:self.circleId forKey:kRechargeTurboCircleId];
433 | [mutableDict setValue:self.companyId forKey:kRechargeTurboCompanyId];
434 |
435 | return [NSDictionary dictionaryWithDictionary:mutableDict];
436 | }
437 |
438 | - (NSString *)description
439 | {
440 | return [NSString stringWithFormat:@"%@", [self dictionaryRepresentation]];
441 | }
442 |
443 | #pragma mark - Helper Method
444 |
445 | - (id)objectOrNilForKey:(id)aKey fromDictionary:(NSDictionary *)dict
446 | {
447 | id object = [dict objectForKey:aKey];
448 | return [object isEqual:[NSNull null]] ? nil : object;
449 | }
450 |
451 | #pragma mark - NSCoding Methods
452 |
453 | - (id)initWithCoder:(NSCoder *)aDecoder
454 | {
455 | self = [super init];
456 |
457 | self.mobile = [aDecoder decodeObjectForKey:kRechargeTurboMobile];
458 | self.userId = [aDecoder decodeDoubleForKey:kRechargeTurboUserId];
459 | self.circle = [aDecoder decodeObjectForKey:kRechargeTurboCircle];
460 | self.recharge = [aDecoder decodeObjectForKey:kRechargeTurboRecharge];
461 | self.company = [aDecoder decodeObjectForKey:kRechargeTurboCompany];
462 | self.circleId = [aDecoder decodeObjectForKey:kRechargeTurboCircleId];
463 | self.companyId = [aDecoder decodeObjectForKey:kRechargeTurboCompanyId];
464 | return self;
465 | }
466 |
467 | - (void)encodeWithCoder:(NSCoder *)aCoder
468 | {
469 | [aCoder encodeObject:_mobile forKey:kRechargeTurboMobile];
470 | [aCoder encodeDouble:_userId forKey:kRechargeTurboUserId];
471 | [aCoder encodeObject:_circle forKey:kRechargeTurboCircle];
472 | [aCoder encodeObject:_recharge forKey:kRechargeTurboRecharge];
473 | [aCoder encodeObject:_company forKey:kRechargeTurboCompany];
474 | [aCoder encodeObject:_circleId forKey:kRechargeTurboCircleId];
475 | [aCoder encodeObject:_companyId forKey:kRechargeTurboCompanyId];
476 | }
477 |
478 | - (id)copyWithZone:(NSZone *)zone
479 | {
480 | RechargeTurboObject *copy = [[RechargeTurboObject alloc] init];
481 |
482 | if (copy) {
483 |
484 | copy.mobile = [self.mobile copyWithZone:zone];
485 | copy.userId = self.userId;
486 | copy.circle = [self.circle copyWithZone:zone];
487 | copy.recharge = [self.recharge copyWithZone:zone];
488 | copy.company = [self.company copyWithZone:zone];
489 | copy.circleId = [self.circleId copyWithZone:zone];
490 | copy.companyId = [self.companyId copyWithZone:zone];
491 | }
492 |
493 | return copy;
494 | }
495 |
496 | @end
497 |
--------------------------------------------------------------------------------
/iOS_APIParser/iOS_APIParser-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // iOS_APIParser-Prefix.pch
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #ifndef iOS_APIParser_Prefix_pch
10 | #define iOS_APIParser_Prefix_pch
11 |
12 | // Include any system framework and library headers here that should be included in all compilation units.
13 | // You will also need to set the Prefix Header build setting of one or more of your targets to reference this file.
14 |
15 | #import "AppDelegate.h"
16 | #import "AppMacros.h"
17 | #import "APIParser.h"
18 |
19 | #endif /* iOS_APIParser_Prefix_pch */
20 |
--------------------------------------------------------------------------------
/iOS_APIParser/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // iOS_APIParser
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/iOS_APIParserTests/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 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/iOS_APIParserTests/iOS_APIParserTests.m:
--------------------------------------------------------------------------------
1 | //
2 | // iOS_APIParserTests.m
3 | // iOS_APIParserTests
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface iOS_APIParserTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation iOS_APIParserTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/iOS_APIParserUITests/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 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/iOS_APIParserUITests/iOS_APIParserUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // iOS_APIParserUITests.m
3 | // iOS_APIParserUITests
4 | //
5 | // Created by Dhruvik Rao on 16/11/15.
6 | // Copyright © 2015 Dhruvik Rao. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface iOS_APIParserUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation iOS_APIParserUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------