I'd like to test what happens if my app can't get the location coordinates. Is it possible to disable the location service in the simulator, like on an iPod Touch with WiFI turned off?
I still don't have my iPhone Developer Program certificate, so I can't test it on my device.
Thanks in advance!
You can disable the location services in the simulator;
Run your app through xcode so the simulator opens
Stop the app via xcode (this should leave the simulator open)
Open the Settings app in the simulator window
Privacy > Location Services. Disable Location Services
Run your app again, location services should be disabled
Hope it helps!
As a workaround you can try to simulate update location failure by constructing NSError object with appropriate values and calling corresponding CLLocationManager delegate didFailWithError: method manually.
To my knowledge, you can't disable the location service on the simulator.
The approach that I normally use when using the location service is to build a simple wrapper class arround NSLocation tailored to the needs of my application.
In this wrapper, you could easily pretend that the service is not working in the simulator. For example, it could have a "isEnabled" method that returns false on the simulator with a compiler define like (#if TARGET_ IPHONE_SIMULATOR)
**Disregard this. This works around the MapKit. Check comments below.
Disconnect the computer from internet connection. How to.
EDIT: You can test the code from this site that can be downloaded here
With AirPort on, you get the map. With the AirPort off you get a blank squared view.
Related
My application uses the core location also after the application terminates with the method startMonitoringSignificantLocationChanges in CLLocationManager class.
My application launches with a location key in iOS 5 and 6 in the method:
- (BOOL) application:application didFinishLaunchingWithOptions:launchOptions;
in AppDelegate class and everything works well.
But in iOS-7 betas the application doesn't launch with a location key after a significant location change.
Has anybody encountered this problem?
I tried it on a simulator and in the device.
Thanks for the help.
I have the same problem in my app, when the app was terminated by user from app switcher.
But it does launch with location key if it was terminated by OS for low memory or other reason.
It is the expected result from iOS7 unfortunately. An official apple response I got from one of their evangelists:
If a user swipes up in the app switcher then the OS will not launch
the app unless explicitly told to do so by the user. So no, SLC will
not be launching the app, nor will silent notifications. The only
thing that will launch the app at that point is the user tapping the
icon. The intention here is that the user has expressed their choice
of not having that app running any more for any reason, so we honor
that. In this situation, there's really nothing that you can do. The
next time the user launches the app you can let them know that some of
the data may be missing, although you really cannot tell whether
there's missing data or not (i.e. you might have been killed by the OS
in the background and the user may not have moved thereby not
triggering any SLC notifications). My suggestion would be to gather
the data you can within the policies of the OS and if the user has
manually killed the app then respect that wish and don't do anything.
By all means, feel free to file a bug report if this change in
behavior winds up causing problems for you or (especially) confusion
for your users.
Attach link to Apple DEV forums:
https://devforums.apple.com/message/882691#882691
Is it possible to simulate a location on iOS Device, say I want to simulate London on the device while I am sitting in Oxford?
Thanks.
Yes, It is possible to simulate the location on device in debug mode. All you need is to debug your application on device, and then enable the location from debug menu.
Check this link...
https://developer.apple.com/library/ios/recipes/xcode_help-debugger/articles/simulating_locations.html
You can create a GPX file with the desired location/coordinates and you can enable it from the debugger or from the Project scheme select run/options/"Allow location simulation".
After you have this enabled and your device connected the location simulation will work on the device to till you reboot it.
A good article that explain this can be found here: https://blackpixel.com/writing/2013/05/simulating-locations-with-xcode.html
Maybe this project can help: https://github.com/futuretap/FTLocationSimulator
It simulate location sending fake data to the coreLocation.
Is there a way to manually tell the device to dispatch a significant location change notification that will wake up any applications registered for this notification?
This is for testing only, and I realize this private API call would get rejected upon submission to the app store.
So two answers:
A) Hop on a train :-)
B) Use the simulator. In iOS 5.x simulator, there is a debug menu that has a location submenu. Choose freeway drive. This will start the simulator on an imaginary journey down the scenic 280 in Northern California. It gives you everything but the view: your app will get Significant Location Change updates, and will also be launched in the background if it has been suspended.
To verify that you are actually moving, launch safari in the simulator, and go to maps.google.com and click the little track my location button. You should be moving.
Awesome! Now how to debug the lifecycle problem of being launched by the system? Easy! Have xCode wait for your app to be launched to start debugging. From the Scheme menu, choose edit scheme. In the Run Scheme, and the Info tab, for the "Launch" setting choose : "Wait for My.app to launch".
Run your app once in the simulator, so that it starts monitoring for location updates, then force quit it, so that it is suspended. Add a break point in your application did finish launching function, and wait. As soon as your simulator has gone far enough, your application will be woken up, your breakpoint hit, and you are in the money.
But really, the train ride is more fun.
Well, I've found that I can do this by toggling on and off Airplane mode and/or WiFi. Perhaps start the app with the device in airplane mode, then close the app and turn airplane mode off. That will turn the GPS on and force a location update to be dispatched.
I also wanted to test the relaunch of my terminated app which uses significant change monitoring. I wrote a piece of code so that it would display a local notification when it gets launched by a location key in the launch options dictionary.
I ran my app in the simulator. Then killed it from the multitasking bar. Then I set the location of the iOS simulator to a custom location. I quit the simulator and started it again. My app received the significant location update and showed the local notification.
I was struggling with the same issue, how to test 'startMonitoringSignificantLocationChanges' and check if my app is receiving location updates when suspended.
I couldn't manage to catch the execution on a breakpoint but I managed to see the results of my implementation working by sending the new location data to the server.
The whole flow:
- Implemented with 'startMonitoringSignificantLocationChanges' and an API call to my server to update the location latitude and longitude
- Set the location updates background mode capability to true
- Run the app so the location manager is initiated and the app is listening for location changes
- Force closed the app
- Set the debug->location on simulator to freeway drive
- Opened maps to see if the location is changing
- Waited on the server to see for location updates and was getting new results every about 3 minutes
However, I'm still not sure if this is fine enough on a real device.
I'm working on Xcode Version 6.0.1 (6A317); tested on Simulator iPhone 5s (8.0).
Adding to MagicSeth's answer, if you need to test this on a real device instead of a simulator, you can trigger a background launch with UIApplication.LaunchOptionsKey.location key by disabling and re-enabling Location Services in General > Privacy screen in the Settings app.
Depending on your scenario I would suggest two solutions:
Use a Timer or LocalNotification that periodically calls stopMonitoringSignificantLocationChanges followed by startMonitoringSignificantLocationChanges which should trigger a new location to be sent to your code (might be the same Location as before).
Build your own GPS Simulator that you start in debug builds and that will call the same delegate methods like CLLocationManager would do.
One thing I noticed in iOS 7 and Xcode 5.1.1 - If you are expecting SLC events to fire up your app into background mode, it may or may not hit the breakpoints you set. For me, sometimes the NSLog message are not even showing.
If that's the case for you, you can view NSLog outputs from the System Log. You can open the System Log from iOS Simulator's Debug menu.
In iOS 4, you can register for significant location changes. From the Apple docs: With this service, location updates are generated only when the user’s location changes significantly; thus, it is ideal for social applications or applications that provide the user with noncritical, location-relevant information. If the application is suspended when an update occurs, the system wakes it up in the background to handle the update. If the application starts this service and is then terminated, the system relaunches the application automatically when a new location becomes available. This service is available in iOS 4 and later, only on devices that contain a cellular radio.
See the Apple docs here and here.
Here is some example code to register for signification location updates:
- (void)startSignificantChangeUpdates {
// Create the location manager if it doesn't exist
if (nil == locationManager)
locationManager = [[CLLocationManager alloc] init];
locationManager.delegate = self;
[locationManager startMonitoringSignificantLocationChanges];
}
The docs say: if you leave this service running and your application is subsequently suspended or terminated, the service automatically wakes up your application when new location data arrives. At wake-up time, your application is put into the background and given a small amount of time to process the location data. Because your application is in the background, it should do minimal work and avoid any tasks (such as querying the network) that might prevent it from returning before the allocated time expires. If it does not, your application may be terminated.
Freeway drive
// MARK: - MKMapViewDelegate
func mapView(_ mapView: MKMapView, didUpdate userLocation: MKUserLocation) {
guard let location = userLocation.location else { return }
print(location.speed)
}
Well, this is not possible as the application scope is limited to its own space and such kind of notification cannot be generated with Apple Documented APIs list.
Of course.. if any undocumented API is used, application will get rejection from apple due to the use of undocumented/private API.
I need to write an application, that every 10 minutes it should be awaken from suspended mode, get user location via gps and send this information to the server by network.
Depending on the response it should return to the suspended mode or show local notification to the user.
Is there a way to do this on iOS 4?
I've tried different approaches, but the only working for me was to start monitoring user location in backgroind and declare the application as location background application. In that case it worked in background and has a network connection. But this approach takes a lot of power and not accepted cause application should work 24/7.
May be there is a way to write some daemon that should work in background and wake my application every 10 minutes?
Apparently, Pastebot tried to do something similar with the 'audio' multitasking declaration (by playing a silent audiofile) and got rejected.. UNTIL they actually presented a option to the user to pick which audiofile they wanted to play. It's in the appstore now. :)
In this case: What is your reason for not wanting to use the location updates? If battery-usage is a concern, you can use the 'significant location changes only' option, after which you can temporarily change to a more accurate option.
This isn't possible outside of the method you have already tried.
The iPhone background task API will allow you to run a location service in the background.
There is no way to write daemons for the iPhone without jailbreaking, and that is not something I'm able/prepared to help you with.
App store friendly: use new APIs in iOS4, which allows u to make use of GPS location
Anti App store: create a daemon by adding a specific plist file to System/Library/LaunchDaemons/ and put ur app under Applications/. this approach requires a jailbroken iPhone however...
detailed information plz google the following keywords: daemon, multitask, background, etc...
cheers, Lloyd
Location Manager Error : Operation could not be completed(KCLErrorDomain error 0)
Why does this error occur?
This error occurs if you have Scheme/Edit Scheme/Options/Allow Location Simulation checked but don't have a default location set. I'm sure there are other causes as well though.
UPDATE
THANKS TO Ben Marten
You can make it permanent using these steps in XCode:
Product > Scheme > Edit Scheme
Click Run .app
Option tab
Already checked Core Location > select your location
Press OK
Besides that, even if you are not connected to wifi, you can set a location in simulator through top menu items Debug>Location and to make it permanent follow steps above
I just had this problem. Took me a while to find the solution, which is only loosely related to the previous poster's answer.
Airport (WiFi) must be on for CoreLocation in the iPhone/iPad Simulator to work. I was connected via Ethernet so CL didn't do anything in the Simulator. Turn on Airport in your Network Settings and try again. You can change the order of your network interfaces by dragging Airport below Ethernet if you want to continue favoring your wired connection over your wireless...
From the API docs:
CLError
Error codes returned by the location
manager object.
typedef enum { kCLErrorLocationUnknown
= 0, kCLErrorDenied, kCLErrorNetwork, kCLErrorHeadingFailure } CLError;
Constants
kCLErrorLocationUnknown The location
manager was unable to obtain a
location value right now.Available in
iPhone OS 2.0 and later. Declared in
CLError.h.
kCLErrorDenied Access to the location
service was denied by the user.
Available in iPhone OS 2.0 and later.
Declared in CLError.h.
kCLErrorNetwork The network was
unavailable or a network error
occurred. Available in iPhone OS 3.0b
and later. Declared in CLError.h.
kCLErrorHeadingFailure The heading
could not be determined. Available in
iPhone OS 3.0 and later. Declared in
CLError.h.
So this means the location could not be determined.
I would guess the most likely cause is that the location manager is using WiFi to triangulate the location, and the database doesn't cover the local networks. That apparently can be fixed by the user if they go here.
However as I noted I have also seen this occasionally as a transient error when running a location based program in a location where the WiFi location stuff normally works.
Lastly I guess it is possible to see this error if there is some kind of hardware failure.
1) check that you actually have a valid WiFi and 3G connection
if you do then
2) go to settings and reset your location services
3) reset your network settings
If you got this in Emulator then do following
Debug > Location > ✓ Apple
This error is thrown when Location Manager is unable to get location information immediately. I found that this error was occurring when startUpdatingLocation method was called. For me, this was happening on iPod but not on iPhone. That makes sense, since, iPhone has more ways (like cellular network) to get location information and is able get a quick estimate on the location whereas iPod takes more time which caused this error to be raised on iPod.
Since, when this error is thrown locationManager:didFailWithError: delegate method is called, one can handle this specific case in a conditional statement by matching "[error domain]" and "[error code]" from the error object passed to this method.
The exact reason what I have found is there is a conflict occuring in the location simulation in both the ios simulator “Debug settings” and in the xcode settings “Edit schemes”.Ensure to set you default user location in any one of this and mark the other to None solved the problem hope this might help for sure.
InXcode:
In iphone/ipad simulator:
You can add your own list of locations to Xcode to test your applications with.
From within Xcode select the menu Debug/Simulate Location and you'll be offered:
a. "Don't Simulate Location"
b. 12 example locations
c. "Add GPX File to Project..."
Select "Add GPX File to Project..." and select the GPX file you've created.
Go to Xcode project >product>scheme>edit scheme>chek location simulation>set your location> and run app again Hope it will works !
Thanks to this article (https://possiblemobile.com/2013/04/using-xcode-to-test-location-services/) I got a hint to look at the data on my custom GPX file and there found the issue.
Some GPX files you might get from different sources might have the following elements indicating the different coordinates in specified path. This wont work with Xcode's Location Simulation.
<gpx>
...
<trkpt lat="" lon="">
<ele></ele>
</trkpt>
...
</gpx>
What you should do is find all occurrences of the "trkpt" element and replace it with "wpt" in your favorite text/xml editor. The end result should be something as follows:
<gpx>
<wpt lat="" lon="">
<ele></ele>
</wpt>
...
</gpx>
Hope this helps! It certainly helped me.
This error occur while you run your program ,but you simulate location after you run the programe.
I get a method :quit your simulator and restart it ,then set your simulator location before you run the programe,and it works for me .
Hope this helps! It certainly helped me.
thanks...
all of this didn't work for me.. what worked for me is :-
set the location from the simulator to none then change it back to custom location while the app is running.
All of the suggestions didn't help in my case. What helped was to uninstall the app from the simulator device, reinstall it and allow it to access the location (in the settings app).
If you are getting this on the device, chances are you did not ask for or the user denied the permission to gather the location.