-
Notifications
You must be signed in to change notification settings - Fork 12
How To Install
With the advent of sandboxing and XPC services in OS X 10.7 and the enforcement of sandboxing in the Mac App Store the iMedia framework had to adapt to an even broader spectrum of deployment scenarios. These are systematically addressed in iMedia 3.
OS X: iMedia 3 is compatible with 10.6.8 and 10.7.3 and up. On 10.6 iMedia will always run non-sandboxed and without utilizing XPC services.
Xcode: Though not mandatory this guide assumes that your app is wrapped into an Xcode workspace. If it isn't yet you may want to consider doing it now (more on workspaces).
Since IMedia 3 no longer consequently implements forward method prototypes you must use llvm version 3.1 or higher. Thus, you should be fine with Xcode 4.3 and up (see also Objective-C Feature Availability Index).
iMedia 3 can adapt to your app's deployment needs along the following dimensions (choose any combination):
- Sandboxed (in terms of OS X) / non-sandboxed
- With / without utilizing XPC services
Note regarding XPC services: When deployed XPC services serve the purpose of media fetching in respect to library types supported by iMedia (e.g. iPhoto or Lightroom libraries)
Let's start with the easiest scenario:
This is straight forward.
-
Add iMedia as a submodule to your app:
$ git submodule add https://github.com/iMediaSandboxing/iMedia.git Frameworks/iMedia
Or, if you don't use git as your app's versioning tool simply clone iMedia:
$ git clone https://github.com/iMediaSandboxing/iMedia.git
and move the framework to your project folder.
-
iMedia 3 depends on other (GitHub hosted) frameworks that are hooked to its repository via the
git submodule
command. These frameworks are (as of iMedia 3.0)- ObjectiveFlickr
- XPCKit
To clone these submodules to your local system in their correct (iMedia compatible) version you must execute the following git commands from the root directory of your local iMedia git repo:
$ git submodule init <some response from git> $ git submodule update <some response from git>
-
Add the
iMedia.xcodeproj
project file to your workspace or add it as a sub-project to your app (by dragging it into the navigator pane of Xcode) -
Open the iMedia project in your app's workspace and locate
Products
>iMedia.framework
-
(This step only if you added iMedia as sub-project) Drag & Drop
iMedia.framework
toBuild Phases
>Target Dependencies
-
Drag & Drop
iMedia.framework
toBuild Phases
>Link Binaries With Libraries
-
Drag & Drop
iMedia.framework
toBuild Phases
>Copy Frameworks
-
Repeat steps 3,4,5 and 7 to the ObjectiveFlickr framework located in the root directory of the iMedia repository
-
You do not have to repeat steps 3,4,5 and 7 for the XPCKit framework since it is not utilized in this scenario
-
Tell your app where to find the iMedia framework: Your application binary and (principally) all XPC services associated with the iMedia framework will link with the iMedia framework located in the application's bundle. Since the (relative) path from the location of these binaries to the location of the app-embedded iMedia framework is (naturally) different, iMedia uses the @rpath variable to tell the loader where to find it (see also Linking and Install Names by Mike Ash). To set the @rpath variable you must set the
Runpath Search Paths
build setting to@loader_path/../Frameworks
for the target that builds your app's main binary.
If you are not yet familiar with app sandboxing on OS X you will like to first read Apple's App Sandboxing Design Guide.
- Apply steps 1-10 as described in scenario 1
- Select your application target and under
Summary
>Entitlements
switch onUse Entitlements File
andEnable App Sandboxing
- Add the following entitlements to your app's entitlement file:
-
com.apple.security.files.user-selected.read-write YES
will enable the user to grant entitlements to directories where necessary when prompted (e.g. library sits on external volume) -
com.apple.security.files.bookmarks.app-scope YES
will ensure that entitlements granted by the user will persist across sessions or even reboot of the system. This one is also mandatory if your app likes to save image URLs obtained from iMedia. -
com.apple.security.temporary-exception.shared-preference.read-only com.apple.iApps
will enable iMedia to locate Aperture and iPhoto libraries (note that this entitlement must be set up as a one-element array) -
com.apple.security.temporary-exception.shared-preference.read-only com.adobe.Lightroom, com.adobe.Lightroom2,...
will enable iMedia to locate Lightroom libraries of their respective version (note that you have to append those entitlements to the entitlement of step 3.3 if you applied step 3.3. Add one entry for each major Lightroom version you want to qualify) - Add access to the resources your app needs. E.g. to use images, you like to at least have
Read Access
to the user's Pictures folder (you may set this on the summary page of your application target)
-
Regardless of whether your app runs sandboxed or not the iMedia rule for XPC services is:
If you deploy an iMedia XPC service to your app's bundle it will be utilized. If you don't, GCD will stand in instead.
Thus, to implement scenario 3 apply the following steps:
-
Apply steps 1-10 as described in scenario 1
-
Apply steps 3,4,5 and 7 of scenario 1 to the XPCKit framework located in the root directory of the iMedia repository
-
Add a new
Copy Files
build phase and name itCopy XPC Services
. SetDestination
of this build phase toWrapper
andSubpath
toContents/XPCServices
-
Open the iMedia project in your app's workspace and locate
Products
>iMedia.framework
-
Make sure that all listed XPC services are already built (by explicitly building their targets)
-
Drag all XPC services of library types your app supports and the FSEvents service to the newly created
Copy XPC Services
build phase (NOTE: if these XPC services have not been built Xcode will not be able to identify their locations and issue errors when trying to copy them).Technically you could just bundle some XPC services with your app and let other library types be handled by GCD – it will work. But it probably wouldn't be a consistent approach.
- Apply steps 1-3 as described in scenario 2 but omit steps 3.2 - 3.4 (they won't harm execution of your app but Apple might not like superfluous entitlements on Mac App Store review). These entitlements are already granted to iMedia's XPC services where needed.
- Apply steps 2-6 as described in scenario 3
The test app provided with the repo (target iMediaTester
) exercises a wealth of configuration options for the framework. Have a look at IMBTestAppDelegate
.
To take advantage of Facebook photo album integration you must provide a Facebook registered app id. You must create one here.
This Facebook app id must be provided by your delegate object (IMBNodeViewControllerDelegate
protocol). When testing the framework through its test application (iMediaTester), you may alternatively add an Application Password
to your login
keychain with account
set to imb_facebook_app_id
and password
set to your Facebook app id.
T.b.d.
While building your project using the new iMedia framework, you may notice some changes:
- The
location
property ofIMBObject
is anNSURL
now - There are no "object promises" in Drag & Drop any more. Instead
IMBObjects
are placed on the pasteboard. You may like to callimb_containsIMBObjects
fromNSPasteboard+iMedia.h
to check wether a drag pasteboard holds iMedia objects. - Thumbnail loading is async now and in case you utilized this operation, you may like to observe the
imageRepresentation
property ofIMBObject
after triggering aloadThumbnail
operation - A couple of subclasses of
IMBObjectViewController
have been renamed. Have a look at commit 0080941501f2cfffb0772180161e79b08738e4e8 of March 28th 2012 for details
In case you are moving from a none-sandboxed version of your app to a sandboxed one, you need to think about migrating your data. For example, your current document file may hold an URL to an image, which is located outside the Pictures folder. Due to the sandboxing constraints, you might not be able to access that image any more.
To make the process for the user as painless as possible, you may want to find a common ancestor of all images used in your document and ask the user to give you permission to access that folder:
- Collect all URLs you can't access. You may like to use
imb_accessibility
fromNSURL+iMedia.h
for this purpose. - Find a common ancestor folder:
+ (NSURL*) commonAncestorForURLs:(NSArray*)inURLs
fromIMBAccessRightsController.h
- Get permission from the user to access that folder. Have a look at
_showForSuggestedURL:name:completionHandler:
inIMBAccessRightsViewController.m
for an idea of how to do this - Now that you have permission, change all URLs into app scoped bookmarks
Persistent IMBObject identifiers are no longer depending on class names because changing a class's name would affect the identifier. iMedia now provides:
-
-[IMBObject identifier]
: a unique identifier for this object at runtime (i.e. explicitly not guaranteeing to be identical across sessions) -
-[IMBObject persistentResourceIdentifier]
: a unique persistent resource identifier for this object -
-[IMBParser iMedia2PersistentResourceIdentifierForObject:]
: to assist you in migrating iMedia 2 persistent resource identifiers to iMedia 3 persistent resource identifiers in case you persisted resource ids in your iMedia 2 based app (e.g. to utilize the badges feature)
Enjoy!