Tutorial for Security Scoped Bookmarksl

// -----------------------------------------------------------------------------
// – Request for shortest example possible
// – of security scoped bookmarks
// -----------------------------------------------------------------------------

Can anyone write an old-school late '70’s early '80’s teaching explanation using top down programming example in XOJO instead of using abstraction?

//----------------------------------------------
// – App Description and issue:
//----------------------------------------------

My small backup app stores the folder the user select and the paths to the files within that folder in a database in plain text for future reference. In order to submit my app to the app store, It has to use security scoped bookmarks.

// -----------------------------------------------------------------------------
// – Instructions / Request:
// -----------------------------------------------------------------------------

// -----------------------------------------------------------------------------
// – Needed: A Security Scoped Bookmarks Tutorial
// –
// – Preferences for this tutorial
// – 1. Use as few objects as possible
// – 2. NO abstraction unless unavoidable
// – 3. NO classes
// – 4. NO modules
// – 5. Use the MBS Plugin if you have it
// – 6. Explain each line of code like you are teaching it.
// -----------------------------------------------------------------------------
// -----------------------------------------------------------------------------
// – Step 1 - have the user select a folder
// – to access the items within that folder
// – Show the path to the folder in a listbox
// -----------------------------------------------------------------------------

Var f as FolderItem                      // -- create a variable to hold a folder path
f = FolderItem.ShowSelectFolderDialog()  // -- present the user with a dialogBox to pick a folder
Listbox1.AddRow(f.NativePath)            // -- put the text version of that path into a listbox

// -----------------------------------------------------------------------------
// – Using MBS example start
// – do I even need to capture this as a string?
// -----------------------------------------------------------------------------

Var aBookmark as string                  // -- create string holder             
// ----------------------------------------------------------------------
// -- assign the bookmark as text to aBookmark - is this even necessary?
// ----------------------------------------------------------------------
aBookmark = CFBookmarkMBS.CreateBookmarkData(f,CFBookmarkMBS.kCreationSuitableForBookmarkFile)  

// -----------------------------------------------------------------------------
// -- What is Apples requirement for saving?
// --   a. 
// --   b.  etc...
// -- 
// -- How to Start Using...
// -- 
// -- How to Stop Using...
// -- 
// -- How to start using again...
// -- 
// -- Other issues concerns?...
// -- 
// -----------------------------------------------------------------------------

You should offer compensation. @Sam_Rowlands went through all of this work to get his simple back up app on the store. That app is no longer for sale, so financing the research didn’t seem to pay out.

Seems like you should offer something for his time, especially given your very particular requirements.

2 Likes

I would be happy to pay for a step by step guide as long as it’s affordable for me. This is just one example of where I would use the bookmarks though. It’s kind of starting point for me with security scoped bookmarks. I would like to publish the example or a variation of it to help others though so please keep that in mind.

I have written about Security-Scoped Bodgemarks many-a-time over the last (almost) decade. If you look at old copies of xDev (forget which issues sorry), you might find a tutorial there, or maybe even in this very forum.

They have so many gotchyas (which I know I’ve documented on this forum and others) that I will try to find another way first and use SSBs as an absolute last resort. In some cases, I simply choose to avoid the App Store all together.

What is more important than supporting SSBs is a solid marketing plan, without one, your application will go into the Mac App Store and die a silent lonely death. All the time that you invested in supporting SSBs and designing your application to work with SSBs will be an absolute waste. Unless of course you intend to release an application that no-one will ever see.

The next most important thing to figure out before development, is how are you going to make money from this application. Charging users has to be done in specific ways on the App Store, and they’re not friendly to either you or your customer. Free trials is the norm for Mac software, but to make it work in accordance to the App Store rules, is sometimes not even worth the effort, especially if you don’t have a reliable marketing plan.

While I think I am pretty good with the coding and understanding of technical issues, I continue to fail at the marketing and business side, so I would recommend you seek advice from others who’re successful in this area.

Thanks Sam. I’ll try and skim through older versions of xDev if I can find them. I don’t really expect to make any money from this one. It’s more of a test run and just bragging rights to my buddies. Maybe between MBS, and xDev I can glean enough to understand and re-write the tutorial with the caveats as necessary. Everyone seems to have the same answer with SSB’s (not single side band). You would think that Apple would try a different approach. I left quite a bit of history out of my post. It’s been several months, (over a year) and multiple re-writes in different languages ending back up in XOJO. No one has an easy tutorial. Not even The Eskimo at Apple support who admitted there were none. That’s why I’d like to simplify and write at least one tutorial so others don’t have to go through the same difficulties that I have had so far. When I do post in a public blog for some help, I usually get snide remarks back. It’s nice to have some lighter responses in this forum.

And for completeness I have already skimmed at these links before posting:

https://www.monkeybreadsoftware.net/example-maccf-sandboxfileaccess-sandboxfiles.shtml
[https://developer.apple.com/library/archive/documentation/Security/Conceptual/AppSandboxDesignGuide/AppSandboxInDepth/AppSandboxInDepth.html#//apple_ref/doc/uid/TP40011183-CH3-SW6]

Well as long as you understand this, I am not saying that you won’t make enough, just that I’ve assisted several developers, get their app on to the App Store. Only to quit after because they’re unable to gain any exposure and their app withers and dies (along with their enthusiasm).

The App Sandbox was introduced when Apple transitioned to the annual update program. SSBs came later with a point update. Last time I checked, Apple don’t use SSBs in their own apps (this may have changed, but Apple gives themselves private entitlements to work around things like SSBs). It’s also worth bearing in mind if you use their tool and “Document based application” template, a lot of things are taken care automagically for you. In your case, a backup application wouldn’t be covered.

The first thing you need to do is to design your product so that it stores SSB data (can be hex encoded) and a path to the file location. You’ll need the SSB data to access that file, but it if fails for any reason, you’ll get no information from the SSB. You can’t even tell the user what the name of the file was, or where it was located. So you store the path yourself, to help the user identify which file/folder that your app can no longer access.

When you want to access that file or folder, you resolve the SSB data to a NSURL. If it works, great, if not, alert the user. If it returns the bookmark as being stale, once you have access recreate the bookmark information and store it. Next you start access to that NSURL, do your thing, get in and out before 90 seconds and release access.

If you are doing what I did for backup, walking down the hierarchy, you should consider start/stop for each item you check, incase walking the hierarchy takes longer than 90 seconds.

Now for the file copy. This is where it gets tricky, as the copy may take more than 90 seconds. At the time, I found if you use an asynchronous file copy, get access, start copy, then release it, it worked. It may not now, so you should test for this.

How do you know if you’ve exceeded your 90 seconds, you don’t. However if you lose access to the file system, it means you’ve done it too many times and have to start checking your code.

When you create the bookmark, you must have access to the file and you want to avoid recreating the bookmark data as it is expensive. Say when the user adds the file/folder to your app, and also if the OS marks the SSB as being stale.

If you want some pre-written code, I have included an example within the Ohanaware App Kit, but I could enhance that for you if needed.

In regards to my own backup program, it was made during the time when Apple didn’t permit FREE trials, and had to be an app that could be used for free with optional extras for sale. While it had a large following, it never made enough money to be worth the effort, and after having to fix it several times for OS updates, I pulled it. I still use it myself every single day, but I don’t bother trying to make it publicly available. If I did, I would skip the App Store.

We have security scoped bookmarks in CFBookmarkMBS module.
Use one of the CreateBookmarkData functions to create it and store the string you get in a preferences file. Later go and use ResolveBookmarkDataToCFURLMBS function to resolve the bookmark.
You may use StartAccessingSecurityScopedResource to start using it and then query the folderitem of the CFURLMBS object.

Check the /MacCF/Sandbox File Access/Sandbox Files example project.

Jim Mckay has SSBookmarks - a class for getting SSBs. I was able to use it to get SSBs working in the app I’m using.

One Caveat - it does not work when running the app in the Xojo IDE. The preference folder that uses is different from the one a built app uses.

I needed this because saved files in my app often include links to audio or video files that have to be loaded along with the rest of the saved data; and for opening items in a Recent Items menu.

Link: Jim McKay’s SSBookmarks

1 Like

OK. Thank you guys for the feedback. I believe this will help me out a lot. I will go back to my desk and dig in deeper and report back any updates.

You need to wrap your debug build with the same entitlements and matching team identity. If you use App Wrapper 4, check out the “Scripting” pane for a Xojo IDE script you can copy / paste into your project.

I do that. It’s one of the reasons I love App Wrapper and why I still have hair!

1 Like

If you have any issue with the Scripting, let me know.