Bug 44526 - actool ignores subdirectories when grabbing files in Assets.xcassets
Summary: actool ignores subdirectories when grabbing files in Assets.xcassets
Alias: None
Product: iOS
Classification: Xamarin
Component: MSBuild ()
Version: XI 10.0 (iOS10)
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: (C9)
Assignee: Jeffrey Stedfast
Depends on:
Reported: 2016-09-20 15:32 UTC by ulrike_axen
Modified: 2018-01-12 11:22 UTC (History)
8 users (show)

Is this bug a regression?: ---
Last known good build:

Xamarin test watch app with complication that won't display (306.60 KB, application/zip)
2016-09-20 15:32 UTC, ulrike_axen
Xcode project with complication that DOES display (51.53 KB, application/zip)
2016-09-20 15:33 UTC, ulrike_axen
Xcode with complication that displays and complication bundle added (51.65 KB, application/zip)
2016-09-22 16:26 UTC, ulrike_axen
Xamarin watch app with complication that won't display and bundle not added to gallery (312.77 KB, application/zip)
2016-09-22 16:27 UTC, ulrike_axen
Result of manually embedding Assets.car from Xcode .appex output (19.99 KB, image/png)
2016-10-04 02:22 UTC, CraigD

Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.

Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:

Description ulrike_axen 2016-09-20 15:32:42 UTC
Created attachment 17614 [details]
Xamarin test watch app with complication that won't display

I've added a complicationController to my same Xamarin test Watch app. The complication image does not display when I add it to a watch face, although tapping on the location does launch the app. So the problem is simply with displaying the image. I've created the same scenario in a test Xcode app that does nothing, although the complication image DOES display there. As far as I can tell, my code in the swift complicationController is functionally the same as the Xamarin one, and the settings in the info.plist are the same, and the assets are the same. I've also tried every way in Xamarin code to create the UIImage (FromBundle, FromResource, etc.) but none of them work. 

I will attach both the Xcode and the Xamarin projects. Repro steps:
1. Build the Xcode project. Run in the simulator. Customize one of the watch faces (i.e., Modular) and add the testComplication Complication. See that it displays. Not all the watch faces allow custom complication (apparently), but in each one that allowed access to this complication, it displays.

2. Go through the same steps with the Xamarin app. Notice that the complication image never displays.
Comment 1 ulrike_axen 2016-09-20 15:33:56 UTC
Created attachment 17615 [details]
Xcode project with complication that DOES display

Compare these two projects. Why does the complication not display with the Xamarin app?
Comment 2 ulrike_axen 2016-09-20 15:34:40 UTC
Here is my current setup:
=== Xamarin Studio Enterprise ===

Version 6.1 (build 5441)
Installation UUID: 0ca42116-8f54-4ad6-bd25-aa90f20c571f
	Mono 4.6.0 (mono-4.6.0-branch/746756c) (64-bit)
	GTK+ 2.24.23 (Raleigh theme)

	Package version: 406000245

=== NuGet ===


=== Xamarin.Profiler ===

Location: /Applications/Xamarin Profiler.app/Contents/MacOS/Xamarin Profiler

=== Apple Developer Tools ===

Xcode 8.0 (11246)
Build 8A218a

=== Xamarin.iOS ===

Version: (Xamarin Enterprise)
Hash: 6c3fee4
Branch: xcode8
Build date: 2016-09-09 13:01:32-0400

=== Xamarin.Android ===

Version: (Xamarin Enterprise)
Android SDK: /Users/axenu/Library/Developer/Xamarin/android-sdk-mac_x86
	Supported Android versions:
		2.3    (API level 10)
		4.0.3  (API level 15)
		4.3    (API level 18)
		4.4    (API level 19)
		4.4.87 (API level 20)
		5.0    (API level 21)
		5.1    (API level 22)
		6.0    (API level 23)

SDK Tools Version: 25.1.1
SDK Platform Tools Version: 23.1
SDK Build Tools Version: 23.0.3

Java SDK: /usr
java version "1.8.0_74"
Java(TM) SE Runtime Environment (build 1.8.0_74-b02)
Java HotSpot(TM) 64-Bit Server VM (build 25.74-b02, mixed mode)

Android Designer EPL code available here:

=== Xamarin Android Player ===

Not Installed

=== Xamarin.Mac ===

Version: (Xamarin Enterprise)

=== Build Information ===

Release ID: 601005441
Git revision: 68292d1ab289911c815ddc715dd7cc29a9752f9f
Build date: 2016-09-09 04:43:23-04
Xamarin addins: ed25d008672663eeb9db55f1ccecb3c24d2fd3b2
Build lane: monodevelop-lion-cycle8

=== Operating System ===

Mac OS X 10.11.6
Darwin ulrikes-mbp-2.ms.starkey.com 15.6.0 Darwin Kernel Version 15.6.0
    Mon Aug 29 20:21:34 PDT 2016
    root:xnu-3248.60.11~1/RELEASE_X86_64 x86_64
Comment 3 ulrike_axen 2016-09-22 16:26:03 UTC
Adding on to this bug because it may be related (but maybe not). Adding a complication bundle to the watch app in Xamarin does not add the watch complication to the WatchApp gallery, as described in Apple docs:


It works for the Xcode project. I will update my sample projects to ones that include the complication bundles generated by the watch simulator.
Comment 4 ulrike_axen 2016-09-22 16:26:50 UTC
Created attachment 17683 [details]
Xcode with complication that displays and complication bundle added
Comment 5 ulrike_axen 2016-09-22 16:27:59 UTC
Created attachment 17684 [details]
Xamarin watch app with complication that won't display and bundle not added to gallery
Comment 6 CraigD 2016-09-27 16:19:09 UTC
Regarding Comment #3 - the bundle goes in the iOS app, not the watch app.

I haven't checked on device yet, but the Complication sample:


includes a bundle:


which shows up in the simulator's gallery:

Comment 7 ulrike_axen 2016-09-27 16:30:44 UTC
I was so excited to hear there was a sample, I went right to it!! The difference is, the sample only includes text in the complication. Mine only includes images. Something is not working with images...

Also, for watch os3, i think you have to use GetLocalizableSampleTemplate in place of GetPlaceholderTemplate (Watch OS 2 only, according to some Apple doc I read).

But, my sample includes both, so hoping to actually _see_ the complication image in a next update of Xamarin, thanks!
Comment 8 ulrike_axen 2016-09-30 13:54:05 UTC
*Crickets*... Is there any chance this could be triaged and assigned soon? It would be of benefit to our users to include a launch complication on the watch face. Thanks!
Comment 9 ulrike_axen 2016-10-03 12:56:59 UTC
@CraigD Reading again Comment 6: I did put the complication bundle in the iOS app, not the watch app. I followed the same procedure in the Xamarin app as the Xcode app. Any chance this could be looked at this week? I know you have a sample app and your documentation includes complications, but they don't have images. We are working on a release and would like to have an image as a launch complication. Thanks!
Comment 10 Timothy Risi 2016-10-04 00:24:24 UTC
Where do you have the images saved you're trying to display?  I don't see them in the project.  I tried adding a new image to the project and set it to use that image for the complications using UIImage.FromFile and it displayed correctly.
Comment 11 CraigD 2016-10-04 02:21:36 UTC
1. I can get an image displaying in the complication (like Tim said) using

if (complication.Family == CLKComplicationFamily.ModularSmall)
   var rimgTemplate = new CLKComplicationTemplateModularSmallSimpleImage();
   rimgTemplate.ImageProvider = CLKImageProvider.Create(UIImage.FromFile("my_image"));
   entry = CLKComplicationTimelineEntry.Create(NSDate.Now, rimgTemplate);

as long as `my_image` is a *BundleResource* in the WatchExtension project root. It does *not* work if the image is in the WatchApp project, nor if I use `FromBundle`. It does *not* work any images in xcassets.

2. On closer examination of the Xamarin project (*Show Package Contents* of  bin/iPhoneSimulator/Debug/WatchApp.app), it appears that we are not building an **Assets.car** file in either the Watch App or Extension.
a. In the WatchApp, the assets are just embedded directly into the .app (no .car file). This makes things "seem" to work (the app icon is displayed) but I don't think it's the correct behavior.
b. In the WatchExtension, the assets I placed in the xcassets aren't there at all! This is definitely a bug.

To prove this further, I built your Xcode project attachment, opened it up and took out the Assets.car file it created in the .appex package. I placed the Assets.car from Xcode's output into the Xamarin WatchExtension project root (BuildType:BundleResource) and THEN the following code works as it should:

if (complication.Family == CLKComplicationFamily.ModularSmall)
   var rimgTemplate = new CLKComplicationTemplateModularSmallSimpleImage();
   rimgTemplate.ImageProvider = CLKImageProvider.Create(UIImage.FromBundle(@"Complication/Modular"));
   entry = CLKComplicationTimelineEntry.Create(NSDate.Now, rimgTemplate);

(see my watch sim screenshot attachment)

So - two workarounds for now:
i. embed images as BundleResource and use .FromFile
ii. generate an Assets.car file via Xcode, and embed it manually until we've fixed everything

It looks to me like we have a bug creating Assets.car files in both WatchApp and WatchExtension projects tho' - at least: we don't produce the same .app/.appex output as Xcode does for the same xcassets.
Comment 12 CraigD 2016-10-04 02:22:48 UTC
Created attachment 17852 [details]
Result of manually embedding Assets.car from Xcode .appex output
Comment 13 CraigD 2016-10-04 04:43:59 UTC
Update on Comment #11 - I've checked other watchOS 3 solutions (eg. the WatchKitCatalog) and both the WatchApp and WatchExtension _have_ Assets.car files. So assume there's an issue specific to Complication xcassets.

Turns out, WatchApp and WatchExtension projects seem to *ignore* the Complication node in Assets.xcassets:
* If there is _only_ a Complication node in your Assets.xcassets folder, NO Assets.car gets generated
* If you add another image asset to Assets.xcassets, an Assets.car is generated BUT it only contains the image (the Complication resources are missing)

Here's the build output

	Target _CoreCompileImageAssets:
		ACTool Task
		  AppManifest: Info.plist
		  DeviceModel: <null>
		  DeviceOSVersion: <null>
		  IntermediateOutputPath: obj/iPhoneSimulator/Debug/
		  IsWatchApp: False
		  OptimizePNGs: True
		  OutputPath: bin/iPhoneSimulator/Debug/
		  ProjectDir: /Users/craigdunn/ProjectsConceptdev/xamarin-ios-samples/WatchComplication/iOSApp.WatchAppExtension
		  ResourcePrefix: Resources
		  SdkBinPath: /Applications/Xcode.app/Contents/Developer/usr/bin
		  SdkPlatform: WatchSimulator
		  SdkVersion: 3.0
		Tool /Applications/Xcode.app/Contents/Developer/usr/bin/actool execution started with arguments: --errors --warnings --notices --output-format xml1 --compress-pngs --target-device iphone --target-device ipad --target-device watch --minimum-deployment-target 3.0 --platform watchsimulator --compile /Users/craigdunn/ProjectsConceptdev/xamarin-ios-samples/WatchComplication/iOSApp.WatchAppExtension/obj/iPhoneSimulator/Debug/actool/bundle /Users/craigdunn/ProjectsConceptdev/xamarin-ios-samples/WatchComplication/iOSApp.WatchAppExtension/Assets.xcassets

but on inspecting with **Show Package Contents** there the complication images are NOT there -- but the glyphish_13_target image is present.

As mentioned in Comment #11, if I take an Assets.car from Xcode output and embed into the Xamarin WatchExtension project, it works.

Unsure if related, but Xcode json seems to use:
"screen-width" : "<=145" and "screen-width" : ">145",
whereas the json Xamarin Studio creates uses:
"screenWidth": "{130,145}" and "screenWidth": "{146,165}"
for Complication image references.
Comment 14 CraigD 2016-10-04 16:14:01 UTC
Further investigation of Comment #13 shows that the Complication images don't get incorporated into an Assets.car because of the nested "/Complication/" directory they're in. If I copy the three assets (Circular, Modular, Utilitarian) into the 'root' of the Assets.xcassets (in the WatchExtension project) then they are correctly built into an Assets.car in the .appex.

Then this code works (workaround iii):

if (complication.Family == CLKComplicationFamily.ModularSmall)
   var rimgTemplate = new CLKComplicationTemplateModularSmallSimpleImage();
   rimgTemplate.ImageProvider = CLKImageProvider.Create(UIImage.FromBundle(@"Modular")); // NOT "Complication/Modular"
   entry = CLKComplicationTimelineEntry.Create(NSDate.Now, rimgTemplate);

Seems like the underlying bug is related to how the `actool` is grabbing files in Assets.xcassets subdirectories (which the Complication assets are, by default). Basically it seems to ignore stuff in subdirs.
Comment 15 ulrike_axen 2016-10-04 19:23:49 UTC
Workaround much appreciated, thank you so much for looking into this! The last one seems to require less steps than the others, I'll give it a try.
Comment 16 Sebastien Pouliot 2016-10-05 01:08:39 UTC
@Jeff, @Vincent our asset logic seems to be missing some cases to handle watch apps.
Comment 17 Jeffrey Stedfast 2016-10-05 19:07:09 UTC
Looks like you forgot to set the "Complications Group" property in the Watch Extension's Info.plist.

Once you set that, it works.
Comment 18 ulrike_axen 2016-10-05 19:10:00 UTC
@Jeffrey Really? Please double check that it works, or maybe it works now. I _did_ keep setting that, and every time I went back to the info.plist, it was blank again. Is there some trick to getting it to stay there?
Comment 19 ulrike_axen 2016-10-05 19:16:44 UTC
Another thing that's strange, i.e., keeps disappearing in the info.plist: I want to set an ExtraLarge complication. I added it manually to the info.plist Source because there is no checkbox for it, and it showed up a couple times on the simulator. Now I see that it is gone from the list. Is there some kind of syncing happening that isn't working? (from the info.plist Application tab to the Source)?
Comment 20 ulrike_axen 2016-10-05 19:40:41 UTC
@Jeff, Even when I set the Complications Group using the UI, I don't see the info.plist xml getting updated (when I check source control). Is the bug that the xml is not getting updated, so not retaining this change?
Comment 21 CraigD 2016-10-05 19:54:23 UTC
I also don't see the Info.plist "Complications Group" being persisted anywhere once set. 

In Xcode it's not an Info.plist setting but in the project build settings, so it's not clear what key we would create to 'manually' do this with Xamarin Studio; in Xcode eg. 

355225A41D9077EB00401EB0 /* Debug */ = {
	isa = XCBuildConfiguration;
	buildSettings = {
Comment 22 ulrike_axen 2016-10-05 21:01:57 UTC
Disregard Comment #19 though. Extra entries for CLKComplicationSupportedFamilies _is_ being persisted.
Comment 23 Jeffrey Stedfast 2016-10-05 21:18:43 UTC
That's possible, I'll check. I manually edited the Info.plist.
Comment 24 Jeffrey Stedfast 2016-10-05 21:24:09 UTC
Yep, the UI did not hook up any event listeners when the combo box was changed and so changes were not saved.

I've fixed this in git master.
Comment 25 CraigD 2016-10-05 21:42:12 UTC
I can confirm manually setting Info.plist key in source view


results in the Assets.car being built correctly, and the complication images being rendered on the simulator (where "Complication" is the default name of the assets entry). This is probably the best workaround for now.
Comment 26 Saurabh 2017-02-02 06:07:17 UTC
For attached project in bug description https://bugzilla.xamarin.com/show_bug.cgi?id=44526#c0, I am getting error when run application. I have reported Issue Bug 52059 . I'll check the Issue once Bug 52059 will be fixed.
Comment 27 GouriKumari 2017-02-21 23:01:58 UTC
CLKComplicationGroup key can be now set in the info.plist and the value persists. 

##Test Env:

##Build Log: 
Comment 28 GouriKumari 2017-02-22 16:50:43 UTC
I am  marking this bug as verified based on comment #27 and comment #25.  
@ulrike: Please reopen this bug if this issue is not resolved at your end.
Comment 29 damian 2018-01-12 11:22:34 UTC
I've just been bitten by this one and lost a day of my time.  It's really *not* fixed since Visual Studio doesn't behave correctly when you set the complication group.