This is a very simple way to pass parameters between various views.
1st in the appDelegate.m file add;
// NSUserDefault setup for passing info around the app the starting default values.
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"list_filtered"];
[[NSUserDefaults standardUserDefaults] setInteger:1 forKey:@"selected_spreadsheet"];
[[NSUserDefaults standardUserDefaults] setInteger:0 forKey:@"selected_map_type"];
[[NSUserDefaults standardUserDefaults] setObject:@"ALL" forKey:@"selected_driver"];
[[NSUserDefaults standardUserDefaults] setObject:@"initialString" forKey:@"selected_plist"];
[[NSUserDefaults standardUserDefaults] setObject:@"initialDictionary" forKey:@"selected_member"];
[[NSUserDefaults standardUserDefaults] setObject:@"selectedIndexPath" forKey:@"selected_indexPath"];
// sync the defaults to disk
[[NSUserDefaults standardUserDefaults] registerDefaults:appDefaults];
[[NSUserDefaults standardUserDefaults] synchronize];
Try the search, it's linked to some great forums
Showing posts with label Xcode. Show all posts
Showing posts with label Xcode. Show all posts
Friday, November 13, 2015
Friday, July 24, 2015
WG Tutorial draft - ArcGIS Vector Layers
ESRI's ArcGIS platform has a huge number of datasets, as well as the ability to generate your own thru the ArcGIS application. Here are a few examples of what we're going to build today.
You’ll need a sample project for this tutorial. Go back and start with the Hello Earth tutorial and work thru the CartoDB Tutorial. We’ll want the tiling logic from that tutorial. If you'd rather just get started with those files, you can download them here;
OK to summarize, in this app we're are going to utilize remote datasets from ESRI's (that's the Environmental Systems Research Institute, I just finally learned) ArcGIS website. ArcGIS is the premier GIS application out there, and it's used by everyone. Check it out, join, whatever, but you'll have to do it on your own time.
In this app, we are going to load one of their great base maps a National Geographic globe found here.
And as a second act we are going to access one of their vector data sets showing New York City's flood zones found here.
As mentioned above, we're not going to get into much of the details of ArcGIS or how the Hello Earth vector tiling works, that's detailed elsewhere. So, let's get setup. I changed the CartoDB files to ArcGISLayer, and it's associated method to addVectors, just to be pedantic about it. Run the app and you should get the CartoDB view of NYC's landlords or whatever. If not, make it so.
you also need to adjust the maxZoom value (in this case - 17) and make sure the ext:file is png. The /tile/{z}/{y}/{x} appended to the end of the URL is a specific requirement of ??Whatever??
Run the app, zoom way out, and you should get a great rendition of everyone's favorite Nat Geo globe. Easy Peasey!
Next up - Vector Layers
Vector layers are datasets that return polygons, attributes and other things. The mechanics of how WhirlyGlobe handles this data is thoroughly detailed in the CartoDB tutorial, and you should review that there if you like. Here today we are simply going to replace the CartoDB data with data from ArcGIS, specifically showing the various different flood zones in the NYC area. We'll also make a few other changes to make the displayed data pop! Here goes;
As discussed, we have created a CartoDBLayer object that conforms to the MaplyPagingDelegate. This object then queries the remote data source for the data required by the tiles displayed with the method startFetchForTile:forLayer:. This query is comprised of 2 portions, a URL for the remote server, and a SQL query that are joined together in the constructRequest method. Let's start by changing the URL to -
code chunk to find;
- (NSURLRequest *)constructRequest:(MaplyBoundingBox)bbox
{
// construct a query string
double toDeg = 180/M_PI;
NSString *query = [NSString stringWithFormat:search,bbox.ll.x*toDeg,bbox.ll.y*toDeg,bbox.ur.x*toDeg,bbox.ur.y*toDeg];
NSString *encodeQuery = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
encodeQuery = [encodeQuery stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
NSString *fullUrl = [NSString stringWithFormat:@"https://pluto.cartodb.com/api/v2/sql?format=GeoJSON&q=%@",encodeQuery];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:[NSURL URLWithString:fullUrl]];
return urlReq;
}
A we'll also need to change the query in the VController's addBuildings method
code chunk to find;
- (void)addBuildings
{
NSString *search = @"WHERE=Zone>=1&f=pgeojson&outSR=4326";
// NSString *search = @"SELECT the_geom,address,ownername,numfloors FROM mn_mappluto_13v1 WHERE the_geom && ST_SetSRID(ST_MakeBox2D(ST_Point(%f, %f), ST_Point(%f, %f)), 4326) LIMIT 2000;";
CartoDBLayer *cartoLayer = [[CartoDBLayer alloc] initWithSearch:search];
cartoLayer.minZoom = 13;
cartoLayer.maxZoom = 15;
outSR is the ouptpu spacial reference, and pgeojson also defines the output format.
Run the project, and you should see the layers for the flood zones. Not? OK, lets adjust a few things to see what's going on;
[NSURLConnection sendAsynchronousRequest:urlReq queue:opQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
NSLog(@"returned data length is %lu", (unsigned long)data.length);
Run the project again, and you should see some data displayed. It's not exactly what we want, but at least we know we're receiving data, Yay! Now lets clean up this bad boy.
Through the magic of files fiddling, we finally end up with -
Very pretty.
Here are the various completed files for your programming pleasure;
You’ll need a sample project for this tutorial. Go back and start with the Hello Earth tutorial and work thru the CartoDB Tutorial. We’ll want the tiling logic from that tutorial. If you'd rather just get started with those files, you can download them here;
- ViewController.m Your main view controller.
- CartoDBLayer.h CartoDBLayer header.
- CartoDBLayer.m CartoDBLayer implementation.
OK to summarize, in this app we're are going to utilize remote datasets from ESRI's (that's the Environmental Systems Research Institute, I just finally learned) ArcGIS website. ArcGIS is the premier GIS application out there, and it's used by everyone. Check it out, join, whatever, but you'll have to do it on your own time.
In this app, we are going to load one of their great base maps a National Geographic globe found here.
And as a second act we are going to access one of their vector data sets showing New York City's flood zones found here.
As mentioned above, we're not going to get into much of the details of ArcGIS or how the Hello Earth vector tiling works, that's detailed elsewhere. So, let's get setup. I changed the CartoDB files to ArcGISLayer, and it's associated method to addVectors, just to be pedantic about it. Run the app and you should get the CartoDB view of NYC's landlords or whatever. If not, make it so.
ArcGIS Base Map - National Geographic World Map
So first thing we're going to load up one of ArcGIS's base maps, the beautiful & revered National Geographic World Map. All we have to do change the URL reference in the existing code & the new map should appear, as if by magic. Find where that's done in viewDidLoad, and replace the URL string with this URL;
http://services.arcgisonline.com/arcgis/rest/services/NatGeo_World_Map/MapServer
code chunk to find;
// Portions Courtesy NASA/JPLCaltech and U.S. Depart. of Agriculture, Farm Service Agency
MaplyRemoteTileSource *tileSource = [[MaplyRemoteTileSource alloc]
initWithBaseURL:@"http://services.arcgisonline.com/arcgis/rest/services/ NatGeo_World_Map/MapServ/tile/{z}/{y}/{x}"
ext:@"png" minZoom:0 maxZoom:maxZoom];
MaplyRemoteTileSource *tileSource = [[MaplyRemoteTileSource alloc]
initWithBaseURL:@"http://services.arcgisonline.com/arcgis/rest/services/ NatGeo_World_Map/MapServ/tile/{z}/{y}/{x}"
ext:@"png" minZoom:0 maxZoom:maxZoom];
you also need to adjust the maxZoom value (in this case - 17) and make sure the ext:file is png. The /tile/{z}/{y}/{x} appended to the end of the URL is a specific requirement of ??Whatever??
Run the app, zoom way out, and you should get a great rendition of everyone's favorite Nat Geo globe. Easy Peasey!
Next up - Vector Layers
Vector layers are datasets that return polygons, attributes and other things. The mechanics of how WhirlyGlobe handles this data is thoroughly detailed in the CartoDB tutorial, and you should review that there if you like. Here today we are simply going to replace the CartoDB data with data from ArcGIS, specifically showing the various different flood zones in the NYC area. We'll also make a few other changes to make the displayed data pop! Here goes;
As discussed, we have created a CartoDBLayer object that conforms to the MaplyPagingDelegate. This object then queries the remote data source for the data required by the tiles displayed with the method startFetchForTile:forLayer:. This query is comprised of 2 portions, a URL for the remote server, and a SQL query that are joined together in the constructRequest method. Let's start by changing the URL to -
http://services.arcgis.com/OfH668nDRN7tbJh0/ArcGIS/rest/services/NYCEvacZones2013/FeatureServer
in the CartoDBLayer constructRequest codecode chunk to find;
- (NSURLRequest *)constructRequest:(MaplyBoundingBox)bbox
{
// construct a query string
double toDeg = 180/M_PI;
NSString *query = [NSString stringWithFormat:search,bbox.ll.x*toDeg,bbox.ll.y*toDeg,bbox.ur.x*toDeg,bbox.ur.y*toDeg];
NSString *encodeQuery = [query stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
encodeQuery = [encodeQuery stringByReplacingOccurrencesOfString:@"&" withString:@"%26"];
NSString *fullUrl = [NSString stringWithFormat:@"https://pluto.cartodb.com/api/v2/sql?format=GeoJSON&q=%@",encodeQuery];
NSURLRequest *urlReq = [NSURLRequest requestWithURL:[NSURL URLWithString:fullUrl]];
return urlReq;
}
A we'll also need to change the query in the VController's addBuildings method
code chunk to find;
- (void)addBuildings
{
NSString *search = @"WHERE=Zone>=1&f=pgeojson&outSR=4326";
// NSString *search = @"SELECT the_geom,address,ownername,numfloors FROM mn_mappluto_13v1 WHERE the_geom && ST_SetSRID(ST_MakeBox2D(ST_Point(%f, %f), ST_Point(%f, %f)), 4326) LIMIT 2000;";
CartoDBLayer *cartoLayer = [[CartoDBLayer alloc] initWithSearch:search];
cartoLayer.minZoom = 13;
cartoLayer.maxZoom = 15;
outSR is the ouptpu spacial reference, and pgeojson also defines the output format.
Run the project, and you should see the layers for the flood zones. Not? OK, lets adjust a few things to see what's going on;
- Change the mni/maxZoom levels = 9 to 13
- Modify the initial zoom level to 0.008
- query for a single zone>=4
- Also let's add in a NSLog statement to see if data is being returned
[NSURLConnection sendAsynchronousRequest:urlReq queue:opQueue completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError)
{
NSLog(@"returned data length is %lu", (unsigned long)data.length);
Run the project again, and you should see some data displayed. It's not exactly what we want, but at least we know we're receiving data, Yay! Now lets clean up this bad boy.
Through the magic of files fiddling, we finally end up with -
![]() |
Tweaking the app to make it look Good! |
Here are the various completed files for your programming pleasure;
- ViewController.m
- ArcGISLayer.h
- ArcGISLayer.m
Friday, July 17, 2015
Simple Database creation for Apps
This is my quick go to for creating a data file to use in an app. There are other better, quicker and more complex, but this is quick & easy/peasey!

That's all she wrote.
- Create a CSV file in the speadsheet of your choice. I use either Google's or OpenOffice.
- Run the file thru my favorite converter - Plist Converter, by cc ccc. It's also easy. Couldn't find the url, but here's what it looks like;
- Copy the resultant fileName.plist into your project.
- Write yourself some code to translae it into an NSArray or somethin'.
That's all she wrote.
Saturday, July 11, 2015
WhirlyGlobe view objects
Here are a few screenshots of the various objects in Maply-WhirlyGlobe (beautiful stuff!);
MaplyMarker MaplyBillboard MaplyScreenMarker
MaplyScreenMarker - 2D, anchored to a MaplyCoordinate point (lat, long), CGSize 100, 100
MaplyMarker - 3D, anchored to a MaplyCoordinate point (lat, long), size is % of Globe = 1.0
MaplyBillboard - A whole 'nudder thing
Feed your images into an NSArray, then add [theViewC addScreenMarkers:theMarkers desc:nil]; and your in!
Here's the resultant Globe with geolocated pics.
MaplyMarker MaplyBillboard MaplyScreenMarker
MaplyScreenMarker - 2D, anchored to a MaplyCoordinate point (lat, long), CGSize 100, 100
MaplyMarker - 3D, anchored to a MaplyCoordinate point (lat, long), size is % of Globe = 1.0
MaplyBillboard - A whole 'nudder thing
Feed your images into an NSArray, then add [theViewC addScreenMarkers:theMarkers desc:nil]; and your in!
Here's the resultant Globe with geolocated pics.
Saturday, January 17, 2015
Facebook Integration notes
Notes & research;
FB Graph API URL - https://developers.facebook.com/docs/graph-api/common-scenarios
From FBs documentation
Good Wenderlich tutorial - http://www.raywenderlich.com/1626/facebook-tutorial-for-ios-how-to-post-to-a-user-wall-upload-photos-and-add-a-like-button-from-your-iphone-app
More Info from FBs API
Stunning example of FBs Story photo album I take back what I said about FBs slideshow features!
https://www.facebook.com/fanpage.it/posts/945924002095941
FB Graph API URL - https://developers.facebook.com/docs/graph-api/common-scenarios
From FBs documentation
Other links:Uploading Photos and Creating Photo AlbumsApps are able to publish and create new photo albums, and publish photos via the Graph API on behalf of people or Facebook Pages. Photos can be uploaded by sending the actual image files, or by using URLs of images already on the internet.
Read These Docs
Use These APIs
- Platform Policies that cover publishing behavior in apps.
- Guide to Publishing with the Graph API.
/{user-id}/albums
to create empty photo albums for people./{user-id}/photos
to add individual photos for people./{page-id}/albums
to create empty photo albums for Facebook Pages./{page-id}/photos
to add individual photos for Facebook Pages./{album-id}/photos
to add photos to an existing album for people or for Pages.
Good Wenderlich tutorial - http://www.raywenderlich.com/1626/facebook-tutorial-for-ios-how-to-post-to-a-user-wall-upload-photos-and-add-a-like-button-from-your-iphone-app
More Info from FBs API
FBs tutorial for an Open Graph Story integration - https://developers.facebook.com/docs/ios/open-graphTelling Stories with Open GraphOpen Graph lets apps tell stories on Facebook through a structured, strongly typed API.
People use stories to share the things they're doing, the people they're doing them with and the places where they happen. Open Graph lets you integrate apps deeply into the Facebook experience, which increases engagement, distribution and growth.
Stunning example of FBs Story photo album I take back what I said about FBs slideshow features!
https://www.facebook.com/fanpage.it/posts/945924002095941
Monday, December 29, 2014
Keyboard configuration
The following will hide a keyboard nicely;
// Hides a keyboard by use of an invisible button on view
// configure UIButton - Custom, no title & size over touch area
-(IBAction)hideButton:(UIButton *)sender
{
NSLog(@"Hides the keyboard");
[self.view endEditing:YES];
}
Here's another way that's less of a cludge;
It sets up a gesture for the view
1- Set the .h file to <UIGestureRecognizerDelegate>
2 - Add this to the viewDidLoad to set up the gestureRecognizer
// Tap to hide keyboard
UITapGestureRecognizer *hideKeyboardTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideTap:)];
[self.view addGestureRecognizer:hideKeyboardTap];
Probably the BEST way;
1 - Don't forget to set the class as a UITextFieldDelegate
2- Add to viewDidLoad for all textFields - self.textField.delegate = self;
3 - And finally the delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
3 - Add this method
- (void)hideTap:(UIGestureRecognizer *)gestureRecognizer
{
[self.view endEditing:YES];
NSLog(@"Hides the keyboard");
}
// Hides a keyboard by use of an invisible button on view
// configure UIButton - Custom, no title & size over touch area
-(IBAction)hideButton:(UIButton *)sender
{
NSLog(@"Hides the keyboard");
[self.view endEditing:YES];
}
Here's another way that's less of a cludge;
It sets up a gesture for the view
1- Set the .h file to <UIGestureRecognizerDelegate>
2 - Add this to the viewDidLoad to set up the gestureRecognizer
// Tap to hide keyboard
UITapGestureRecognizer *hideKeyboardTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(hideTap:)];
[self.view addGestureRecognizer:hideKeyboardTap];
Probably the BEST way;
1 - Don't forget to set the class as a UITextFieldDelegate
2- Add to viewDidLoad for all textFields - self.textField.delegate = self;
3 - And finally the delegate method
- (BOOL)textFieldShouldReturn:(UITextField *)textField
{
[textField resignFirstResponder];
return YES;
}
3 - Add this method
- (void)hideTap:(UIGestureRecognizer *)gestureRecognizer
{
[self.view endEditing:YES];
NSLog(@"Hides the keyboard");
}
Thursday, July 24, 2014
iOS Constraints and view layouts
iOS 5 has a nicely implemented auto layout feature called constraints. This posting provides a quickstart tutorial plus tips & hints. As usual Ray Wenderlich has a great intro tutorial that I used.
It seems the big secret is this button at the bottom of the storyboard. This button will allow Xcode to resolve most of your layout issues. If you still have problems check out the video tutorial - Beginning Auto Layout by Ray Wenderlich
The Auto Resolve Layout button displays the following selections;
Use - Reset to Suggested Constraints in ......... , to allow Xcode to resolve the constraints.
Small blue lines indicate that this view is properly laid out.
Orange lines & text indicate conflicting contraints that need fixing
This screenshot shows both the good (blue) & bad (orange) layouts described above.
I fixed the Map cell layout by;

It seems the big secret is this button at the bottom of the storyboard. This button will allow Xcode to resolve most of your layout issues. If you still have problems check out the video tutorial - Beginning Auto Layout by Ray Wenderlich
I fixed the Map cell layout by;
- selecting Clear all restraints in tableview cell
- manually dragging the label & image around for a basic layout
- selecting Reset to suggested restraints in .........
Easy - Peasey !
Subscribe to:
Posts (Atom)