Developer Area

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

Revision 442, 16.3 kB (checked in by henri, 5 years ago)

Centralized parsing .tel query string, and fixed "www" prefix removal.

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 loadingView;
35@synthesize labelForLoadingView;
36@synthesize telSearch;
37@synthesize progressView;
38@synthesize progressLabel;
39@synthesize logo;
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        shouldUpdateLocation = YES;
48    return self;
49}
50
51- (void)viewDidLoad {
52        [super viewDidLoad];
53        if (!self.title) {
54                self.title = @"Contacts";
55               
56                // NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];   
57                FriendsData *sharedFriendsInstance = [FriendsData sharedInstance];
58                sharedFriendsInstance.delegate = self;
59                friendsTableView.dataSource = sharedFriendsInstance;
60               
61                // Do the other setup tasks
62                [telSearch setKeyboardType:UIKeyboardTypeASCIICapable];
63                [telSearch setAutocorrectionType:UITextAutocorrectionTypeNo];
64                keyboardShown = NO;
65                [[NSNotificationCenter defaultCenter] addObserver:self
66                                                                                                 selector:@selector(keyboardWillShow:) name:UIKeyboardWillShowNotification object:nil ];
67                [[NSNotificationCenter defaultCenter] addObserver:self
68                                                                                                 selector:@selector(keyboardDidShow:) name:UIKeyboardDidShowNotification object:nil ];
69                [[NSNotificationCenter defaultCenter] addObserver:self
70                                                                                                 selector:@selector(keyboardWillHide:) name:UIKeyboardWillHideNotification object:nil ];
71                isUpdatingLocation = FALSE;
72                needsFriendsTableRefresh = TRUE;
73        }
74}
75
76- (void)viewWillAppear:(BOOL)animated {
77        [super viewWillAppear:animated];
78        // become the delegate of MyCLController, which could have been taken by a .tel tableview
79        [MyCLController sharedInstance].delegate = self;
80}
81
82- (void)viewDidAppear:(BOOL)animated {
83        [super viewDidAppear:animated];
84        // Must animate the hiding of the navbar and put it in this method
85        // otherwise the frame of the view is reduced and pushed up by the size of the navbar
86        [self.navigationController setNavigationBarHidden:YES animated:YES];
87        if (! isUpdatingLocation) {
88                [[MyCLController sharedInstance].locationManager startUpdatingLocation];
89                isUpdatingLocation = TRUE;
90        }
91
92        if (needsFriendsTableRefresh) {
93                // Now load our friends using a timer, so that the application can finish initializing
94                // and it can display the "loading..." information. Once the friend data has been loaded,
95                // friendsDataDidLoad() is called and we complete building the table.
96                // Don't use a background thread because the AddressBook framework may not be threadsafe
97                [self.labelForLoadingView setText:LocStr(@"Loading AddressBook...")];
98                [self.view addSubview:loadingView];
99                loadingView.center = self.view.center;
100                [[FriendsData sharedInstance] refreshPreferences];
101                [[FriendsData sharedInstance] performSelector:@selector(loadFriendsDataFromAB:) withObject:nil afterDelay:0.1];
102                needsFriendsTableRefresh = FALSE;
103        }
104}
105
106// Delegate for FriendsData that gets called when data has been loaded and we can update the tableview
107- (void)friendsDataDidLoad {
108
109        //[NSThread sleepForTimeInterval:5];    // for testing loadingView only
110        [friendsTableView reloadData];
111        [loadingView removeFromSuperview];
112        if ([friendsTableView numberOfRowsInSection:0] == 0) {
113                [friendsTableView setHidden:NO];
114                instructionsView = [[[UILabel alloc] initWithFrame:friendsTableView.frame] autorelease];
115                instructionsView.numberOfLines = 0;
116                instructionsView.text = LocStr(@"NoContactsWithTel");
117                instructionsView.textAlignment = UITextAlignmentCenter;
118                instructionsView.font = [instructionsView.font fontWithSize:18];
119                instructionsView.alpha = 0.8;
120                [self.view insertSubview:instructionsView aboveSubview:friendsTableView];
121                [instructionsView resignFirstResponder];
122        } else {
123                [friendsTableView setHidden:NO];
124                if (instructionsView != nil) {
125                        [instructionsView removeFromSuperview];
126                }
127        }
128
129        if (isFirstRun) {
130                isFirstRun = NO;
131                // Check to see if the user has disabled location services altogether
132                // In that case, we show an alert and disable the find button and gps switch
133                // TODO: re-enable when find location button is brought back
134//              if ( ! [MyCLController sharedInstance].locationManager.locationServicesEnabled ) {
135//                      BOOL shouldQuit = NO;
136//                     
137//                      CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:NSLocalizedString(@"LocationDenied", nil)
138//                                                                                                                              message:nil
139//                                                                                                                         delegate:nil
140//                                                                                                                       shouldQuit:shouldQuit
141//                                                                                                        cancelButtonTitle:nil
142//                                                                                                        otherButtonTitles:NSLocalizedString(@"OK", nil), nil];
143//                      [alertView show];
144//                      [alertView release];
145//              }
146
147
148                //register whenever a change to the underlying dataset happens, so we can update the friends list view
149                [[FriendsData sharedInstance] addObserver:self forKeyPath:@"lastFriendsUpdate"
150                                                                                  options:NSKeyValueObservingOptionNew context:NULL];
151        }
152        if (shouldUpdateLocation) {
153                shouldUpdateLocation = FALSE;
154                NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
155                if ([defaults boolForKey:@"startupLocatePreference"]) {
156                        progressLabel.text = LocStr(@"Searching contact locations");
157                        logo.hidden = YES;
158                        progressLabel.hidden = NO;
159                        progressView.hidden = NO;                       
160                        [self performSelectorInBackground:@selector(updateFriendsListInBackground) withObject:nil];
161                }
162        }
163}
164
165- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
166        // Return YES for supported orientations
167
168        return (interfaceOrientation == UIInterfaceOrientationPortrait);
169}
170
171- (void)didReceiveMemoryWarning {
172    [super didReceiveMemoryWarning]; // Don't release the view
173}
174
175- (void)dealloc {
176        [mapViewController release];
177        [locationRefreshButton release];
178        [locationRefreshingButton release];
179        [super dealloc];
180}
181
182#pragma mark ---- Main Friend Update methods ----
183- (void)updateFriendsListInBackground {
184        // This method is to be called as a new thread and updates the friends list in the background
185        // As it updates, it will request the table view and maybe a status indicator to update in the main thread
186        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
187        mapViewController = [FriendsMapViewController sharedInstance];
188        [[MyCLController sharedInstance] findFriendsTel];
189        [pool release];
190}
191
192- (void) observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context {
193
194    if ([keyPath isEqual:@"lastFriendsUpdate"]) {
195                // Make sure we're in the main thread to update the UI
196                [self performSelectorOnMainThread:@selector(updateFriendsTableViewWithTimestamp:)
197                                                           withObject:[change objectForKey:NSKeyValueChangeNewKey] waitUntilDone:YES];
198                [mapViewController setMarkers:[FriendsData sharedInstance].peopleCurrentList];
199                mapViewController.navigationItem.rightBarButtonItem = locationRefreshButton;
200        }
201        else {
202                [super observeValueForKeyPath:keyPath ofObject:object change:change context:context];
203        }
204}
205
206- (void)updateFriendsTableViewWithTimestamp:(NSDate *)theStamp {
207        [[FriendsData sharedInstance] updateDataSet];   
208        [friendsTableView reloadData];
209}
210
211#pragma mark ---- Row and Accessory Click ----
212
213- (void)tableView:(UITableView *)tableView accessoryButtonTappedForRowWithIndexPath:(NSIndexPath *)indexPath {
214       
215        // Do the same as if the row is selected
216        [self tableView:tableView didSelectRowAtIndexPath:indexPath];
217
218        return;
219}
220
221- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
222       
223        mapViewController.zoomLevel = 14.0;
224        NSNumber *personId = [[FriendsData sharedInstance] getABRecordIdForIndexPath:indexPath];
225        [tableView deselectRowAtIndexPath:indexPath animated:YES];
226        [self launchNavControllerForTel:nil personId:personId];
227        return;
228}
229
230#pragma mark ---- Action methods ----
231
232- (void)launchNavControllerForTel:(NSString *)aTel personId:(NSNumber *)aPersonId {
233        NaptrViewController *nVC = [[[NaptrViewController alloc] initWithNibName:@"TelView" bundle:[NSBundle mainBundle]] autorelease];
234        if (aPersonId) {
235                if (![nVC setupWithPersonId:aPersonId])
236                        return;
237        } else if (aTel) {
238                if (![nVC setupWithTel:aTel])
239                        return;
240        } else {
241                return;
242        }
243        [self.navigationController pushViewController:nVC animated:YES];
244}       
245
246#pragma mark ---- UISearchBar delegate and keyboard methods ----
247
248- (void)keyboardWillShow:(NSNotification*)aNotification {
249        if (keyboardShown)
250                return;
251       
252        NSDictionary* info = [aNotification userInfo];
253    // Get the size of the keyboard.
254    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
255    CGSize keyboardSize = [aValue CGRectValue].size;
256        // Move the search box up above the keyboard
257        CGRect tSFrame = telSearch.frame;
258        CGRect aboveKeyboard = CGRectMake(tSFrame.origin.x, tSFrame.origin.y - keyboardSize.height,
259                                                                          tSFrame.size.width, tSFrame.size.height);
260        telSearch.barStyle = UIBarStyleBlackOpaque;
261        self.friendsTableView.hidden = YES;
262        [UIView beginAnimations:nil context:NULL];
263        [UIView setAnimationBeginsFromCurrentState:YES];
264        [UIView setAnimationDuration:0.3];      // TODO: Change this to UIKeyboardAnimationDurationUserInfoKey for 3.x
265        telSearch.frame = aboveKeyboard;
266        [UIView commitAnimations];
267        keyboardShown = YES;
268}
269
270- (void)keyboardDidShow:(NSNotification*)aNotification {
271        // If we show the cancel button in the WillShow notification, it is disabled (2.x at least)
272        telSearch.showsCancelButton = YES;
273}
274
275- (void)keyboardWillHide:(NSNotification*)aNotification {
276        if (!keyboardShown)
277                return;
278       
279        NSDictionary* info = [aNotification userInfo];
280    // Get the size of the keyboard.
281    NSValue* aValue = [info objectForKey:UIKeyboardBoundsUserInfoKey];
282    CGSize keyboardSize = [aValue CGRectValue].size;
283        // Move the search box back down
284        CGRect tSFrame = telSearch.frame;
285        CGRect noKeyboard = CGRectMake(tSFrame.origin.x, tSFrame.origin.y + keyboardSize.height,
286                                                                          tSFrame.size.width, tSFrame.size.height);
287        telSearch.frame = noKeyboard;
288        telSearch.barStyle = UIBarStyleBlackTranslucent;
289        telSearch.text = @"";
290        telSearch.showsCancelButton = NO;
291        self.friendsTableView.hidden = NO;
292        keyboardShown = NO;
293}
294
295- (void)searchBarTextDidEndEditing:(UISearchBar *)searchBar {
296}
297
298- (void)searchBarCancelButtonClicked:(UISearchBar *)searchBar {
299    [searchBar resignFirstResponder];
300}
301
302- (void)searchBarSearchButtonClicked:(UISearchBar *)searchBar {
303        //Must grab the text before resigning first responder
304        NSString *query = [NSString stringWithString:searchBar.text];
305    [searchBar resignFirstResponder];
306        [self launchNavControllerForTel:query personId:nil];
307}
308
309#pragma mark ---- MyCLController delegate methods ----
310
311-(void)gpsUpdate:(CLLocation *)aLoc {
312//      Enable this to display the GPS update info on this controller's view
313//      if (!aLoc) {
314//              [self.labelGpsLastUpdateDate setText:LocStr(@"LatLongUnavailable")];
315//              [self.labelGpsLastUpdateDate setNeedsDisplay];
316//              return;
317//      }
318//      NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
319//      [dateFormatter setDateStyle:NSDateFormatterShortStyle];
320//      [dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
321//      [self.labelGpsLastUpdateDate setText:[dateFormatter stringFromDate:aLoc.timestamp]];
322//      [self.labelGpsLastUpdateDate setNeedsDisplay];
323//      [dateFormatter release];
324        if (!mapViewController.view.superview) {
325                // the map view is not active, we can update my location there
326                // Let's not do it for now, it's debatable from a usability perspective
327                mapViewController.initialLoc = aLoc;
328        }
329        return;
330}
331
332-(void)statusUpdate:(NSString *)update {       
333        return;
334}
335
336- (void)updateProgressView:(NSNumber *)val {
337
338        // technique to ensure we're updating the UI in the main thread, otherwise it doesn't work
339        if (![NSThread isMainThread]) {
340                return([self performSelectorOnMainThread:_cmd withObject:val waitUntilDone:YES]);
341        }
342        progressView.progress = [val floatValue];
343        if ([val floatValue] == 1.0f) {
344                progressView.hidden = YES;
345                progressLabel.hidden = YES;
346                logo.hidden = NO;
347        }
348}
349
350-(void)newError:(NSString *)text shouldQuit:(BOOL)shouldQuit {
351
352        NSString *alertMessage;
353        if (shouldQuit) {
354                alertMessage = [NSString stringWithString:NSLocalizedString(@"AppWillQuit", nil)];
355        } else {
356                alertMessage = nil;
357        }
358       
359        CustomAlertView *alertView = [[CustomAlertView alloc] initWithTitle:text
360                                                                                                                                message:alertMessage
361                                                                                                                           delegate:nil
362                                                                                                                         shouldQuit:shouldQuit
363                                                                                                          cancelButtonTitle:nil
364                                                                                                          otherButtonTitles:NSLocalizedString(@"Quit", nil), nil];
365        [alertView show];
366        [alertView release];
367        if (alertMessage)
368                [alertMessage release];
369}       
370
371#pragma mark ------ Buttons
372
373- (IBAction)didPressMapButton:(id)sender {
374        // Load up the shared map view
375        // Make the map view do a background update of the friends and display them
376        mapViewController = [FriendsMapViewController sharedInstance];
377        // Put in a dummy map navcontroller so it looks the same as when we navigate .tel domains
378        mapViewController.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemDone
379                                                                                                                                                                                 target:self
380                                                                                                                                                                                 action:@selector(closeMapNavController)];
381        // Create the buttons to refresh the markers
382        if (!locationRefreshButton) {
383                UIImage *pinrefresh = [UIImage imageNamed:@"button-pin-refresh.png"];
384                locationRefreshButton = [[UIBarButtonItem alloc] initWithImage:pinrefresh style:UIBarButtonItemStyleBordered
385                                                                                                                                target:self
386                                                                                                                                action:@selector(didPressLocationRefreshButton:)];
387        }
388        if (!locationRefreshingButton) {
389                UIActivityIndicatorView *aIV = [[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhite] autorelease];
390                [aIV startAnimating];
391                locationRefreshingButton = [[UIBarButtonItem alloc] initWithCustomView:aIV];
392        }
393        mapViewController.navigationItem.rightBarButtonItem = locationRefreshButton;
394       
395        // Do data setup
396        [mapViewController didPressCenterGps:nil];
397        mapViewController.zoomLevel = 6.0;
398        [self.navigationController pushViewController:mapViewController animated:YES];
399}
400
401- (IBAction)didPressSettingsButton:(id)sender {
402        SettingsViewController *sVC = [[[SettingsViewController alloc] initWithNibName:@"SettingsView" bundle:[NSBundle mainBundle]] autorelease];
403        sVC.delegate = self;
404        sVC.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
405                                                                                                                                                                                 target:sVC
406                                                                                                                                                                                 action:@selector(didPressSave:)];
407        sVC.navigationItem.backBarButtonItem.title = LocStr(@"Cancel");
408        [self.navigationController pushViewController:sVC animated:YES];
409}
410
411- (IBAction)didPressLocationRefreshButton:(id)sender {
412        mapViewController.navigationItem.rightBarButtonItem = locationRefreshingButton;
413        [self performSelectorInBackground:@selector(updateFriendsListInBackground) withObject:nil];
414}
415
416#pragma mark ------ SettingsViewDelegate
417- (void)settingsDidChange {
418        needsFriendsTableRefresh = TRUE;
419        shouldUpdateLocation = TRUE;
420}
421
422- (void)launchTelUrl:(NSString *)url {
423        [self launchNavControllerForTel:url personId:nil];
424}
425
426@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