Swift WCSession not reachable and counterpart app not installed (WatchConnectivity) - ios

I have an iOS app (MyApp) with a corresponding watch app (MyAppWatch). Using WatchConnectivity, I want to establish a connection between both device. Activating a WC session on both devices is succesful, but when testing the connection, something does wrong. It turns out that my session.isReachable returns false. Also, I get a message that WCSession counterpart app not installed. It may be interesting to add that session.isPaired (on iOS) returns true, so nothing seems to be wrong in the connection between the devices. I need isReachable to be true by installing the counterpart app on the watch, before being able to sendMessage(). But how? And why is this failing?
What I've tried so far:
Removing the app on both devices
Cleaning Build Folder
Restarting XCode
Adding MyAppWatch.app to the Frameworks, Libraries and Embedded content of MyApp Target
Enabling and disabling Supports Runnings Without iOS App Installation (MyAppWatch Target)
All possible combinations of this
Can someone please help fixing this, I'm struggeling for days now.

Related

IOS app stuck in splash screen on IOS version 10.2.1 with no error

My iOS app was perfectly working till yesterday. My QA was testing and there was no bug at all. But when I tried to install from Xcode to my iPhone 6 somehow it got stuck in splash screen and debugger shows absolutely no error. I googled a lot but no luck. I even tried to run previous version by switching my current branch but no luck.
This is what my debugger look like:
2018-02-07 12:49:56.982145 Marham[547:85300] 4.8.1 - [Firebase/Analytics][I-ACS023007] Firebase Analytics v.40009000 started
2018-02-07 12:49:56.982649 Marham[547:85300] 4.8.1 - [Firebase/Analytics][I-ACS023008] To enable debug logging set the following application argument: -FIRAnalyticsDebugEnabled (see [some-Link])
2018-02-07 12:49:56.983029 Marham[547:85300] 4.8.1 - [Firebase/Messaging][I-FCM001000] FIRMessaging Remote Notifications proxy enabled, will swizzle remote notification receiver handlers. If you'd prefer to manually integrate Firebase Messaging, add "FirebaseAppDelegateProxyEnabled" to your Info.plist, and set it to NO. Follow the instructions at:
[some-Link]to ensure proper integration.
(lldb)
and here is the surprising thing for me that, app runs without any issue on simulator but got stuck only on real device.
Do you still have this issue ?
Because I had a similar one and that was because a local storage variable was blocking the execution of the first view on the phone (the simulator was working fine).
So I advise you to put your phone on debut mode and make a breakpoint on the main function in the App Delegate.
This way, you should be able to se if there's an async function waiting for nothing.

"[Crashlytics:Crash] Reporting is disabled"

I am getting the following error messages when our production iOS app initializes:
[Crashlytics] Version 3.8.4 (121)
[Crashlytics] Running on iOS Simulator (iPhone), 10.3.0 (16E195)
[Crashlytics:Crash] Reporting is disabled
[Crashlytics] Crash reporting could not be initialized
[Answers] Initialized
[Fabric] Initialized with kit versions: {
"com.twitter.answers.ios" = "1.3.4";
"com.twitter.crashlytics.ios" = "3.8.4";
"io.fabric.sdk.ios" = "1.6.11";
}
Every subsequent call to log an event gets the following error:
[Crashlytics:Crash] WARNING: CLSLog has been used before (or concurrently with)
Crashlytics initialization and cannot be recorded. The message was: ...
The non-production versions of the app work fine running the exact same code but with different bundleIDs. Normally when the app initializes for the first time, then I see the app populate in the Fabric dashboard, but in this case the app is not showing up.
We have an Android and an iOS version of the app, and they both use the same bundleID, so I am wondering if there is a conflict because of that? I see the Android version of the app in the dashboard, and it seems to be working properly. This is an app that originally was a Xamarin app that compiled to both platforms, neither of which incorporated Fabric/Crashlytics. We have now written native apps on each platform, and both are using Fabric/Crashlytics.
Since this is a pre-existing app in both stores, we do not have the option of changing either app’s bundleID.
Make sure you initialize Crashlytics with Fabric before calling any Crashlytics methods:
Fabric.with([Crashlytics.self])
One step I routinely miss is to make sure you've added the build phase on your target:
"${PODS_ROOT}/Fabric/run" ${FABRIC_API_KEY} ${FABRIC_BUILD_SECRET}
and either replace ${FABRIC_API_KEY} and ${FABRIC_BUILD_SECRET} with your key and secret or add custom build settings for each.
There are apparently cases where Crashlytics does not auto-activate new apps so that they show up under your list of apps, even though everything is coded correctly and data is going to their servers. In this case, send an email to Crashlytics support (support#fabric.io) that contains a copy of the info.plist entries for the app in question and they will activate it for you. I have had to do this several times, especially with app extensions.
When I finally traced it down in my situation, the error was entirely correct, but not obvious.
I saw these errors in various testing targets where the code we tested was using a custom logging wrapper which called CLSNSLogv(), but the test didn't actually go through the AppDelegate and therefore did NOT initialize Crashlytics. After trying a few things I was convinced that it worked when executed as an app, but in our configuration it was not working under the unit test configuration.
I'll likely alter our custom wrapper to bypass CLSNSLogv() during testing anyway. The biggest benefit of using that is when crashes occur on devices, so we won't be missing anything.

Xamarin.UITests - testing on real device - iOS - app permissions popups issue

I've iOS app that needs some privileges (GPS, Push notifications).
When app starts for a first time iOS asks user if they're ok with granting those permissions to application.
I've written some UITests and want to automate running them on locally connected iPhone.
The problem is that I cannot override permissions questions and my tests fails.
I found out that application deployed by IDE (Xamarin Studio) will ask for permissions, but application deployed via UITests will not.
So I tried with .AppBundle(path_to_app) but it says this is only valid for deploying to Simulator.
SetUp : System.Exception : This app bundle is not valid for running on
a simulator. To fix this issue please ensure that your target device
is a simulator. DTPlatformName is 'iphoneos', not 'iphonesimulator' in
the apps Info.plist.
Like it's trying to deploy iPhone app to Simulator. But Target in Xamarin Studio is set to real device.
I tried to add .DeviceIdentifier. When Used with .InstalledApp it was starting up (still asking for permissions).
But when I used DeviceIdentifier and AppBundle there was the same error as above.
My tests works fine on Test Cloud. They work fine on Simulator.
They work fine when I deploy to device manually, start app and approve permissions then run UI tests.
What I cannot achieve is to make UITests override permissions questions on real device.
Anyone made this work?
Last thing is that I found is in documentation for AppBundle method
"Will force a run on simulator"
https://developer.xamarin.com/api/member/Xamarin.UITest.Configuration.iOSAppConfigurator.AppBundle/p/System.String/
So I may be doomed with the task but maybe someone knows a workaround?
You can dismiss system dialogs with UITest by using InvokeUIA. The test below works by tapping the "OK" button of an iOS system alert:
[Test]
public void AppLaunches ()
{
app.Screenshot ("First screen.");
app.InvokeUia ("uia.query('[:view {:marked \"OK\"}]')");
app.InvokeUia ("uia.tapMark(\"OK\")");
}
A working sample app & UITest is also here:
https://github.com/King-of-Spades/InvokeUia-for-System-Dialogs
Warning about system dialogs in Test Cloud
The reason that you don't see this issue in Test Cloud is because Test Cloud automatically dismisses the system alerts; so usually you don't have to worry about it. However, if your alert launches too soon; so that it appears before the automation has fully started your app, then it will be unable to detect & dismiss the alert and cause your test to fail.
So you want to make sure that when running your app in Test Cloud that the request for permissions are delayed, or you can even deactivate them if they aren't explicitly needed for a particular test. More information is available in this Calabash guide: https://github.com/calabash/calabash-ios/wiki/Managing-Privacy-Alerts%3A--Location-Services%2C-APNS%2C-Contacts
(Even though it's Calabash, you can use the same strategy in UITest; albeit with a C# syntax.)
Update for Xcode 8 / iOS 10
Xcode 8 / iOS 10 removed UIAutomation, so the InvokeUIA workaround will only continue to be possible if you're using Xcode 7 and iOS 7-9. References:
UITest: https://developer.xamarin.com/guides/testcloud/UITest/xcode7/
Calabash: https://developer.xamarin.com/guides/testcloud/calabash/xcode7/#Automation_API
For real devices you dont need any of those.
{
app = ConfigureApp
.iOSAppBundle
.StartApp();
}
this piece of code is good enough, if you are connecting real device to the system, then select that before running.
We use this to execute the UI tests on iPhones:
ConfigureApp.iOS.InstalledApp("com.appcenter.UITestDemo").StartApp();
InstalledApp requires you to build an IPA using the Debug
configuration & a valid provisioning profile, and preinstalling it on
the target device.
https://github.com/microsoft/appcenter-Xamarin.UITest-Demo/blob/main/UITestDemo.UITest/AppInitializer.cs
To confirm system dialogs we use this:
private Query ConfirmLocalNetworkPermissionDialogButton
=> AppInitializer.Platform == Platform.iOS
? new Query(x => x.ClassFull("_UIAlertControllerActionView").Marked("OK"))
: x => x.Class("AppCompatButton").Marked("button1");

WatchConnectivity connection in iPhone -> Watch direction

I'm trying to make WCSession (Xcode 7.0 beta 5) work in the Phone -> Watch direction on real devices (in a simulator it works perfectly) but every time get an error:
Error: "Domain=WCErrorDomain Code=7006 Watch app is not installed".
I mean everything works in the Watch -> Phone direction (sendMessage:, updateApplicationContext:, CoreLocation, etc.). In order to exclude code-related problems I'm using the Apple's Potloc application for tests.
It seems I've tried everything and here's a full list:
Paired/Unpaired Watch.
Rebooted iPhone/Watch.
Reset Watch.
Reset iPhone (reset all settings).
Reinstalled iPhone/Watch applications a bunch of times.
Switched on/off "Show App on Apple Watch" in "My Watch" application on iPhone.
The only way iPhone is able to communicate with Watch is to answer using a callback in WCSession methods.
What else can I do?
As expected the problem has been solved in Xcode 7.0 beta6. A project just has been rebuilt without any additional configuration and then the item #6 from my aforementioned list has solved the problem:
Switched on/off "Show App on Apple Watch" in "My Watch" application on iPhone.
This seems similar to this:
WatchOS 2 (beta 5): watchAppInstalled returns false
Did you watch out for "isWatchAppInstalled"? If yes, did it say YES or NO?
Maybe the other solutions mentioned over there work for you?

Xcode+watchkit simulation: does not support a debuggable architecture:

I am trying to run in Xcode both the main App (which is active in background) and the WatchkitApp (which sends requests to main App through the watchkit extension). Everything works fine in standalone, but no way to make it work simultaneously.
My main concern is to understand this message when trying to attach a process: what does this mean ?
Xcode couldn't attach to "myApp"
"myApp" does not support a debuggable architecture
Thank you.
Edit:
I just read that main app in ObjectiveC and watch app in swift is a problem: https://mkswap.net/m/blog/How+to+debug+an+iOS+app+while+the+WatchKit+app+is+currently+running+in+the+simulator
It happened to me when an extension process was hanging around refusing to terminate. Find and kill it in the Activity Monitor.
Actually, I had that same error message, and I fixed it by resolving a bug that crashed my phone app on launch.
I didn't think to run just the phone in debug so I got confused too.
I'm running ObjC on the phone and Swift on the Watch App.

Resources