swift


How to persist permissions with security scope bookmarks in a OSX sandboxed app


I am trying to persist read/write permissions to Applications folder through security-scoped bookmarks but unsuccessfully.
I use grandAccess() to open a panel and select the Applications folder and gain permissions. At the same time, the panel's URL is stored as a security-scoped bookmark in UserDefaults. Then I can delete apps in the Applications folder with FileManager.
When I relaunch my app, I resolve the stored bookmark for Applications folder path and while the startAccessingSecurityScopedResource() returns TRUE for this URL, If I try to delete the application I then get a permission error.
Any idea why this happens???
My code is below:
// Move to Trash
let startAccess = SecurityScopeManager.shared.startAccess()
guard startAccess == true else {
log.warning("Starting file access failed")
}
do {
let url = URL(fileURLWithPath: application.path)
try FileManager.default.trashItem(at: url, resultingItemURL: nil)
} catch let error {
log.error(error)
}
// End
class SecurityScopeManager: NSObject {
static let shared = SecurityScopeManager()
private let defaultsKey = DefaultsKeys.securityScopeBookmark.rawValue
private var url: URL?
func grandAccess() -> Bool {
guard resolveBookmarkData() == false else {
return true
}
let success = runPanel()
return success
}
private override init() {
super.init()
}
/// In the panel, I select the Applications folder and press the Open button
private func runPanel() -> Bool {
let applicationsFolderPath = FileManager.default.urls(for: .applicationDirectory, in: .localDomainMask).first!
let panel = NSOpenPanel()
panel.canChooseDirectories = true
panel.canChooseFiles = false
panel.directoryURL = FileManager.default.urls(for: .userDirectory, in: .localDomainMask).first!
if panel.runModal() == NSModalResponseOK {
guard let url = panel.url, url == applicationsFolderPath else {
return false
}
return storeBookmarkData(url: url)
} else {
return false
}
}
/// Save bookmark data to UserDefaults. Returns true if success
private func storeBookmarkData(url: URL) -> Bool {
do {
let data = try url.bookmarkData(options: .withSecurityScope, includingResourceValuesForKeys: nil, relativeTo: nil)
UserDefaults.standard.set(data, forKey: defaultsKey)
return true
} catch {
log.error(error.localizedDescription)
return false
}
}
/// Load bookmark data from UserDefaults
private func resolveBookmarkData() -> Bool {
guard let data = UserDefaults.standard.data(forKey: defaultsKey) else {
return false
}
do {
var isStale = Bool()
url = try URL(resolvingBookmarkData: data, options: .withSecurityScope, relativeTo: nil, bookmarkDataIsStale: &isStale)
if isStale { // If cannot update bookmark delete previous bookmark data
UserDefaults.standard.removeObject(forKey: defaultsKey)
}
return true
} catch {
log.error(error)
return false
}
}
func startAccess() -> Bool {
_ = resolveBookmarkData()
guard url != nil else {
_ = grandAccess()
return false
}
let result = url?.startAccessingSecurityScopedResource() ?? false
return result
}
func stopAccess() {
url?.stopAccessingSecurityScopedResource()
}
}

Related Links

Display windows present in different storyboards
Annotations for MKLocalSearch in Swift 3 — Map View Current Location
data is not transferring at the right time in my prepare for segue function
$set paramater in Alamofire .put request?
Unable to 'open' frameworks with cocoapods; Couldn't generate swift representation
How to use MTLBlitCommandEncoder for copying interlaced video fields into a MTLBuffer
How to format code in Xcode INCLUDING MarkUps
How to create files with different names using the least amount of processing power in Swift?
How to create infinite motion effect?
Swift 3 Collection subclass won't compile
Passing parameters with #selector
Swift Run Time Library vs. Swift Standard Library
Using functional programming to map one array to another
How to force on touch.location to work only in special place on screen?
Connecting to remote mongodb using perfect server swift with AWS
Most efficient way to flatten an array of dictionaries containing arrays

Categories

HOME
itext
drupal-7
windows-store-apps
phpstorm
histogrammar
gspread
schemacrawler
requirejs
sudo
actionscript-2
vuex
window
wordpress-theming
google-shopping
uiview
squarespace
jacoco
spring-cloud-config
titan
zoomcharts
arraylist
ada
flat-file
boolean-expression
deb
os161
header-files
samsung-mobile
sumo
pipelinedb
classpath
weinre
twitter-bootstrap-2
oracle-xml-db
ifstream
phpspreadsheet
.net-assembly
nashorn
bing-translator-api
service-fabric-stateful
taglib
rapidweaver
ajp
chunked-encoding
amazon-machine-learning
ti-basic
web-deployment-project
istorage
persistent
component-pascal
cdk
launch
adler32
gmt
autoresize
iron.io
pdfkit
cjson
software-product-lines
zurb-foundation-apps
boost-hana
nssplitview
achievements
emokit
interactive-brokers
portfolio
optionbutton
subresource-integrity
wif
graphical-logo
sqoop2
jai
python-ggplot
orientation-changes
viewflipper
rhel5
hidden-field
eclipse-classpath
korma
android-looper
data-generation
delphi-xe3
opensocial
ksoap2
edit-in-place
operations
bignum
sslexception
adomd.net
database-permissions
reporting-tools
htmltextwriter
xmlslurper
parameterization
userid
scraperwiki
libavformat
querypath
google-instant
project-lifecycle
associativity

Resources

Mobile Apps Dev
Database Users
javascript
java
csharp
php
android
MS Developer
developer works
python
ios
c
html
jquery
RDBMS discuss
Cloud Virtualization
Database Dev&Adm
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App