Access to SpecialFolder.ApplicationData blocked after signing with App Wrapper

My application converts video files and saves them in the Application Support folder (SpecialFolder.ApplicationData.child (“My App”) ) as required by an Apple MAS reviewer, who doesn’t let me use the ‘Movies’ folder. The app works as intended, it converts a video and then opens the App Support folder with the converted file for the user.

However after wrapping and signing my app with Ohanaware App Wrapper, the app no longer works. It doesn’t save in the Application Support folder and it doesn’t open that folder. Does anyone know which setting or entitlement in App Wrapper I need to set to make this work?

Sandboxes applications no longer point to Library/Application Support, but

Library/Containers/com.MyCompanyName.MyAppName/Data

You may want to sign your application, but not sandbox it.

A sandboxed app ‘sees’ a completely different Application Support folder than the user.

If you save in SpecialFolder.ApplicationData.child (“My App”)
its not saving where you expect it saves, but into a private version just for your app.
Sandboxing means it cannot accidently or deliberately affect things that OTHER apps have placed in there.

If you .LAUNCH SpecialFolder.ApplicationData.child (“My App”) then the folder it reveals should be the correct one.

Alternatively you can request permissions to use ‘open and save dialogs’, and allow the user to select where the saved video will go.
Thats a much better idea, since once saved, the average user is going to struggle to find your converted video if they close your app.

The thing is: SpecialFolder.ApplicationData.child (“My App”).launch doesn’t open the folder after signing/wrapping (it does before wrapping)

TBH. It’s not really clear to me where the MAS reviewer wants me to save the files. The logical place would be the ‘Movies’ folder, but for some reason, that doesn’t seem to be allowed. This what the Apple reviewer wrote:

[quote]2. 4 Performance: Hardware Compatibility (macOS)
Hello,

Thank you for your resubmission. However, upon further review, we found that your app is still out of compliance with the following guideline(s):

Guideline 2.4.5(i) - Performance

Your application still accesses the following location(s):

‘~/Movies/H265 Studio Lite’

The majority of developers encountering this issue are opening files in Read/Write mode instead of Read-Only mode, in which case it should be changed to Read-Only.

Other common reasons for this issue include:

  • creating or writing files in the above location(s), which are not valid locations for files to be written as stated in documentation.

  • writing to the above location(s) without using a valid app-id as a container for the written files.

Next Steps

Please review the File-System Usage Requirements for the App Store of Submitting to the Mac App Store for the locations apps are allowed to write and for further guidance.[/quote]

Any idea where it should save?

writing to the above location(s) without using a valid app-id as a container for the written files.

Are they looking for ~/Movies/com.yourwebsite.H265StudioLite ?

MAS does not like developers predefine locations. I had an app suggesting locations but at the same time leaving users free to choose a different one, but even after appeal I had to remove the list of suggested locations. Yet the app had been on the Store seven years.

If you do not like asking every time the users to select a destination folder, then I’d suggest:

  1. Make the user select a destination folder. Something like Safari setting the download folder in the Preferences. Then bookmark it (for that I use Jim McKay’s free software) and in App Wrapper add the necessary entitlement (and explain the reason in the Metas of iTunes Connect).
  2. Appeal to MAS explaining your reasons supporting your original choice.

[quote=424669:@Vincent Verweij]Thank you for your resubmission. However, upon further review, we found that your app is still out of compliance with the following guideline(s):

Guideline 2.4.5(i) - Performance

Your application still accesses the following location(s):

‘~/Movies/H265 Studio Lite’[/quote]

It is pretty clear what you should do : search in your app where you access that path, and change it so the user picks that path.

I hate to tell you this, but I had an application rejected this year for doing just that. I argued that it’s been doing this for years, but the App review team don’t care. They suggested the following (which I told them is BS and destined to fail).

  1. When you first export, ask the user where they want to export too.
  2. Store this as a Security-Scoped Bodgemark in your application.
  3. Request access to this location from the bodgemark.
  4. Write the files to this location.
  5. Release access to the bodgemark.

For various reasons the above is a joke with Apple’s security model, helper apps can’t access that location (unless you do some funky massaging). You’re only allowed a maximum of 90 seconds for your file operations, exceed that and you run the risk of corrupting your applications security resulting in your application being locked out of everything. On top of that Security-Scoped Bodgemarks fail, and when they do you have no idea or any means to report to the user where they were pointed too.

So you must do your work in a location such as the Application Data folder, now as to why you’re locked out once you’ve wrapped with App Wrapper (App Wrapper applies the Apple security protocols to your application, so it’s not really App Wrapper that’s preventing you, it’s Apple), it suggests to me that something is wrong with how you specify the location for the temporary folder. Let me dig out the code I use in my own applications, as that works (for me anyway).

Once your work is complete, you request access to the original location, if it’s granted, you then Move the file there. Do not copy, it can take too long, and release access. Moving is instantaneous.

I fixed it for you.

Put the following code in a module, and you call it by Dim mySupportFolder as folderitem = app.supportFolder

[code]Public Function supportFolder(extends a as application) as folderItem
static base as folderItem
if base = nil then
#if TargetMacOS then
declare Function NSClassFromString lib “Foundation” ( className as CFStringRef ) as integer
declare Function NSBundleMainBundle lib “Foundation” selector “mainBundle” ( NSBundleClass as integer ) as integer
declare Function NSBundleIdentifier lib “Foundation” selector “bundleIdentifier” ( bundleInstance as integer ) as CFStringRef

  base = specialFolder.applicationData.child( NSBundleIdentifier( NSBundleMainBundle( NSClassFromString( "NSBundle" ) ) ) )
  
  if base.exists = false then base.createAsFolder
#endif

end if

Return base
End Function
[/code]

For console based helpers, you may want to use the temporary folder instead. I’ve had some trouble with console helpers and the support folder. Put the following code into a module and call it by Dim myTempFolder as folderitem = app.tempFolder

[code]static base as folderItem

if base = nil then
#if targetMacOS then
declare Function NSTemporaryDirectory lib “Foundation” () as CFStringRef
base = getFolderItem( NSTemporaryDirectory, folderItem.pathTypeNative )

if base.exists = false then base.createAsFolder

#endif
end if

return base[/code]

Thanks Sam !

You’re welcome, sorry I hadn’t responded to your e-mail until today.