-(void)viewDidLoad{connection=[[NSURLConnectionalloc]initWithRequest:[NSURLRequestrequestWithURL:[NSURLURLWithString:@"http://www.cwb.gov.tw/V7/prevent/typhoon/Data/PTA_NEW/js/datas/ty_infos.js"]]delegate:selfstartImmediately:YES];}#pragma mark NSURLConnection delegate-(void)connection:(NSURLConnection*)connectiondidReceiveResponse:(NSURLResponse*)response{connectionData=[[NSMutableDataalloc]init];}-(void)connection:(NSURLConnection*)connectiondidReceiveData:(NSData*)data{[connectionDataappendData:data];}-(void)connectionDidFinishLoading:(NSURLConnection*)connection{// process connection data here.}-(void)connection:(NSURLConnection*)connectiondidFailWithError:(NSError*)error{connectionData=nil;}
Process data
Read data as string.
Get JSON from JavaScript using regular expression.
Use NSJSONSerialization to parse JSON
Parsed data is combination of NSArray, NSDictionary, NSString,
NSNumber, and NSNull.
-(void)connectionDidFinishLoading:(NSURLConnection*)connection{NSString*ty_infos=[[NSStringalloc]initWithData:connectionDataencoding:NSUTF8StringEncoding];connectionData=nil;NSError*err=nil;NSRegularExpression*regex=[NSRegularExpressionregularExpressionWithPattern:@"\\[.+?\\];"options:NSRegularExpressionDotMatchesLineSeparatorserror:&err];NSRangerange_of_match=[regexrangeOfFirstMatchInString:ty_infosoptions:NSRegularExpressionDotMatchesLineSeparatorsrange:NSMakeRange(0,ty_infos.length)];NSString*json=[ty_infossubstringWithRange:NSMakeRange(range_of_match.location,range_of_match.length-1)];NSArray*arr=[NSJSONSerializationJSONObjectWithData:[jsondataUsingEncoding:NSUTF8StringEncoding]options:0error:nil];for(NSDictionary*typhooninarr){// Use autoreleasepool to release temporary objects@autoreleasepool{size_tlength=[[typhoonvalueForKey:@"fcst"]count]+[[typhoonvalueForKey:@"best_track"]count];CLLocationCoordinate2D*line_points=(CLLocationCoordinate2D*)malloc(length*sizeof(CLLocationCoordinate2D));inti=0;for(NSDictionary*trackin[typhoonvalueForKey:@"best_track"]){CGFloatlat=[[trackvalueForKey:@"lat"]floatValue];CGFloatlon=[[trackvalueForKey:@"lon"]floatValue];CLLocationCoordinate2Dlocation=CLLocationCoordinate2DMake(lat,lon);line_points[i++]=location;MKPointAnnotation*centerPoint=[[MKPointAnnotationalloc]init];centerPoint.coordinate=location;[self.mapViewaddAnnotation:centerPoint];}for(NSDictionary*fcstin[typhoonvalueForKey:@"fcst"]){CGFloatlat=[[fcstvalueForKey:@"lat"]floatValue];CGFloatlon=[[fcstvalueForKey:@"lon"]floatValue];CGFloatrad=[[fcstvalueForKey:@"pr70"]floatValue];CLLocationCoordinate2Dlocation=CLLocationCoordinate2DMake(lat,lon);line_points[i++]=location;MKCircle*cir=[MKCirclecircleWithCenterCoordinate:locationradius:rad*1000];[self.mapViewaddOverlay:cir];MKPointAnnotation*centerPoint=[[MKPointAnnotationalloc]init];centerPoint.coordinate=location;[self.mapViewaddAnnotation:centerPoint];}MKPolyline*line=[MKPolylinepolylineWithCoordinates:line_pointscount:length];[self.mapViewaddOverlay:line];free(line_points);}}}
MapKit
MapKit is simular to most UI elements. You setup a MKMapView, add data
(MKAnnotation, MKOverlay, …etc.) to it, and handle drawing delegate methods.
This is a prototype app, so I only use built-in MKPointAnnotation and
MKPolyline overlay. If you want to assign custom properties to annotation or
overlays, you can subclass them and implement drawing functions in delegate.
1234567891011121314151617181920212223242526272829
#pragma mark Map View Delegate methods-(MKOverlayView*)mapView:(MKMapView*)mapViewviewForOverlay:(id<MKOverlay>)overlay{if([overlayisKindOfClass:[MKCircleclass]]){MKCircleView*view=[[MKCircleViewalloc]initWithCircle:overlay];view.fillColor=[[UIColorredColor]colorWithAlphaComponent:0.02];view.strokeColor=[[UIColorredColor]colorWithAlphaComponent:0.15];view.lineWidth=2;returnview;}elseif([overlayisKindOfClass:[MKPolylineclass]]){MKPolylineView*view=[[MKPolylineViewalloc]initWithPolyline:overlay];view.strokeColor=[[UIColorblackColor]colorWithAlphaComponent:0.2];view.lineWidth=2;returnview;}returnnil;}-(MKAnnotationView*)mapView:(MKMapView*)mViewviewForAnnotation:(id<MKAnnotation>)annotation{NSString*identifier=@"pinView";MKAnnotationView*annotationView=(MKAnnotationView*)[mViewdequeueReusableAnnotationViewWithIdentifier:identifier];if(annotationView==nil){annotationView=[[MKAnnotationViewalloc]initWithAnnotation:annotationreuseIdentifier:identifier];UIImage*img=[UIImageimageNamed:@"typh.png"];annotationView.image=img;annotationView.canShowCallout=NO;}returnannotationView;}
That’s it. Now we have a native interface to show typhoon prediction!