xamarin-macios
xamarin-macios copied to clipboard
[xcode12] WidgetKit
This is a feature released in Xcode 12.
For now, this is what is known: https://developer.apple.com/widgets/
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:
- Expose xamarin lib project to an XCode framework
- And use a XCode framework as a xamarin project lib
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.
@BrenoAngelotti https://github.com/xamarin/xamarin-macios/issues/8931#issuecomment-701357996
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?