Open chamons opened 4 years ago
Just an update on this - direct support for WidgetKit in C# did not make it this year, and isn't in our initial Xcode 12 support release.
However, we did add support for using a new AdditionalAppExtensions property in your project to embed Swift extensions in your Xamarin.iOS project.
More complete support is on our backlog for future possible features now.
See the PR for an example. More details in a future blog post as well.
@chamons Thank you for the update. If it's convenient, can Xamarin team share us a simple guide from project setting up to release to App Store?
And another idea related to the tech you are using:
Best Regards,
Philip
I downloaded the sample app from https://github.com/chamons/xamarin-ios-swift-extension/blob/master/App/TestApplication/TestApplication.csproj#L143 but the demo Extension doesn't compile with Xcode 12 GM.
Same problem here. Visual Studio 2019 version 16.7.4 ends the build with the following error: "ditto" exited with code 1
.
this happened to me when path(AdditionalAppExtensions Include + BuildOutput), didn't point to the widget which xcode built. Haven't tried it on windows yet, so @dajbych your issue could be something else.
@programmation (and others here) - Please post a full build log
Hi @chamons thanks for your work with this. I created a draft PR to get the sample compiling in Xcode 12 GM. However building the Xamarin iOS app with the widget in Visual Studio is impossible for me atm, due to the ditto
compile error.
The PR is here: https://github.com/chamons/xamarin-ios-swift-extension/pull/1
Cheers
Love the PR, it does not surprise me that Apple broke the Widget after the Beta I wrote that in.
Above PR is updated and merged, everything is working in Visual Studio now, no more "ditto" exited with code 1
error. Thanks @chamons!
Is it possible to make an API call into my Xamarin phone app from the Swift widget to get data to display?
@t9mike - Not easily. The WidgetKit extension is in a separate process space than your main application, and can be invoked arbitrarily by Apple to get more timeline data.
It would be theoretically possible to use something like https://github.com/mono/Embeddinator-4000 to start up mono and then invoke C#, but that project has been in community support for awhile and isn't in the best shape today.
Due to this, I believe the best approach is to either serialize data in your application (or background task) to a common location (what the sample does) or fetch the data from a shared web service.
Thanks for the great demo app Chris! Based on your example, I managed to create a widget extension for my app, using group identifiers. All is working just fine in the simulator. Also, running directly from Xcode (swiftUI) on a real device works great. When I run the app from VS for Mac however (hybrid mode) on a real device, I get following error in the console log of the device:
container_create_or_lookup_path_for_platform: client is not entitled container_create_or_lookup_app_group_path_by_app_group_identifier: client is not entitled
I did include all group entitlements and also registered them at Apple Developer account.. Any idea what I'm missing? Thanks!
Love the fact that we can get Widgets working in Xamarin.iOS already. Don't mind having to implement the widget in SwiftUI. This may be a bit on the side - but at least a tip to make this easier for .NET developers not familiar with xcode builds, would be to describe how to build the native extension from the command line. We are using AppCenter for CI, and before I invest time in building the widget, I need to figure out how to build it (I expect I will spend more time on building the extension and signing it, than actually implementing the SwiftUi and the data exchange between the Xamarin app and the Swift UI widget) 😅
I'm finding it impossible to upload an app with a Widget to Apple. When I upload the app, this is the only error I am getting:
ERROR ITMS-90075: "This bundle is invalid. The application-identifier entitlement is missing; it should contain your 10-character Apple Developer ID, followed by a dot, followed by your bundle identifier."
I've inspected the package contents and everything seems in order. Is there any known issue around this @chamons?
No known issue - I'd verify all of your signing/entitlement/info.plsits.
Without a sample showing it, I'm not sure anyone will be able to help you here. Getting signing right is sometime non-trivial.
No known issue - I'd verify all of your signing/entitlement/info.plsits.
Without a sample showing it, I'm not sure anyone will be able to help you here. Getting signing right is sometime non-trivial.
Thanks. So after banging my head on a number of long nights, throwing everything including the kitchen sink at my code, I can finally build a version that is accepted by the App Store. I have no idea why this worked, but to save other people from experiencing the same issue, this was my fix:
In the Entitlements
files, in both the app and widget, I added application-identifier
with my full application identifier.
ie:
<key>application-identifier</key>
<string>XXXXXXXXXX.com.mysite.myapp</string>
And for the widget
<key>application-identifier</key>
<string>XXXXXXXXXX.com.mysite.myapp.mywidget</string>
Note that placeholders $(AppIdentifierPrefix)$(CFBundleIdentifier)
did not work.
Hi @chamons, when do you think direct support for WidgetKit in C# will be available?
This information will be useful with regards to our current scheduling plans, wether to go for SwiftUI right now, or wait for C# if its only a few months away.
Your example looks good, but having to use SwiftUI largely defeats the point of using Xamarin.iOS.
No known issue - I'd verify all of your signing/entitlement/info.plsits. Without a sample showing it, I'm not sure anyone will be able to help you here. Getting signing right is sometime non-trivial.
Thanks. So after banging my head on a number of long nights, throwing everything including the kitchen sink at my code, I can finally build a version that is accepted by the App Store. I have no idea why this worked, but to save other people from experiencing the same issue, this was my fix:
In the
Entitlements
files, in both the app and widget, I addedapplication-identifier
with my full application identifier. ie:<key>application-identifier</key> <string>XXXXXXXXXX.com.mysite.myapp</string>
And for the widget
<key>application-identifier</key> <string>XXXXXXXXXX.com.mysite.myapp.mywidget</string>
Note that placeholders
$(AppIdentifierPrefix)$(CFBundleIdentifier)
did not work.
I can confirm that was also the fix for my group-identifier issue above. Great find @michaeldimoudis !
@Csaba8472 Thank you, I didn't know that Visual Studio does not copy the extension code from Windows to Mac and does not build it there.
I'm able to create and build a SwiftUI app with widget on Mac with Xcode and deploy it to my iPhone. When I copy the widget extension to Windows and set AdditionalAppExtensions in the Xamarin.iOS project correctly, Visual Studio builds the project:
2> /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin/mtouch @/Users/user/Library/Caches/Xamarin/mtbs/builds/MyApp/116272d3d5ca5387493a48c56e38ac90/obj/iPhone/Debug/device-builds/iphone8.1-14.0.1/response-file.rsp
2> /usr/bin/ditto -rsrc "C:/Users/user/iCloudDrive/Documents/MyApp/MyApp-Widget-Build/Build/Products/Debug-iphoneos/WidgetExtension.appex" bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/PlugIns/WidgetExtension.appex
2> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil -num-threads 4 -z -o bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/../Mono.framework.dSYM bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/Frameworks/Mono.framework/Mono
2> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -S -x bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/Frameworks/Mono.framework/Mono
2> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil -num-threads 4 -z -o bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app.dSYM bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/MyApp
2> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -i -s obj/iPhone/Debug/device-builds/iphone8.1-14.0.1/mtouch-symbols.list bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/MyApp
2> /usr/bin/mdimport bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/../
2> /usr/bin/codesign --verify -vvvv "-R=anchor apple generic and certificate 1[field...] exists and (certificate leaf[field...] exists or certificate leaf[field...] exists)" bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/PlugIns/WidgetExtension.appex
2> /usr/bin/codesign --verify -vvvv "-R=anchor apple generic and certificate 1[field...] exists and (certificate leaf[field...] exists or certificate leaf[field...] exists)" bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app
========== Rebuild All: 2 succeeded, 0 failed, 0 skipped ==========
Both the Xamarin.iOS app and the SwiftUI widget extension are successfully signed, but the app is deployed to device without the widget extension:
1> /Library/Frameworks/Xamarin.iOS.framework/Versions/Current/bin/mtouch @/Users/user/Library/Caches/Xamarin/mtbs/builds/MyApp/116172d3d5ca5387493a48c56e38ac90/obj/iPhone/Debug/device-builds/iphone8.1-14.0.1/response-file.rsp
1> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil -num-threads 4 -z -o bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/../Mono.framework.dSYM bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/Frameworks/Mono.framework/Mono
1> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -S -x bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/Frameworks/Mono.framework/Mono
1> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/dsymutil -num-threads 4 -z -o bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app.dSYM bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/MyApp
1> /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/strip -i -s obj/iPhone/Debug/device-builds/iphone8.1-14.0.1/mtouch-symbols.list bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/MyApp
1> /usr/bin/mdimport bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/../
1> /usr/bin/codesign --verify -vvvv "-R=anchor apple generic and certificate 1[field...] exists and (certificate leaf[field...] exists or certificate leaf[field...] exists)" bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app/PlugIns/WidgetExtension.appex
1> /usr/bin/codesign --verify -vvvv "-R=anchor apple generic and certificate 1[field...] exists and (certificate leaf[field...] exists or certificate leaf[field...] exists)" bin/iPhone/Debug/device-builds/iphone8.1-14.0.1/MyApp.app
2>Starting deploy 'MyApp' into the device 'My iPhone 6s'...
2>Deploying 'MyApp' into the device 'My iPhone 6s'...
Installing application bundle 'com.dajbych.MyApp' on 'My iPhone 6s'
...
2>Deploy succeeded. The app 'MyApp' has been successfully deployed on My iPhone 6s.
...
Application bundle 'com.dajbych.MyApp' installed on 'My iPhone 6s'
I have noticed that the file in C:\Users\user\Documents\Sources\MyApp\bin\iPhone\Debug\device-builds\iphone8.1-14.0.1\MyApp.app\PlugIns\WidgetExtension.appex
is empty. The source file in C:\Users\user\iCloudDrive\Documents\MyApp\MyApp-Widget-Build\Build\Products\Debug-iphoneos\WidgetExtension.appex
has 40 kB. Am I doing something wrong, or it is a bug in the build chain?
Hi @chamons, when do you think direct support for WidgetKit in C# will be available?
I have your example working (thank you for that!) in so far as I can see a widget and add it to the simulator, although I don't see any data in the widget itself, Ive probably forgotten to do something there. However I have zero knowledge of working in SwiftUI, I did some ObjC back in the day but I chose Xamarin.iOS for a reason. :) It is going to be a bit of a slog to get my SwiftUI knowledge up to a level that will mean I can produce anything half decent. Are there any imminent plans to continue developing WidgetKit in C#? If you said it might be available in the next 3 months we would probably wait, otherwise we would need to start learning/deveping in SwiftUI now.
Cheers John
@JohnHDev I think it would be too much effort to map XAML to SwiftUI. Therefore, I think native WidgetKit will be the only option, unfortunately.
@wojciech-kulik
@JohnHDev I think it would be too much effort to map XAML to SwiftUI. Therefore, I think native WidgetKit will be the only option, unfortunately.
I am actually referring to writing widgets in Xamarin.iOS, so C#. Anything above that would be a bonus. But as a minimum I would want to see C# support. After all, that is the foundation of what Xamarin provides.
@JohnHDev Anyway, I think it would be a huge effort to support that, that’s why I think it won’t happen. I think in best case scenario, there will be some support for Widget project in VS, but you will have to work on that in Xcode. Similarly to Android, where you can add xml layouts. Maybe here you will be able to add SwiftUI files.
I already made widgets in Xcode in my project and I recommend to do the same, because even if they try to provide somehow some support for swiftui, it will take a long time IMO.
SwiftUI is nice and easy, but the only problem is if you need API then you will need to rewrite your service and models to Swift.
@wojciech-kulik well, lets see what Xamarin says.
@wojciech-kulik Are you using Visual Studio for Mac, or Visual Studio 2019? I already made my Widget in Xcode and SwiftUI and it works fine when deployed from Xcode, but I not able to integrate it into my Xamarin.iOS application in Visual Studio 2019 on Windows.
@dajbych I'm using Visual Studio For Mac. I've seen some issue somewhere, that on Windows doesn't work copying additional extensions. So maybe that's the problem.
As a workaround, you could try to add build phase and copy your appex file manually into your bundle to PlugIns
directory. If you are using app groups for sharing data, you also need to sign it.
I don't mind developing the widget on SwiftUI, but WidgetKit should be accessible somehow. Without it we can't reload timelines when data is updated. I really need to be able to use WidgetCenter.shared.reloadTimelines(ofKind: "com.myapp.mywidget")
or WidgetCenter.shared.reloadAllTimelines()
from the main app to make the widgets useful.
Has anyone successfully integrated WidgetKit built in Xcode 12.2 with Xamarin in VS Mac? When this first came out, I could build, run and publish the app with widgeet, but now I notice that my widget doesn't even show up in the search on the phone. I can run the Swift code from XCode just fine. I can see the appex being picked up in the build logs:
Target "_CopyAppExtensionsToBundle" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets":
Building target "_CopyAppExtensionsToBundle" completely.
Output file "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex" does not exist.
Task "MakeDir"
Creating directory "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns".
Done executing task "MakeDir".
Using "Ditto" task from assembly "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Tasks.dll".
Task "Ditto"
/usr/bin/ditto -rsrc Widget/Build/Products/Debug-iphoneos/AppWidgetExtension.appex bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex
Done executing task "Ditto".
Task "RemoveDir"
Removing directory "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex/_CodeSignature".
Directory "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/../AppWidgetExtension.appex.dSYM" doesn't exist. Skipping.
Done executing task "RemoveDir".
Done building target "_CopyAppExtensionsToBundle" in project "App.iOS.csproj".
...
Target "_CodesignAppExtensions" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets":
Building target "_CodesignAppExtensions" completely.
Output file "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex/_CodeSignature/CodeResources" does not exist.
Task "CodesignNativeLibraries" skipped, due to false condition; ('$(IsMacEnabled)' == 'true' And '%(_AppExtensionCodesignProperties.LibrarySigningKey)' != '') was evaluated as ('true' == 'true' And '' != '').
Task "Codesign"
Tool /usr/bin/codesign execution started with arguments: -v --force --timestamp=none --sign "Apple Development: XXXXX" --entitlements /Users/admin/Documents/grammaire/App/App.iOS/Widget/AppWidgetExtension.entitlements --timestamp=none /Users/admin/Documents/grammaire/App/App.iOS/bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex
Tool /usr/bin/codesign execution finished (exit code = 0).
Done executing task "Codesign".
Task "Touch" skipped, due to false condition; ('$(IsMacEnabled)' == 'true' And ('$(_CanOutputAppBundle)' == 'true' And '%(_AppExtensionCodesignProperties.SigningKey)' != '') And Exists ('$(AppBundleDir)\..\%(_AppExtensionCodesignProperties.Identity).dSYM\Contents\Info.plist')) was evaluated as ('true' == 'true' And ('True' == 'true' And 'Apple Development: XXXXX' != '') And Exists ('bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app\..\AppWidgetExtension.appex.dSYM\Contents\Info.plist')).
Task "Touch"
Touching "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex/_CodeSignature/CodeResources".
Done executing task "Touch".
Done building target "_CodesignAppExtensions" in project "App.iOS.csproj".
Here is my VS Mac version: === Visual Studio Community 2019 for Mac ===
Version 8.8.3 (build 16) Installation UUID: 33ba9349-a2e6-4f41-b8f4-0ead5fc49e6e GTK+ 2.24.23 (Raleigh theme) Xamarin.Mac 6.18.0.23 (d16-6 / 088c73638)
Package version: 612000107
=== Mono Framework MDK ===
Runtime: Mono 6.12.0.107 (2020-02/a22ed3f094e) (64-bit) Package version: 612000107
=== Roslyn (Language Service) ===
3.8.0-5.20519.18+4c195c3ac1974edcefa76774d7a59a2350ec55fa
=== NuGet ===
Version: 5.8.0.6860
=== .NET Core SDK ===
SDK: /usr/local/share/dotnet/sdk/5.0.100/Sdks SDK Versions: 5.0.100 3.1.404 3.1.403 3.1.402 3.1.401 3.1.302 3.1.301 3.1.300 3.1.202 3.1.200 3.1.102 3.1.101 3.1.100 3.0.101 3.0.100 2.1.810 2.1.701 2.1.700 2.1.505 2.1.504 2.1.503 2.1.302 2.1.301 2.1.4 2.0.0 MSBuild SDKs: /Applications/Visual Studio.app/Contents/Resources/lib/monodevelop/bin/MSBuild/Current/bin/Sdks
=== .NET Core Runtime ===
Runtime: /usr/local/share/dotnet/dotnet Runtime Versions: 5.0.0 3.1.10 3.1.9 3.1.8 3.1.7 3.1.6 3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.1 3.0.0 2.1.23 2.1.22 2.1.21 2.1.20 2.1.19 2.1.18 2.1.17 2.1.16 2.1.15 2.1.14 2.1.13 2.1.12 2.1.11 2.1.9 2.1.8 2.1.7 2.1.2 2.1.1 2.0.5 2.0.0
=== .NET Core 3.1 SDK ===
SDK: 3.1.404
=== Xamarin.Profiler ===
Version: 1.6.12.26 Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler
=== Updater ===
Version: 11
=== Apple Developer Tools ===
Xcode 12.2 (17535) Build 12B45b
=== Xamarin.Mac ===
Version: 7.0.0.15 (Visual Studio Community) Hash: 87a1b18d8 Branch: d16-8 Build date: 2020-11-16 21:39:40-0500
=== Xamarin.iOS ===
Version: 14.6.0.15 (Visual Studio Community) Hash: 87a1b18d8 Branch: d16-8 Build date: 2020-11-16 21:39:41-0500
=== Xamarin Designer ===
Version: 16.8.0.507 Hash: e87b24884 Branch: remotes/origin/d16-8 Build date: 2020-10-29 00:31:38 UTC
=== Xamarin.Android ===
Version: 11.1.0.17 (Visual Studio Community) Commit: xamarin-android/d16-8/c0e2b8e Android SDK: /Users/admin/Library/Developer/Xamarin/android-sdk-macosx Supported Android versions: 6.0 (API level 23) 7.1 (API level 25) 8.1 (API level 27)
SDK Tools Version: 26.1.1 SDK Platform Tools Version: 30.0.5 SDK Build Tools Version: 30.0.2
Build Information: Mono: be2226b Java.Interop: xamarin/java.interop/d16-8@79d9533 ProGuard: Guardsquare/proguard/proguard6.2.2@ebe9000 SQLite: xamarin/sqlite/3.32.1@1a3276b Xamarin.Android Tools: xamarin/xamarin-android-tools/d16-8@2fb1cbc
=== Microsoft OpenJDK for Mobile ===
Java SDK: /Users/admin/Library/Developer/Xamarin/jdk/microsoft_dist_openjdk_8.0.25 1.8.0-25 Android Designer EPL code available here: https://github.com/xamarin/AndroidDesigner.EPL
=== Android SDK Manager ===
Version: 16.8.0.32 Hash: 01a7774 Branch: remotes/origin/d16-8 Build date: 2020-10-13 23:32:30 UTC
=== Android Device Manager ===
Version: 16.8.0.45 Hash: fc0af5f Branch: remotes/origin/d16-8 Build date: 2020-10-13 23:32:54 UTC
=== Build Information ===
Release ID: 808030016 Git revision: cc6375d2fdcc1b42532e551e24ce650eaca1ae45 Build date: 2020-11-25 13:16:20-05 Build branch: release-8.8 Xamarin extensions: cc6375d2fdcc1b42532e551e24ce650eaca1ae45
=== Operating System ===
Mac OS X 10.15.7 Darwin 19.6.0 Darwin Kernel Version 19.6.0 Thu Oct 29 22:56:45 PDT 2020 root:xnu-6153.141.2.2~1/RELEASE_X86_64 x86_64
@chamons any suggestion on how to debug this?
No known issue - I'd verify all of your signing/entitlement/info.plsits. Without a sample showing it, I'm not sure anyone will be able to help you here. Getting signing right is sometime non-trivial.
Thanks. So after banging my head on a number of long nights, throwing everything including the kitchen sink at my code, I can finally build a version that is accepted by the App Store. I have no idea why this worked, but to save other people from experiencing the same issue, this was my fix:
In the
Entitlements
files, in both the app and widget, I addedapplication-identifier
with my full application identifier. ie:<key>application-identifier</key> <string>XXXXXXXXXX.com.mysite.myapp</string>
And for the widget
<key>application-identifier</key> <string>XXXXXXXXXX.com.mysite.myapp.mywidget</string>
Note that placeholders
$(AppIdentifierPrefix)$(CFBundleIdentifier)
did not work.
Regarding adding the "application-identifier" for creating a store release. I experienced the same problems, you will only need to put in the "application-identifier" in NativeWidgetExtension.Entitlements, not in the other ones. Checking the ipa archive with " codesign -d --entitlements :-" it seems to be done automatically for the other entitlements. And also when running in Debug iPhoneSimulator I needed to remove the application-identifier from the Entitlements again otherwise it doesn't work. I tried to create multiple Entitlements files in XCode depending on the Configuration (Debug/Release) but that also didn't seem to work. I suspect this is a problem of the Xamarin build process ?
Just because this wasn't immediately clear to me, and in case this is helpful for anyone else having trouble trying to get widget & intents extensions working with Xamarin: For the signing fix from wojciech-kulik (thank you very much!) to work, it looks like the entitlements for your widget or other extensions need to be in the folder mentioned in the AdditionalAppExtensions Include, and it needs to match the name that's mentioned there. E.g., if you have something like this in your csproj:
<AdditionalAppExtensions Include="$(MSBuildProjectDirectory)/../WidgetFolder">
<Name>WidgetExtensionName</Name>
<!-- Snip -->
</AdditionalAppExtensions>
You need to have WidgetExtensionName.entitlements directly in WidgetFolder.
I initially had my entitlements files in different folders, and the codesign steps in the Xamarin build weren't picking them up, even though they worked fine in Xcode builds.
Also, I had the same experience as JeroenBer with application-identifier
-- I needed to add application-identifier
to my extensions (I have both a widget extension and an intents extension in the app I'm working with), but not the main app. It looks like because of the way the build is done in Xamarin, it's always using the entitlements? So I also had to remove the application-identifiers temporarily when using the iOS Simulator, otherwise neither the widget nor the intents extensions worked, even when a debug version was specified in Xcode (when built/run through Visual Studio).
Has anyone successfully integrated WidgetKit built in Xcode 12.2 with Xamarin in VS Mac? When this first came out, I could build, run and publish the app with widgeet, but now I notice that my widget doesn't even show up in the search on the phone. I can run the Swift code from XCode just fine. I can see the appex being picked up in the build logs:
Target "_CopyAppExtensionsToBundle" in file "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Common.targets": Building target "_CopyAppExtensionsToBundle" completely. Output file "bin/iPhone/Debug/device-builds/iphone10.1-14.2/App.iOS.app/PlugIns/AppWidgetExtension.appex" does not <skipped> @chamons any suggestion on how to debug this?
Hi all,
I'm still struggling to get this working. I have the widget built on XCode on the Mac, but then I copied the DerivedData (the output of the build process on the mac) to the windows machine where we build the xamarin.ios project itself and tried to integrate the built extension into it but it fails.
C:\Program Files (x86)\Microsoft Visual Studio\2019\Community\MSBuild\Xamarin\iOS\Xamarin.iOS.Common.targets(1543,3): error MSB6006: "ditto" exited with code 1.
I've built with the diagnostics level of logging and it says:
ditto: Cannot get the real path for source 'D:/Work/%mypathtowhere-appex-should-be%/MyWidget.appex' (TaskId:349)
I've double checked and all the pathes are correct, exist, etc. Is that because ditto meant to be run on Mac only? So I can't build the xamarin.ios project using VS for Windows and run from it?
If so, is it the only way then to publish widget separately from Mac, then publish updated version of the main app from Windows into the appstore and hope they will work together when tested using TestFlight?
@alex-konstantinov My experience: I wasn't able to get the app with extensions built in Windows, though I may go back at some point and try again/try to narrow down the problem. I build my debug/test versions on Mac, and I build release versions sent to TestFlight using AppCenter (https://appcenter.ms) in a way that's pretty close to what's described in Michael Dimoudis' article: https://michaeldimoudis.medium.com/ios-14-widgets-with-xamarin-forms-e186d24a0638
I admire people who keep fighting with iOS apps on Windows. I know this is quite a big expense, but in the long term, the best thing you can do is to invest in MacBook. Many problems will disappear and you will be more flexible with adding some native code.
I've been working in a team where some people had Windows and some macOS. The difference was huge in terms of daily iOS development problems.
Hi guys, thanks for sharing your thoughts and experience. Yes, I mostly used Michael's article from the beginning so it was a good starting point!
We do have the mac mini in the office as we also build/debug/test some other native apps, but I have a lot of other .net & .net core related development so it is just more convenient for me to stay on my windows laptop and just use the VS to build the main xamarin.ios app (as well as android app). It's just connecting to mac mini via the network when it needs to.
I'm sure at some point in future Xamarin team will make it working the same way for widgets projects. From what I understand, it is enough to have the built on mac widget output copied into a proper place and signed. In order to be able to run it along with main app during debugging on Windows machine from VS.
I still think this scenario may be common for some people out there so I'll try to find a solution or a workaround. Maybe to alter the xamarin targets file and replace the dittor running task with just copying/signing. I'll have a look into it. It's just a lot more convenient for me to debug both android and ios apps from the Windows machine. And it is OK to use mac once just to create the extension itself and its UI there and then just use its build output.
P.S. Obviously the publishing will have to be done from XCode for the widget (if not the AppCenter) as there is no such project in VS yet, so it knows nothing about the publishing of the widgets. However I do publish both android and ios apps from VS without any issues. P.P.S. Actually while I was writing this reply I realised that ditto is a macos command to copy files. So this task is being run on the mac while VS builds there. And the input path of the 'build widget' should be in the context of mac machine. So I need to figure out where to copy the built widget output to be run when I'm debugging from windows. I thought it was meant to be put into MyMainApp.iOS\bin\iPhone\Debug\MyMainApp.iOS.app\PlugIns folder on the windows machine but probably I was wrong and Ditto task is expecting the path on mac machine, even if I started the build from VS on Windows. This is a bit messed up now in my head. I need to understand first all of the build phases and debug run phases when I do debug from VS on Windows but Mac is used via network connection to build and run main app.
Well, I gave up trying to make it build from Windows. It still tries to run the tasks on Mac, but it's rejecting my paths. I've tried to replace Ditto task with SmartCopy task in the .targets file. Still doesn't work.
So I think I'll use the VS for Mac just to debug the Widget. Then I'll use XCode to publish widget. I guess the publishing of the main app from VS for Windows will not be affected in any way? Or is it incorporating the widget somehow into the build of the main application?
How do you want to use Xcode to publish the widget? You can just add in csproj AdditionalAppExtensions
section which will copy automatically widget extension into xcarchive/ipa or you can build the widget in Xcode, create xcarchive from VS and then copy widget extension into xcarchive. However, it might a bit tricky, if you mess up something it won't work.
I would recommend to create sample project with widget, generate xcarchive and see what do you need to copy into your project. I think that for widgets it's enough to copy "appex" file into "PlugIns" directory.
Hi Wojciech, I probably was too tired after fighting this to make it working on Windows so I mistyped. Certainly, I've installed the VS on mac and once it builds on mac for me properly, after debugging and final changes to the widget, I'll try to publish it from VS on mac with the node in the project file to specify additionalAppExtensions.
However, once the widget is done, you might be actually right and we may look into incorporating the widget manually after all and proceed with development on windows. We'll try all options and see what would be most convenient for us.
Thanks for the ideas!
Thanks to all of the commenters out there. This thread turned out to be very useful!
Afterall I've managed to proceed with the development and debugging on our mac (I just still do that from my windows laptop, via remote desktop to the mac :) ) & VS for Mac. Built, tested and published to AppStore. The widget itself and the opening of the main app via custom URL type to pass the mode and params to the main app works like a charm.
Hopefully, someday VS for Windows will be able to build the Widget just like it is done with the main app. So mac would be used over the network for compile only. That would be handy.
Code Signing the SwitfUO App Extension is not working yet. I have integrated a Hybrid Version, but the Codesigning step failed with the Error: iPhone Developer: no identity found
Target _CodesignAppExtensions:
Building target "_CodesignAppExtensions" completely.
Output file "bin/iPhone/Debug/Hoermann.BleApp.iOS.app/PlugIns/Hoermann.BleApp.iOS.Native.WidgetExtensionExtension.appex/_CodeSignature/CodeResources" does not exist.
Task "CodesignNativeLibraries" skipped, due to false condition; ('$(IsMacEnabled)' == 'true' And '%(_AppExtensionCodesignProperties.LibrarySigningKey)' != '') was evaluated as ('true' == 'true' And '' != '').
Using "Codesign" task from assembly "/Library/Frameworks/Mono.framework/External/xbuild/Xamarin/iOS/Xamarin.iOS.Tasks.dll".
Task "Codesign"
Tool /usr/bin/codesign execution started with arguments: -v --force --timestamp=none --sign "iPhone Developer" --entitlements /Users/sprenger_m/source/bluesecur_raw/src/Hoermann.BleApp.iOS.Native/Hoermann.BleApp.iOS.Native.WidgetExtensionExtension.entitlements --timestamp=none /Users/sprenger_m/source/bluesecur_raw/src/Hoermann.BleApp.iOS/bin/iPhone/Debug/Hoermann.BleApp.iOS.app/PlugIns/Hoermann.BleApp.iOS.Native.WidgetExtensionExtension.appex
Tool /usr/bin/codesign execution finished (exit code = 1).
bin/iPhone/Debug/Hoermann.BleApp.iOS.app/PlugIns/Hoermann.BleApp.iOS.Native.WidgetExtensionExtension.appex : error : iPhone Developer: no identity found
Done executing task "Codesign" -- FAILED.
Done building target "_CodesignAppExtensions" in project "Hoermann.BleApp.iOS.csproj" -- FAILED.
How can I fix this problem? And how can I produce an AppStore Version with correct Distribution Certificate?
Hi @SprengerS ,
did you find any solution to this?
Edit: found the problem in my .csproj where the property "CodesignKey" was set to "iPhone Developer".
-- Eddy
Just because this wasn't immediately clear to me, and in case this is helpful for anyone else having trouble trying to get widget & intents extensions working with Xamarin: For the signing fix from wojciech-kulik (thank you very much!) to work, it looks like the entitlements for your widget or other extensions need to be in the folder mentioned in the AdditionalAppExtensions Include, and it needs to match the name that's mentioned there. E.g., if you have something like this in your csproj:
<AdditionalAppExtensions Include="$(MSBuildProjectDirectory)/../WidgetFolder"> <Name>WidgetExtensionName</Name> <!-- Snip --> </AdditionalAppExtensions>
You need to have WidgetExtensionName.entitlements directly in WidgetFolder.
I initially had my entitlements files in different folders, and the codesign steps in the Xamarin build weren't picking them up, even though they worked fine in Xcode builds.
Also, I had the same experience as JeroenBer with
application-identifier
-- I needed to addapplication-identifier
to my extensions (I have both a widget extension and an intents extension in the app I'm working with), but not the main app. It looks like because of the way the build is done in Xamarin, it's always using the entitlements? So I also had to remove the application-identifiers temporarily when using the iOS Simulator, otherwise neither the widget nor the intents extensions worked, even when a debug version was specified in Xcode (when built/run through Visual Studio).
You saved my day @adam-russell . Thanks!!!
Hi.
I cloned @chamons sample repo, it works fine until I place the widget on the screen it never loads data...
I configure app groups everywhere in entitlements, provisioning.
Also changed group identifier on:
ViewController.cs
and also at
TestDataReader.swift
Am I missing something?
Any help would be really appreciated, Thanks!
Data sharing using App group container not working when tested on real device with iOS Version 15 and 15.1.
Check in release mode if possible
Note : It does work on simulator just fine but when deployed on real device widget does not load any data and only grey line placeholder showing over views.
It does work if I provide static/hardcoded data to the Swift widget application.But not through App group data sharing using xamarin app
I have also tried with NSUserDefaults using suite name but the same result
Steps : Download this project Set up App group and certificates on both side native and xamarin application Run Xamarin test application on real device having iOS 15 or 15.1 version
Xcode Version : 13,13.1 iOS Version : 15.0,15.1 Device : iPhone 12,13 Visual Studio : Everything updated to the latest stable VS 2019
Screenshot attached
@SarthakGz I had the same issue as you can see in this thread. I got it working now, this is what I did:
@Jon2G thanks for your response.just confirming if you are able to test this on Xcode 13 and latest iOS 15 or 15.1 and on real device especially Yes everything working fine for iOS 12,12.5 but not for iOS 15 with XCode 13 and on real device
@SarthakGz Working with XCode 13, macOS Monterrey, iPhone SE2 running IOS 15.0.2 The widget never works for me on the simulator by the way so I had to develop it using the real device only.
@SarthakGz We also use the Xamarin App with an WidgetKit App Extensions. Both have the same AppGroup and we habe NO Problems with data Sharing over the App Group. We are using a SQLite Database which is filled by the App and the Widget and the IntentExtension are reading the data from our SQLite Database.
_ExtendAppExtensionReferences
Build Target in order to sign our Widget correctly during the Build Process. Signing the AdditionalAppExtension has only worked for an iPhone Distribution
Certificate and not for an Apple Distribution´. For Develop builds we use the default Target, but for Distribution we use our
Apple Distribution` certificateThanks @SprengerS for the info.I guess I will try with XCode automatically manage signing option if that helps Though I am creating iOS build with enterprise certificates but that should not make any difference.Will think more about this
This is a feature released in Xcode 12.
For now, this is what is known: https://developer.apple.com/widgets/