I know that we can use the CoreLocation API in the AppleWatchKit code itself. But still, from the documentation, I read that the fetching of locations should be done only in the parent app and not in the watch app. Which is the standard way for doing this?
My requirement is simple. I need to show an annotation for the user location.
Get location like this in Apple Watch:
CLLocationManager *locationManager = [[CLLocationManager alloc]init];
locationManager.delegate = self;
locationManager.distanceFilter = kCLDistanceFilterNone;
locationManager.desiredAccuracy = kCLLocationAccuracyBest;
[locationManager startUpdatingLocation];
location = [locationManager location];
coordinate = [location coordinate];
latitude = [NSString stringWithFormat:#"%f", coordinate.latitude];
longitude = [NSString stringWithFormat:#"%f", coordinate.longitude];
Set annotation like this:
CLLocationCoordinate2D mapLocation = CLLocationCoordinate2DMake([lati floatValue], [longi floatValue]);
MKCoordinateSpan coordinateSpan = MKCoordinateSpanMake(1, 1);
[self.map setRegion:(MKCoordinateRegionMake(mapLocation, coordinateSpan))];
//For coloured pin
//[self.map addAnnotation:mapLocation withPinColor: WKInterfaceMapPinColorGreen];
[self.map addAnnotation:mapLocation withImage:[UIImage imageNamed:#"mapPin.png"] centerOffset:CGPointMake(0,-7)];
Here, "map" is the object of watchkit map.
Related
I am developing an iPhone app, where i have to monitor more then 20 Regions.
Development Environment: Xcode (Version 8.3.2)
IOS 10.3
please have a look at the code below:
I initialize my locationmanager :
- (id)init {
self = [super init];
if(self != nil) {
self.locationManager = [[CLLocationManager alloc] init];
// self.locationManager.distanceFilter = 100; // meters
self.locationManager.allowsBackgroundLocationUpdates = YES;
self.locationManager.delegate = self;
self.locationManager.desiredAccuracy = kCLLocationAccuracyBestForNavigation;
}
return self;
}
and then i start updating Location using below code:
- (void)startUpdatingLocation
{
NSLog(#"Starting location updates");
// Turn on location updates for accuracy and so processing can happen in the background.
[self.locationManager stopUpdatingLocation];
[self.locationManager startUpdatingLocation];
// Turn on significant location changes to help monitor the current region.
[self.locationManager startMonitoringSignificantLocationChanges];
}
- (void)locationManager:(CLLocationManager *)manager didUpdateLocations:(NSArray *)locations
{
if (locations.count > 0) {
//stop all monitored region
for (CLRegion *monitored in [self.locationManager monitoredRegions]){
[self.locationManager stopMonitoringForRegion:monitored];
}
CLLocation *location = locations[0];
NSArray *allGeoFences = [self getAllGeoFences];
NSMutableArray *sortedFences = [[NSMutableArray alloc] init];
// add distance to each fence to be sorted
for (locationInterface *geofence in allGeoFences) {
// create a CLLocation object from my custom object
//CLLocationCoordinate2D coordinate = CLLocationCoordinate2DMake(geofence.region., geofence.longitude);
CLLocation *fenceLocation = [[CLLocation alloc] initWithLatitude:
geofence.region.center.latitude
longitude:geofence.region.center.longitude];
// calculate distance from current location
CLLocationDistance distance = [location distanceFromLocation:fenceLocation];
// save distance so we can filter array later
geofence.distance = distance;
[sortedFences addObject:geofence];
}
// sort our array of geofences by distance and add we can add the first 20
NSSortDescriptor *sortByName = [NSSortDescriptor sortDescriptorWithKey:#"distance" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByName];
NSArray *sortedArray = [sortedFences sortedArrayUsingDescriptors:sortDescriptors];
//get nearest 20 regions
NSMutableArray *nearestRegions = [[NSMutableArray alloc] init];
for (int i = 1; i <= 20; i++) {
[nearestRegions addObject:sortedArray[i]];
locationInterface* monitorRegion = sortedArray[i];
[self.locationManager startMonitoringForRegion:monitorRegion.region] ;
}
}
}
When i receive didUpdateLocations , first i stop all the monitored regions, After that i find 20 nearest locations,and start monitoring the 20 nearest locations.
The problem that I am facing is monitoredRegions always returned nil.That is why I cannot stop monitoring the regions and my newly added regions get ignored.Please help me.
OK so I am attempting to add an array of SCNGeometry to an SCNMorpher object and add this object to the root node on a scene and export the result to a DAE file.
For some reason, whenever I attempt to save the file I get a BAD_ACCESS error on the writeToURL call.
This only happens if I set the node.morpher property. It happens even if I set the morpher property to [[SCNMorpher alloc] init]] or to an instance with an empty array of targets.
This is on a Mac app.
My code:
NSMutableArray *frames = [[NSMutableArray alloc] init];
for (int f=0; f<self.Animations[0].framesCount; f++) {
SCNGeometry *frameGeo = [self MorphedModel:self.Animations[0] atFrame:f+1];
SCNMaterial *framemat = [SCNMaterial material];
framemat.diffuse.contents = texture;
framemat.name = #"Dino Skin";
frameGeo.firstMaterial = framemat;
[frames addObject:frameGeo];
}
self.MorphedModels = [[SCNMorpher alloc] init];
self.MorphedModels.targets = [[NSArray alloc] initWithArray:frames];
node.morpher = self.MorphedModels;
SCNScene *scene = [SCNScene scene];
[scene.rootNode addChildNode:node];
NSString *path = [NSHomeDirectory() stringByAppendingPathComponent:#"Documents/Dino.dae"];
[scene writeToURL:[NSURL fileURLWithPath:path] options:nil delegate:nil progressHandler:nil];
Any ideas? I'm clueless at this point.
Ah I figured it out. There isn't any documentation on this but it makes sense. You have to set one of the targets to a full weight (1.0f) on your SCNMorpher instance:
[self.MorphedModels setWeight:1.0f forTargetAtIndex:0];
Once I did this, everything saved correctly.
I'm developing a beacon app which has a tour mode option. So when the user taps the switch to turn on the tour, I'm creating beacon regions and using below code I'm listening for beacons
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:beacon.beaconID];
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid major:[beacon.major integerValue] minor:[beacon.minor integerValue] identifier:beacon.identifier];
[self.locationManager startMonitoringForRegion:region];
region.notifyEntryStateOnDisplay = YES;
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
[self.locationManager startRangingBeaconsInRegion:region];
Now to stop the ranging, I know I have to use
[self.locationManager stopRangingBeaconsInRegion:region];
But how do I get the same CLBeaconRegion created for monitoring? Should I save the CLBeaconRegion in an array?
CLLocationManager has a property called rangedRegions which is an NSSet of all regions being currently ranged. So if you do something like:
for (CLBeaconRegion *region in self.locationManager.rangedRegions) {
[self.locationManager stopRangingBeaconsInRegion:region];
}
If you want to stop ranging all regions.
Let me tell you how can we first range for all available beacons then how to monitor a particular beacon.
NSUUID *uuid = [[NSUUID alloc] initWithUUIDString:beacon.beaconID];
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:uuid identifier:beacon.identifier];
[self.locationManager startRangingBeaconsInRegion:region];
This will give you all available beacons in Range which matches with uuid.
Then you need to start monitoring for a particular beacon.(say beacon)
CLBeaconRegion *region = [[CLBeaconRegion alloc] initWithProximityUUID:beacon.uuid major:[beacon.major integerValue] minor:[beacon.minor integerValue] identifier:beacon.identifier];
[self.locationManager startMonitoringForRegion:region];
region.notifyEntryStateOnDisplay = YES;
region.notifyOnEntry = YES;
region.notifyOnExit = YES;
This will notify you when you comes in or goes out from beacon region
Let me know if anything else you need
I am creating an app that pulls data from a server and pinpoints the different houses on a map. My problem is that it does display the annotations but when I click on them they do not respond
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
I put my annotations in an array by:
int s;
self.mapAnnotations = [[NSMutableArray alloc] init];
for(s=0; s < numberOfAnnotations; s++)
{
//NSDictionary *dict2 = [parser objectWithString:[[arrayOfResults objectAtIndex:0] description]];
CLLocationDegrees daLong = [[[[[arrayOfResults objectAtIndex:s] objectForKey:#"map"] objectForKey:#"longitude"] description] floatValue];
CLLocationDegrees daLat = [[[[[arrayOfResults objectAtIndex:s] objectForKey:#"map"] objectForKey:#"latitude"] description] floatValue];
/*self.customAnnotation = [[BasicMapAnnotation alloc] initWithLatitude:daLat andLongitude:daLong];
[self.mapView addAnnotation:self.customAnnotation];*/
BasicMapAnnotation *m = [[BasicMapAnnotation alloc] initWithLatitude:daLat andLongitude:daLong];
[self.mapAnnotations addObject:m];
}
[self.mapView addAnnotations:self.mapAnnotations];
NSLog(#"this number of annotations %d", [self.mapAnnotations count]);
I also noticed when I created a separate house to place on the map in my viewDidLoad:
self.normalAnnotation = [[BasicMapAnnotation alloc] initWithLatitude:38 andLongitude:-90.2045];
self.normalAnnotation.title = #" ";
[self.mapView addAnnotation:self.normalAnnotation];
It did work when I clicked on it, but the ones passed through the array didn't work.
Can anyone help me figure out why it's not responding?
That's because annotations should have a title for them to display a callout. In your for loop, set the title property like you did with self.normalAnnotation.title = #" ".
Im trying to implement your implementation to my project as a button called 'Gallery" but receive an error when trying to run the project.
My implementation file looks like this.
-(IBAction) gallery{
NSMutableArray *photos = [[NSMutableArray alloc] init];
MWPhoto *photo;
{
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans1" ofType:#"jpg"]];
photo.caption = #"My fans 1";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans2" ofType:#"jpg"]];
photo.caption = #"My fans 2";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans3" ofType:#"jpg"]];
photo.caption = #"Fans3";
[photos addObject:photo];
photo = [MWPhoto photoWithFilePath:[[NSBundle mainBundle] pathForResource:#"fans4" ofType:#"jpg"]];
photo.caption = #"Fans4";
[photos addObject:photo];
}
self.photos = photos;
// Create browser
MWPhotoBrowser *browser = [[MWPhotoBrowser alloc] initWithDelegate:self];
browser.displayActionButton = YES;
//browser.wantsFullScreenLayout = NO;
//[browser setInitialPageIndex:2];
// Show
if (_segmentedControl.selectedSegmentIndex == 0) {
// Push
[self.navigationController pushViewController:browser animated:YES];
} else {
// Modal
UINavigationController *nc = [[UINavigationController alloc] initWithRootViewController:browser];
nc.modalTransitionStyle = UIModalTransitionStyleCrossDissolve;
[self presentModalViewController:nc animated:YES];
}
}
#pragma mark - MWPhotoBrowserDelegate
- (NSUInteger)numberOfPhotosInPhotoBrowser:(MWPhotoBrowser *)photoBrowser {
return _photos.count;
}
- (MWPhoto *)photoBrowser:(MWPhotoBrowser *)photoBrowser photoAtIndex: (NSUInteger)index {
if (index < _photos.count)
return [_photos objectAtIndex:index];
return nil;
}
When I run the project but the image gallery is not displayed. Im fairly new to ioS development.If you can please point me in the right direction i will deeply appreciate it. The main goal is to have the image gallery displayed when the user touches the Gallery button.
I copied and edited the code from the MWPhotoBrowser Demo Project File I don't receive any errors but I can't get the gallery to appear once button is touched. (BTW I assigned the IBACTION to the buttons). If there is another source code or alternative Framework I can use please advise. Thanks!
Some Ideas:
1) try using 'initWithPhotos'.
2) put a breakpoint at the place you are pushing, check that the push is called.
3) check that the navigationController is not null (0x0) in debugging.
4) remember to release 'browser'.