Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device specific build: actool --filter-for-device-model #13116

Open
yaliashkevich opened this issue Oct 26, 2021 · 7 comments
Open

Device specific build: actool --filter-for-device-model #13116

yaliashkevich opened this issue Oct 26, 2021 · 7 comments
Labels
bug If an issue is a bug or a pull request a bug fix external-xamarin-vs Issues affecting the Xamarin in Visual Studio and are not specific to Xamarin.iOS or Xamarin.Mac iOS Issues affecting iOS
Milestone

Comments

@yaliashkevich
Copy link
Contributor

Preamble

actool (_CoreCompileImageAssets, ACTookTask) is called with "--filter-for-device-model" whenever project has "device specific build" option enabled.

The value for the option is extracted from $(TargetiOSDevice) build property. I guess it is provided to msbuild by IDE.

Reference from man:

   --filter-for-device-model device
          Causes actool to filter the files  put  into  the  CAR  file  by
          device.  This  simulates  how the App Store will thin the devel-
          oper's application. For example, if you pass  iPhone9,1,  actool
          will only include images appropriate to iPhone 7. This is useful
          for testing to make sure thinned applications  will  work  prop-
          erly.   During   build   time,   this  is  driven  by  the  TAR-
          GET_DEVICE_MODEL build setting, and is selected by choosing  the
          active  run  destination in the scheme pop-up. When the argument
          is not present, no thinning will occur

If your target is physical device that call looks like this:

$(TargetiOSDevice)

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>device</key>
    	<dict>
    		<key>architecture</key>
    		<string>ARMv6, ARMv7, ARMv7s, ARM64</string>
    		<key>model</key>
    		<string>iPhone8,1</string>
    		<key>os</key>
    		<string>iOS</string>
    		<key>os-version</key>
    		<string>13.6</string>
    	</dict>
    </dict>
    </plist>

actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist /Users/Yauheni/Projects/assetclone/assetclone/obj/iPhone/Debug/device-builds/iphone8.1-13.6/actool/partial-info.plist --app-icon AppIcon --compress-pngs --filter-for-device-model iPhone8,1 --filter-for-device-os-version 13.6 --target-device iphone --target-device ipad --minimum-deployment-target 13.0 --platform iphoneos --compile /Users/Yauheni/Projects/assetclone/assetclone/obj/iPhone/Debug/device-builds/iphone8.1-13.6/actool/bundle /Users/Yauheni/Projects/assetclone/assetclone/obj/iPhone/Debug/device-builds/iphone8.1-13.6/actool/cloned-assets/Assets.xcassets

If your target device is simulator you get following:

$(TargetiOSDevice)

<?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
    <plist version="1.0">
    <dict>
    	<key>device</key>
    	<dict>
    		<key>architecture</key>
    		<string>i386, x86_64</string>
    		<key>model</key>
    		<string>iPhone 13</string>
    		<key>os</key>
    		<string>iOS</string>
    		<key>os-version</key>
    		<string>15.0</string>
    	</dict>
    </dict>
    </plist>

actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist "/Users/Yauheni/Projects/assetclone/assetclone/obj/iPhoneSimulator/Debug/device-builds/iphone 13-15.0/actool/partial-info.plist" --app-icon AppIcon --compress-pngs --filter-for-device-model iPhone 13 --filter-for-device-os-version 15.0 --target-device iphone --target-device ipad --minimum-deployment-target 13.0 --platform iphonesimulator --compile "/Users/Yauheni/Projects/assetclone/assetclone/obj/iPhoneSimulator/Debug/device-builds/iphone 13-15.0/actool/bundle" "/Users/Yauheni/Projects/assetclone/assetclone/obj/iPhoneSimulator/Debug/device-builds/iphone 13-15.0/actool/cloned-assets/Assets.xcassets"

Problems

Value is not quoted

--filter-for-device-model iPhone 13

this causes following error which can be observed in asset-manifest.plist (output of actool)

   <key>com.apple.actool.notices</key>
   <array>
   	<dict>
   		<key>description</key>
   		<string>Failed to read file attributes for "/Users/Yauheni/Projects/assetclone/assetclone/13"</string>
   		<key>failure-reason</key>
   		<string>No such file or directory</string>
   	</dict>
   	<dict>
   		<key>description</key>
   		<string>Could not get trait set for device iPhone with version 15.0</string>
   	</dict>
   </array>

At first we supplied "iPhone" instead of "iPhone 13" to the --filter-for-device-model parameter. So the system can not get any traits for such a device.

At second we supplied extra "13" parameter. That is tried to be proceed as input file for actool, and actool can not find it.

Value is wrong itself

"iPhone 13" human friendly string is not what actool expects. It expects device model code iPhone14,5 instead. Passing wrong value leads to "Could not get trait set for device iPhone with version 15.0" warning. That makes impossible to test assets thinning, assets are not filtered.

I don't know exactly how $(TargetiOSDevice) plist is populated. By its model key should be set to code instead of name.

@yaliashkevich yaliashkevich changed the title Device specific build: ACTool Device specific build: actool --filter-for-device-model Oct 26, 2021
@yaliashkevich
Copy link
Contributor Author

I believe Apple calls this "modelIdentifer" here:

/Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Library/Developer/CoreSimulator/Profiles/DeviceTypes/iPhone 13.simdevicetype/Contents/Resources/profile.plist

	<key>modelIdentifier</key>
	<string>iPhone14,5</string>

@chamons
Copy link
Contributor

chamons commented Oct 26, 2021

Thanks for the feedback.

TargetiOSDevice is set by the IDE (VS or VSfM) based upon the device selector.

This seems to be a case where TargetiOSDevice is being incorrectly set, but I'm having real difficulty reproducing your issue.

Could you please provide concrete steps to reproduce your issue?

@chamons chamons added the need-info Waiting for more information before the bug can be investigated label Oct 26, 2021
@chamons chamons added this to the Future milestone Oct 26, 2021
@yaliashkevich
Copy link
Contributor Author

yaliashkevich commented Oct 26, 2021

Use Visual Studio Mac

  1. Create iOS -> Single View App from template (name it ModelIdentifier)
  2. Go to project Options-> iOS Build and ensure that "Enable device specific builds" is on (usually it is by default)
  3. Select any iPhone simulator in device selector. Lets say for instance: iPod Touch (7th generation) 15.0
  4. Build
  5. Check Build output for actool invacation:

_Target CoreCompileImageAssets:
Tool /usr/bin/xcrun execution started with arguments: actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/partial-info.plist" --app-icon AppIcon --compress-pngs --filter-for-device-model iPod touch (7th generation) --filter-for-device-os-version 15.0 --target-device iphone --target-device ipad --minimum-deployment-target 15.0 --platform iphonesimulator --compile "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/bundle" "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/cloned-assets/Assets.xcassets"

  1. Open actool results from here: /ModelIndetifier/ModelIndetifier/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/asset-manifest.plist
  2. Observe warnings there:
	<key>com.apple.actool.notices</key>
	<array>
		<dict>
			<key>description</key>
			<string>Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/(7th"</string>
			<key>failure-reason</key>
			<string>No such file or directory</string>
		</dict>
		<dict>
			<key>description</key>
			<string>Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/generation)"</string>
			<key>failure-reason</key>
			<string>No such file or directory</string>
		</dict>
		<dict>
			<key>description</key>
			<string>Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/touch"</string>
			<key>failure-reason</key>
			<string>No such file or directory</string>
		</dict>
		<dict>
			<key>description</key>
			<string>Could not get trait set for device iPod with version 15.0</string>
		</dict>
	</array>

--filter-for-device-model iPod touch (7th generation)

Actual value for --filter-for-device-model is iPod. It is obviously not valid. There is no model with such an identifier:

Could not get trait set for device iPod with version 15.0

That means that resulting app bundle has all image assets instead of applicable for ipod 7gen only.

besides that 3 junk extra parameters passed

  • touch
  • 7th
  • generation)

_Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/(7th"

Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/generation)"

Failed to read file attributes for "/Users/Yauheni/Projects/ModelIndetifier/ModelIndetifier/touch"_

ModelIndetifier.zip

@yaliashkevich
Copy link
Contributor Author

So, VS for MAC (haven't checked on windows) reports wrong value for "model" key in $(TargetiOSDevice) plist if it simulator - kind of human friendly model name.

For real devices it reports model identifier - that should be an input for actool.

@chamons
Copy link
Contributor

chamons commented Oct 26, 2021

I am able to confirm this issue now. Thanks for the steps to reproduce!

@chamons chamons added iOS Issues affecting iOS bug If an issue is a bug or a pull request a bug fix and removed need-info Waiting for more information before the bug can be investigated labels Oct 26, 2021
@chamons
Copy link
Contributor

chamons commented Oct 26, 2021

As a concrete example:

This fails, and is what VSfM executes by default:

/usr/bin/xcrun actool --errors --warnings --notices --output-format xml1 --output-partial-info-plist "/Users/donblas/Projects/simtest/simtest/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/partial-info.plist" --app-icon AppIcon --compress-pngs --filter-for-device-model "iPod touch \(7th generation\)" --filter-for-device-os-version 15.0 --target-device iphone --target-device ipad --minimum-deployment-target 15.0 --platform iphonesimulator --compile "/Users/donblas/Projects/simtest/simtest/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/bundle" "/Users/donblas/Projects/simtest/simtest/obj/iPhoneSimulator/Debug/device-builds/ipod touch (7th generation)-15.0/actool/cloned-assets/Assets.xcassets"

And changing it to --filter-for-device-model iPhone14,5 for example things start to not warn/error.

@chamons
Copy link
Contributor

chamons commented Oct 26, 2021

As this is an IDE issue, I've filed an internal bug.

I will leave this open for now as a public facing record.

@chamons chamons added the external-xamarin-vs Issues affecting the Xamarin in Visual Studio and are not specific to Xamarin.iOS or Xamarin.Mac label Oct 26, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug If an issue is a bug or a pull request a bug fix external-xamarin-vs Issues affecting the Xamarin in Visual Studio and are not specific to Xamarin.iOS or Xamarin.Mac iOS Issues affecting iOS
Projects
None yet
Development

No branches or pull requests

2 participants