CFBookmark Problems - again

I use cfBookmarkMBS to allow access to particular folders and files on consecutive runs of the app. Works fine until I send out an upgrade to the app (with new Notarization) and then all the bookmarks fail to load.

The app is Sandboxed but not on MAS.

Any clues?

Code? Can you reproduce the problem? Why would you sandbox a non-MAS app?

[quote=487833:@James Pitchford]I use cfBookmarkMBS to allow access to particular folders and files on consecutive runs of the app. Works fine until I send out an upgrade to the app (with new Notarization) and then all the bookmarks fail to load.

The app is Sandboxed but not on MAS.

Any clues?[/quote]
This was a problem back in macOS 10.7 as Apple took into account the version number of the application in part of their security protocols.

Which version of the macOS are you using?

Also is there any reason as to why you’re using the lower level API as opposed to the higher level NSURL functions?

Touch wood, I’ve not seen this problem when using the NSURL functions for bookmarks… He says, then goes off to double check with a machine running macOS 10.15.5…

For consistency - same app used in both non MAS and MAS. The non-MAS is currently used for Beta testing. Curiously the MAS version doesn’t exhibit this problem.

10.15.4

It was just what had worked before and not being in tune (enough) with all the options that are available - i.e. how is one supposed to know??? I’ll have to investigate the NSURL equivalents to see if they work but I’m not seeing Bookmarks in MBS’s NSURLMBS - is it a bookmark by any other name?

There were also problems with 10.7 when sharing a single container between a MAS application and a non MAS application.

I’d like to say that I haven’t seen this for a while, but I realized that because of Apple’s requested changes, my MAS app and my website app actually have different bundle identifiers and therefore use different containers. So it’s not easy for me to confirm this anymore :frowning:

With the NSURL classes, you don’t actually have a bookmark object. They use a NSData object.
To create.

[NSURL bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error:]

I use these constants when creating NSURLBookmarkCreationWithSecurityScope + NSURLBookmarkCreationSecurityScopeAllowOnlyReadAccess

To resolve.

[NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:]

These constants when resolving NSURLBookmarkResolutionWithSecurityScope + NSURLBookmarkResolutionWithoutMounting

To request access.

[NSURL startAccessingSecurityScopedResource]

To release access.

[NSURL stopAccessingSecurityScopedResource]

The users aren’t interested in consistency. They just want an app. Bonus points are for non-crippled apps.

I wasn’t able to get the bookmark functions from MBS to work, too. I’m using Sams code which he posted to the forum. Holler, if you need it again. That has worked for several versions of my app.

@James Pitchford — After a question about bookmarks on this forum some months ago, I wrote a small standalone module to create and resolve Bookmarks to/from FolderItems. Hope it can be useful. Here are the 2 methods of the module:

[code]Public Function GetBookmarkData(extends f as FolderItem, relativeTo as FolderItem = nil, Mode as Integer = 0) as String
//# Mimicks (better) FolderItem.GetSaveInfo with modern system calls. Mode is actually not used. The bookmark will be relative if and only if you set a RelativeTo FolderItem.

declare function NSClassFromString Lib CocoaLib ( aClassName as CFStringRef ) As Ptr
declare function URLWithString lib CocoaLib selector “URLWithString:” ( cls as Ptr, URLString as CFStringRef ) as Ptr
declare function BookmarkDataWithOptions lib CocoaLib selector “bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error:” (id as Ptr, options as Integer, rsrc as Ptr, relativeTo as Ptr, byref error as Ptr) as Ptr
declare function DataLength lib CocoaLib selector “length” (id as Ptr) as integer
declare sub DataBytes lib CocoaLib selector “getBytes:length:” (id as Ptr, dest as Ptr, length as integer)

const CocoaLib = “Cocoa.framework”

dim url as Ptr = URLWithString( NSClassFromString( “NSURL” ), f.URLPath )
dim relativeNSURL as Ptr
dim err as Ptr

if relativeTo<>nil then
relativeNSURL = URLWithString( NSClassFromString( “NSURL” ), relativeTo.URLPath )
end if

dim data as Ptr = BookmarkDataWithOptions( url, 0, nil, relativeNSURL, err )

if data<>nil then
dim L as integer = DataLength( data )
dim mb as new MemoryBlock( L )
DataBytes data, mb, L
return mb.StringValue( 0, L )
end if

End Function
[/code]

[code]Public Function ResolveBookmark(data as String, relativeTo as FolderItem = nil) as FolderItem
//# Resolves a bookmark and returns the corresponding FolderItem. If you created a relative Bookmark, you MUST provide the same RelativeTo parameter as during creation.

declare function NSClassFromString Lib CocoaLib ( aClassName as CFStringRef ) As Ptr
declare function URLWithString lib CocoaLib selector “URLWithString:” ( cls as Ptr, URLString as CFStringRef ) as Ptr
declare function URLByResolvingBookmarkData lib CocoaLib selector “URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:” (cls as Ptr, data as Ptr, options as integer, relativeto as Ptr, byref stale as Boolean, byref err as Ptr) as Ptr
declare function DataWithBytes lib CocoaLib selector “dataWithBytes:length:” (cls as Ptr, bytes as Ptr, length as integer) as Ptr
declare function absoluteString lib CocoaLib selector “absoluteString” (id as Ptr) as CFStringRef

dim url as Ptr
dim relativeNSURL as Ptr
dim stale as boolean
dim err as Ptr

if relativeTo<>nil then
relativeNSURL = URLWithString( NSClassFromString( “NSURL” ), relativeTo.URLPath )
end if

dim mb as MemoryBlock = data
dim nsdata as Ptr = DataWithBytes( NSClassFromString( “NSData” ), mb, mb.size )

url = URLByResolvingBookmarkData( NSClassFromString( “NSURL” ), nsdata, 0, relativeNSURL, stale, err )

if url<>nil then
return new FolderItem( absoluteString( url ), FolderItem.PathTypeURL )
end if

End Function
[/code]

Fully agree of course. In this case I was trying to make the Beta testing version (non MAS) entirely consistent with the MAS version - but I guess this was the exception that proved the rule. Also I’m fully expecting Sandboxing to become a requirement for all apps at some stage.

Thank you Stéphane. Are there also modules for start and stop using bookmarks?

@James Pitchford — Start and stop are more about “security scope” which my module does not handle at all.

I’m looking for the equivalents in MBS (I’m not proficient in Declares so maintenance is a concern).

Can find:
NSURLMBS.startAccessingSecurityScopedResource
NSURLMBS.stopAccessingSecurityScopedResource

But I can’t find the creation and resolving methods for bookmarks. I’m assuming it is part of:
NSURLMBS.setResourceValue
NSURLMBS.getResourceValue

But I can’t find keys associated with securityScope.

Christian - if you are listening - do you have any examples for this code?

Well, we have ResolveBookmarkDataToCFURLMBS in CFBookmarkMBS module.
There you get a CFURLMBS object.

That module also has StartAccessingSecurityScopedResource method to start the access.

Key thing is to keep the CFURLMBS around as security scope is linked to it.

Christian - yes I was using those but they were giving me problems per earlier on in this thread. Sam was recommending using NSURL equivalents. Those are what I was looking for in your plug-ins.

Lol! I’ve been expecting this since it’s first release. There’s a lot of capability that’s still missing from the Mac App Sandbox, and at this point in the game, I don’t expect it to get added.

I personally expect the ARM Macs to be an iPad in a Mac case, running a modified version of iPadOS that looks like the Mac, with the only way to get apps for these new devices will be directly from the App Store. Overtime as ARM devices replace x86 ones, Apple can then wind down Notarization and many independent devs (especially the ones who whine a lot) can leave for Windows.

[quote=487909:@James Pitchford]NSURLMBS.setResourceValue
NSURLMBS.getResourceValue[/quote]
These are for getting meta data from files, I would recommend checking out the options for these functions as there’s quite a bit of meta data you can get at from these.