Skip to content

Commit 930580c

Browse files
author
Mannie Tagarira
committed
- Misc UI updates
- Added functionality to allow users to email the resources found using the app (iPad) - Added a method to check for internet connection so that error messages are shown more appropriately. The app can also handle some tasks accordingly as; for instance, if no internet connection is found after "pull to refresh" the app does not attempt to load anything. Also, when the app starts up without an internet connection, the app does not try to automatically login. - Added the FlatWebView library which has been swapped in for descriptions since this has a much cleaner feel. - Updated README
1 parent aeeb559 commit 930580c

33 files changed

+747
-402
lines changed

BioMonitor.xcodeproj/project.pbxproj

+14
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
361BEF66139791F100939B04 /* fullscreen.png in Resources */ = {isa = PBXBuildFile; fileRef = 361BEF65139791F100939B04 /* fullscreen.png */; };
3232
361BF06A1397D3D000939B04 /* Licence in Resources */ = {isa = PBXBuildFile; fileRef = 361BF0691397D3D000939B04 /* Licence */; };
3333
361BF0821397D56000939B04 /* ReadMe.rdoc in Resources */ = {isa = PBXBuildFile; fileRef = 361BF0811397D56000939B04 /* ReadMe.rdoc */; };
34+
361BF0CE1397DDD100939B04 /* FlatWebView.m in Sources */ = {isa = PBXBuildFile; fileRef = 361BF0CD1397DDD100939B04 /* FlatWebView.m */; };
3435
3628D4751307300C009BD8F3 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3628D4741307300C009BD8F3 /* Security.framework */; };
3536
3628D5881307350B009BD8F3 /* Base64Transcoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 3628D56C1307350A009BD8F3 /* Base64Transcoder.c */; };
3637
3628D5891307350B009BD8F3 /* NSMutableURLRequest+Parameters.m in Sources */ = {isa = PBXBuildFile; fileRef = 3628D56F1307350A009BD8F3 /* NSMutableURLRequest+Parameters.m */; };
@@ -202,6 +203,8 @@
202203
361BEF65139791F100939B04 /* fullscreen.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = fullscreen.png; sourceTree = "<group>"; };
203204
361BF0691397D3D000939B04 /* Licence */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Licence; sourceTree = "<group>"; };
204205
361BF0811397D56000939B04 /* ReadMe.rdoc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = ReadMe.rdoc; sourceTree = "<group>"; };
206+
361BF0CC1397DDD100939B04 /* FlatWebView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FlatWebView.h; sourceTree = "<group>"; };
207+
361BF0CD1397DDD100939B04 /* FlatWebView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = FlatWebView.m; sourceTree = "<group>"; };
205208
3628D4741307300C009BD8F3 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
206209
3628D56C1307350A009BD8F3 /* Base64Transcoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = Base64Transcoder.c; sourceTree = "<group>"; };
207210
3628D56D1307350A009BD8F3 /* Base64Transcoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Base64Transcoder.h; sourceTree = "<group>"; };
@@ -527,6 +530,15 @@
527530
path = SVWebViewController;
528531
sourceTree = "<group>";
529532
};
533+
361BF0CB1397DDD100939B04 /* FlatWebView */ = {
534+
isa = PBXGroup;
535+
children = (
536+
361BF0CC1397DDD100939B04 /* FlatWebView.h */,
537+
361BF0CD1397DDD100939B04 /* FlatWebView.m */,
538+
);
539+
path = FlatWebView;
540+
sourceTree = "<group>";
541+
};
530542
3628D56A1307350A009BD8F3 /* OAuthConsumer */ = {
531543
isa = PBXGroup;
532544
children = (
@@ -647,6 +659,7 @@
647659
365C68DA125BC5FC0099CE38 /* Frameworks */ = {
648660
isa = PBXGroup;
649661
children = (
662+
361BF0CB1397DDD100939B04 /* FlatWebView */,
650663
361BEDEB1396934E00939B04 /* SVWebViewController */,
651664
361BEDA613968B1700939B04 /* TPKeyboardAvoiding */,
652665
36FA63AD134E090800B2A97A /* TVOutManager */,
@@ -1159,6 +1172,7 @@
11591172
361BEDAB13968B1700939B04 /* TPKeyboardAvoidingScrollView.m in Sources */,
11601173
361BEDAC13968B1700939B04 /* TPKeyboardAvoidingTableView.m in Sources */,
11611174
361BEDF51396934E00939B04 /* SVWebViewController.m in Sources */,
1175+
361BF0CE1397DDD100939B04 /* FlatWebView.m in Sources */,
11621176
);
11631177
runOnlyForDeploymentPostprocessing = 0;
11641178
};

Frameworks/FlatWebView/FlatWebView.h

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
//Copyright (c) 2011 Aaron Brethorst
2+
//
3+
//Permission is hereby granted, free of charge, to any person obtaining a copy
4+
//of this software and associated documentation files (the "Software"), to deal
5+
//in the Software without restriction, including without limitation the rights
6+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
//copies of the Software, and to permit persons to whom the Software is
8+
//furnished to do so, subject to the following conditions:
9+
//
10+
//The above copyright notice and this permission notice shall be included in
11+
//all copies or substantial portions of the Software.
12+
//
13+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
//THE SOFTWARE.
20+
21+
22+
#import <UIKit/UIKit.h>
23+
24+
@interface FlatWebView : UIWebView
25+
{
26+
27+
}
28+
29+
@end

Frameworks/FlatWebView/FlatWebView.m

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
//Copyright (c) 2011 Aaron Brethorst
2+
//
3+
//Permission is hereby granted, free of charge, to any person obtaining a copy
4+
//of this software and associated documentation files (the "Software"), to deal
5+
//in the Software without restriction, including without limitation the rights
6+
//to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
//copies of the Software, and to permit persons to whom the Software is
8+
//furnished to do so, subject to the following conditions:
9+
//
10+
//The above copyright notice and this permission notice shall be included in
11+
//all copies or substantial portions of the Software.
12+
//
13+
//THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
//IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
//FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
//AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
//LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
//OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
//THE SOFTWARE.
20+
21+
22+
#import "FlatWebView.h"
23+
24+
@interface FlatWebView ()
25+
- (void)hideImageViewsIn:(UIView*)view;
26+
@end
27+
28+
@implementation FlatWebView
29+
30+
- (void)layoutSubviews
31+
{
32+
[super layoutSubviews];
33+
34+
[self hideImageViewsIn:self];
35+
}
36+
37+
- (void)hideImageViewsIn:(UIView*)view
38+
{
39+
for (UIView *v in view.subviews)
40+
{
41+
if ([v isKindOfClass:[UIImageView class]])
42+
{
43+
v.hidden = YES;
44+
}
45+
else
46+
{
47+
[self hideImageViewsIn:v];
48+
}
49+
}
50+
}
51+
52+
@end

Frameworks/SVWebViewController/SVWebViewController.m

+2
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ - (void)viewDidLoad {
5555

5656
CGRect deviceBounds = [[UIApplication sharedApplication] keyWindow].bounds;
5757

58+
[rWebView setBackgroundColor:[UIColor clearColor]];
59+
5860
if(!deviceIsTablet) {
5961
separatorWidth = 50;
6062
buttonWidth = 18;

Frameworks/SVWebViewController/SVWebViewController.xib

+5-8
Original file line numberDiff line numberDiff line change
@@ -47,9 +47,9 @@
4747
<int key="NSvFlags">274</int>
4848
<string key="NSFrameSize">{320, 372}</string>
4949
<reference key="NSSuperview" ref="191373211"/>
50-
<object class="NSColor" key="IBUIBackgroundColor">
51-
<int key="NSColorSpace">1</int>
52-
<bytes key="NSRGB">MSAxIDEAA</bytes>
50+
<object class="NSColor" key="IBUIBackgroundColor" id="29595309">
51+
<int key="NSColorSpace">3</int>
52+
<bytes key="NSWhite">MCAwAA</bytes>
5353
</object>
5454
<int key="IBUIContentMode">9</int>
5555
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
@@ -4462,10 +4462,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
44624462
</object>
44634463
</object>
44644464
</object>
4465-
<object class="NSColor" key="NSColor">
4466-
<int key="NSColorSpace">3</int>
4467-
<bytes key="NSWhite">MCAwAA</bytes>
4468-
</object>
4465+
<reference key="NSColor" ref="29595309"/>
44694466
</object>
44704467
<string key="IBUIColorCocoaTouchKeyPath">scrollViewTexturedBackgroundColor</string>
44714468
</object>
@@ -4573,7 +4570,7 @@ AAgAAAAIAAIACAACAAAAAgAAAAEAAQABAAE</bytes>
45734570
<bool key="EncodedWithXMLCoder">YES</bool>
45744571
<string>SVWebViewController</string>
45754572
<string>UIResponder</string>
4576-
<string>{{1120, 376}, {320, 480}}</string>
4573+
<string>{{807, 376}, {320, 480}}</string>
45774574
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
45784575
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
45794576
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>

ReadMe.rdoc

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
= BioCatalogue Mass Curator
1+
= BioCatalogue iOS
22

33
Author:: Mannie Tagarira
44
Version:: 0.1

Shared/AppConstants.h

+6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ extern NSString *const ProviderResourceScope;
4040

4141
extern NSString *const AnnouncementResourceScope;
4242

43+
extern NSString *const InternetConnectionTestResourceScope;
44+
4345
extern NSString *const RESTService;
4446
extern NSString *const SOAPService;
4547

@@ -174,6 +176,10 @@ typedef enum {
174176
InvalidPasswordError
175177
} BioCatalogueErrorCode;
176178

179+
typedef enum {
180+
NoInternetConnectionError = -1009,
181+
ConnectionToServerError = -1004
182+
} NSErrorCode;
177183

178184
/* * *** *** *** ** *** *** *** ** *** *** *** ** *** *** *** ** *** *** *** * */
179185

Shared/AppConstants.m

+2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@
4242

4343
NSString *const AnnouncementResourceScope = @"announcements";
4444

45+
NSString *const InternetConnectionTestResourceScope = @"agents";
46+
4547
NSString *const RESTService = @"REST";
4648
NSString *const SOAPService = @"SOAP";
4749

Shared/AppDelegate_Shared.m

+3-3
Original file line numberDiff line numberDiff line change
@@ -56,8 +56,8 @@ -(void) handleError:(NSNotification *)notification {
5656

5757
dispatch_async(dispatch_get_main_queue(), ^{
5858
switch ([[notification object] code]) {
59-
case -1009: // no internet connection error
60-
case -1004: // connection to server error
59+
case NoInternetConnectionError:
60+
case ConnectionToServerError:
6161
[self showUIAlertViewTitle:@"Connection Error" message:[[notification object] localizedDescription]];
6262
break;
6363
case InvalidEmailAddressError:
@@ -83,7 +83,7 @@ -(void) handleError:(NSNotification *)notification {
8383
Save changes in the application's managed object context before the application terminates.
8484
*/
8585

86-
- (void)applicationWillEnterForeground:(UIApplication *)application {
86+
- (void)applicationWillEnterForeground:(UIApplication *)application {
8787
[UpdateCenter killUpdateCheckDaemon];
8888
}
8989

Shared/AppImports.h

+2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333

3434
#import "SVWebViewController.h"
3535

36+
#import "FlatWebView.h"
37+
3638
// * *** *** *** ** *** *** *** ** *** *** *** *
3739

3840
#pragma mark -

Shared/Categories/NSString+Helper.h

+2
Original file line numberDiff line numberDiff line change
@@ -17,4 +17,6 @@
1717
-(NSString *) stringByAddingPercentEscapes;
1818
-(NSString *) stringByReformattingJSONDate:(BOOL)includeTime;
1919

20+
-(NSString *) printableResourceScope;
21+
2022
@end

Shared/Categories/NSString+Helper.m

+12
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,17 @@ -(NSString *) stringByReformattingJSONDate:(BOOL)includeTime {
120120
}
121121
} // stringByReformattingJSONDate
122122

123+
-(NSString *) printableResourceScope {
124+
if ([self isEqualToString:AnnouncementResourceScope]) {
125+
return @"Announcement";
126+
} else if ([self isEqualToString:ServiceResourceScope]) {
127+
return @"Web Service";
128+
} else if ([self isEqualToString:UserResourceScope]) {
129+
return @"User";
130+
} else {
131+
return nil;
132+
}
133+
} // printableBioCatalogueResourceScope
134+
123135

124136
@end

Shared/Categories/UIDevice+Helper.h

+2
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@
1212
-(BOOL) inPortraitOrientation;
1313
-(BOOL) isIPadDevice;
1414

15+
-(BOOL) hasInternetConnection;
16+
1517
@end

Shared/Categories/UIDevice+Helper.m

+13
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,17 @@ -(BOOL) isIPadDevice {
1919
return [[self model] isEqualToString:@"iPad"] || [[self model] isEqualToString:@"iPad Simulator"];
2020
}
2121

22+
-(BOOL) hasInternetConnection {
23+
NSError *error = nil;
24+
25+
NSString *path = [NSString stringWithFormat:@"/%@?per_page=1", InternetConnectionTestResourceScope];
26+
NSURL *url = [BioCatalogueClient URLForPath:path withRepresentation:JSONFormat];
27+
NSURLRequest *request = [NSURLRequest requestWithURL:url
28+
cachePolicy:NSURLRequestReloadRevalidatingCacheData
29+
timeoutInterval:APIRequestTimeout];
30+
[NSURLConnection sendSynchronousRequest:request returningResponse:nil error:&error];
31+
32+
return error == nil;
33+
}
34+
2235
@end

Shared/Controllers/LoginViewController.m

+7-4
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ -(void) attemptToSignInWithUsername:(NSString *)username
5959
dispatch_async(dispatch_queue_create("Login", NULL), ^{
6060
[self performSelectorOnMainThread:@selector(updateView) withObject:nil waitUntilDone:NO];
6161

62-
if (![BioCatalogueClient signInWithUsername:username withPassword:password]) {
62+
if (![BioCatalogueClient signInWithUsername:username withPassword:password] && [[UIDevice currentDevice] hasInternetConnection]) {
6363
[[NSError errorWithDomain:BioCatalogueClientErrorDomain code:LoginError userInfo:nil] log];
6464
}
6565

@@ -84,10 +84,11 @@ -(IBAction) signInToBioCatalogue {
8484
[[NSError errorWithDomain:BioCatalogueClientErrorDomain code:InvalidEmailAddressError userInfo:nil] log];
8585
} else if (![[passwordField text] isValidJSONValue]) {
8686
[[NSError errorWithDomain:BioCatalogueClientErrorDomain code:InvalidPasswordError userInfo:nil] log];
87-
} else {
87+
} else {
8888
[self setEnabledForUILoginElements:[NSNumber numberWithBool:NO]];
8989
[self attemptToSignInWithUsername:[usernameField text] andPassword:[passwordField text] updatingUILoginElements:YES];
9090
}
91+
9192
} // signInToBioCatalogue
9293

9394
-(IBAction) signOutOfBioCatalogue {
@@ -129,8 +130,10 @@ - (void)awakeFromNib {
129130

130131
if ([password isValidJSONValue]) {
131132
[passwordField setText:password];
132-
[self setEnabledForUILoginElements:[NSNumber numberWithBool:NO]];
133-
[self attemptToSignInWithUsername:username andPassword:password updatingUILoginElements:NO];
133+
if ([[UIDevice currentDevice] hasInternetConnection]) {
134+
[self setEnabledForUILoginElements:[NSNumber numberWithBool:NO]];
135+
[self attemptToSignInWithUsername:username andPassword:password updatingUILoginElements:NO];
136+
}
134137
}
135138
} else {
136139
[self setEnabledForUILoginElements:[NSNumber numberWithBool:YES]];

Shared/Controllers/ProviderServicesViewController.m

+1-1
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
121121

122122
-(NSInteger) tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
123123
return [[paginatedServices objectForKey:[NSNumber numberWithInt:section]] count];
124-
} // tableView:titleForHeaderInSection
124+
} // tableView:numberOfRowsInSection
125125

126126
// Customize the appearance of table view cells.
127127
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

Shared/Controllers/PullToRefreshViewController.m

+3-2
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ - (void)reloadTableViewDataSource{
9292
[self performSelector:@selector(refreshTableViewDataSource)];
9393
}
9494
});
95-
[self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:1.0];
95+
96+
[self performSelector:@selector(doneLoadingTableViewData) withObject:nil afterDelay:1.5];
9697
}
9798

9899

@@ -113,7 +114,7 @@ - (void)scrollViewDidScroll:(UIScrollView *)scrollView{
113114
}
114115

115116
- (void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate{
116-
if ([scrollView contentOffset].y <= contentOffset && !_reloading) {
117+
if ([scrollView contentOffset].y <= contentOffset && !_reloading && [[UIDevice currentDevice] hasInternetConnection]) {
117118
_reloading = YES;
118119
[self reloadTableViewDataSource];
119120
[refreshHeaderView setState:EGOOPullRefreshLoading];

Shared/Controllers/ServiceComponentsDetailViewController.m

+1
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
169169
}
170170

171171
[UIContentController customiseTableViewCell:cell];
172+
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
172173

173174
if ([collection count] == 0) {
174175
[[cell detailTextLabel] setText:[NSString stringWithFormat:@"No %@", [self tableView:tableView titleForHeaderInSection:[indexPath section]]]];

Shared/Controllers/ServiceComponentsViewController.m

+9-5
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,13 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N
119119
[[cell detailTextLabel] setText:[NSString stringWithFormat:@"No %@", (serviceIsREST ? RESTComponentsText : SOAPComponentsText)]];
120120
}
121121

122+
[cell setSelectionStyle:UITableViewCellSelectionStyleNone];
123+
122124
return cell;
123125
}
124-
126+
127+
[cell setSelectionStyle:UITableViewCellSelectionStyleBlue];
128+
125129
// Configure the cell...
126130
if (serviceIsREST) {
127131
NSString *endpointLabel = [[serviceComponents objectAtIndex:[indexPath row]] objectForKey:JSONEndpointLabelElement];
@@ -153,11 +157,11 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath
153157
NSURL *url = [NSURL URLWithString:[[serviceComponents objectAtIndex:[indexPath row]] objectForKey:JSONResourceElement]];
154158
[detailViewController updateWithComponentAtPath:[url path]];
155159

156-
[[self navigationController] pushViewController:detailViewController animated:YES];
160+
[[self navigationController] pushViewController:detailViewController animated:YES];
161+
162+
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
163+
[tableView deselectRowAtIndexPath:indexPath animated:YES];
157164
}
158-
159-
[tableView selectRowAtIndexPath:indexPath animated:YES scrollPosition:UITableViewScrollPositionMiddle];
160-
[tableView deselectRowAtIndexPath:indexPath animated:YES];
161165
} // tableView:didSelectRowAtIndexPath
162166

163167

0 commit comments

Comments
 (0)