Developer Area

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

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

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

Line 
1//
2//  NaptrViewController.m
3//  LocateThem
4//
5//  Created by Henri Asseily on 8/25/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 "NaptrViewController.h"
30
31static UIFont *headerFont;
32static UIFont *txtFont;
33
34@interface NaptrViewController (PrivateMethods)
35
36- (void)decrementLoadingCount;
37- (void)showError:(NSError *)error;
38@end
39
40@implementation NaptrViewController
41
42@synthesize theTable;
43@synthesize cleanTelName;
44@synthesize headerText;
45@synthesize naptrArray;
46@synthesize txtArray;
47@synthesize locArray;
48@synthesize country;
49@synthesize timeZone;
50@synthesize prefsReverseGeo;
51@synthesize loadingAIView;
52@synthesize loadingAIButton;
53@synthesize storeContactButton;
54@synthesize abId;
55
56#define kHeaderTextFontSize 14.0
57#define kTextFontSize 14.0
58
59#pragma mark ------- canonical init methods
60
61
62- (BOOL)setupWithPersonId:(NSNumber *)personId {
63        NSString *telName = [[FriendsData sharedInstance] getTelForABRecordId:personId withABRecordRef:nil];
64        self.abId = personId;
65        return [self setupWithTel:telName];
66}
67
68- (BOOL) setupWithTel:(NSString *)telName {
69       
70        headerFont = [UIFont boldSystemFontOfSize:kHeaderTextFontSize];
71        txtFont = [UIFont boldSystemFontOfSize:kTextFontSize];
72
73        self.title = [self telFromQueryString:telName];
74        if (!self.title)
75                return FALSE;
76        self.abId = [NSNumber numberWithInt:NSUIntegerMax];
77        self.cleanTelName = [NSMutableString stringWithString:self.title];
78        [self.cleanTelName replaceOccurrencesOfString:@"-"
79                                                                  withString:@" "
80                                                                         options:NSLiteralSearch
81                                                                           range:NSMakeRange(0, [self.cleanTelName length])];
82
83        self.headerText = nil;
84        self.country = nil;
85        self.timeZone = nil;
86        geoLocDidFinish = NO;
87        if (self.naptrArray) {
88                self.naptrArray = nil;
89                self.txtArray = nil;
90                self.locArray = nil;
91        }
92        self.naptrArray = [NSMutableArray arrayWithCapacity:10];
93        self.txtArray = [NSMutableArray arrayWithCapacity:10];
94        self.locArray = [NSMutableArray arrayWithCapacity:1];
95
96        self.loadingAIView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
97        self.loadingAIView.hidesWhenStopped = YES;
98        self.loadingAIButton = [[UIBarButtonItem alloc] initWithCustomView:self.loadingAIView];
99       
100        self.storeContactButton = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemSave
101                                                                                                                                                        target:self
102                                                                                                                                                        action:@selector(saveContact:)];
103       
104        // set the uinavbar of the root viewcontroller of the navcontroller
105        self.navigationItem.rightBarButtonItem = self.loadingAIButton;
106       
107        [self.theTable reloadData];
108        loadingCount = 3;
109        [self performSelectorInBackground:@selector(getNaptrInBackgroundForTel:) withObject:self.title];
110        [self performSelectorInBackground:@selector(getTxtInBackgroundForTel:) withObject:self.title];
111        [self performSelectorInBackground:@selector(getLocInBackgroundForTel:) withObject:self.title];
112        return TRUE;
113}
114
115#pragma mark ------- Basic methods
116
117- (void)viewDidLoad {
118        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
119        self.prefsReverseGeo = [defaults integerForKey:@"reverseGeoPreference"];
120}
121
122- (void)viewWillAppear:(BOOL)animated {
123        [super viewWillAppear:animated];
124        // set the uinavbar of the non-root viewcontrollers of the navcontroller
125        self.navigationItem.title = self.title;
126        if (!self.navigationItem.rightBarButtonItem)
127                self.navigationItem.rightBarButtonItem = self.loadingAIButton;
128}
129
130- (void)viewDidAppear:(BOOL)animated {
131        [super viewDidAppear:animated];
132        self.navigationController.navigationBarHidden = NO;
133}
134
135- (void)didReceiveMemoryWarning {
136        [super didReceiveMemoryWarning];
137}
138
139- (void)dealloc {
140        [super dealloc];
141}
142
143#pragma mark ------ set up loading stuff
144
145- (NSUInteger)loadingCount {
146        return loadingCount;
147}
148
149- (void)decrementLoadingCount {
150        // Must call this on main thread, because it has UI needs and is called from background threads
151        if (![NSThread isMainThread]) {
152                [self performSelectorOnMainThread:_cmd
153                                                           withObject:nil
154                                                        waitUntilDone:YES];
155                return;
156        }
157        loadingCount--;
158        if (loadingCount == 0) {
159                [self.loadingAIView stopAnimating];
160                self.navigationItem.rightBarButtonItem = self.storeContactButton;
161        } else {
162                [self.loadingAIView startAnimating];
163                self.navigationItem.rightBarButtonItem = self.loadingAIButton;
164        }
165}
166
167#pragma mark ------ tableView datasource methods
168
169- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
170        return SECTION_LOC+1;
171}
172
173- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section {
174        switch (section) {
175                case SECTION_HEADER:
176                        return @"Header";
177                        break;
178                case SECTION_NAPTR:
179                        return @"Contact Info";
180                        break;
181                case SECTION_TXT:
182                        return @"Keywords";
183                        break;
184                case SECTION_LOC:
185                        return @"Location";
186                        break;
187                default:
188                        return @"Other Records";
189                        break;
190        }
191}
192
193- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
194        switch (section) {
195                case SECTION_HEADER:
196                        if (!headerText) {
197                                return 0;
198                        }
199                        return 1;
200                        break;
201                case SECTION_NAPTR:
202                        return [naptrArray count];
203                        break;
204                case SECTION_TXT:
205                        return [txtArray count];
206                        break;
207                case SECTION_LOC:
208                        return [locArray count];
209                        break;
210                default:
211                        return 0;
212                        break;
213        }
214}
215
216- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
217       
218        switch (indexPath.section) {
219                case SECTION_HEADER:
220                {
221                        static NSString *MyIdentifier = @"headerCell";
222                       
223                        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
224                        if (cell == nil) {
225                                cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:MyIdentifier] autorelease];
226                        }
227                        //Working with a resizable cell
228                        //If there is already a subview, remove it.
229                        if ([[cell.contentView subviews] count] > 0) {
230                                UIView *labelToClear = [[cell.contentView subviews] objectAtIndex:0];
231                                [labelToClear removeFromSuperview];
232                        }
233                        UILabel *cellLabel;
234                        cellLabel = [headerText sizeCellLabelWithFont:headerFont paddingWidth:10.0f Height:10.0f];
235                        [cell.contentView addSubview:cellLabel];
236                        return cell;
237                }
238                        break;
239                       
240                case SECTION_NAPTR:
241                {
242                        static NSString *MyIdentifier = @"naptrCells";
243                       
244                        RecordNaptr *theRec = [self.naptrArray objectAtIndex:indexPath.row];
245                       
246                        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
247                        if (cell == nil) {
248                                NSArray *naptrCellNib = [[NSBundle mainBundle] loadNibNamed:@"NaptrTableViewCell" owner:self options:nil];
249                                cell = (UITableViewCell *)[naptrCellNib objectAtIndex:0];
250                        }
251                       
252                        [(UILabel *)[cell viewWithTag:NAPTRCELL_SERVICETYPE_TAG] setText:theRec.serviceDescription];
253                       
254                        // Check if it's a nonterminal naptr. If so, add the accessory indicator
255                        // and remove the trailing part of the string if it is a subdomain of the current domain
256                        if (theRec.isTerminal) {
257                                [(UILabel *)[cell viewWithTag:NAPTRCELL_LABEL_TAG] setText:theRec.labelDescription];
258                                [(UILabel *)[cell viewWithTag:NAPTRCELL_VALUE_TAG] setText:theRec.uriContent];
259                        } else {
260                                [(UILabel *)[cell viewWithTag:NAPTRCELL_LABEL_TAG] setText:@""];
261                                [(UILabel *)[cell viewWithTag:NAPTRCELL_VALUE_TAG] setText:theRec.labelDescription];
262                                // If NTN points within domain, shorten text to only display the subdomain of this domain
263                                if ([[theRec.labelDescription lowercaseString] hasSuffix:[self.cleanTelName lowercaseString]]) {
264                                        NSInteger suffixIndex = [theRec.labelDescription length] - [self.cleanTelName length] - 1;
265                                        if (suffixIndex > 0) {
266                                                [(UILabel *)[cell viewWithTag:NAPTRCELL_VALUE_TAG] setText:[theRec.labelDescription substringToIndex:suffixIndex]];
267                                        }
268                                }
269                                [cell setAccessoryType:UITableViewCellAccessoryDisclosureIndicator];
270                        }
271                       
272                        return cell;
273                }
274                        break;
275                       
276                case SECTION_TXT:
277                {
278                        static NSString *MyIdentifier = @"txtCells";
279                       
280                        RecordTxt *theRec = [self.txtArray objectAtIndex:indexPath.row];
281                       
282                        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
283                        if (cell == nil) {
284                                NSArray *txtCellNib = [[NSBundle mainBundle] loadNibNamed:@"TxtTableViewCell" owner:self options:nil];
285                                cell = (UITableViewCell *)[txtCellNib objectAtIndex:0];
286                        }
287                        [(UILabel *)[cell viewWithTag:1] setText:theRec.primaryDescription];
288                        if (theRec.primaryValue != NULL) {
289                                [(UILabel *)[cell viewWithTag:3] setText:theRec.primaryValue];
290                        } else {
291                                [(UILabel *)[cell viewWithTag:3] setText:@""];
292                        }
293                       
294                        // Set the text description and resize the label accordingly
295                        // We're not doing it like the header because we're using a nib for the cell
296                        // (but we override the font size here)
297                        UILabel *textDescriptionLabel = (UILabel *)[cell viewWithTag:2];
298                        textDescriptionLabel.text = theRec.textValue;
299                        CGFloat width = textDescriptionLabel.frame.size.width;
300                        CGFloat height = [textDescriptionLabel.text cellHeightForFont:txtFont paddingWidth:10.0f Height:6.0f];
301                        CGRect newframe = CGRectMake(textDescriptionLabel.frame.origin.x, textDescriptionLabel.frame.origin.y, width, height);
302                        textDescriptionLabel.frame = newframe;
303
304                        return cell;
305                }
306                        break;
307                       
308                case SECTION_LOC:
309                {
310                        static NSString *MyIdentifier = @"locCell";
311                       
312                        RecordLoc *theRec = [self.locArray objectAtIndex:indexPath.row];
313                       
314                        // Get the cell
315                        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
316                        if (cell == nil) {
317                                NSArray *locCellNib = [[NSBundle mainBundle] loadNibNamed:@"LocTableViewCell" owner:self options:nil];
318                                cell = (UITableViewCell *)[locCellNib objectAtIndex:0];
319                        }                       
320                       
321                        // Display cell info
322                       
323                        if (timeZone) {
324                                NSCalendar *cal = [NSCalendar currentCalendar];
325                                [cal setTimeZone:timeZone];
326                                NSDate *now = [NSDate date];
327                                // Set the color of the background of the cell, based on whether the person should be awake or not
328                                // Possibility: Make the hours a preference
329//                              unsigned unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit;
330//                              NSDateComponents *comps = [cal components:unitFlags fromDate:now];
331//                              if (([comps hour] < 8) || ([comps hour] > 22)) {
332//                                      cell.contentView.backgroundColor = [UIColor colorWithRed:0 green:0.15 blue:0.3 alpha:1];
333//                                      cell.accessoryView.backgroundColor = [UIColor colorWithRed:0 green:0.15 blue:0.3 alpha:1];
334//                              } else {
335//                                      cell.contentView.backgroundColor = [UIColor colorWithRed:0.3 green:0.9 blue:0.9 alpha:1];
336//                                      cell.accessoryView.backgroundColor = [UIColor colorWithRed:0.3 green:0.9 blue:0.9 alpha:1];
337//                              }
338                                // Now display the time properly
339                                NSDateFormatter *dF = [[NSDateFormatter alloc] init];
340                                [dF setTimeZone:timeZone];
341                                [dF setTimeStyle:NSDateFormatterShortStyle];
342                                [dF setDateStyle:NSDateFormatterNoStyle];
343                                [(UILabel *)[cell viewWithTag:LOCCELL_LOCALTIME_TAG] setText:[dF stringFromDate:now]];
344                                [dF release];
345                        } else {
346                                // no timezone
347                                [(UILabel *)[cell viewWithTag:LOCCELL_LOCALTIME_TAG] setText:@""];
348                        }
349                        if (prefsReverseGeo) {
350                                if (country) {
351                                        [(UILabel *)[cell viewWithTag:LOCCELL_COUNTRY_TAG] setText:country];
352                                        [(UIActivityIndicatorView *)[cell viewWithTag:LOCCELL_ACTIVITYINDICATOR_TAG] stopAnimating];
353                                } else {
354                                        if (geoLocDidFinish) {
355                                                [(UILabel *)[cell viewWithTag:LOCCELL_COUNTRY_TAG] setText:@"Unknown Country"];
356                                                [(UIActivityIndicatorView *)[cell viewWithTag:LOCCELL_ACTIVITYINDICATOR_TAG] stopAnimating];
357                                        } else {
358                                                [(UIActivityIndicatorView *)[cell viewWithTag:LOCCELL_ACTIVITYINDICATOR_TAG] startAnimating];
359                                        }
360                                }
361                        } else {        // not prefsReverseGeo
362                                [(UILabel *)[cell viewWithTag:LOCCELL_COUNTRY_TAG] setText:@"(country lookup disabled)"];
363                                [(UIActivityIndicatorView *)[cell viewWithTag:LOCCELL_ACTIVITYINDICATOR_TAG] stopAnimating];
364                        }
365                       
366                        [(UILabel *)[cell viewWithTag:LOCCELL_LATLONG_TAG] setText:[NSString stringWithFormat:@"%.4f, %.4f",
367                                                                                                                                                theRec.coordinate.latitude, theRec.coordinate.longitude]];
368                        return cell;
369                }
370                        break;
371                       
372                default:
373                {
374                        UITableViewCell *cell = nil;
375                        return cell;
376                }
377                        break;
378        }
379}
380
381#pragma mark ---------- Table view Delegate methods ----------
382
383// Row selection actions:
384//  - terminal naptr: fire off the url, and let the OS handle it
385//  - non-terminal naptr: query that domain
386//  - loc: display the mapview
387- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
388        NSUInteger row = indexPath.row;
389        if (row != NSNotFound) {
390                [tableView deselectRowAtIndexPath:indexPath animated:NO];
391                switch (indexPath.section) {
392                        case SECTION_NAPTR:
393                        {
394                                RecordNaptr *naptr = [self.naptrArray objectAtIndex:row];
395                                if (naptr.isTerminal) {
396                                        [self actOnUri:naptr.uriContent];
397                                } else {
398                                        // Non-Terminal NAPTR
399                                        NaptrViewController *newDetailsViewController = [[[NaptrViewController alloc] initWithNibName:@"TelView"
400                                                                                                                                                                                                                  bundle:[NSBundle mainBundle]]
401                                                                                                                                         autorelease];
402                                        [newDetailsViewController setupWithTel:naptr.uriContent];
403                                        [tableView deselectRowAtIndexPath:indexPath animated:NO];
404                                        [self.navigationController pushViewController:newDetailsViewController animated:YES];
405                                }
406                        }
407                                break;
408                        case SECTION_LOC:
409                        {
410                                RecordLoc *loc = [locArray objectAtIndex:row];
411                                FriendsMapViewController *fMVC = [FriendsMapViewController sharedInstance];
412                                fMVC.initialLoc = loc;
413                                if ([abId integerValue] == NSUIntegerMax) {     // not one of our address book .tel domains
414                                        [fMVC setMarkerWithABRecordId:self.abId title:nil telname:self.title location:loc];
415                                } else {
416                                        NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
417                                        if (![defaults boolForKey:@"startupLocatePreference"]) {
418                                                // need to draw the marker, as we didn't locate the user earlier
419                                                NSString *personName = [[FriendsData sharedInstance] getNameForABRecordId:self.abId];
420                                                [fMVC setMarkerWithABRecordId:abId title:personName telname:self.title location:loc];
421                                        }
422                                }
423                                [tableView deselectRowAtIndexPath:indexPath animated:NO];
424                                [self.navigationController pushViewController:fMVC animated:YES];
425                        }
426                                break;
427                        default:
428                                break;
429                }
430        }
431}
432
433- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
434        switch (indexPath.section) {
435                case SECTION_HEADER:
436                {
437                        return [headerText cellHeightForFont:headerFont paddingWidth:10.0f Height:10.0f];
438                }
439                case SECTION_TXT:
440                {
441                        RecordTxt *theRec = [self.txtArray objectAtIndex:indexPath.row];
442                        return [theRec.textValue cellHeightForFont:txtFont paddingWidth:10.0f Height:18.0f];
443                }
444                default:
445                        return (CGFloat)44.0;
446        }
447}
448
449/*
450- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath {
451       
452        if (editingStyle == UITableViewCellEditingStyleDelete) {
453        }
454        if (editingStyle == UITableViewCellEditingStyleInsert) {
455        }
456}
457*/
458/*
459- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath {
460        return YES;
461}
462*/
463/*
464- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath {
465}
466*/
467/*
468- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath {
469        return YES;
470}
471*/
472
473#pragma mark ------ Custom Data Methods
474
475- (NSString *)telFromQueryString:(NSString *)query {
476        if (!query)
477                return nil;
478        NSMutableString *qry = [NSMutableString stringWithString:query];
479        if ([qry length] == 0)
480                return nil;
481        if ([qry hasPrefix:@"http://"]) {
482                [qry deleteCharactersInRange:NSMakeRange(0, [@"http://" length])];
483        } else if ([qry hasPrefix:@"https://"]) {
484                [qry deleteCharactersInRange:NSMakeRange(0, [@"https://" length])];
485        }
486        if ([qry hasPrefix:@"www."]) {
487                [qry deleteCharactersInRange:NSMakeRange(0, [@"www." length])];
488        }
489        if ([qry hasPrefix:@"+"]) {
490                // Check if it's a phone number, try the sip version
491                BOOL isValidNumber = YES;
492                NSMutableString *enumStr = [NSMutableString stringWithCapacity:30];
493                NSRange prefixR = NSMakeRange(0, 0);
494                for (int i = 1; i < [qry length]; i++) {
495                        unichar aChar = [qry characterAtIndex:i];
496                        if ((aChar < 47) || (aChar > 58)) {     // Not in range of Unicode digits 0-9
497                                isValidNumber = NO;
498                                break;
499                        }
500                        [enumStr replaceCharactersInRange:prefixR withString:[NSString stringWithFormat:@"%c.", aChar]];
501                }
502                if (isValidNumber) {
503                        [enumStr appendString:@"e164.arpa"];
504                        qry = enumStr;
505                }
506        } else if ([qry hasSuffix:@".tel"]) {
507                // .tel domain, do nothing
508        } else if ([qry hasSuffix:@".e164.arpa"]) {
509                // ENUM domain, let's add support for it, why not!
510                // Superbook will be the best ENUM client too! :)
511        } else {
512                qry = [NSString stringWithFormat:@"%@.tel", qry];
513        }
514        return qry;
515}
516
517- (void)getNaptrForTel:(NSString *)telName {
518        NSError *error = nil;
519        [[NetworkUtility sharedInstance] networkwillActivate:YES];
520        DnsResolver *res = [[DnsResolver alloc] init];
521        NSUInteger naptrCount = [res getNAPTRForTel:telName inArray:self.naptrArray withError:&error];
522        [res release];
523        if (naptrCount == 0) {
524#ifdef DEBUG
525                NSLog(@"Warning: Error or No NAPTR records in domain %@", telName);
526#endif
527        }
528        [[NetworkUtility sharedInstance] networkwillActivate:NO];
529        [self decrementLoadingCount];
530        [self.theTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
531        if (error) {
532                // Show all errors unless the answer is invalid, which generally means there aren't any NAPTRs
533                if ([error code] != RESOLVER_STATUS_INVALID_ANSWER) {
534                        [self showError:error];
535                }
536        }
537}
538
539- (void)getTxtForTel:(NSString *)telName {
540        NSError *error = nil;
541        [[NetworkUtility sharedInstance] networkwillActivate:YES];
542        DnsResolver *res = [[DnsResolver alloc] init];
543        self.headerText = [res getTXTForTel:telName inArray:self.txtArray withError:&error];
544        [res release];
545        [[NetworkUtility sharedInstance] networkwillActivate:NO];
546        [self decrementLoadingCount];
547        [self.theTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
548}
549
550- (void)getLocForTel:(NSString *)telName {
551        NSError *error = nil;
552        [[NetworkUtility sharedInstance] networkwillActivate:YES];
553        DnsResolver *res = [[DnsResolver alloc] init];
554        NSUInteger locCount = [res getLOCForTel:telName inArray:self.locArray withError:&error];
555        [res release];
556        [[NetworkUtility sharedInstance] networkwillActivate:NO];
557        [self decrementLoadingCount];   // Don't wait for reverse geo to say we're done, that's a bonus
558        if (locCount > 1) {
559                //NSLog(@"Warning: %d LOC records in domain %@", locCount, telName);
560        }
561        [self.theTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
562        if (locCount > 0) {
563                if (prefsReverseGeo) {
564                        // and now look up the timezone and other goodies that take a while because they use the web
565                        [[NetworkUtility sharedInstance] networkwillActivate:YES];
566                        [self getCountryAndTimeZoneForLoc:(RecordLoc *)[self.locArray objectAtIndex:0]];
567                        [[NetworkUtility sharedInstance] networkwillActivate:NO];
568                        [self.theTable performSelectorOnMainThread:@selector(reloadData) withObject:nil waitUntilDone:YES];
569                }
570        }
571}
572
573- (void) getNaptrInBackgroundForTel:(NSString *)telName {
574        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
575        [self getNaptrForTel:telName];
576        [pool release];
577}
578
579- (void) getTxtInBackgroundForTel:(NSString *)telName {
580        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
581        [self getTxtForTel:telName];
582        [pool release];
583}
584
585- (void) getLocInBackgroundForTel:(NSString *)telName {
586        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
587        [self getLocForTel:telName];
588        [pool release];
589}
590
591- (void)getCountryAndTimeZoneForLoc:(CLLocation *)aLoc {
592        // Get country and timezone
593        // Don't get current time because the url may be cached. Use the timezone to regenerate the current time
594        NSString *uS = [NSString stringWithFormat:@"http://ws.geonames.org/timezone?lat=%f&lng=%f",
595                                        aLoc.coordinate.latitude, aLoc.coordinate.longitude];
596        NSURL *url = [NSURL URLWithString:uS];
597        NSURLRequest *urlReq = [NSURLRequest requestWithURL:url
598                                                                                        cachePolicy:NSURLRequestReturnCacheDataElseLoad
599                                                                                timeoutInterval:60.0];
600        NSHTTPURLResponse *response = [[[NSHTTPURLResponse alloc]
601                                                                        initWithURL:url
602                                                                        MIMEType:@"text/xml"
603                                                                        expectedContentLength:1024
604                                                                        textEncodingName:nil] autorelease];
605        NSError *error;
606        NSData *tzData = [NSURLConnection sendSynchronousRequest:urlReq
607                                                                                   returningResponse:&response
608                                                                                                           error:&error];
609        if (tzData) {
610                // Got data
611                NSString *sData = [[NSString alloc] initWithData:tzData encoding:NSUTF8StringEncoding];
612                // Now get country
613                NSRange rC1 = [sData rangeOfString:@"<countryName>"];
614                if (rC1.location != NSNotFound) {
615                        NSRange rC2 = [sData rangeOfString:@"</countryName>"];
616                        if (rC2.location != NSNotFound) {
617                                NSRange rC = NSMakeRange(rC1.location+rC1.length, rC2.location - (rC1.location+rC1.length));
618                                self.country = [sData substringWithRange:rC];
619                        }
620                }
621                // And get timezone
622                NSRange rTZ1 = [sData rangeOfString:@"<timezoneId>"];
623                if (rTZ1.location != NSNotFound) {
624                        NSRange rTZ2 = [sData rangeOfString:@"</timezoneId>"];
625                        if (rTZ2.location != NSNotFound) {
626                                NSRange rTZ = NSMakeRange(rTZ1.location+rTZ1.length, rTZ2.location - (rTZ1.location+rTZ1.length));
627                                self.timeZone = [NSTimeZone timeZoneWithName:[sData substringWithRange:rTZ]];
628                        }
629                }
630                [sData release];
631        }
632        geoLocDidFinish = YES;
633}
634
635#pragma mark ------ Methods to handle URI actions
636
637- (void)actOnUri:(NSString *)uri {
638        if (!uri)
639                return;
640        if ([uri hasPrefix:@"tel:"]) {
641                // if a telephone number, ask if we want to send SMS.
642                // Plus, this acts as a user acceptance to call or not
643                UIActionSheet *actionSheet = [[UIActionSheet alloc] initWithTitle:uri
644                                                                                                                                 delegate:self
645                                                                                                                cancelButtonTitle:nil
646                                                                                                   destructiveButtonTitle:nil
647                                                                                                                otherButtonTitles:nil];
648                callButtonIndex = [actionSheet addButtonWithTitle:LocStr(@"Call this number")];
649                smsButtonIndex = [actionSheet addButtonWithTitle:LocStr(@"Send an SMS Message")];
650                actionSheet.cancelButtonIndex = [actionSheet addButtonWithTitle:LocStr(@"Cancel")];
651                [actionSheet showInView:self.view];
652                [actionSheet release];
653        } else if ([uri hasPrefix:@"http:"] || [uri hasPrefix:@"https:"]) {
654                WebUrlViewController *wVC = [[[WebUrlViewController alloc] initWithNibName:@"WebUrlView" bundle:nil] autorelease];
655                wVC.title = LocStr(@"Web View");
656                [self.navigationController pushViewController:wVC animated:YES];
657                [wVC showPage:uri];
658        } else {
659                // directly act on anything not a number or url
660                NSURL *naptrUrl = [NSURL URLWithString:uri];
661                [[UIApplication sharedApplication] openURL:naptrUrl];
662        }
663}
664
665- (void)actionSheet:(UIActionSheet *)actionSheet clickedButtonAtIndex:(NSInteger)buttonIndex {
666        if (buttonIndex == actionSheet.cancelButtonIndex) {
667                // Clicked cancel
668                return;
669        }
670        NSURL *naptrUrl;
671        NSString *uri = [actionSheet title];
672    if (buttonIndex == callButtonIndex) {
673                naptrUrl = [NSURL URLWithString:[uri stringByAddingPercentEscapesUsingEncoding:NSASCIIStringEncoding]];
674                [[UIApplication sharedApplication] openURL:naptrUrl];
675        } else if (buttonIndex == smsButtonIndex) {
676                NSRange telPrefixRange = [uri rangeOfString:@"tel:"];
677                naptrUrl = [NSURL URLWithString:[uri stringByReplacingCharactersInRange:telPrefixRange withString:@"sms:"]];
678                [[UIApplication sharedApplication] openURL:naptrUrl];
679    }
680        return;
681}
682
683#pragma mark ------ Methods to save a contact
684
685- (IBAction)saveContact:(id)sender {
686        if (abD)
687                [abD release];
688        abD = [[DotTelABDelegate alloc] initWithViewController:self telName:self.title];
689        abD.naptrArray = self.naptrArray;
690        abD.txtArray = self.txtArray;
691        NSError *err;
692        if ([abId integerValue] == NSUIntegerMax) {     // not one of our address book .tel domains
693                err = [abD saveRecord];
694        } else {
695                err = [abD saveRecordWithRecordId:[abId integerValue]];
696        }
697        if (err) {
698                NSLog([err localizedDescription]);
699        }
700}
701
702#pragma mark ------ Error Methods
703
704- (void)showError:(NSError *)error {
705        if (![NSThread isMainThread]) {
706                [self performSelectorOnMainThread:_cmd
707                                                           withObject:error
708                                                        waitUntilDone:NO];
709                return;
710        }       
711        UIAlertView *errAlert = [[UIAlertView alloc] initWithTitle:@"Error"
712                                                                                                           message:[error localizedDescription]
713                                                                                                          delegate:nil cancelButtonTitle:@"OK"
714                                                                                         otherButtonTitles:nil];
715        [errAlert show];
716        [errAlert release];
717}       
718@end
719
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