Xamarin iOS Library can't get location - xamarin

I have a vendor provided .framework file that I created an iOS binding project for using Objective Sharpie. I can call into the library, get callbacks, pull data, mostly everything works except the library being able to access the current location. The public headers for that project are here StripeTerminal
In my C# code, I used the Xamarin.Essentials to pull the current location.
var location = await Geolocation.GetLastKnownLocationAsync();
This returns with my location both in the simulator and on a real iPhone. I can see the access is granted to my app in the Privacy-> Location Services menu.
I have the below in my info.plist file, which I have tried targeting 9.0 SDK and 12.0 SDK.
<key>NSLocationWhenInUseUsageDescription</key>
<string>Location required for accepting payments.</string>
In an example XCode project provided by the vendor, that is able to pull the location by inspecting their verbose logs. In the Xamarin app, their logs get stuck on a requestLocation and never continue past it. I even tried setting the Link option to Don't Link and the result is the same.
What is wrong with my binding project that would prevent a native framework library from being able to access the location?

The issue was a mix of how Xamarin works and iOS. I created a CLLocationManager object in my C# code and setup a listener for location changes, except it never worked. So I tried the Xamarin.Essentials package to get the current location using GetLastKnownLocationAsync and that worked every time, so it wasn't a permission issue or a simulator issue. Digging into the Xamarin.Essentials code I found the below.
NSRunLoop.Main.InvokeOnMainThread(() => manager = new CLLocationManager());
Reading more documentation, I found that the CLLocationManager can only be successfully created from an active run loop. Wrapping calls into the Stripe Terminal iOS SDK in the NSRunLoop.Main.InvokeOnMainThread allowed things to work as they were creating a CLLocationManager expecting the call to be in an active run loop without checking first, or documenting that behavior. Stripe's internal code waited on a callback, which never happened, thus hanging the SDK in a weird state.

Related

What is calling requestWhenInUseAuthorization?

I am working on a react-native app. I send it to Testflight. Apple says it's missing NSLocationAlwaysUsageDescription. However, I don't see where is my app asking for location data? The app doesn't show a prompt for it. I looked at the code, and nowhere is it actually calling requestAlwaysAuthorization nor requestWhenInUseAuthorization.
How can I find out what is calling requestAlwaysAuthorization or requestWhenInUseAuthorization? Does XCode allow to have some breakpoint for those functions?
Thank you,
Slackware

Google Sign-In for iOS using Xamarin throws exception logs point to podfile

Trying to implement the Google Sign-In for IOS in a Xamarin project. Right on the Google page where it generates your GoogleService-Info.plist file, it says, "Insure you have CocoaPods installed and configured for your project. In you Podfile, include the following: pod 'Google/SignIn'".
And sure enough, the log on the Mac shows a similar error when going through the initial configuration.
But, I can't find anything that really tells me how to add a "Podfile" to a Xamarin IOS project (from within Visual Studio 2017, running on Windows 10).
So, when it comes time to actually click the Sign-In with Google button, in an IOS 10.3 IPhone 6 simulator, it throws an exception,
"Foundation.MonoTouchException: Objective-C exception thrown. Name:
NSInvalidArgumentException Reason: -[__NSCFString
countByEnumeratingWithState:objects:count:]: unrecognized selector
sent to instance 0x608000047200".
I can only hope it is really because of a missing component that the Podfile is supposed to resolve.
Saw a sample from a year ago that supposedly worked, but with what seems to be current right now, I can't get it to.
Update:
The sample I am trying to use, creates a custom class for the View so it can implement a custom Renderer, and a custom class for the page, again, so it can implement a custom Renderer. The View Renderer simply does:
signInButton = new SignInButton();
signInButton.Style = ButtonStyle.Wide;
signInButton.ColorScheme = ButtonColorScheme.Dark;
SetNativeControl(signInButton);
The Google button shows up, but when you click, you get the exception listed above.
A recent update to Xamarin required an update to XCode. With the update to XCode 9,the problem went away, and Google authorization is working.

iOS 10 Notification Service Extension

I'm working on the iOS 10 APNs function, trying to add Notification Service Extension to an existing App, add the function of pushing an image to the App.
After the extension was added, it did receive the pushed message. But couldn't receive the image, the function(wrote in the extension) of downloading the pushed image didn't execute during debugging. I checked the content in the App package, confirmed that the extension was installed in the App, it just didn't work.
What made me confused was that: I built a new testing project with same bundle id. The testing app could receive the pushed message and show the image correctly.(please see below screen shot)
What's wrong with the existing project? I tried to find the difference between the existing project and the testing project, yet found nothing in the code, setting, environment.
Does anyone encountered this before? I have been struggling in this for a week...
reference:
WWDC 2016 APNS Guide: https://willowtreeapps.com/ideas/wwdc-2016-rich-notifications-in-ios-10
Apple notification guide:https://developer.apple.com/library/content/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/ModifyingNotifications.html#//apple_ref/doc/uid/TP40008194-CH16-SW1
Finally this bug was fixed, please see the attached image. XCode recommends setting the architecture as automatic and I did so, then the notification service extension worked and could receive the pushed image. I don't know why this setting caused the problem, but I'm sure it works.

Watch Connectivity not starting

My Watch Connectivity is not working at all - no response, but also no error messages.
I have copied in a WatchSessionManager and all Swift files including Extension Delegate from another Swift 2.2 project where it works fine. But on my new project it gives no response. I've tried starting the partner iPhone, and it doesn't trigger it.
Are there any project settings that I have to change or frameworks I need to add for watch connectivity?
Solved. In Capabilities I turned on 'background modes' and selected 'audio, airplay and picture in picture' and 'background fetch'.

Xamarin.Forms application properties not saved between sessions with Android

In my cross-platform app I save application properties in the following way:
Application.Current.Properties["myValue"] = "Test";
await Application.Current.SavePropertiesAsync();
I then retrieve them later like this:
string myVal = Application.Current.Properties["myValue"];
This works perfectly when using the Android emulator. I can close the emulator down, and when I restart it again, my app data is preserved.
However, when I deploy this app to a physical Android device, data preservation works as expected until I close the app and open it again. At this point I retrieve an empty value. It's as though the data is only saved to memory (and not to file).
Furthermore, the iOS version of the exact same app works faultlessly. When I open the app up, all previous values have been saved and I can retrieve them.
What am I doing wrong on the Android version? Is there an Android setting, permission, or option which I need to enable to have the values saved between app sessions when actually deployed to a phone?
I had a similar problem where only the debug version saved Properties. I think we're still waiting for the bug fix, and this is the workaround on Xamarin Forms bugzilla.
In short: go to .Droid project settings -> Android Options -> Linker
and enter/add "System.Runtime.Serialization" to Skip linking assemblies.
Wow! After lots of research, I have getting solution for same issue in mine. Problem is that, when i store List or DataTable in Application.Current.Properties then all properties are removed after reopen app but if i store List or DataTable as serialize, it working fine.
In VS you need to enable the option:
Preserve application data/cache on device between deploys
You can find this at Tools > Options > Xamarin > Android Settings.
I don't know if this has stopped in the latest updates of Xamarin Forms, the data is available until the application is running similar to session but persistent storage does not work.
The best api I think available for this is Akavache https://github.com/akavache/Akavache.
You can read this blog https://codemilltech.com/akavache-is-aka-awesome/.
Update
There is a bug filed in bugzilla:
https://bugzilla.xamarin.com/show_bug.cgi?id=26444
I don't remember exactly which part of this solved the issue, but when I followed the instructions to prepare the Android application for release from start to finish, the issue went away. The problem occurred when debug builds were used on an Android device.
https://developer.xamarin.com/guides/android/deployment,_testing,_and_metrics/publishing_an_application/part_1_-_preparing_an_application_for_release/
The link details the suggested settings for the Android project when releasing to device. Following these instructions should solve the issue.

Resources