How to get GPS coords on button click ? (most simple) - ios

i tried to implement GPS functionality into my app using the few tutorials.
I do it by using this:
http://www.tutorialspoint.com/ios/ios_location_handling.htm
Gps coords are obtained after start of the app.
But problem is that, i am not able to call GPS coords again after button click, it means somethong like:
- (IBAction)getGpsCoords:(id)sender {
[[LocationHandler getSharedInstance]setDelegate:self];
[[LocationHandler getSharedInstance]startUpdating];
}
How should be right solution? I will glad id somebody can explain how to do it better (with some good example or link).
Thanks for any advice.

It's not really clear what you're having difficulty doing. You don't say what LocationHandler is, but the flow is pretty much correct:
Start location services
A delegate method gets called periodically as the location information changes
You can't just tap a button and get the current location; that's not how the API works. I suppose you could start location services when the app starts and record the current location in a singleton (like your LocationHandler class?) and just call that when you press the button?

Related

gps alert the user when reaches the particular location

I am developing the location based application. I just stop the location manager when user reaches the particular location(which is selected by user). I have tried in all combinations but no luck.Please help me on this.
Thanks in advance.
What you are looking for is called Geofencing.
It's built-in in CoreLocation and really easy to use.
Have a look at this tutorial.

IOS - Running background task for update user location using swift

i'm new user here, but I have used stackoverflow a lot of times :)... I'm android developer, but now i'm working in an ios app using swift. I'm totally new using xcode, maybe my question es very simple for a lot... Great, I really need help.
I'm trying to implement a backgroud task that updates the user location each ten minutes. I need to get the lat and long data and after send this info to an API web service. I have been rading the backgroud docs, all documentation, and all the documentation about user location services. There is a lot of information, pretty information, but, maybe i'm very wonted to the android information, with s lot of information too, but a lot of easy examples also, then, is very easy for me. and an previous stackoverflow questionmaybe helpme a lot.
I understand a lot of concepts, and I cofigured my info.plist like the documentation says, but... how can I run a background task for get the user location? Where I must write the background task code? What is the beginning? I have a project with three diferent viewcontrollers and I need to start the service with a button... Thank you so much, I really need to understand the start point of all this.
I am currently doing kind of the same thing as my first iOS-project - what helped me was this :
Periodic iOS background location updates
And from there on I found a Swift-Port of https://github.com/voyage11/Location: https://github.com/silento/Location. In the project from voyage11, there is also linked a blog post that a bit of clarifies what is happening and that also links to a second one that tells how to restart location services using "significant location changes". I am currently trying to implement this with "region location monitoring", but not sure if it will work.
Oh, and I moved the code that triggers a new background task out of the didUpdateLocation-part to the restartLocationUpdates-part - so you can be sure your task is restarted even if you do not get a location in time.
It did not work from the start, but when I added the code from https://stackoverflow.com/a/19085518/3085985 as a replacement for the stopUpdatingLocation() and startUpdatingLocation() - parts.
It is really more complicated than it should be and what I am used from Android - but it is how it is. If you are developing for Iphone5+ you can also consider this post (I could not test it right now as I only have an iPhone 4S and the feature is not supported in the Simulator): https://stackoverflow.com/a/24666487/3085985.
I hope you got some starting points, I am currently still testing my solution but it seems to work as far as I can see now ;)
P.S.: I somewhere read something about background tasks sleeping for more than 5 minutes being canceled - as I only wait 30 seconds I do not have this issue, but you might have. But maybe keeping location services running with a really high distance prevents this from happening.
P.P.S.: As Swift is new you should get used to reading Objective C-Code and trying to translate it to Swift. It often is the only way to find good tutorials.
One more thing - for iOS8 you need something like :
if (self.locationManager.respondsToSelector(Selector("requestWhenInUseAuthorization"))) {
// on iOS8+, we need to request the location authorization ourselves -.-
self.locationManager.requestAlwaysAuthorization()
}
And don't forget to add the "NSLocationAlwaysUsageDescription" to your Info.plist as well as allowing background location updates in your project capabilities.
Sorry for this mess of text, but it is a really complicated topic ;)
edit: Regarding your first comment :
You should create a Swift project, e.g. with a single window and in Main. storyboard add a switch. Then you should implement a ToggleActionChanged-event enabling or disabling the listeners, depending on the new state of the switch. I cannot explain all the basics, you should watch a basic tutorial, I like https://www.youtube.com/playlist?list=PL_4rJ_acBNMHa_RGZigG2nQI3aL1kTa4r and used especially the 7th video as an example of how to build a basic app. The only thing that can be made easier than shown there is using right-click-dragging from the storyboard to the code view instead of implementing some methods by hand. There is a handy assistant.
For your location event listeners you can add a new swift class and name it e.g. LocationDelegate.swift . It makes it a bit more clean. I use a Singleton-pattern for that, you can look up how to do this. Or you could use the structure of the github-project I posted above. I can't provide the complete source as you need to change it so it fits your individual needs ;)
Oh, and one more thing : To remember if your switch is enabled between application launches, you can use something like this :
#IBAction func toggleTrackingChanged(sender: UISwitch) {
// This is your method for when the switch changed... put your location activation/deactivation here
let userDefaults = NSUserDefaults.standardUserDefaults()
userDefaults.setBool(sender.on, forKey: "ODLTrackingActive")
}
}
and in your viewDidLoad-Method :
let userDefaults = NSUserDefaults.standardUserDefaults()
var trackingActive = userDefaults.boolForKey("ODLTrackingActive")
toggleTrackingSwitch.setOn(trackingActive, animated: false)
// reactivate location tracking if necessary
Good luck!

Objective C: get location without delegate

I have a problem in Objective C (writing an app for the iPhone). I know how to use the locationManager and its delegates. Once I called startUpdatingLocation on the locationManager, it will call the delegate method didUpdateToLocation whenever the location is updated. But the problem is, that this way is now suitable for what I want to do. I have a method (in a class) which looks as follows:
#implementation SomeClass
- (someType)getDbContentsOrderByDistance
{
... //here I need the current location
return dbContents;
}
#end
Now this function selects entries from a sqlite database ordered by their distance to the users current location. That is why I need the location in this function. What I want to do in the above method is: get the location, then select the stuff from the database and return it. I know that I could just try to access locationManager.location.coordinate.longitude, but I know that there won't be anything useful inside until the first location update has arrived. And I don't want to start the location updates before (e.g. when starting the app) because that would not be very efficient if I only need the location once.
I know how to do it the way that the delegate is called as soon as a location update arrives. The problem is that I don't know how to get that updated location from there into my method above. Basically I would need to let the method 'wait' until there is the first location update and then continue execution with that location.
Thank you for your help!
The short answer is, you can't. Getting the users location is an asynchronous process, and MUST be an asynchronous process. The device has to fire up various hardware like the GPS, cell tower locator, and WiFi triangulation system, get input from those different devices, and synthesize that into a location. That takes multiple seconds to do.
Putz's suggestion of starting a timer is a good one. I would add a few things however.
Typically the first readings you get from the location manager are really bad and should be discarded. The first reading you get is usually the last location reading when the GPS was active, and will have an out-of-date timestamp. The accuracy reading in that location might appear quite good, but it's a lie. I have seen the first location reading be off by several kilometers. You need to check the timestamp on your location updates and discard any reading that is more than 1 second old.
Once you've discarded the stale readings, the first several location updates are often really bad because the GPS hasn't settled down yet. The horizontal accuracy reading (which is really a "circle of confusion", or radius of possible positions) is an absurdly large value, sometimes a kilometer or more. Again, you need to write your location manager delegate method to discard readings that are too inaccurate. I suggest discarding values with a horizontal accuracy reading of >= 100 meters. How much inaccuracy you can tolerate depends on the specific appellation, but beware of making the accuracy requirement too accurate. Sometimes the GPS refuses to settle down. If you require a 5 meter accuracy, you might not get an acceptable accuracy during the entire run of your app. (If you're in an urban environment, a building, or other area where there is a lot of interference/obstruction of GPS signals)
Once you finally do get a value that's accurate enough, save the location and set your locationAvailable flag to YES.
Note that instead of a timer you could use the notification manager to broadcast a "got a good location" message. Any object that needs location information could register for your notification, and get called when the location manager gets an acceptable location reading.
Start a timer that fires every second or so that calls the function you need the location in. check to see if the location has been set. If the location is valid then kill the timer, if not then let the timer continue and check again in one second or so.
The way of knowing if the location is valid is in the delegate method. Set a global variable like locationAvailable = false. Then when the delegate method gets called set that variable to true.
Using location property can solve the purpose
From apple documentation
location The most recently retrieved user location. (read-only)
#property(readonly, nonatomic, copy) CLLocation *location
The value of this property is nil if no location data has ever been retrieved.
In iOS 4.0 and later, this property may contain a more recent location object at launch time. Specifically, if significant location updates are running and your app is terminated, this property is updated with the most recent location data when your app is relaunched (and you create a new location manager object). This location data may be more recent than the last location event processed by your app.
It is always a good idea to check the timestamp of the location stored in this property. If the receiver is currently gathering location data, but the minimum distance filter is large, the returned location might be relatively old. If it is, you can stop the receiver and start it again to force an update.
Whenever I create a new instance of location manager I get the most recent value of location in location property and since my distance filter is not set , it has the current timestamp. This means I dont have to call startUpdatingLocation and my data is accurate. I also need this for calculating distance between user location and a place so I can immediately return true or false if it is within the range. I find this very useful as I get location within 0.006 seconds and handy and got it from apple documentation only but still I dont know if it is a best practice.

When close view that started locations service notification error occure

I have created small app that use this project as it's core:
https://github.com/dsdavids/TTLocationHandler
And it worked fine until I have moved stating location services from another view in app.
What app is doing: When it is started you can tap on START button and (in emulator locations must be enabled) on the map route of movement is displayed as you move.
The problem came when I moved starting action in a second view.
In that second view I just want to start location service and close it.
The problem is when I start locating on the second view I get error (application crash EXC_BAD) here:
TTLocationHandler
...
dispatch_async(dispatch_get_main_queue(), ^{
if (OUTPUT_LOGS) NSLog(#"Sending notification out");
NSNotification *aNotification = [NSNotification notificationWithName:LocationHandlerDidUpdateLocation object:[locationToSave copy]];
[[NSNotificationCenter defaultCenter] postNotification:aNotification];
});
...
I think that it is because I close the second view (view that started service) and TTLocationHandler still tries to send it something.
For better understanding my problem I have added project at git hub:
https://github.com/1110/common-location-features
You can download it and run start service from second view and when close that view app will crash in a few seconds.
I would be really thankful if someone can find a little time to tell me what am I doing wrong here as I am sure that it is some small thing that I probably doing wrong.
Whole code is in SecondViewController.m
Thanks
The problem is probably that the location manager is sending location updates to an object that no longer exists.
I don't have the time to dig through all of your code, but generally speaking once you tell the location manager to startUpdatingLocation, you need to keep your location manager delegate object around until you tell it to stop. If what you refer to as the "second view" is your delegate object, then you can't let that view get deallocated until you tell the location manager to stopUpdatingLocation.
Generally you want to have one object be the CLLocationManagerDelegate, and keep that object around for as long as you need it. The delegate will get notified every time the location changes, and it is the delegate's responsibility to update any views that care about the location.

how to find users location when a photo is taken and display+save in a UIMapView

was just wondering how i would basically go about finding the user's location and then displaying this in an un-editable UImapView. This would be used to location stamp photos and videos taken within the app and must still be displayed whilst the app is open.Just as a disclaimer i am not asking anyone to sit and write this code for me (but feel free to if you want) i was just hoping that someone else may have already done this and so might provide their code as a reference. thanks for any help you can provide
As rokjarc says, you need to break this into pieces.
The camera app that's built into iOS already has the option to save location data into your photos.
Are you saying that you want to be able embed location information in pictures that you take from within your app?
You have at least 3 different things you need to read about:
CLLocationManager. You would create an instance of the location manager and ask it to start updating your location. It takes a while to settle down, so you would want to start it when your app is launched. You'll want to fine-tune the settings so it only notifies you on fairly large location changes to conserve battery. The location manager is an async library, so you start it updating, then wait for it to notify you, and parse the location updates it gives you to make sure they are current/accurate enough.
Next, map kit. You would need to add an MKMapView to your app's views, and set it up to display to a window. you could either use the option that shows the user's location automatically, or use location manager information to change the map region and/or create a map annotation showing the user's current location.
Third, you will need to figure out how to save location metadata to the images you take. That's not something I've done, so I don't have any specific help for you.

Resources