xamarin / xamarin-macios

.NET for iOS, Mac Catalyst, macOS, and tvOS provide open-source bindings of the Apple SDKs for use with .NET managed languages such as C#
Other
2.47k stars 512 forks source link

[xcode12] WidgetKit #8933

Open chamons opened 4 years ago

chamons commented 4 years ago

This is a feature released in Xcode 12.

For now, this is what is known: https://developer.apple.com/widgets/

chamons commented 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.

chamons commented 4 years ago

See the PR for an example. More details in a future blog post as well.

mobilinked commented 4 years ago

@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

programmation commented 4 years ago

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.

dajbych commented 4 years ago

Same problem here. Visual Studio 2019 version 16.7.4 ends the build with the following error: "ditto" exited with code 1.

Csaba8472 commented 4 years ago

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.

chamons commented 4 years ago

@programmation (and others here) - Please post a full build log

michaeldimoudis commented 4 years ago

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

chamons commented 4 years ago

Love the PR, it does not surprise me that Apple broke the Widget after the Beta I wrote that in.

michaeldimoudis commented 4 years ago

Above PR is updated and merged, everything is working in Visual Studio now, no more "ditto" exited with code 1 error. Thanks @chamons!

t9mike commented 4 years ago

Is it possible to make an API call into my Xamarin phone app from the Swift widget to get data to display?

chamons commented 4 years ago

@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.

lunoit commented 4 years ago

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!

follesoe commented 4 years ago

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) 😅

michaeldimoudis commented 4 years ago

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?

chamons commented 4 years ago

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.

michaeldimoudis commented 4 years ago

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.

JohnHDev commented 4 years ago

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.

lunoit commented 4 years ago

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.

I can confirm that was also the fix for my group-identifier issue above. Great find @michaeldimoudis !

dajbych commented 4 years ago

@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?

JohnHDev commented 4 years ago

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

wojciech-kulik commented 4 years ago

@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.

JohnHDev commented 4 years ago

@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.

wojciech-kulik commented 4 years ago

@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.

JohnHDev commented 4 years ago

@wojciech-kulik well, lets see what Xamarin says.

dajbych commented 4 years ago

@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.

wojciech-kulik commented 4 years ago

@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.

BrenoAngelotti commented 3 years ago

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.

wojciech-kulik commented 3 years ago

@BrenoAngelotti https://github.com/xamarin/xamarin-macios/issues/8931#issuecomment-701357996

motoko89 commented 3 years ago

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?

JeroenBer commented 3 years ago

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.

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 ?

adam-russell commented 3 years ago

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).

alex-konstantinov commented 3 years ago

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?

adam-russell commented 3 years ago

@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

wojciech-kulik commented 3 years ago

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.

alex-konstantinov commented 3 years ago

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.

alex-konstantinov commented 3 years ago

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?

wojciech-kulik commented 3 years ago

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.

alex-konstantinov commented 3 years ago

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!

alex-konstantinov commented 3 years ago

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.

SprengerS commented 3 years ago

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?

DevEddy commented 3 years ago

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

ramonesteban78 commented 3 years ago

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).

You saved my day @adam-russell . Thanks!!!

Jon2G commented 3 years ago

Hi. image 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!

SarthakGz commented 2 years ago

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

Screenshot 2021-11-16 at 3 06 03 PM
Jon2G commented 2 years ago

@SarthakGz I had the same issue as you can see in this thread. I got it working now, this is what I did:

SarthakGz commented 2 years ago

@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

Jon2G commented 2 years ago

@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.

SprengerS commented 2 years ago

@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.

SarthakGz commented 2 years ago

Thanks @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