Photo Editing Extension Details (with App filter demo)

Source: Internet
Author: User

Extension is a new open-iOS8 extension mechanism for several fixed system regions, which can compensate to some extent the limitation of iOS sandbox mechanism to inter-application communication. Allows the app Help system to extend custom functionality to implement tasks for a specific scope, such as photo editing, custom keyboards, notification hubs, action actions, share sharing, and more. This is undoubtedly a great boon for iOS, which has always been closed.

Although IOS8 is far away from now, sharing "Extension" related articles are also many, but for "Photo Editing", I think it is necessary to say, one of the most tutorials introduced Extension When you take Widgets for example, and then Photo Editing is the richest of the customizable content, you can completely use it as an additional interface in the app.

Just before a while in the internship, the realization of the relevant functions, summed up is also excellent.

1. Related Concepts 1.1 Extension point

The system supports Extension areas, Extension categories are also differentiated, on iOS, there are today, Share, Action, Photo Editing, Storage Provider, Custom keyboard several, One of the extension in today is also known as a widget.

    • today (today, also known as widgets): You can quickly get updates or perform a quick task in the Today view of the notification hub.
    • Share (Share): Publish to a shared site or share content with other applications.
    • Action: Manipulate or view content in the context of another application.
    • photo Editing(iOS only): Edit photos or videos in the Photos app.
    • Finder (iOS only): Displays status information for file synchronization directly in the Finder.
    • Document provider (Storage Provider)(iOS only): Provides access to and management of a vault.
    • Custom Keyboard(iOS only): replaces the iOS system keyboard with a custom keyboard and is used in all applications.

Because each extensibility point has its associated usage policies and specialized APIs, developers must choose the right extensibility points for the kind of functionality they want to provide, each extension point is used in a different way than it does for the job, so there is no generic extension.

For example, by default, the keyboard extension "cannot access the network and cannot share the same container with its containing application." Such restrictions can be removed by properly configuring extension, but developers still need to follow the specific Web keyboard guidelines in the Apple Store Review guide and the iOS Developer program License Agreement.

1.2 App Extension

That is the extension of this article. Extension is not a standalone app, it has a separate bundle,extension bundle suffix that is included in the app bundle. Appex. The life cycle is different from the normal app, which will be described in detail later.

Extension cannot exist alone, there must be a containing App that contains it.

In addition, extension requires manual activation by the user, and different extension activation methods are also different.

Like what:

    • The widgets in today need to be activated and closed in today;
    • Custom keyboard needs to be set in the settings;
    • Photo editing needs to be activated or turned off in Photo manager when using photos;
    • Storage provider can appear when selecting a file;
    • Share and action can be activated in any application, but only if the developer needs to set up activation Rules to determine extension needs to appear appropriately.
1.3 Containing APP

Although Apple has opened the extension, but in iOS extension does not exist alone, in order to submit to AppStore, extension must be included in an app to submit, and the app's implementation part can not be empty, This app, which contains extension, is called the containing app.

Extension will be installed with the containing app and uninstalled as the containing app is uninstalled.

1.4 Host APP

The app that can tune up extension is called the host app.

Like what:

    • The widget's host app is today.
    • Photo Editing's Host App is Photos
2. Extension and containing app, host app Communication 2.1 extension and host app


Extension and host apps can communicate directly through the Extensioncontext property, which is the newly added Uiviewcontroller category:

 @interface  uiviewcontroller  (nsextensionadditions ) < > // Returns  the extension context. also  acts as a convenience method for  a View Controller to check if  it participating in  an Extension request.  @property  (Nonatomic,readonly,retain) nsextensioncontext  *extensioncontext NS_AVAILABLE _ios  (8_0 );  @end   

In fact, the extension and the host app are implemented through the IPC (interprocess communication), but the API is highly abstracted by Apple, and we don't need to focus on the underlying stuff.

2.2 containing app and host app

There is no direct relationship between them, and they never need communication.

2.3 Extension and containing App

The relationship between the two is the most complex, and the entanglement is confusing.

As is known to all, each iOS application has its own sandbox. There are similar requirements for OS X applications distributed through the Mac Apple Store, but many OS X applications are distributed outside the Mac Apple App Store and do not need to comply with this sandbox requirement.

Sandbox is one of the cornerstones of Apple's iOS security strategy. Sandboxes are designed to limit the application's access to files, preferences, network resources, hardware, and so on, specifically to limit the damage that a compromised application may cause to the system.

Given that not all APIs that can be used in an application can be used in extension, the app extension runs in a sandbox with more restrictions than the usual application. APIs that cannot be used in extension are marked as unavailable macros, such as ns_extensions_unavailable, which causes a failure at link time.

In addition, Apple has several mandatory requirements for communication between extension and other applications:

    1. The application that calls extension is the main application that cannot start extension; Extension can only be started by the system.
    2. When extension is started, the main application communicates directly with it.
    3. The main application never communicates directly with the containing application.
    4. Extension is not an application, but it is generated by the system and has its own individual processes.
    5. In order to share data between the containing application and its extension, both the containing application and its extension must be part of the application group. For two members of an application group, part of the data can be shared in a third container outside the sandbox.

As Andrew Cunningham of Ars Technica summarizes, the final result of these rules is that one application cannot enter the sandbox of another application. This is in contrast to Android, where content providers and resolvers can still work together to provide applications with access to data in other applications.

Cannot communicate directly:

First, although extension bundles are placed in the bundle of the containing app, they are two completely independent processes that cannot communicate directly with each other. However, extension can start the containing app in OpenURL Way (and of course it can launch other apps), but it must be done by Extensioncontext with the host app:

//通过openURL的方式启动Containing APP - (void)openURLContainingAPP {     [self.extensionContext openURL:[NSURL URLWithString:@"appextension://123"]                  completionHandler:^(BOOL success) {                      NSLog(@"open url result:%d",success);                  

It is not possible to use OpenURL directly in extension.

You can share shared Resources:

The extension and containing apps can read and write a storage area called shared resources, which is implemented through the app groups, which will be described in detail later.

The relationship between the three can be illustrated by two images given by the official website:

3. Data sharing

App Groups This is the new open feature of IOS8, which is already available on OS X. It is primarily used by apps under the same group to share the same read-write space for data sharing.

3.1 Function Open

For easy follow-up, make sure your developer account is logged on to Xcode.

3.1.1 Open in App

APP groups is located at:

Targets–>appextensiondemo–>capabilities–>app Groups '

When you find it, open the switch in the upper-right corner of the app groups and choose Add Groups, the formal naming rule should be:

After the add succeeds as shown:

3.1.2 opens in extension.

In the same way as the app, it's important to be sure that the app groups name is the same as the app.

3.2 extension and containing app data sharing

App groups provides us with areas where apps in the same group can read and write, and data sharing can be done in the following ways:

3.2.1 Sharing data through Nsuserdefaults

Save data

Save data to Nsuserdefaults in the following ways:

- (void)saveTextByNSUserDefaults{    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@""];    [shared setObject:_textField.text forKey:@"test"];    [shared synchronize];}

It is important to note that:

    1. The group ID must be specified when saving the data;
    2. Also note that the data nsuserdefaults can handle can only be plist objects, see Property List Programming Guide for details.
    3. To prevent data synchronization problems, don't forget to call[shared synchronize];

Read data

The corresponding read data mode:

- (NSString *)readDataFromNSUserDefaults{    NSUserDefaults *shared = [[NSUserDefaults alloc] initWithSuiteName:@""];    NSString *value = [shared valueForKey:@"test"];    return value;}
3.2.1 Sharing data through Nsfilemanager

Nsfilemanager provides a containerurlforsecurityapplicationgroupidentifier method in iOS7 that can be used to implement the app group sharing data.

Save data

- (BOOL) savetextbynsfilemanager{Nserror*err =Nil;Nsurl*containerurl = [[NsfilemanagerDefaultmanager] containerurlforsecurityapplicationgroupidentifier:@""]; Containerurl = [Containerurl urlbyappendingpathcomponent:@"Library/caches/good"];NSString*value = _textfield. Text;BOOLresult = [value Writetourl:containerurl atomically:YESEncoding:nsutf8stringencoding error:&err];if(!result) {NSLog(@"%@", err); }Else{NSLog(@"Save value:%@ success.", value); }returnResult;}

Read data

- (NSString *)readTextByNSFileManager{    NSErrornil;    NSURL *containerURL = [[NSFileManager defaultManager] containerURLForSecurityApplicationGroupIdentifier:@""];    containerURL = [containerURL URLByAppendingPathComponent:@"Library/Caches/good"];    NSString *value = [NSString stringWithContentsOfURL:containerURL encoding:NSUTF8StringEncoding error:&err];    return value;}


Two applications that read the same data together can cause data synchronization problems. In WWDC2014 's video, it is recommended to use nsfilecoordination to achieve read and write synchronization of normal files, and the database can use Coredata,sqlite to support synchronization.

3.3 Dynamic loading, resource sharing

This is interesting to look at, it doesn't matter ~

Similar to data sharing, the extension and containing apps naturally have some code that can be shared by the business logic, which can be achieved through the framework that was just opened in IOS8. Apple describes this in the app Extension Programming Guide:

In IOS 8.0 and later, you can use a embedded framework to share code between your extension and its containing app. For example, if you develop image-processing code this you want both your Photo Editing extension and its containing app T o Share, you can put the code to a framework and embed it in both targets.

Code sharing is being implemented in target for the framework to be embedded in the extension and containing apps, respectively. But wouldn't it be necessary to copy the framework separately into the main bundle of the extension and containing apps?

Referring to extension and containing app data sharing, I wonder if I can save only one copy of the framework in the app groups area?

3.3.1 Copy Framework to app Groups

Put the framework into the app groups area when the app is first launched:

- (BOOL) copyframeworkfrommainbundletoappgroup{Nsfilemanager*manager = [NsfilemanagerDefaultmanager];Nserror*err =Nil;Nsurl*containerurl = [[NsfilemanagerDefaultmanager] containerurlforsecurityapplicationgroupidentifier:@""];NSString*sorpath = [NSStringstringwithformat:@"%@/dylib.framework",[[NSBundleMainbundle] Bundlepath];NSString*despath = [NSStringstringwithformat:@"%@/library/caches/dylib.framework", Containerurl. Path];BOOLRemoveresult = [Manager Removeitematpath:despath error:&err];if(!removeresult) {NSLog(@"%@", err); }Else{NSLog(@"remove success."); }BOOLCopyresult = [[NsfilemanagerDefaultmanager] Copyitematpath:sorpath Topath:despath error:&err];if(!copyresult) {NSLog(@"%@", err); }Else{NSLog(@"copy success."); }returnCopyresult;}
3.3.2 Using the framework
- (BOOL) loadframeworkinappgroup{Nserror*err =Nil;Nsurl*containerurl = [[NsfilemanagerDefaultmanager] containerurlforsecurityapplicationgroupidentifier:@""];NSString*despath = [NSStringstringwithformat:@"%@/library/caches/dylib.framework", Containerurl. Path];NSBundle*bundle = [NSBundleBundlewithpath:despath];BOOLresult = [Bundle loadandreturnerror:&err];if(Result) {Class root = nsclassfromstring (@"Person");if(Root) {Person *person = [[Root alloc] init];if(person)            {[Person run]; }        }    }Else{NSLog(@"%@", err); }returnResult;}

Tested to be able to load successfully.

In contrast, here's a summary:

There are two main ways of verifying this:

    1. Import the common framework into the project, only the containing app 's Link Binary with Libraries adds the corresponding framework. The extension dynamically loads the framework at runtime.
    2. The containing app and the extension link Binary with Libraries are linked to the common framework, respectively (Compile Sources Included in the framework target only)

Both of these methods can be used to achieve common resources. The difference is as follows:

  1. Way one needs app Groups, sharing resources. The way two does not need.

  2. Mode one needs containing app to start first, copy the data to the app groups, entension to load. The way two does not need.

  3. Mode one cannot initialize a class directly, for example:

    #import <TestFrameWork/FilterImage.h>for"_OBJC_CLASS_$_FilterImage"from:     objc-class-refinnotforerrorwithexit1to see invocation)

    It needs to be done in such a way:

       Class root = NSClassFromString(@"FilterImage");   if (root) {       FilterImage *filter = [[root alloc] init];       NSString *nameLUT = [NSString stringWithFormat:@"%@/TestFrameWork.bundle/images/filter_lut_%d"2];       self.imageView.image = [filter filterImage:self.input.displaySizeImage imageName:nameLUT];   }

    Mode two can be used directly. (#import "FilterImage.h")


    Compare the size of the exported package.

    Wrote 3 demos,

      1. Mode one, dynamic loading 12.1M
      2. Mode two, static link 23.7M
      3. Way three, contains only the framework, no extension 11.2M
4. Life cycle

From an official document detailing the life cycle of the extension app


When the user clicks extension through the Host app, the system instantiates the extension application, which is the beginning of the life cycle.

Perform tasks

After the launch of the extension, it began to perform its mission.


The system kills a task when the user cancels it, or when the task executes, or when a long background task is turned on.

This shows that extension is born for the task!

5. Photo Editing using filter combat

Because of the time relationship here, the official Apple example is used directly and no longer re-written. If the practice process, have encountered any problems, welcome message or other ways to communicate with me ~

Demo:photo Editing Extension Demo

Here are a few things to keep in mind.

  1. Because the host app is photos, our extension must be adaptable to the screen, because it's in the same state as the host app, not the containing app. As for the adjustment of the screen, it is recommended to use size Class, then listen to zoom mode to fit the screen


     #pragma mark- Uicontentcontainer -(void ) Willtransitiontotraitcollection: ( Uitraitcollection *) newcollection withtransitioncoordinator: (id  <UIViewCo ntrollertransitioncoordinator>) coordinator{[super  Willtransitiontotraitcollection:newcollection Withtransitioncoordinator:coordinator]; [Coordinator animatealongsidetransition:^ (id  < Uiviewcontrollertransitioncoordinatorcontext> context) {//horizontal screen processing } Span class= "Hljs-keyword" >else {//vertical screen processing } [self  .view  setneedslayout]; } completion:nil ];} 

    Again, you need to get the initial state to handle.


       if (selfUIUserInterfaceSizeClassCompact) {       //ToDo:for compact vertical size   }   else {       //ToDo:for other vertical size   }
  2. If a third-party library is managed with pods, you need to modify the target of the pod and add links.

    Build Settings — > Other Linker Flags **-l"Pods-MBProgressHUD"**

6. Related Information

APP Extension Programming Guide

APP Extensions for IOS 8 in Depth

WWDC2014 's app Extensions learning notes

Sample Photo Editing Extension

Photo Editing Extension Details (with App filter demo)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.