Developer Area

root/apps/iphone/superbook/trunk/Classes/LocateThem_ViewController.m @ 400

Revision 400, 16.2 kB (checked in by henri, 5 years ago)

Made loading view label dynamic

Line 
1//
2//  LocateThem_AppDelegate.m
3//  LocateThem
4//
5//  Created by Henri Asseily on 8/13/08.
6/*
7 Copyright (c) 2008-2009, Telnic Ltd. All rights reserved.
8 
9 Redistribution and use in source and binary forms, with or without modification,
10 are permitted provided that the following conditions are met:
11 
12 Redistributions of source code must retain the above copyright notice, this list of conditions
13 and the following disclaimer. Redistributions in binary form must reproduce the above copyright
14 notice, this list of conditions and the following disclaimer in the documentation and/or other
15 materials provided with the distribution.
16 Neither the name of the Telnic Ltd. nor the names of its contributors may be used to endorse or
17 promote products derived from this software without specific prior written permission.
18 THIS DOCUMENTATION IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS
19 OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
20 AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
21 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
24 IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
25 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27//
28
29#import "LocateThem_ViewController.h"
30
31@implementation LocateThem_ViewController
32
33@synthesize friendsTableView;
34@synthesize labelGpsLastUpdateDate;
35@synthesize progressView;
36@synthesize loadingView;
37@synthesize labelForLoadingView;
38@synthesize telSearch;
39@synthesize telNavController;
40
41- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
42    if (self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil]) {
43        // Custom initialization
44                [MyCLController sharedInstance].delegate = self;
45    }
46        isFirstRun = YES;
47    return self;
48}
49
50- (void)viewDidLoad {
51        [super viewDidLoad];
52        if (!self.title) {
53                self.title = @"Contacts";
54               
55                // NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];   
56                FriendsData *sharedFriendsInstance = [FriendsData sharedInstance];
57                sharedFriendsInstance.delegate = self;
58                friendsTableView.dataSource = sharedFriendsInstance;
59               
60                // Do the other setup tasks
61                [telSearch setKeyboardType:UIKeyboardTypeASCIICapable];
62                [telSearch setAutocorrectionType:UITextAutocorrectionTypeNo];
63                keyboardShown = NO;
64                [[NSNotificationCenter defaultCenter] addObserver:self
65                                                                                                 selector:@selector(keyboardWasShown:) name:UIKeyboardDidShowNotification object:nil ];
66                [[NSNotificationCenter defaultCenter] addObserver:self
67                                                                                                 selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil ];
68                isUpdatingLocation = FALSE;
69                needsFriendsTableRefresh = TRUE;
70        }
71}
72
73- (void)viewWillAppear {
74        // become the delegate of MyCLController, which could have been taken by a .tel tableview
75        [MyCLController sharedInstance].delegate = self;
76}
77
78- (void)viewDidAppear:(BOOL)animated {
79        if (! isUpdatingLocation) {
80                [[MyCLController sharedInstance].locationManager startUpdatingLocation];
81                isUpdatingLocation = TRUE;
82        }
83
84        if (needsFriendsTableRefresh) {
85                // Now load our friends using a timer, so that the application can finish initializing
86                // and it can display the "loading..." information. Once the friend data has been loaded,
87                // friendsDataDidLoad() is called and we complete building the table.
88                // Don't use a background thread because the AddressBook framework may not be threadsafe
89                [self.labelForLoadingView setText:LocStr(@"Loading AddressBook...")];
90                [self.view addSubview:loadingView];
91                loadingView.center = self.view.center;
92                [[FriendsData sharedInstance] performSelector:@selector(loadFriendsDataFromAB:) withObject:nil afterDelay:0.1];
93                needsFriendsTableRefresh = FALSE;
94        }
95}
96
97// Delegate for FriendsData that gets called when data has been loaded and we can update the tableview
98- (void)friendsDataDidLoad {
99
100        //[NSThread sleepForTimeInterval:5];    // for testing loadingView only
101        [friendsTableView reloadData];
102        [loadingView removeFromSuperview];
103        if ([friendsTableView numberOfRowsInSection:0] == 0) {
104                [friendsTableView setHidden:NO];
105                instructionsView = [[[UILabel alloc] initWithFrame:friendsTableView.frame] autorelease];
106                instructionsView.numberOfLines = 0;
107                instructionsView.text = LocStr(@"NoContactsWithTel");
108                instructionsView.textAlignment = UITextAlignmentCenter;
109                instructionsView.font = [instructionsView.font fontWithSize:18];
110                instructionsView.alpha = 0.8;
111                [self.view insertSubview:instructionsView aboveSubview:friendsTableView];
112                [instructionsView resignFirstResponder];
113        } else {
114                [friendsTableView setHidden:NO];
115                if (instructionsView != nil) {
116                        [instructionsView removeFromSuperview];
117                }
118        }
119
120        if (isFirstRun) {
121                isFirstRun = NO;
122                // Check to see if the user has disabled location services altogether
123                // In that case, we show an alert and disable the find button and gps switch
124                // TODO: re-enable when find location button is brought back
125//              if ( ! [MyCLController sharedInstance].locationManager.locationServicesEnabled ) {
126//                      BOOL shouldQuit = NO;
127//                     
128//                      CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:NSLocalizedString(@"LocationDenied", nil)
129//                                                                                                                              message:nil
130//                                                                                                                         delegate:nil
131//                                                                                                                       shouldQuit:shouldQuit
132//                                                                                                        cancelButtonTitle:nil
133//                                                                                                        otherButtonTitles:NSLocalizedString(@"OK", nil), nil];
134//                      [alertView show];
135//                      [alertView release];
136//              }
137
138
139                //register whenever a change to the underlying dataset happens, so we can update the friends list view
140                [[FriendsData sharedInstance] addObserver:self forKeyPath:@"lastFriendsUpdate"
141                                                                                  options:NSKeyValueObservingOptionNew context:NULL];
142               
143                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
144                if ([defaults boolForKey:@"startupLocatePreference"]) {
145                        [self performSelectorInBackground:@selector(updateFriendsListInBackground) withObject:nil];
146                }
147        } else {
148                // check if the db has been updated, then get rid of alertView
149        }
150}
151
152- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
153        // Return YES for supported orientations
154
155        return (interfaceOrientation == UIInterfaceOrientationPortrait);
156}
157
158- (void)didReceiveMemoryWarning {
159    [super didReceiveMemoryWarning]; // Don't release the view
160}
161
162- (void)dealloc {
163        [mapViewController release];
164        [super dealloc];
165}
166
167#pragma mark ---- Main Friend Update methods ----
168- (void)updateFriendsListInBackground {
169        // This method is to be called as a new thread and updates the friends list in the background
170        // As it updates, it will request the table view and maybe a status indicator to update in the main thread
171        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
172
173        //UIView *currentView = [friendsTableView superview];
174        mapViewController = [FriendsMapViewController sharedInstance];
175        [[MyCLController sharedInstance] findFriendsTel];
176        [pool release];
177}
178
179- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
180
181    if ([keyPath isEqual:@"lastFriendsUpdate"]) {
182                // Make sure we're in the main thread to update the UI
183                [self performSelectorOnMainThread:@selector(updateFriendsTableViewWithTimestamp:)
184                                                           withObject:[change objectForKey:NSKeyValueChangeNewKey] waitUntilDone:YES];
185                [mapViewController setMarkers:[FriendsData sharedInstance].peopleCurrentList];
186        }
187        else {
188                [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
189        }
190}
191
192- (void)updateFriendsTableViewWithTimestamp:(NSDate *)theStamp {
193        [[FriendsData sharedInstance] updateDataSet];   
194        [friendsTableView reloadData];
195}
196
197#pragma mark ---- Row and Accessory Click ----
198
199- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
200       
201        // Do the same as if the row is selected
202        [self tableView:tableView didSelectRowAtIndexPath:indexPath];
203
204        return;
205}
206
207- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
208       
209        NSNumber *personId = [[FriendsData sharedInstance] getABRecordIdForIndexPath:indexPath];
210        [tableView deselectRowAtIndexPath:indexPath animated:YES];
211        [self launchNavControllerForTel:nil personId:personId];
212        return;
213}
214
215#pragma mark ---- Action methods ----
216
217- (void)launchNavControllerForTel:(NSString *)aTel personId:(NSNumber *)aPersonId {
218        NaptrViewController *nVC = [[[NaptrViewController alloc] initWithNibName:@"TelViewController" bundle:[NSBundle mainBundle]] autorelease];
219        if (aPersonId) {
220                [nVC setupWithPersonId:aPersonId];
221        } else if (aTel) {
222                [nVC setupWithTel:aTel];
223        } else {
224                return;
225        }
226        if (self.telNavController) {
227                self.telNavController = nil;
228        }
229        self.telNavController = [[UINavigationController alloc] initWithRootViewController:nVC];
230        self.telNavController.navigationBar.barStyle = UIBarStyleBlackOpaque;
231        self.telNavController.navigationBar.tintColor = [UIColor colorWithRed:0 green:0.15 blue:0.3 alpha:1];
232        nVC.navigationItem.leftBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
233                                                                                                                                                                                 target:self
234                                                                                                                                                                                 action:@selector(cancelNavController:)];
235        // Insert our view at the absolute top
236        [[UIApplication sharedApplication].keyWindow addSubview:self.telNavController.view];
237        // Set up the animation
238    CATransition *animation = [CATransition animation];
239    //[animation setDelegate:self];
240        [animation setType:kCATransitionMoveIn];
241        [animation setSubtype:kCATransitionFromRight];
242    [animation setDuration:0.3];
243    [animation setTimingFunction:[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut]];   
244    [[[UIApplication sharedApplication].keyWindow layer] addAnimation:animation forKey:@"kEditAnimation"];
245}       
246
247- (IBAction)cancelNavController:(id)sender {
248    [[self.telNavController view] removeFromSuperview];
249        self.telNavController = nil;
250}
251
252#pragma mark ---- UISearchBar delegate and keyboard methods methods ----
253
254- (void)keyboardWasShown:(NSNotification*)aNotification {
255        if (keyboardShown)
256                return;
257       
258        NSDictionary* info = [aNotification userInfo];
259    // Get the size of the keyboard.
260    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
261    CGSize keyboardSize = [aValue CGRectValue].size;
262        // Move the search box up above the keyboard
263        CGRect tSFrame = telSearch.frame;
264        CGRect aboveKeyboard = CGRectMake(tSFrame.origin.x, tSFrame.origin.y - keyboardSize.height,
265                                                                          tSFrame.size.width, tSFrame.size.height);
266        telSearch.barStyle = UIBarStyleBlackOpaque;
267        self.friendsTableView.hidden = YES;
268        telSearch.showsCancelButton = YES;
269        telSearch.frame = aboveKeyboard;
270        keyboardShown = YES;
271}
272
273- (void)keyboardWillHide:(NSNotification*)aNotification {
274        if (!keyboardShown)
275                return;
276       
277        NSDictionary* info = [aNotification userInfo];
278    // Get the size of the keyboard.
279    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
280    CGSize keyboardSize = [aValue CGRectValue].size;
281        // Move the search box back down
282        CGRect tSFrame = telSearch.frame;
283        CGRect noKeyboard = CGRectMake(tSFrame.origin.x, tSFrame.origin.y + keyboardSize.height,
284                                                                          tSFrame.size.width, tSFrame.size.height);
285        telSearch.frame = noKeyboard;
286        telSearch.barStyle = UIBarStyleBlackTranslucent;
287        telSearch.text = @"";
288        telSearch.showsCancelButton = NO;
289        self.friendsTableView.hidden = NO;
290        keyboardShown = NO;
291}
292
293- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
294        if ([telSearch.text length] == 0)
295                return;
296        // TODO: should make this faster by parsing the string char-by-char in C
297        if ([telSearch.text hasPrefix:@"http"]) {
298                telSearch.text = [telSearch.text stringByReplacingOccurrencesOfString:@"http://" withString:@""];
299                telSearch.text = [telSearch.text stringByReplacingOccurrencesOfString:@"https://" withString:@""];
300        }
301        if ([telSearch.text hasPrefix:@"www."]) {
302                telSearch.text = [telSearch.text substringFromIndex:[@"www." length]];
303        }
304        if ([telSearch.text hasSuffix:@".tel"]) {
305                // .tel domain, do nothing
306        } else if ([telSearch.text hasSuffix:@".e164.arpa"]) {
307                // ENUM domain, let's add support for it, why not!
308                // Superbook will be the best ENUM client too! :)
309        } else {
310                telSearch.text = [NSString stringWithFormat:@"%@.tel", telSearch.text];
311        }
312        [self launchNavControllerForTel:telSearch.text personId:nil];
313}
314
315- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
316    [searchBar resignFirstResponder];
317}
318
319- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
320    [searchBar resignFirstResponder];
321}
322
323#pragma mark ---- MyCLController delegate methods ----
324
325-(void)gpsUpdate:(CLLocation *)aLoc {
326
327        if (!aLoc) {
328                [self.labelGpsLastUpdateDate setText:LocStr(@"LatLongUnavailable")];
329                [self.labelGpsLastUpdateDate setNeedsDisplay];
330                return;
331        }
332        NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
333        [dateFormatter setDateStyle:NSDateFormatterShortStyle];
334        [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
335        [self.labelGpsLastUpdateDate setText:[dateFormatter stringFromDate:aLoc.timestamp]];
336        [self.labelGpsLastUpdateDate setNeedsDisplay];
337        [dateFormatter release];
338        if (!mapViewController.view.superview) {
339                // the map view is not active, we can update my location there
340                // Let's not do it for now, it's debatable from a usability perspective
341                mapViewController.initialLoc = aLoc;
342        }
343        return;
344}
345
346-(void)statusUpdate:(NSString *)update {       
347        return;
348}
349
350- (void)updateProgressView:(NSNumber *)val {
351
352        // technique to ensure we're updating the UI in the main thread, otherwise it doesn't work
353        if (![NSThread isMainThread]) {
354                return([self performSelectorOnMainThread:_cmd withObject:val waitUntilDone:YES]);
355        }
356        progressView.progress = [val floatValue];
357}
358
359-(void)newError:(NSString *)text shouldQuit:(BOOL)shouldQuit {
360
361        NSString *alertMessage;
362        if (shouldQuit) {
363                alertMessage = [NSString stringWithString:NSLocalizedString(@"AppWillQuit", nil)];
364        } else {
365                alertMessage = nil;
366        }
367       
368        CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:text
369                                                                                                                                message:alertMessage
370                                                                                                                           delegate:nil
371                                                                                                                         shouldQuit:shouldQuit
372                                                                                                          cancelButtonTitle:nil
373                                                                                                          otherButtonTitles:NSLocalizedString(@"Quit", nil), nil];
374        [alertView show];
375        [alertView release];
376        if (alertMessage)
377                [alertMessage release];
378}       
379
380#pragma mark ------ info view
381
382- (IBAction)didPressInfoButton:(id)sender {
383        NSArray *nibItems = [[NSBundle mainBundle] loadNibNamed:@"AboutView" owner:self options:nil];
384        UINavigationController *aboutNC = [nibItems objectAtIndex:0];
385        aboutNC.view.frame = CGRectIntersection([UIScreen mainScreen].applicationFrame,
386                                                                                        [UIApplication sharedApplication].statusBarFrame);
387        aboutNC.topViewController.navigationItem.rightBarButtonItem.target = self;
388        aboutNC.topViewController.navigationItem.rightBarButtonItem.action = @selector(dismissModalViewControllerAnimated:);
389        UIWebView *helpV = (UIWebView *)[aboutNC.topViewController.view viewWithTag:666];
390        helpV.delegate = self;
391        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"About" ofType:@"html"]]];
392        [helpV loadRequest:req];
393        [self presentModalViewController:aboutNC animated:YES];
394}
395
396- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType;
397{
398    NSURL *loadURL = [ [ request URL ] retain ]; // retain the loadURL for use
399    if ( ( [ [ loadURL scheme ] isEqualToString: @"http" ] || [ [ loadURL scheme ] isEqualToString: @"https" ] )
400                && ( navigationType == UIWebViewNavigationTypeLinkClicked ) ) { // Check if the scheme is http/https.
401                // if it's a .tel url, open it in the app!
402                if ([[loadURL host] hasSuffix:@".tel"]) {
403                        [self launchNavControllerForTel:[loadURL host] personId:nil];
404                        [ loadURL release ];
405                        return NO;
406                }
407        return ![ [ UIApplication sharedApplication ] openURL: [ loadURL autorelease ] ]; // Auto release the loadurl because we wont get to release later. then return the opposite of openURL, so if safari cant open the url, open it in the UIWebView.
408        }
409        [ loadURL release ];
410    return YES; // URL is not http/https and should open in UIWebView
411}
412
413@end
Note: See TracBrowser for help on using the browser.
Telnic
Search This Site
Partners
Neustar
ICANN
Main site | WHOIS | Sell .tel | FAQ | Archived Site | About Telnic | Contact Us