際際滷

際際滷Share a Scribd company logo
Escaping)the
Mac$App$Sandbox
(or$at$least$a$small$part$of$it)
Ma#$Welch
Developer(working(on(iOS,(Mac,(and(node(
apps(by(night,(and(on(the(Force.com(
pla=orm(by(day.
ma#@welcher.net
@_Ma#Welch_
h#p://ma#wel.ch
Bearings
What%is%the%Mac%App%Sandbox?
App#Sandbox!is!an!access!control!technology!provided!in!OS!X,!
enforced!at!the!kernel!level.!Its!strategy!is!twofold:
 App$Sandbox$enables$you$to$describe$how$your$app$interacts$
with$the$system.$The$system$then$grants$your$app$the$access$it$
needs$to$get$its$job$done,$and$no$more.
 App$Sandbox$allows$the$user$to$transparently$grant$your$app$
addi=onal$access$by$way$of$Open$and$Save$dialogs,$drag$and$
drop,$and$other$familiar$user$interac=ons.
(From&the&Apple&"App&Sandbox&Design&Guide")
Sandbox(Filesystem(Limita2ons
Speci鍖cally,+sandboxing+limits+an+app+to+only+those+鍖les+or+
directories+explicitly+opened+by+the+user.
For$most$cases$this$is$OK.$(In$fact,$Deckset$here$regularly$asks$
permission$to$access$a$photo$I$want$to$use$that's$on$my$鍖lesystem.)
Temporary)Files
The$problem$is$that$temporary$鍖les$are$
supposed$to$be$invisible$to$the$end$user.
What%kind%of%experience%would%this%be?
Now$mul(ply$this$bad$experience$by$10.$
Or$100.$Or$however$many$hundreds$of$
photos$(in$the$case$of$Bearings$app)$that$
need$to$be$processed.
Workaround:*File*Presenters
File%Presenters?
Yes,%File%Presenters.
 Around(since(10.7,(File(Presenters((and(their("parents"(File(
Coordinators)(have(made(working(with(the(鍖le(system(in(a(mulDE
threaded,(mulDEprocessing(environment(easier(and(safer.
Yes,%File%Presenters.
 Around(since(10.7,(File(Presenters((and(their("parents"(File(
Coordinators)(have(made(working(with(the(鍖le(system(in(a(mulDE
threaded,(mulDEprocessing(environment(easier(and(safer.
Yes,%File%Presenters.
 Around(since(10.7,(File(Presenters((and(their("parents"(File(
Coordinators)(have(made(working(with(the(鍖le(system(in(a(mulDE
threaded,(mulDEprocessing(environment(easier(and(safer.
Yes,%File%Presenters.
 Around(since(10.7,(File(Presenters((and(their("parents"(File(
Coordinators)(have(made(working(with(the(鍖le(system(in(a(mulDE
threaded,(mulDEprocessing(environment(easier(and(safer.
Yes,%File%Presenters.
 Around(since(10.7,(File(Presenters((and(their("parents"(File(
Coordinators)(have(made(working(with(the(鍖le(system(in(a(mulDE
threaded,(mulDEprocessing(environment(easier(and(safer.
Implemen'ng)File)Presenters)for)Related)
Items
Apple%has%repurposed%File%Presenters%to%enable%"Related%Items"%in%
sandboxed%apps.
Related'Items
 Must&have&the&same&name&(minus&extension)&as&the&item&to&
which&they&are&related
 Must&have&a&known9ahead9of9;me&extension
Implemen'ng)File)Presenters)for)Related)
Items
Create&a&class&that&conforms&the&the&NSFilePresenter&protocol.&
Implement&these&methods:
1. primaryPresentedItemURL##The#URL#for#the#original#鍖le
2. primaryItemURL##the#URL#for#the#temporary#鍖le#(the#same#as#
above,#but#with#di鍖erent#extension)
3. presentedItemOperationQueue##the#queue#on#which#the#
app#will#perform#鍖le#presentaGon#tasks
WRFilePresenter
// WRFilePresenter.m
// Bearings
//
// Created by Matt Welch on 3/17/14.
//
#import "WRFilePresenter.h"
@implementation WRFilePresenter
{
NSOperationQueue* queue;
NSURL* pFileURL;
NSURL* tFileURL;
}
- (id) init {
self = [super init];
if (self) {
queue = [NSOperationQueue new];
[NSFileCoordinator addFilePresenter:self];
}
return self;
}
- (NSURL*) primaryPresentedItemURL {
return pFileURL;
}
- (NSURL *) presentedItemURL {
return tFileURL;
}
- (NSOperationQueue*) presentedItemOperationQueue {
return queue;
}
-(void) setURLs:(NSURL*)url {
pFileURL=url;
NSString *fURLS=[url absoluteString];
NSString *fURLSt=[NSString stringWithFormat:@"%@%@",fURLS,@"_temp_file_extension" ];
NSURL *surl = [NSURL URLWithString:fURLSt];
tFileURL=surl;
}
@end
Implemen'ng)File)Presenters
Given&a&鍖le&with&a&url&of&realFileURL,&implement&a&presenter&for&
it:
WRFilePresenter *filePresenter=[[WRFilePresenter alloc] init];
[filePresenter setURLs:realFileURL];
And$we're$all$set$(at$least$as$far$as$code$is$concerned).
XCode&Target&Setup
In#the#Project#Navigator,#under#the#"Info"#tab,#there#is#a#
"Documents#Type"#sec=on.
 Set%"Extension"%to%be%the%known%temporary%鍖le%extension.
 Add%NSIsRelatedItemType%of%type%Boolean%to%"Addi<onal%
document%type%proper<es"%and%set%it%to%YES
XCode&Target&Setup
Demo
Further'Informa.on
More%in(depth%informa0on%can%be%found%at:
h5p://ma5wel.ch/temporary(鍖les(in(sandboxed(mac(apps/
This%presenta,on%is%on%github:
h2ps://github.com/ma2welch/mac_sandbox_temp鍖les_deckset
A"ribu'ons
 happiness)from)a)sandbox)1)h2ps://www.鍖ickr.com/photos/
celinesphotographer/326629023/
 App)Sandbox)Design)Guide)1)h2ps://developer.apple.com/
library/mac/documentaIon/Security/Conceptual/
AppSandboxDesignGuide/AboutAppSandbox/
AboutAppSandbox.html
 永温沿艶姻温馨温)1)鞄2沿壊://敬敬敬.鍖i界一姻.界看馨/沿鞄看岳看壊/一温壊温温/3103799093/

More Related Content

Escaping the Mac App Store Sandbox (or at least a small part of it)