[Swift] PhotoKit- photo frame

★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
➤ micro-channel public number: Shan Wing Chi ( let_us_code)
➤ blog Park address: San-ching Wing Chi ( https://www.cnblogs.com/strengthen/ )
➤GitHub address: https://github.com/strengthen/LeetCode
➤ original address: HTTPS: // the WWW. cnblogs.com/strengthen/p/12604638.html
➤ text has been modified update! Click strongly recommended that the original address read! Support authors! Support the original!
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

1 Introduction

PhotoKitIs App framework in use, manage pictures and video, but also includes iCloud above picture and real-time photographs.

2. Overview

  • In iOS , the PhotoKitsupport to build applications and photo editing extensions, you can also manage access to resources as well as photos and videos yuan yuan a set of resources such as direct album, time and shared album.

 

 

3. Official Demo-PhotoBrowse

Browsing and Modifying Photo Albums

This example demonstrates how to use a custom implementation of a similar layout. It uses PhotoKitaccess to resources thumbnails, and then displays them as a single photograph, video or motion pictures. Also sample application PhotoBrowsealso demonstrates how the user's photos into albums and built a collection, for example, recently added and favorites. It supports the creation of the album, delete, modify, edit and personal resources and collections.

3.1 Get all albums, all photos request

    let allPhotosOptions = PHFetchOptions()
    allPhotosOptions.sortDescriptors = [NSSortDescriptor(key: "creationDate", ascending: true)]
    // 获取所有照片
    allPhotos = PHAsset.fetchAssets(with: allPhotosOptions)
    // 获取智能相册
    smartAlbums = PHAssetCollection.fetchAssetCollections(with: .smartAlbum, subtype: .albumRegular, options:     nil)
    // 获取用户创建的所有相册
    userCollections = PHCollectionList.fetchTopLevelUserCollections(with: nil)
复制代码

Get operation is an entity class method implemented by the above described which class / method to use, depending on the scope of the problem and show you the way to traverse the photo gallery of all the acquisition method of naming is similar:.. class func fetchXXX(..., options: PHFetchOptions) -> PHFetchResult. optionsA parameter to the us a way to filter the results and sort of this and NSFetchRequestof predicatethe sortDescriptorsparameters are similar.

 

 

 

 

3.2 observe changes

First, you need to share PHPhotoLibraryobjects, by registerChangeObserver(...)registering a change in the method observer (observer to comply with this PHPhotoLibraryChangeObserveragreement), as long as another application or user to do in Photo Gallery modification affects any resources or resource you get before change a collection of words, changes in the observer's photoLibraryDidChange(...)method is called. this method is only one PHChangetype of parameter, you can use it to verify whether these changes and you get the object of interest is associated.

Get updated results PHChangeprovides several ways, so that you can pass anything you are interested in PHObjectobjects or PHFetchResultto track changes in their target. This method is few changeDetailsForObject(...)and changeDetailsForFetchResult(...)if there is no change, these methods will return nil, or you can With PHObjectChangeDetailsor PHFetchResultChangeDetailsobjects to observe these changes.

PHObjectChangeDetailsIt provides a picture of the latest entity object references, and tell you whether the image data objects have been changes, Boolean whether the object had been deleted. PHFetchResultChangeDetailsEncapsulates applied before you get through the resulting PHFetchResultchange in the information . PHFetchResultChangeDetailsis to simplify as much as possible CollectionViewor TableViewupdate operation and design. it happens to be mapped to the properties you're using a classic CollectionViewof update handlerthe information they need time. Note that the right to update UITableView/UICollectionView, you must be in the correct order to deal with change, that is: RICE —— removedIndexes,insertedIndexes,changedIndexes,enumerateMovesWithBlock(if hasMovesis true. if) in addition, PHFetchResultChangeDetailsthe hasIncrementalChangesproperty can be set false. this means that the old should get the results have all been replaced by a new value in this case, you should call 1UITableView / UICollectionView1 of reloadData.

Note: There is no need to deal with changes in a centralized manner if you need multiple components applications with photos entities, then they each must have its own. PHPhotoLibraryChangeObserverThen the components will be able to rely on their own inquiries. PHChangeObject detecting whether (and how) update their own status.

    // 注册监听,获取相册数据源变化,系统提供回调方法-photoLibraryDidChange
    PHPhotoLibrary.shared().register(self)

    func photoLibraryDidChange(_ changeInstance: PHChange) {
        // 接收通知可能会在后台线程,所以此处的UI更新需放于主线程调用
        DispatchQueue.main.sync {
            // Check each of the three top-level fetches for changes.
            if let changeDetails = changeInstance.changeDetails(for: allPhotos) {
                // 更新缓存的数据源
                allPhotos = changeDetails.fetchResultAfterChanges
            }
            
            // 更新缓存的数据源并更新UI
            if let changeDetails = changeInstance.changeDetails(for: smartAlbums) { smartAlbums = changeDetails.fetchResultAfterChanges tableView.reloadSections(IndexSet(integer: Section.smartAlbums.rawValue), with: .automatic) } if let changeDetails = changeInstance.changeDetails(for: userCollections) { userCollections = changeDetails.fetchResultAfterChanges tableView.reloadSections(IndexSet(integer: Section.userCollections.rawValue), with: .automatic) } } } // 取消监听 PHPhotoLibrary.shared().unregisterChangeObserver(self) 复制代码

3.3 cache and display a list of thumbnails

When the image is about to be displayed on the screen, such as when you want to set rolling collectionwhen showing a lot of resources thumbnail image on view, advance some images loaded into memory is sometimes very useful. PhotoKitProvides a PHImageManagersubclass to handle this particular usage scenario - PHImageCachingManager.

PHImageCachingManagerProvides a key method startCachingImagesForAssets(...)you pass an PHAssetsarray of type, number of request parameters, as well as some requests when a single image is about to be used option. In addition, there are some ways you can inform the cache manager to stop a specific list of cache resources, and stop all cached images.

By default, if the image manager decided to use the optimal strategy, it will deliver the high-quality version of the image before you, to pass a version lower quality you can. deliveryModeTo control this behavior property; above the default behavior is as described .Opportunistic. If you want only high-quality images, and can accept a longer load time, then set the property .HighQualityFormat. If you want faster loading speed, image quality and can sacrifice a little, then set the property .FastFormat.

You can use PHImageRequestOptionsthe synchronousproperty, so that requestImage...the series way into synchronous operation. Note: When synchronousset true, the deliveryModeproperty will be ignored, and treated as .HighQualityFormat. To deal with when you set these parameters, must take into account some of your users may have opened iCloud. Photo gallery, it is very important to PhotoKitthe API is not necessarily photos and have equipment iCloudon the photo distinguish - they all use the same requestImage. this means that any method to load a picture requests are likely to be a very slow network request via the cellular network when you use .HighQualityFormator make a synchronous request, when this note to keep in mind: If you want to make sure the request does not go through the network, networkAccessAllowed can be set false. another and iCloudrelated properties are progressHandler. you can set it to one PHAssetImageProgressHandlerof block, when the iClouddownload photos , it will be automatically invoked image manager.

Pre-cached data and other pages show after show after taking the data here.

let (addedRects, removedRects) = differencesBetweenRects(previousPreheatRect, preheatRect)
let addedAssets = addedRects
    .flatMap { rect in collectionView!.indexPathsForElements(in: rect) }
    .map { indexPath in fetchResult.object(at: indexPath.item) } let removedAssets = removedRects .flatMap { rect in collectionView!.indexPathsForElements(in: rect) } .map { indexPath in fetchResult.object(at: indexPath.item) } // 更新缓存数据 imageManager.startCachingImages(for: addedAssets, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil) imageManager.stopCachingImages(for: removedAssets, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil) 复制代码
guard let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "GridViewCell", for: indexPath) as? GridViewCell
    else { fatalError("Unexpected cell in collection view") } // 给动态照片Cell添加一个badge if asset.mediaSubtypes.contains(.photoLive) { cell.livePhotoBadgeImage = PHLivePhotoView.livePhotoBadgeImage(options: .overContent) } // 通过PHCachingImageManager请求照片 cell.representedAssetIdentifier = asset.localIdentifier imageManager.requestImage(for: asset, targetSize: thumbnailSize, contentMode: .aspectFill, options: nil, resultHandler: { image, _ in // UIKit may have recycled this cell by the handler's activation time. // 只有请求到通用类型标识符一致的资源时才配置图片 if cell.representedAssetIdentifier == asset.localIdentifier { cell.thumbnailImage = image } }) 复制代码

 

 

3.4 editorial change resource file

Used PhotoKitin the photo gallery to make changes, the final analysis, in fact, is to create a collection of resources, or a change in the resource request object to a link, and then set the relevant properties or call request object appropriate way to describe the changes you want to submit. This must be performChanges(...), in submission to the shared method PHPhotoLibraryof blockcompletion within Note: you need to be prepared to performChangesapproach completion block. in the case of treatment failure, although treatment is to be more participants (such as your application, users of other applications, photos expansion and other state), but this approach can provide security, but also relatively easy to use.

Resource you want to modify, you need to create a PHAssetChangeRequest, then you can modify the creation date of creation, resource location, and whether hidden resources, whether the user will be seen as a collection of resources, etc. In addition, you can also delete resources from the user's library. Similar , a set of resources or to modify the set list, you need to create a PHAssetCollectionChangeRequestor PHCollectionListChangeRequestobject. then you can change the title of the collection, adding or deleting a collection of members, or completely remove the collection.

Before you submit changes to the user's photo library, the system will show a definite obtain permission alert box to the user.

3.4.1 modify resources

DispatchQueue.global(qos: .userInitiated).async {
    // 创建调整的数据源.
    // 如果你对一张照片进行了滤镜处理,你应该会创建一个adjustmentData对象,它记录了用户选择了什么滤镜、相关配置的参数、以及使用这(款/些)滤镜的命令.接下去,用户可以用你的app或者别的可以获取你的adjustmentData对象的app来恢复这张照片到初始状态
    let adjustmentData = PHAdjustmentData(formatIdentifier: self.formatIdentifier,
                                          formatVersion: self.formatVersion,
                                          data: filterName.data(using: .utf8)!)
    
    // 创建输出数据源.
    let output = PHContentEditingOutput(contentEditingInput: input)
    output.adjustmentData = adjustmentData
    
    // 设置滤镜类型.
    let applyFunc: (String, PHContentEditingInput, PHContentEditingOutput, @escaping () -> Void) -> Void
    if self.asset.mediaSubtypes.contains(.photoLive) {
        applyFunc = self.applyLivePhotoFilter
    } else if self.asset.mediaType == .image { applyFunc = self.applyPhotoFilter } else { applyFunc = self.applyVideoFilter } // 使用滤镜. applyFunc(filterName, input, output, { // 当滤镜提交使用后,再更新到资源库. PHPhotoLibrary.shared().performChanges({ let request = PHAssetChangeRequest(for: self.asset) request.contentEditingOutput = output }, completionHandler: { success, error in if !success { print("Can't edit the asset: \(String(describing: error))") } }) }) } 复制代码

3.4.2 modify the collection or collection list

PHPhotoLibrary.shared().performChanges({
    PHAssetCollectionChangeRequest.creationRequestForAssetCollection(withTitle: title)
}, completionHandler: { success, error in
    if !success { print("Error creating album: \(String(describing: error)).") }
})
复制代码

3.4.3 Adding a new resource

PHPhotoLibrary.shared().performChanges({
    let creationRequest = PHAssetChangeRequest.creationRequestForAsset(from: image)
    if let assetCollection = self.assetCollection {
        let addAssetRequest = PHAssetCollectionChangeRequest(for: assetCollection) addAssetRequest?.addAssets([creationRequest.placeholderForCreatedAsset!] as NSArray) } }, completionHandler: {success, error in if !success { print("Error creating the asset: \(String(describing: error))") } }) 复制代码

3.4.4 Delete Resource

if assetCollection != nil {
    // 从当前选中的相册|集合中删除资源
    PHPhotoLibrary.shared().performChanges({
        let request = PHAssetCollectionChangeRequest(for: self.assetCollection)!
        request.removeAssets([self.asset] as NSArray)
    }, completionHandler: completion)
} else {
    // 直接从资源库中删除.
    PHPhotoLibrary.shared().performChanges({
        PHAssetChangeRequest.deleteAssets([self.asset] as NSArray)
    }, completionHandler: completion)
}
复制代码

3.5 Other

Determine whether the Favorite album, as well as add Favorite

PHPhotoLibrary.shared().performChanges({
    let request = PHAssetChangeRequest(for: self.asset)
    request.isFavorite = !self.asset.isFavorite
}, completionHandler: { success, error in
    if success {
        DispatchQueue.main.sync {
            sender.title = self.asset.isFavorite ? "♥︎" : "♡" } } else { print("Can't mark the asset as a Favorite: \(String(describing: error))") } }) 复制代码

4.API Introduction

4.1 PhotoKitframework commonly used class Introduction Figure

 

 

4.2 PhotoKitthe frame configuration in FIG.

 

 

4.3 Common Class

Original: iOS photo frame

4.3.1 Basic

PHPhotoLibrary: Indicates the user's photo library for request to obtain permission to photograph library, photo library monitor changes; `

4.3.2 Resource

PHObject: Abstract base class, other classes inherit PhotoKit class provides a localIdentifier attribute;

PHAsset: Represent a single resource Photo Gallery (pictures can be, can also be video; and ALAsset similar), to acquire, conserve resources metadata; PHAsset only contain metadata (such as image size, creation date, etc.), specifically pictures, video data is required PHImageManager loaded; if representsBurst property of a resource is true, it indicates that the resource is a burst of photos representative photograph, you can fetchAssetsWithBurstIdentifier () method, passing burstIdentifier property, get even pictures remaining other photos;

PHCollection: PHAssetCollection and PHCollectionList parent;

PHAssetCollection: Collection, represents a group of resources; can represent a Photos library, always, Smart Album; Smart Album: Default album provided specific, such as the recently deleted, the list of videos, favorites, etc.;

PHCollectionList: Represents a collection of PHCollections; which itself is PHCollection, it may also contain other PHCollectionList PHCollectionList;

4.3.3 acquisition

PHFetchResult: Represents a series PHAsset result set, or may be the result of a series of PHCollection set;

PHFetchOptions: Incoming parameter acquisition PHFetchResult, functions as filtering, sorting, etc., can filter type, date, name and the like; nil incoming system default values ​​are used;

PHImageManager: For loading resources;

PHCachingImageManager: Inherited PHImageManager, loading resources with a cache; when a large amount of resources, you can prepare in the background picture of resources and reduce the delay of a single resource request at a later; such as when you want to use photos, video thumbnail resources It can be used to fill a set of view PHCachingImageManager; startCachingImagesForAssets method used to prepare resources, but also after the loading of resource use request method PHImageManager;

PHImageRequestOptions: Incoming parameter when loading resources, control of resources output size and other specifications;

4.3.4 update

PHAssetChangeRequest: Used to create, delete, and modify PHAsset objects;

PHAssetCollectionChangeRequest: Used to create, delete, and modify PHAssetCollection objects;

PHCollectionListChangeRequest: Used to create, delete, and modify PHCollectionList objects;

PHAssetCreationRequest: PHAssetChangeRequest subclasses can also be used to create, enrich the way to add resources;

4.3.5 Related enumeration value

Note: Gets the type of album, the main type and sub-type to match, if not match, the system will be in accordance with anysub-type of treatment; for momenttype, subtype use any; for the smartAlbumtype, subtype use albumRegularthan use anyone more Recently Deleted(recently deleted) albums ;

enum PHAssetCollectionType : Int {
    case album // 用户自己在Photos app中建立的相册、从iTunes同步来的相册
    case smartAlbum // Photos app内置的相册(内容动态更新)
    case moment // Photos app自动生成的时间、地点分组的相册
}
复制代码
enum PHAssetCollectionSubtype : Int {
    // PHAssetCollectionTypeAlbum regular subtypes
    case albumRegular // 用户自己在Photos app中建立的相册
    case albumSyncedEvent // 已废弃;从iPhoto同步来的事件相册
    case albumSyncedFaces // 从iPhoto同步来的人物相册
    case albumSyncedAlbum // 从iPhoto同步来的相册
    case albumImported // 从相机或外部存储导入的相册 // PHAssetCollectionTypeAlbum shared subtypes case albumMyPhotoStream // 用户的iCloud照片流 case albumCloudShared // //用户使用iCloud共享的相册 // PHAssetCollectionTypeSmartAlbum subtypes case smartAlbumGeneric // 非特殊类型的相册,从macOS Photos app同步过来的相册 case smartAlbumPanoramas // 相机拍摄的全景照片的相册 case smartAlbumVideos // 相机拍摄的视频的相册 case smartAlbumFavorites // 收藏的照片、视频的相册 case smartAlbumTimelapses // 延时视频的相册 case smartAlbumAllHidden // 包含隐藏照片、视频的相册 case smartAlbumRecentlyAdded // 相机近期拍摄的照片、视频的相册 case smartAlbumBursts // 连拍模式拍摄的照片的相册 case smartAlbumSlomoVideos // Slomo是slow motion的缩写,高速摄影慢动作解析(iOS设备以120帧拍摄)的相册 case smartAlbumUserLibrary // 相机相册,包含相机拍摄的所有照片、视频,使用其他应用保存的照片、视频 @available(iOS 9.0, *) case smartAlbumSelfPortraits @available(iOS 9.0, *) case smartAlbumScreenshots @available(iOS 10.2, *) case smartAlbumDepthEffect @available(iOS 10.3, *) case smartAlbumLivePhotos @available(iOS 11.0, *) case smartAlbumAnimated @available(iOS 11.0, *) case smartAlbumLongExposures // Used for fetching, if you don't care about the exact subtype case any // 包含所有类型 } 复制代码

5. Summary

In iOS 8 before, developers can only use the AssetsLibraryframework to handle photos, but with the continuous progress of Apple's phone constantly updated, equipment, photo feature constantly updated, the existing AssetsLibraryframework is no longer able to keep up the pace, but with with the arrival of iOS 8, Apple has provided us with a modern framework PhotoKitso that developers can better adapt to the trend, better develop its application, allowing applications and devices to seamlessly work perfectly.

Guess you like

Origin www.cnblogs.com/strengthen/p/12604638.html