Proper way to initialize application support file

  • I am working on a Document-based application that needs to have a
    certain file in ~/Library/Application Support/<appname> before it can
    do anything. It needs to be created the first time the program is run
    (or if it has been deleted by the user).

    I've created a class XXAppDelegate and declared it as implementing the
    NSApplicationDelegate protocol, and I defined
    -(void)applicationDidFinishedLaunching:(NSNotification*)aNotification.
    In this method I want to perform the file creation. Does this sound
    like I'm on the right track? (Newbie as you can tell.)

    I should add that the file needs to be created by accessing the
    internet and could take even a minute to finish, so I will no doubt
    have to worry about informing the user about the delay when the
    program is run for the first time, but before I charge in this
    direction I would appreciate some affirmation I'm on the right track.
  • Apple's docs explicitly say that this folder should only contain files that
    are *not* necessary for the app to function normally. Files that are
    necessary should be inside your app bundle, usually.

    -Steven

    On Wed, Feb 17, 2010 at 4:21 PM, Paul Johnson <paul...> wrote:

    > I am working on a Document-based application that needs to have a
    > certain file in ~/Library/Application Support/<appname> before it can
    > do anything. It needs to be created the first time the program is run
    > (or if it has been deleted by the user).
    >
    > I've created a class XXAppDelegate and declared it as implementing the
    > NSApplicationDelegate protocol, and I defined
    > -(void)applicationDidFinishedLaunching:(NSNotification*)aNotification.
    > In this method I want to perform the file creation. Does this sound
    > like I'm on the right track? (Newbie as you can tell.)
    >
    > I should add that the file needs to be created by accessing the
    > internet and could take even a minute to finish, so I will no doubt
    > have to worry about informing the user about the delay when the
    > program is run for the first time, but before I charge in this
    > direction I would appreciate some affirmation I'm on the right track.
    >

    --
    Steven Degutis
    http://www.thoughtfultree.com/
    http://www.degutis.org/
  • On Wed, Feb 17, 2010 at 1:25 PM, Steven Degutis
    <steven.degutis...> wrote:
    > Apple's docs explicitly say that this folder should only contain files that
    > are *not* necessary for the app to function normally. Files that are
    > necessary should be inside your app bundle, usually.

    As has been covered before, I believe you are misinterpreting the documentation.

    The documentation is advising you against putting frameworks, static
    libraries, resources, or other pieces of what could rightly be
    considered your app bundle inside your App Support directory. Plugins,
    licenses, and other non-integral yet critical portions of your app
    belong in App Support.

    Library/Caches is for stuff that could be blown away at any moment.

    --Kyle Sluder
  • On 17 Feb 2010, at 21:25, Steven Degutis wrote:

    > Apple's docs explicitly say that this folder should only contain files that
    > are *not* necessary for the app to function normally. Files that are
    > necessary should be inside your app bundle, usually.
    >
    > -Steven
    >

    I would stretch to say that this is an acceptable usage.
    The generated file should not be inside the bundle as non admins don't have write access.

    As long as the app can regen the file if it gets deleted then I would say it's okay.

    Regards

    Jonathan Mitchell

    Developer
    On Feb 17, 2010, at 3:21 PM, Paul Johnson wrote:

    > I am working on a Document-based application that needs to have a
    > certain file in ~/Library/Application Support/<appname> before it can
    > do anything. It needs to be created the first time the program is run
    > (or if it has been deleted by the user).
    >
    > I've created a class XXAppDelegate and declared it as implementing the
    > NSApplicationDelegate protocol, and I defined
    > -(void)applicationDidFinishedLaunching:(NSNotification*)aNotification.
    > In this method I want to perform the file creation. Does this sound
    > like I'm on the right track? (Newbie as you can tell.)
    >
    > I should add that the file needs to be created by accessing the
    > internet and could take even a minute to finish, so I will no doubt
    > have to worry about informing the user about the delay when the
    > program is run for the first time, but before I charge in this
    > direction I would appreciate some affirmation I'm on the right track.

    Yes, you're on the right track.  You could start it earlier by putting it in -applicationWillFinishLaunching:, but I wouldn't bother in your case.  If the file could be created immediately, and if other parts of your app which might run between -applicationWillFinishLaunching: and -applicationDidFinishLaunching: would be simpler to code by assuming it's already present, then doing it in the earlier method would be good.  Since it's going to take a while to download the file, there's no real benefit to starting it earlier.

    Regards,
    Ken
  • Steve and Kyle, I may not understand the term "Application bundle"
    correctly, but to me it shouldn't be something that the program can
    store data intot. If I'm wrong, then, for example, reinstalling the
    program (and presumably recreating the 'Application bundle') would
    destroy the acquired data, which is not a desirable behavior.

    I see the data I get from the internet as not in the strictest sense
    'necessary' for the program to run, just that it would be unable to do
    very much without it. So using my loose definition, the Application
    Support folder would be the place to create my data file.

    Finally, if the Application Support directory and the Application
    bundle are not the proper places to put the data (which will be
    retained for many future activations of the program), where would that
    place be? I certainly don't want to keep it in the Documents folder as
    the data is really to be considered as part of the program rather than
    as data created by the program.

    On Wed, Feb 17, 2010 at 4:25 PM, Steven Degutis
    <steven.degutis...> wrote:
    > Apple's docs explicitly say that this folder should only contain files that
    > are *not* necessary for the app to function normally. Files that are
    > necessary should be inside your app bundle, usually.
    > -Steven
    >
    > On Wed, Feb 17, 2010 at 4:21 PM, Paul Johnson <paul...> wrote:
    >>
    >> I am working on a Document-based application that needs to have a
    >> certain file in ~/Library/Application Support/<appname> before it can
    >> do anything. It needs to be created the first time the program is run
    >> (or if it has been deleted by the user).
    >>
    >> I've created a class XXAppDelegate and declared it as implementing the
    >> NSApplicationDelegate protocol, and I defined
    >> -(void)applicationDidFinishedLaunching:(NSNotification*)aNotification.
    >> In this method I want to perform the file creation. Does this sound
    >> like I'm on the right track? (Newbie as you can tell.)
    >>
    >> I should add that the file needs to be created by accessing the
    >> internet and could take even a minute to finish, so I will no doubt
    >> have to worry about informing the user about the delay when the
    >> program is run for the first time, but before I charge in this
    >> direction I would appreciate some affirmation I'm on the right track.
    >
    >
    >
    > --
    > Steven Degutis
    > http://www.thoughtfultree.com/
    > http://www.degutis.org/
    >
  • Kyle, I've reread your post and now see your last sentence, where you
    mention Library/Caches. I guess that could be an acceptable location
    for the data I download from the internet. I still feel the data as
    being more "persistent" than data associated with a 'cache' though.

    I'm considering adding a build phase that runs a little program to
    acquire data from the internet and copy it to the Application bundle.
    That would avoid an annoying delay in starting up the program for the
    first time after installation. Then if the user ever wanted to update
    the data, he/she could explicitly do it.

    Thanks for all the replies to my original post. I hope I can get up to
    speed before long so I don't post very basic questions.

    On Wed, Feb 17, 2010 at 4:41 PM, Kyle Sluder <kyle.sluder...> wrote:
    > On Wed, Feb 17, 2010 at 1:25 PM, Steven Degutis
    > <steven.degutis...> wrote:
    >> Apple's docs explicitly say that this folder should only contain files that
    >> are *not* necessary for the app to function normally. Files that are
    >> necessary should be inside your app bundle, usually.
    >
    > As has been covered before, I believe you are misinterpreting the documentation.
    >
    > The documentation is advising you against putting frameworks, static
    > libraries, resources, or other pieces of what could rightly be
    > considered your app bundle inside your App Support directory. Plugins,
    > licenses, and other non-integral yet critical portions of your app
    > belong in App Support.
    >
    > Library/Caches is for stuff that could be blown away at any moment.
    >
    > --Kyle Sluder
    >
  • On Wed, Feb 17, 2010 at 8:49 PM, Paul Johnson <paul...> wrote:
    > Kyle, I've reread your post and now see your last sentence, where you
    > mention Library/Caches. I guess that could be an acceptable location
    > for the data I download from the internet. I still feel the data as
    > being more "persistent" than data associated with a 'cache' though.

    The point of Library/Caches is that the data can disappear at any
    time. You are right that Library/Caches would not be the appropriate
    place for that data.

    > I'm considering adding a build phase that runs a little program to
    > acquire data from the internet and copy it to the Application bundle.
    > That would avoid an annoying delay in starting up the program for the
    > first time after installation. Then if the user ever wanted to update
    > the data, he/she could explicitly do it.

    In that case, I would put that data in the Resources folder inside the
    app bundle, but put the fresh data in Library/Application Support, and
    defer to data in that location if present.

    --Kyle Sluder
  • On Wed, Feb 17, 2010 at 9:15 PM, Paul Johnson <paul...> wrote:
    > Steve and Kyle, I may not understand the term "Application bundle"
    > correctly, but to me it shouldn't be something that the program can
    > store data intot. If I'm wrong, then, for example, reinstalling the
    > program (and presumably recreating the 'Application bundle') would
    > destroy the acquired data, which is not a desirable behavior.

    Correct, the app should not write into its own app bundle. It might
    not even be allowed to, if the user doesn't have administrative
    rights.

    > I see the data I get from the internet as not in the strictest sense
    > 'necessary' for the program to run, just that it would be unable to do
    > very much without it. So using my loose definition, the Application
    > Support folder would be the place to create my data file.

    Correct.

    > Finally, if the Application Support directory and the Application
    > bundle are not the proper places to put the data (which will be
    > retained for many future activations of the program), where would that
    > place be? I certainly don't want to keep it in the Documents folder as
    > the data is really to be considered as part of the program rather than
    > as data created by the program.

    Also correct. The Documents folder is for user-created content only.

    --Kyle Sluder
  • "....  Files that are necessary should be inside your app bundle,
    usually."

    I put some files into the app bundle which were essential for the app
    to run -
    but also needed to be modified at run time.

    The first time our app was installed on a server ( for a number of
    users to have access to )
    we got into trouble as the sysadmin would not give write permission on
    the application folder
    to anybody.

    Is there another way to do this ?

    Peter
  • On 18 Feb 2010, at 09:36, Peter Hudson wrote:

    > "....  Files that are necessary should be inside your app bundle, usually."
    >
    >
    >
    > I put some files into the app bundle which were essential for the app to run -
    > but also needed to be modified at run time.
    >

    Those definitely shouldn't be changed inside the app bundle, as you'll break your code's identity.

    > The first time our app was installed on a server ( for a number of users to have access to )
    > we got into trouble as the sysadmin would not give write permission on the application folder
    > to anybody.
    >
    > Is there another way to do this ?

    You could _distribute_ them in the app bundle, then copy the files to ~/Library/Application Support/com.yourcompany.yourapp/ when it is first launched. Use and change the deployed copies from then on.

    Cheers,
    Graham.

    --
    Graham Lee
    http://blog.securemacprogramming.com/
    Coming soon - Professional Cocoa Application Security
    http://eu.wiley.com/WileyCDA/WileyTitle/productCd-0470525959.html
  • I'm getting confused.

    It seems that any files that are 'essential to the running of the
    app'  are placed in the bundle.

    It also seems that any files that are 'essential to the running of the
    app',  if they are in the bundle,  must not be modified.

    The type of files which I put in the bundle are both essential for the
    app to run and need ( from time to time ) to be modified.

    Copying from bundle to elsewhere and then modifying the copies is not
    a runner - as the user would want their format data back as it was
    when they restart the app.

    Peter
  • On 18/02/2010, at 11:09 PM, Peter Hudson wrote:

    > I'm getting confused.
    >
    > It seems that any files that are 'essential to the running of the app'  are placed in the bundle.
    >
    > It also seems that any files that are 'essential to the running of the app',  if they are in the bundle,  must not be modified.
    >
    > The type of files which I put in the bundle are both essential for the app to run and need ( from time to time ) to be modified.
    >
    > Copying from bundle to elsewhere and then modifying the copies is not a runner - as the user would want their format data back as it was when they restart the app.

    Think of it this way. Files you open directly from your bundle should be considered READ ONLY. Therefore if you want to use a modified version, you have to copy them elsewhere so that they can be read/write, and that somewhere else is usually ~/Library/Application Support/<your app>/<whatever>

    I don't see a conflict between this and your users getting the modified versions when they rerun the app. The modified files are still right where you left them. Your app will need to perform some sort of merge between the unmodified bundle version and any modified versions it finds in app support, so that the total set of files the user is working with is the latest. It can be a lot of work - in fact I'm working on something like that right now.

    If you mean they need up-to-date files if the app is moved to another machine or installed for another user, there's not a lot you can do about that except instruct them to take the modified files with them. Most apps would not be designed that way.

    --Graham
  • On Feb 18, 2010, at 12:30 AM, Paul Johnson wrote:

    > I see the data I get from the internet as not in the strictest sense
    > 'necessary' for the program to run, just that it would be unable to do
    > very much without it. So using my loose definition, the Application
    > Support folder would be the place to create my data file.

    This does not to me sound like a loose definition, and in my opinion this is exactly the kind of circumstance in which you should use the Application Support folder. If that data is specific to a user, then put it in ~/Application Support/appInfo. You can (and should) get the path for such directories  from NSPathUtilities:

    For the system's Application Folder:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSSystemDomainMask, YES);
    s = [paths objectAtIndex:0];

    For the user's Application Folder:
    NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
    s = [paths objectAtIndex:0];

    NSSearchPathForDirectoriesInDomains is described in Foundation Functions Reference. Values for the parameters (NSSearchPathDirectory and NSSearchPathDomainMask) are described in  the Foundation Data Types Reference. Or just look at the enums declared in NSPathUtilities.h
  • On 18/02/2010, at 11:46 PM, Peter Hudson wrote:

    > I started out this way to avoid exactly the problem you get from requiring users to move critical files around.  Most of our users are not comfortable with computers, let alone moving files around !  Add in the problem of making sure they read the right pages of the manual ( if they can find it ) and then do this through language barriers ... ( we run in many languages )

    I'm not suggesting they do move the files around. Your app can move them around to do what it needs to do, and the user is none the wiser. They need not care if a resource they are using comes from the bundle or from app support, it Just Works, right?

    Since you haven't really defined what these files are or how they're used, I can only give general and vague suggestions. My app does something apparently similar - we supply a default set of content in the form of graphics and these come in the bundle. On first startup we copy the file to app support so that the user can customise and add to the available graphics. Currently this is just one file, so "the latest" is always the one in app support, but actually this is a drawback on a number of levels so I'm working on splitting this out into one file per graphic, and the app will combine the bundle (read only) files with the app support (read/write) files to present a unified set to the user. They don't care where they come from, they just use them.

    If the same app is copied/installed elsewhere, all the new installation gets is the original bundle set, not any new ones the other user made. That's completely normal and I would say expected behaviour.

    The simple fact is that you cannot reliably update your app as it runs by writing files to its bundle. So however you need it to work, this option is not available.

    --Graham
previous month february 2010 next month
MTWTFSS
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
Go to today