An explanation of the photo framework for IOS Development

Source: Internet
Author: User

I. Summary

In IOS devices, photos and videos are a fairly important part. I've just been working on a custom iOS image selector, and I've recently made a list of how to use the photo frame in iOS. Before the advent of iOS 8, developers could only use the Assetslibrary framework to access the device's photo library, which is a bit less than the pace of iOS app development and code design principles but a really powerful framework, considering that IOS7 still occupies a lot of permeability, so assetslibrary also Is the part that this article focuses on. And after the advent of iOS8, Apple provided a framework called Photokit, a framework that would allow the application to better interface with the device photo library, as well as the framework at the end of the paper.

It is also worth emphasizing that in IOS, photo gallery is not just a collection of photos, but also includes videos. In Assetslibrary, both have the same type of object to describe, but the type is different. For convenience, most of the time, "resources" is used to represent photos and videos in IOS.

Two. Assetslibrary Composition Introduction

The composition of the assetslibrary is in line with the composition of the photo library itself, the photo gallery of the complete Photo gallery objects, albums, photos can be found in the Assetslibrary one by one corresponding composition, which makes the use of assetslibrary become intuitive and convenient.

    • Assetslibrary: Represents the resource pool (photo gallery) across the entire device, and assetslibrary allows you to get and include photos and videos from your device
    • Alassetsgroup: Maps an album in photo gallery, Alassetsgroup can get information about an album, resources under the album, and you can add resources to an album.
    • Alasset: Maps a photo or video in a photo gallery, Alasset to get more information about a photo or video, or to save photos and videos.
    • alassetrepresentation: Alassetrepresentation is the encapsulation of alasset (but not its subclasses), which makes it easier to get the resource information in Alasset, each alasset There is at least one Alassetrepresentation object that can be obtained through defaultrepresentation. For example, using raw + JPEG photos taken with the system camera app, there will be two alassetrepresentation, one that encapsulates the raw information for the photo, and the other that encapsulates the JPEG information for the photo.
Three. Basic use of Assetslibrary

Assetslibrary a lot of functions, the basic can be divided into resources to get/save two parts, save the relatively simple, the API is relatively small, so there is no detailed introduction. The API to get resources is richer, and a common example of using a large number of assetslibrary APIs is the image selector (Alasset picker). To make a picture selector, the idea should be to get a photo gallery-list All albums-show all the pictures in the album-Preview a larger image.

The first thing to check is whether the APP has a photo action authorization:

12345678910 NSString *tipTextWhenNoPhotosAuthorization; // 提示语// 获取当前应用对照片的访问授权状态ALAuthorizationStatus authorizationStatus = [ALAssetsLibrary authorizationStatus];// 如果没有获取访问授权,或者访问授权状态已经被明确禁止,则显示提示语,引导用户开启授权if (authorizationStatus == ALAuthorizationStatusRestricted || authorizationStatus == ALAuthorizationStatusDenied) {    NSDictionary *mainInfoDictionary = [[NSBundle mainBundle] infoDictionary];    NSString *appName = [mainInfoDictionary objectForKey:@"CFBundleDisplayName"];    tipTextWhenNoPhotosAuthorization = [NSString stringWithFormat:@"请在设备的\"设置-隐私-照片\"选项中,允许%@访问你的手机相册", appName];    // 展示提示语}

If you have already obtained authorization, you can get a list of albums:

12345678910111213141516171819 _assetsLibrary = [[ALAssetsLibrary alloc] init];_albumsArray = [[NSMutableArray alloc] init];[_assetsLibrary enumerateGroupsWithTypes:ALAssetsGroupAll usingBlock:^(ALAssetsGroup *group, BOOL *stop) {    if (group) {        [group setAssetsFilter:[ALAssetsFilter allPhotos]];        if (group.numberOfAssets > 0) {            // 把相册储存到数组中,方便后面展示相册时使用            [_albumsArray addObject:group];        }    } else {        if ([_albumsArray count] > 0) {            // 把所有的相册储存完毕,可以展示相册列表        } else {            // 没有任何有资源的相册,输出提示        }    }} failureBlock:^(NSError *error) {    NSLog(@"Asset group not found!\n");}];

In the code above, the list of all albums is traversed, and a reference to the album Alassetgroup object with the same number of resources in the album is stored in an array. Here are a few things to emphasize:

    • Allow albums to be empty in IOS, that is, there are no resources in the album, and if you do not want to get empty albums, you need to manually filter them as in the code above
    • Alassetsgroup has a setassetsfilter way to pass in a filter that controls only the photos in the album or just the video. Once the filter is set, the resource list and the number of resources in the Alassetsgroup are automatically updated.
    • The acquisition and preservation of albums, resources, and the entire assetslibrary is using asynchronous processing (asynchronous), which takes into account that the resource file size is quite large (and possibly large). For example, the above Traversal album operation, the results of the album using block output, if the album traversal, the last output block of the group parameter value is nil. The stop parameter is used to manually stop the traversal, and the next traversal is stopped as long as the *stop is set to YES. This is often a misunderstanding, so you need to be aware of it.

Now that you're ready to get the album, here's how to get the resources in the album:

12345678 _imagesAssetArray = [[NSMutableArray alloc] init];[assetsGroup enumerateAssetsWithOptions:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {    if (result) {        [_imagesAssetArray addObject:result];    } else {        // result 为 nil,即遍历相片或视频完毕,可以展示资源列表    }}];

Like the process of traversing a photo album, traversing a photo is also a series of asynchronous methods in which the above method outputs a block in which, in addition to the result parameter, which represents the resource information, stop is used to manually stop the traversal, and an index parameter is provided that represents the index of the resource. In general, the display resource list uses thumbnails (result.thumbnail), so even with a lot of resources, traversing resources can be quite fast. But if you do need to load a high-definition diagram of a resource or other time-consuming processing, you can use the index parameter above and the stop parameter to make a segmented pull resource. For example:

1234567891011121314151617181920212223 NSUInteger _targetIndex; // index 目标值,拉取资源直到这个值就手工停止拉取NSUInteger _currentIndex; // 当前 index,每次拉取资源时从这个值开始_targetIndex = 50;_currentIndex = 0;- (void)loadAssetWithAssetsGroup:(assetsGroup *)assetsGroup {    [assetsGroup enumerateAssetsAtIndexes:[NSIndexSet indexSetWithIndex:_currentIndex] options:NSEnumerationReverse usingBlock:^(ALAsset *result, NSUInteger index, BOOL *stop) {        _currentIndex = index;        if (index > _targetIndex) {            // 拉取资源的索引如果比目标值大,则停止拉取            *stop = YES;        } else {            if (result) {                [_imagesAssetArray addObject:result];            } else {                // result 为 nil,即遍历相片或视频完毕            }        }    }];}// 之前拉取的数据已经显示完毕,需要展示新数据,重新调用 loadAssetWithAssetsGroup 方法,并根据需要更新 _targetIndex 的值

The final step is to get the picture details, for example:

1234 //get detailed resource information for a resource picture, where Imageasset is the Alasset object of a resource //get the Fullscreenimage of the resource picture uiimage *contentimage = [UIImage imagewithcgimage:[representation fullscreenimage]];

For a alassetrepresentation, it contains multiple versions of the image. The most commonly used are fullresolutionimage and fullscreenimage. Fullresolutionimage is the original image of the picture, the picture obtained through the fullresolutionimage does not have any processing, including through the System album "Edit" function after processing the information is not included therein, so need to show the "edit" function after the processing of information, using Fullresolutionimage is more inconvenient, the other fullresolutionimage pull also will be relatively slow, in the multi-fullresolutionimage switch can obviously feel the loading process of the picture. Therefore, it is recommended to get the image of the fullscreenimage, which is the full-screen image version of the picture, this version contains the system album in the "edit" function after the processing of information, but also a thumbnail image, but the picture is very little distortion, the disadvantage is that the size of the picture is a screen size to adapt to the version, As a result, additional processing is required to display the picture, but the fullscreenimage is still recommended, given the reason for the very fast loading (switching between multiple images does not make the picture load time-consuming).

The process of the system album is probably the same as above, you can see, throughout the process and did not use the image of the Fullresolutionimage, from the album list display to the final view of resources, are using thumbnails, which is also an important reason for the rapid loading of IOS albums.

Three. Pit point of Assetslibrary

As a set of old framework, assetslibrary not only have pits, but also a lot of, in addition to the above mentioned resources asynchronous pull to pay attention to matters, the following points are worth noting:

1. Assetslibrary instances require strong references

Once the instance is assetslibrary, as shown above, we can obtain the required albums and resources through a series of enumeration methods and store them in an array for easy presentation. However, when we store these acquired albums and resources in an array, we actually store the references (pointers) to these albums and resources in the assetslibrary in the array, so that regardless of how the albums and resources are stored in the array, you first need to make sure The Assetslibrary is not released by ARC, or the data is removed from the array, and the corresponding reference data is lost (see). This is easier to ignore, so it is recommended to use the Assetslibrary Viewcontroller as a strongly held property or private variable, avoiding the Assetslibrary The Assetslibrary is released by ARC after the data is needed.

Example: Instantiate a assetslibrary local variable, enumerate all the albums and store them in an array named _albumsarray, view the array again when the album is displayed, and find that the data in the Alassetsgroup is lost.

2. Assetslibrary follows the write priority principle

Write priority is to say that in the process of reading resources with Assetslibrary, any other process (not necessarily the same App) will receive alassetslibrarychangednotification when the resource is saved. Let the user interrupt the read operation themselves. The most common is to read fullresolutionimage, with the process in writing, because the read fullresolutionimage time-consuming, it is easy to exception.

3. Opening Photo Stream can easily lead to exception

Essentially, this is the same problem as the above assetslibrary follows the write precedence principle. If a user turns on shared photo stream, the shared photo stream will be "secretly" executed in MSTREAMD, and when someone writes the photo to a Camera roll, it will automatically be saved to the photo stream Album, if the user is just reading it, That's as exception as it says. Because shared photo Stream is the user's decision whether to open, so the developer cannot change, but can use the following interface at the moment of need to protect the shared photo stream to turn off the frequent notification information generated.

1 [ALAssetsLibrary disableSharedPhotoStreamsSupport];
Four. Photokit Introduction

Photokit is a more complete and efficient library than assetslibrary, and the processing of resources is much different from assetslibrary.

Let's start with a brief introduction to several concepts:

    • Phasset: Represents a resource in photo gallery, similar to Alasset, where resources can be obtained and saved through Phasset
    • phfetchoptions: The parameter to get the resource, can pass nil, even with the system default value
    • Phfetchresult: Represents a collection of resources, or a collection of albums
    • phassetcollection: Represents an album or a moment, or a "smart album" (System-provided specific series of albums, such as: recently deleted, video list, favorites, etc., as shown)
    • Phimagemanager: Used to handle the loading of resources, the process of loading pictures with cache processing, you can pass in a phimagerequestoptions control the output size of the resource and other specifications
    • phimagerequestoptions: As mentioned above, control a series of parameters when loading a picture

The second section in UITableView is all the smart albums listed in Photokit

A few more snippets are listed to show you how to get the code for the album and the resources under an album:

1234567891011121314151617181920212223 // 列出所有相册智能相册PHFetchResult *smartAlbums = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum subtype:PHAssetCollectionSubtypeAlbumRegular options:nil];// 列出所有用户创建的相册PHFetchResult *topLevelUserCollections = [PHCollectionList fetchTopLevelUserCollectionsWithOptions:nil];// 获取所有资源的集合,并按资源的创建时间排序PHFetchOptions *options = [[PHFetchOptions alloc] init];options.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:YES]];PHFetchResult *assetsFetchResults = [PHAsset fetchAssetsWithOptions:options];// 在资源的集合中获取第一个集合,并获取其中的图片PHCachingImageManager *imageManager = [[PHCachingImageManager alloc] init];PHAsset *asset = assetsFetchResults[0];[imageManager requestImageForAsset:asset                         targetSize:SomeSize                        contentMode:PHImageContentModeAspectFill                            options:nil                      resultHandler:^(UIImage *result, NSDictionary *info) {                                                     // 得到一张 UIImage,展示到界面上                                                }];

Combined with the above several code snippets, Photokit relative assetslibrary has three important improvements:

    • Getting data from assetslibrary, whether it's a photo album or a resource, is essentially using enumerations to traverse the photo gallery to get the data. The Photokit is to obtain the corresponding data directly by passing parameters, so the efficiency will be improved a lot.
    • In Assetslibrary, albums and resources correspond to different objects (Alassetgroup and Alasset), so getting a photo album and getting the resources is two completely unrelated interfaces. In Photokit, there are phfetchresult that can be used to store albums or resources uniformly, so it is also easier to process albums and resources.
    • When Photokit returns the resource results, it also returns the metadata for the resource, and getting the metadata is a difficult thing to do in Assetslibrary. At the same time, through Phasset, developers can also directly obtain whether the resources are collected (favorite) and hidden (hidden), when the picture is opened HDR or Panorama mode, even through a continuous shot image to get to the other images in the burst image. This is also said at the beginning of the article,Photokit can be better with the device photo library access to an important factor.

For Photokit, it is recommended that you refer to Apple's Example app using Photos framework

An explanation of the photo framework for IOS Development

Related Article

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: info-contact@alibabacloud.com 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.