Codesign reporting detritus ... a new thread

I’ve moved this to a new conversation since it doesn’t apply to @Sam Rowlands App Wrapper.

I have a tool that I build with 16r4.1. It has no helper components and I do not use anything that involved WebKit, QuickTime, or non-PNG images with resource fork of Finder cruft.

When I codesign, I’m still receiving the error message and failure about “resource fork, Finder information, or similar detritus not allowed”.

The only thing that I can find is that the build process included a pair of default config files in the App folder by mistake. I edited the CopyFilesStep and changed them to the Resources folder and that problem goes away, so there’s a tip for others:

It appears that we shouldn’t put anything in our app’s MacOS folder aside from the app.

The next thing that I notice is that my local copy of the built and run app can access and modify the ~/Library/Preferences folder contents. However, after wrapping the app, it appears that the app is being sandboxed and can no longer access the ~/Library/Preferences folder.

I don’t see an exemption for the Preferences folder, so this one has me stumped. Any ideas?

This tool is one that I’m prepping for MAS distribution.

I found a “temporary” exemption for preferences:

com.apple.security.temporary-exception.shared-preference.read-write

How should I add this to my app’s entitlements?

Yes. Sam knows more details on where everything should go.

Apple will not let you write into ~/Library/Preferences at all (to submit to the app store.) They require that you use NSUserDefaults.
The workaround for Xojo apps (aside from declares) is to store your own preferences config in your App Support folder.

(TPSF will help GitHub - devtimi/TPSF: Module for accessing build step folders with the old framework. )

If you need to migrate preferences into the sandbox, I believe App Wrapper has settings to help you with that.

Also, I don’t think that entitlement is for what you want.
Shared Preferences is likely /Library/Preferences and not the local one.

[quote=316761:@Tim Parnell]Also, I don’t think that entitlement is for what you want.
Shared Preferences is likely /Library/Preferences and not the local one.[/quote]
According to Apple’s docs:

Enables read/write access to the contents of the specified preference domain or domains in the user’s home directory.

However, I did locate the temporary exemptions option in App Wrapper on the “Capabilities” page by scrolling (not intuitive, Sam - needs a visible scrollbar or other indicator that there is more on the page). I entered Library/Preferences and checked the relative checkbox. However, it won’t allow me to check the “write” checkbox and I do need read/write permissions.

@Sam Rowlands - maybe you should preset options for known temporary exceptions described on this page:
App Sandbox Temporary Exemptions

Otherwise, what would be a user-specific, permanent store location besides ~/Library/Preferences/?

[quote=316762:@Tim Jones]According to Apple’s docs:

Enables read/write access to the contents of the specified preference domain or domains in the user’s home directory.

[/quote]
Good to know!

Inside a directory in app support: SpecialFolder.ApplicationData.Child(%your-reverse-domain%)
The reasoning is that we’re allowed to put whatever we want in there, and Apple didn’t say we can’t store our settings there. Whereas, they’ve said we can’t write in ~/Library/Preferences/ anymore.

[quote=316763:@Tim Parnell]Inside a directory in app support: SpecialFolder.ApplicationData.Child(%your-reverse-domain%)
[/quote]
The issue with that is that my app stores settings specific to a given user account. And, I don’t want other users to be able to sniff around in the shared ApplicationData folder to mess around with them (schools use this app in labs).

SpecialFolder.ApplicationData is just as user localized as SpecialFolder.Preferences
http://documentation.xojo.com/index.php/Specialfolder

One more thing that I just realized that I forgot to mention - I also need to be able to interact with an existing app’s preferences com.domain.app.plist file.

I knew there was another reason for using the user’s ~Library/Preferences/ folder for this stuff (been a while since I got into that layer of the code).

I think it’s on the first “page” in App Wrapper.

Are you using NSUserDefaults declares to read/write the settings? You don’t have to worry about any of this (except maybe importing) if you are, otherwise using plist is going to come back and bite you.

The tool allows a user to replace an existing preference plist file with a new one. They can then swap back and forth, create, or delete settings for a given assignment.

I see that Preferences is automatically added to the container, but my manipulation within the container’s version of the info doesn’t modify the associated preference of the running app. That’s the sticking point in that I need to be able to interact with another app’s preferences in a manner that is easier for the user than editing the volume of preference options supplied by the app.

Oh you can’t do that from a sandbox.
Not being able to mess around with other apps is kind of the point of a sandbox. :confused:

[quote=316758:@Tim Jones]I found a “temporary” exemption for preferences:

com.apple.security.temporary-exception.shared-preference.read-write

How should I add this to my app’s entitlements?[/quote]
You shouldn’t, the temporary entitlements were designed to help migrate legacy apps into the App Sandbox and 90% of the time Apps are rejected for using them.

There’s a couple of places where there can be Finder cruft, and it’s more than possible that these files do contain some.

This is correct and has always been a guideline, it’s just in the last few years that Apple have been making the code signing functions more and more strict.

Rule of thumb:
Executable code (Mach-O based executables) should be in “MacOS”, “Plugins”, “Frameworks” or “Helpers”, executable code should never be in any other folder. Fonts should be in the Fonts folder and everything else should be in the “Resources” folder.

Understood, I’m constantly thinking about how to improve App Wrapper. I am using a standard NSScrollView and so the scrollbar visibility is controller by the OS.[quote=316768:@Tim Parnell]Are you using NSUserDefaults declares to read/write the settings? You don’t have to worry about any of this (except maybe importing) if you are, otherwise using plist is going to come back and bite you.[/quote]
Apple have always advised against manually reading and writing preferences files in the prefs folder; you should use CFPreferences or NSUserDefaults for reading and writing preferences. Since 10.9 strange things can happen when manually operating on file, don’t be surprised if a future OS version simply can’t operate on the files.[quote=316771:@Tim Parnell]Oh you can’t do that from a sandbox.
Not being able to mess around with other apps is kind of the point of a sandbox. :/[/quote]
@Tim Jones - I know this is no fault of your own, but trying to interact with other applications preferences is kind of an issue with a Sandboxed application. I think I understand what you’re trying to do, import previous applications setting into the new version? There’s a couple of ways I can think of that would be Sandbox safe.

  1. Use the same bundle Identifier.
  2. Use a “Group Container”; group containers are shared containers between applications, but it does require that your old version also use a Group container and move all of it’s data into the group container before the new one can read it.
  3. Slightly hacky; but add a “Upgrade” wizard. After you’ve explained to the user they can use this wizard to upgrade, offer them a OpenDialog and point it to the original files, then when they click “Open” your application will have access to those files. Import what you need and move on. If you want to retain access throughout successive launches, use a Security-Scoped Bodgemark.

Here is an article I just found

https://forums.macrumors.com/threads/no-detritus-allowed.2033369/

talking about that exact Error

Got it - add the following call to your OS X codesign step before the call to codesign:

DoCommand "xattr -c -r " + AppParentFolder

Where the AppParentFolder is the .app folder created by your Xojo build.

I’ve tried it on 5 test apps and it solved the “detritus” issue.

No - actually it’s to set the preferences for a system app that the user interacts with in different project assignments. Normally, the user (usually a student) has to change the primary app’s preferences for different assignment types - and there are a lot of options to slog through. My tool allows the user to update the settings directly using a number of predefined template settings without the need to open the app’s preferences and drill through the options.

Since the user must manually cause these events, and they can only affect that user’s setting for that specific app, I’m at a loss as to how this is could possibly be a bad thing in Apple’s eyes.

You may have good intentions, but not everyone does.
For example, maybe a developer of a clone app hates their competitor so much they design their app to corrupt the competitor app’s preferences. That would be bad. And that’s just stupid petty things. Malware creators get real clever.

In my use case, there’s no “hidden” anything - the user knows exactly what is being done and it can be very easily “undone”. And, since Apple has no way of limiting this option if the app is NOT delivered via the MAS, it’s sort of like closing the barn doors after the horses have escaped.

It would just be nice to be able to make this tool available more easily through the MAS.

[quote=316893:@Tim Jones]In my use case, there’s no “hidden” anything - the user knows exactly what is being done and it can be very easily “undone”. And, since Apple has no way of limiting this option if the app is NOT delivered via the MAS, it’s sort of like closing the barn doors after the horses have escaped.

It would just be nice to be able to make this tool available more easily through the MAS.[/quote]
It can be done, you just need to show a open dialog and ask the user to select it, then store the location in a Security-Scoped Bodegmark (the code is available as part of the Sandbox Kit). Although I would try to avoid these as they’re cumbersome and erratic and can even crash your machine if not coded correctly (Thomas Templeman helped design the solution that the Sandbox Kit uses to help prevent crashes).

The other way I just thought of is to use a series of helper applications that use the same bundle identifiers of the prefs files that they need to edit. It’s a lot of work as they’d have to be individually wrapped and then you’d have to instruct App Wrapper not to wrap them when it wraps the entire application. As long as the you use the same code sign identity it can be done.

Oh, basically when you launch them you pass them the keys and values to modify, or use IPC to instruct the helpers to do the job.

I would imagine that overall, it would be better to make all the applications use the same “Group Container” and use that to read/write settings.