Google Places Callback not being called in Swift iOS - ios

I am using the GoogleMaps SDK (maps & places). For some reason the following callback is not being called. I have put loggers in there but nothing happens.
var placesClient : GMSPlacesClient?
...
func run(){
self.placesClient?.currentPlaceWithCallback({ (list: GMSPlaceLikelihoodList?, error: NSError?) -> Void in
if let error = error {
println("error: \(error.description)")
return
}
if let list = list {
self.renderList(list)
}
})
}
For some reason the block in currentPlaceWithCallback does not get called. Yesterday it happened because my API had a wrong bundle identifier, after changing which it started working. But today it stopped.
Any idea why this would happen ? Also, are we exposed to any API logs by Google ?

I was getting the same issue on my iPhone 6 device AND iPhone 6 simulator.
The fix was to add the NSLocationWhenInUseUsageDescription permission in Info.plist! But, it worked only on my iPhone 6 device, NOT the simulator.
As mentioned in the Google Place Guide:
(https://developers.google.com/places/ios-api/start)
Please note, as this sample requires access to the location of the device to get the current location, you will need to set the NSLocationWhenInUseUsageDescription key with appropriate explanatory text in your project's Info.plist file. For more details, see the guide to getting current place.
Now, the way I got it working on the iPhone simulator was by changing my location on the Simulator: Debug -> Location. That is, it was set to 'Apple' by default, I just changed it to Bicycle Ride.
It worked for me, may not for all.

Related

Strange #NullIsland warning from CoreMotion.framework

Since recently, I get in the Xcode logs a lot of strange warnings from the CoreMotion framework, related to function getLocationForBundleID:
[Client] {"msg":"#NullIsland Either the latitude or longitude was exactly 0! That's highly unlikely", "latIsZero":0, "lonIsZero":0}
[Client] {"msg":"#NullIsland Received a latitude or longitude from getLocationForBundleID that was exactly zero", "latIsZero":0, "lonIsZero":0, "location":'28 5B E0 D7 EB 7F 00 00'}
I do not see any malfunction of my app. So maybe these logs can be ignored, but they are annoying anyway.
My questions are:
How can I correct a potential error?
How can I stop these warnings?
Apparently this error message is logged if property location of a CLLocationManager is read, before the CLLocationManager delivered the very first location.
My solution is the following:
I use anyway a subclass of CLLocationManager that allows me to set the location property for tests programmatically.
This is done as follows:
private var _location: CLLocation?
#objc dynamic override var location: CLLocation? {
get {
let usedLocation = _location ?? super.location // Here the error is logged if no location has been delivered yet
return usedLocation
}
set {
_location = newValue
}
}
This subclass has now an additional property
var anyLocationDelivered = false
that is set true in
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
locationManager.anyLocationDelivered = true
// …
}
and the getter is now
get {
guard anyLocationDelivered else { return nil }
let usedLocation = _location ?? super.location
return usedLocation
}
Now this error message is no longer logged.
I was getting this same error when trying to get a user's location in an app. There were two things preventing me from getting a valid lat/long. The main issue I was having was that I was using a simulator and had to set the location manually. If you're using the simulator, go to XCode, click Debug --> Simulate Location, and choose a location. I also had to make sure the correct location permission keys were added to Info.plist. You're also probably already aware, but you'll know if any keys are missing from Info.plist because a separate error message will print out to the console above or below these lat/long error messages, and it will tell you which key is missing. So basically:
Make sure you have all necessary location permissions accepted on the device/simulator being used to test the application.
Once you have location permissions, set a location if using a simulator.
Not sure if this will help at all, but I hope it does. If you've already confirmed that these are not issues, I'm not sure what may be causing the issue in your case, but stepping through the parts of your code responsible for fetching the user location would probably be beneficial to see which link in the process is failing.
The issue is likely that you ran your application on the simulator, which does NOT use your current location by default unless you manually change the simulation location in Debug, Simulate Location.
To fix the issue, either simulate your current location (as stated above) OR run your application on your physical signed device, close the application completely, and then relaunch your application.
OS_ACTIVITY_MODE = disable
To get rid of the warning do the following:
Steps
Navigate to Product -> Scheme -> Edit Scheme.
Open the Arguments tab
Environment Variables section add OS_ACTIVITY_MODE = disable

loadAppContextDataFromInbox error loading in application context from inbox NSFileReadNoPermissionError -> EACCES

I have been developing an app the works with the apple watch's workouts and an iPhone. The app is written in swift and communication has been working properly for weeks while I add features. I am suddenly getting the following error code when I try to run my app on my iPhone.
[WCFileStorage loadAppContextDataFromInbox] error loading in application context from inbox NSFileReadNoPermissionError -> EACCES
This error is being generated on a program that was working fine using the same code. I believe the error is coming from the following line of code:
WCSession.default.updateApplicationContext(dictionary)
in the func shown below.
func sendAppStateToWatch(appState : String?) {
if WCSession.isSupported() {
if let appStatus = appState {
do {
let dictionary = ["iOSAppState" : appStatus]
try WCSession.default.updateApplicationContext(dictionary)
} catch {
print("sendActiveTimeToPhone() ERROR: \(error)")
}
}
}
}
This function has been working without problem for at least a month. Suddenly, I am getting the error shown above. I have rebooted the watch, phone and Xcode without effect. I suspect the error comes from some privacy setting on the phone or watch that flipped, but looking around I cannot find the problem. Any help is appreciated.

iOS 11.4 not asking Privacy Usage ( Privacy - Motion Usage Description has been set )

I'm stumped, iOS 11.4 ( 15F79 ), iPhone 6. Cannot get the App to Ask for Motion Data. info.plist has been set via the editor and double checked via the info.plist open in textWrangler, Also deleted key and saved via textWrangler.
<key>NSMotionUsageDescription</key>
<string>This app needs your Phones motion manager to update when the phone is tilted. Please allow this App to use your phones tilt devices</string>
I have deleted then reinstalled the app about 10 times. I have restared the phone 5 times. I have checked through settings and my app does NOT show up in Privacy-Motion and Fitness or anywhere else in settings. I am using a free developer account, maybe that has something to do with it?
I created a new Xcode game template and changed nothing apart from importing CoreMotion and this code
**** Edited, sorry I forgot to say I had started the instance, just forgot to put it here, just in case someone thinks that's the problem ************
let motionManager = CMMotionManager()
override func didMove(to view: SKView) {
motionManager.startDeviceMotionUpdates()
if motionManager.isDeviceMotionActive == true {
motionManager.accelerometerUpdateInterval = 0.2
motionManager.startAccelerometerUpdates(to: OperationQueue.current!, withHandler: {
(accelerometerData: CMAccelerometerData!, error: NSError!) in
let acceleration = accelerometerData.acceleration
print(accelerometerData)
} as! CMAccelerometerHandler)
}else{
print(CMMotionActivityManager.authorizationStatus().rawValue)
}
which prints a 0 ( an Enum - case not determined ) to the console.
In my actual app it was a 3 ( same Enum - case Denied ).
As I've said, I have uninstalled, reinstalled, edited plist via Xcode and text wrangler ( a code editor ) , tried different versions of the code above, tried the code in different places ( in did move to view, in class )tried code off apple docs. etc.... I haven't been asked the NSUsage question and the App keeps crashing.
I have looked for ways to get the Alert fired up, As in CLLocationManager.requestWhenInUseAuthorization() but I cannot find a comparable CMMotion version ( I don't think there is one. ) I have created a new swift file , imported Foundation and CMMotion and just put that code there, But still no Alert asking for Motion Data.
I tried a single view app template instead of a game template thinking that might be the issue, Nope.
What do I do?
Any help Appreciated. Thanks
You are confusing two related but different classes.
CMMotionManager gives access to accelerometer, magnetometer and gyroscope data. It does not require any user permission as this information is not considered privacy related.
In your else clause you are checking the authorisation status of CMMotionActivityManager. This object reports the device motion type (walking, running, driving). This information is considered privacy related and when you create an instance of this class and request data from it, the permissions alert is displayed.
The reason your else is being triggered is because you are checking isDeviceMotionActive; this will be false until you call startDeviceMotionUpdates, which you never do. Even if you used isAccelerometerActive you would have a problem because you call startAccelerometerUpdates in the if clause which will never be reached.
You probably meant to check isAccelerometerAvailable. If this returns false then there isn't much you can do; the device doesn't have an accelerometer.
Update
It doesn't make sense to check isDeviceMotionActive immediately after calling startDeviceMotion:
You know it's active; you just started it
I imagine the start up takes some time, so you could expect to get false if you check immediately.
Apple recommends that you do not have more than one observer in place for each motion device type, so the purpose of check the is...Active to ensure you don't call start... again if you have already done so.
If you only want gyroscope data then you don't need to call startDeviceMotionUpdates at all.

How to acknowledge system alerts on a device with KIF testing framework?

I found out how to acknowledge system alerts while on a simulator from this post using this line of code:
self.viewTester.acknowledgeSystemAlert()
Unfortunately, the KIF code has #if TARGET_IPHONE_SIMULATOR wrapped around it, so it won't work on a device. How can I get around permission alerts on a device during automated testing?
I had same issue and here the solution I found:
its right than this KIF function doesn't work on device, its only for simulators! so, You can have a UITest in the UITarget and just a single Test case in it that will add a UIMonitors like this:
// ask for all the permission from users then :
_ = addUIInterruptionMonitor(withDescription: "") { alert -> Bool in
let confirmLabels = ["Allow", "OK"]
for (_, label) in confirmLabels.enumerated() {
let allow = alert.buttons[label]
if allow.exists {
allow.tap()
break
}
}
return true
}
// do some UI interaction here like tapping on some view in app
So you can call this UITest each time before running your UnitTests and that will prepare your app to have all the permissions.
btw, if anyone has better solution please provide cause I wanna know, too ;)

iOS: GooglePlaces API error

I am getting this error when trying to use the sample code from Google Places getting started Link
Error: Current Place error: The operation couldn’t be completed. An internal error occurred in the Places API library.
I am calling this function on viewDidLoad. I also created a IBAction with this code to make sure it wasn't a timing issue. I got the same error this way as well.
placesClient.currentPlace { (placeLikelihoods, error) in
guard error == nil else {
print("Current Place error: \(error!.localizedDescription)")
return
}
if let placeLikelihoods = placeLikelihoods {
for likelihood in placeLikelihoods.likelihoods {
let place = likelihood.place
print(place.name)
}
}
}
I have created a new project in Firebase, which created a new project in Google Dev Console. I created new API Key, Enabled Google Maps and Google Places API. I added CoreLocation framework, my pods are up to date. I should not be hitting any limits as it is just me learning. I have the Location When In Use set up i the Plist - user gets the dialog on fresh install. I accepted it. I added location manager code from here to make sure I am getting the location. I signed up for Apple developer to get the app on my device just in case the location wasn't staying on the simulator. I have a feeling this is something stupid. Please let me know any ideas to get passed this. Thanks!

Resources