Access to SpecialFolder.ApplicationData blocked after signing with App Wrapper

  1. 6 months ago

    Vincent V

    11 Feb 2019 Amsterdam, The Netherlands

    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?

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

    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

    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

    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
  2. David C

    12 Feb 2019 Pre-Release Testers, Xojo Pro Derby, ITM
    Edited 6 months ago

    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.

  3. Jeff T

    12 Feb 2019 Pre-Release Testers Midlands of England, Europe

    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.

  4. Vincent V

    12 Feb 2019 Amsterdam, The Netherlands

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

    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:

    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.

    Any idea where it should save?

  5. Jeff T

    12 Feb 2019 Pre-Release Testers Midlands of England, Europe

    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 ?

  6. 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.
  7. Michel B

    12 Feb 2019 Pre-Release Testers, Xojo Pro RubberViews.com

    @Vincent V 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’

    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.

  8. Sam R

    12 Feb 2019 Pre-Release Testers, Xojo Pro Hengchun, Pingtung, Taiwan

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

    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.

    @Carlo R MAS Apple do not like developers

    I fixed it for you.

  9. Sam R

    12 Feb 2019 Pre-Release Testers, Xojo Pro Answer Hengchun, Pingtung, Taiwan

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

    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

    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

    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
  10. Vincent V

    13 Feb 2019 Amsterdam, The Netherlands

    Thanks Sam !

  11. Sam R

    13 Feb 2019 Pre-Release Testers, Xojo Pro Hengchun, Pingtung, Taiwan

    @Vincent V Thanks Sam !

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

or Sign Up to reply!