How to access files in the resource folder

I want t o deploy a data file together with the app. The app should be sandboxed. The data file is part of the apps resource folder. At the first start the data file should be mirrored into the ApplicationData directory. Later the user can load an other datafile to replace this one in the ApplicationData directory.

Is it possible and correct to copy it from the apps resource folder to the ApplicationData folder in a sandboxed app?

[quote=124016:@Torsten Gaidies]I want t o deploy a data file together with the app. The app should be sandboxed. The data file is part of the apps resource folder. At the first start the data file should be mirrored into the ApplicationData directory. Later the user can load an other datafile to replace this one in the ApplicationData directory.

Is it possible and correct to copy it from the apps resource folder to the ApplicationData folder in a sandboxed app?[/quote]

That is exactly the way to go :slight_smile:

I have a sqlite database file in the resource folder. Currently it is not possible to access that file in a sandboxes app. So I copy it out to the ApplicationData folder, just as you describe it. I use such function to copy that file:

[code]Function BinaryCopyFile(fSource As FolderItem, fTarget As FolderItem) As Boolean
Dim bs1 As BinaryStream
Dim bs2 As binaryStream

//make sure it exists before we try to read it
If fSource.exists Then

//open the folderitem as a binary file without write privelages
//     To open with write privelages, use true instead of false
bs1 = BinaryStream.Open(fSource, False)

//create a binary file with the type of text (defined in the file types dialog)
bs2 = BinaryStream.Create(fTarget, True)  // True = overwrites existing file

//make sure we have a binary stream to read from
If bs1 <> Nil And bs2 <> Nil Then
  Try
    //read and write the whole binaryStream
    bs2.write(bs1.read(bs1.length))
    
    //close the binaryStream
    bs1.close
    bs2.close
    Return True
  Catch exc as IOException
    MsgBox "ERROR - failed to create the output file."
    Return False
  End Try
Else
  Return False
End If

Else
Return False
End If

End Function
[/code]

In my latest App Store app I use FolderItem.CopyFileTo and it is quite efficient.

Thanks,

it is always good to have more than one way to create a solution. Michel’s solution fits my needs, so I use this one.

Another question is, if there is an Xojo Build in way, to access the resource folder?
At the moment my app uses this lines of code to access the file in the resource folder.

  dim f as FolderItem
  f = App.ExecutableFile.Parent.Parent.Child("Resources").Child("data.csv")

[quote=124026:@Torsten Gaidies]Thanks,

it is always good to have more than one way to create a solution. Michel’s solution fits my needs, so I use this one.

Another question is, if there is an Xojo Build in way, to access the resource folder?
At the moment my app uses this lines of code to access the file in the resource folder.

dim f as FolderItem f = App.ExecutableFile.Parent.Parent.Child("Resources").Child("data.csv") [/quote]

That is the way I proceed.

Below is what I believe to be the correct way of getting the Resources Folder. This function should continue to work even if Apple ever change the layout of a bundle.

[code]Function resourcesFolder() As folderitem
static mResourcesFolder as folderitem

if mResourcesFolder = nil or mResourcesFolder.exists = false then
declare function NSClassFromString lib “AppKit” ( className as CFStringRef ) as Ptr
declare function mainBundle lib “AppKit” selector “mainBundle” ( NSBundleClass as Ptr ) as Ptr
declare function resourcePath lib “AppKit” selector “resourcePath” ( NSBundleRef as Ptr ) as CfStringRef
mResourcesFolder = getFolderItem( resourcePath( mainBundle( NSClassFromString( “NSBundle” ) ) ), folderItem.pathTypeNative )
end if

return mResourcesFolder
End Function[/code]

Simply put this into a module. Be aware that it’s possible to create an application without a resources folder, so you should always check that it’s valid before you start working on the application (or if a user screws up the permissions and your application can’t access it’s own resources folder, or the Sandbox container gets corrupted).

Thanks to all for your posts. Without the information you provided, i wouldn’t have had any solution. I’m following the suggestions of Torsten and Sam and they appear to work.

Thanks … jeff

You might also want to look at http://developer.xojo.com/xojo-io-specialfolder$GetResource

Don’t know when that one came in… It’s not in documentation.xojo.com so I do wonder if you need to use the new framework for this?

Yes, it is new framework.

Couple important details about GetResource :

  • That method works with Xojo.IO.FolderItem, not with the older FolderItem class. Typically, to go from the new to the old, GetFolderItem is necessary :

dim f as xojo.IO.FolderItem = Xojo.IO.SpecialFolder.GetResource("robot100.png") dim ff as FolderItem = GetFolderItem(f.path, FolderItem.PathTypeShell) msgbox ff.shellPath

  • The file MUST be there, otherwise a Xojo.Core.InvalidArgumentException occurs. Better wrap in a try catch if unsure.

dim f as xojo.IO.FolderItem = Xojo.IO.SpecialFolder.GetResource("robot100.png") dim ff as FolderItem = GetFolderItem(f.path, FolderItem.PathTypeShell) msgbox ff.shellPath

Off topic, but this new syntax discourages me from upgrading to current Xojo.

Jeff,
do you realise that you can still use the current framework in the latest version of Xojo?

You basically get the choice of sticking with the current framework, or, use the new framework :slight_smile:

Ah… Excellent…

[quote=194827:@Michel Bujardet] dim f as xojo.IO.FolderItem = Xojo.IO.SpecialFolder.GetResource(“robot100.png”)
dim ff as FolderItem = GetFolderItem(f.path, FolderItem.PathTypeShell)
msgbox ff.shellPath[/quote]
Hmm… Not so excellent… I can see a bunch of module extensions to simplify conversions between the two frameworks.