├── SDWebImagePhotosPlugin
├── Assets
│ └── .gitkeep
├── Module
│ ├── SDWebImagePhotosPlugin.modulemap
│ ├── Info.plist
│ └── SDWebImagePhotosPlugin.h
└── Classes
│ ├── SDWebImagePhotosError.m
│ ├── PHAsset+SDWebImagePhotosPlugin.m
│ ├── PHAsset+SDWebImagePhotosPlugin.h
│ ├── PHImageRequestOptions+SDWebImagePhotosPlugin.h
│ ├── SDWebImagePhotosError.h
│ ├── SDWebImagePhotosDefine.m
│ ├── NSURL+SDWebImagePhotosPlugin.h
│ ├── PHImageRequestOptions+SDWebImagePhotosPlugin.m
│ ├── NSURL+SDWebImagePhotosPlugin.m
│ ├── SDImagePhotosLoader.h
│ ├── SDWebImagePhotosDefine.h
│ └── SDImagePhotosLoader.m
├── Cartfile
├── Cartfile.resolved
├── Example
├── Tests
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── Images
│ │ ├── TestImage.gif
│ │ ├── TestImage.jpg
│ │ ├── TestImage.png
│ │ ├── TestImageStatic.webp
│ │ ├── TestImageAnimated.apng
│ │ └── TestImageAnimated.webp
│ ├── Tests-Prefix.pch
│ ├── SystemAlert.h
│ ├── Tests-Info.plist
│ ├── SDTestCase.h
│ ├── SystemAlert.m
│ ├── SDTestCase.m
│ └── SDPhotosPluginTests.m
├── SDWebImagePhotosPlugin
│ ├── en.lproj
│ │ └── InfoPlist.strings
│ ├── MasterViewController.h
│ ├── SDWebImagePhotosPlugin-Prefix.pch
│ ├── main.m
│ ├── DetailViewController.h
│ ├── SDAppDelegate.h
│ ├── MasterViewController.xib
│ ├── SDWebImagePhotosPlugin-Info.plist
│ ├── Base.lproj
│ │ └── LaunchScreen.storyboard
│ ├── Images.xcassets
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── DetailViewController.m
│ ├── DetailViewController.xib
│ ├── SDAppDelegate.m
│ └── MasterViewController.m
├── SDWebImagePhotosPlugin_Example macOS
│ ├── Assets.xcassets
│ │ ├── Contents.json
│ │ └── AppIcon.appiconset
│ │ │ └── Contents.json
│ ├── ViewController.h
│ ├── main.m
│ ├── AppDelegate.h
│ ├── TestCollectionViewItem.h
│ ├── TestCollectionViewItem.m
│ ├── SDWebImagePhotosPlugin_Example_macOS.entitlements
│ ├── AppDelegate.m
│ ├── Info.plist
│ ├── TestCollectionViewItem.xib
│ └── ViewController.m
├── SDWebImagePhotosPlugin.xcodeproj
│ ├── project.xcworkspace
│ │ └── contents.xcworkspacedata
│ └── xcshareddata
│ │ └── xcschemes
│ │ ├── SDWebImagePhotosPlugin_Tests.xcscheme
│ │ ├── SDWebImagePhotosPlugin_Example macOS.xcscheme
│ │ └── SDWebImagePhotosPlugin-Example.xcscheme
├── SDWebImagePhotosPlugin.xcworkspace
│ ├── xcshareddata
│ │ └── WorkspaceSettings.xcsettings
│ └── contents.xcworkspacedata
├── Podfile
└── SDWebImagePhotosPlugin_Example.entitlements
├── SDWebImagePhotosPlugin.xcodeproj
├── project.xcworkspace
│ └── contents.xcworkspacedata
├── xcshareddata
│ └── xcschemes
│ │ ├── SDWebImagePhotosPlugin.xcscheme
│ │ ├── SDWebImagePhotosPlugin-tvOS.xcscheme
│ │ └── SDWebImagePhotosPlugin-macOS.xcscheme
└── project.pbxproj
├── Package.resolved
├── .github
├── ISSUE_TEMPLATE
│ ├── feature_request.md
│ └── bug_report.md
├── config.yml
└── stale.yml
├── .gitignore
├── LICENSE
├── Package.swift
├── .travis.yml
├── SDWebImagePhotosPlugin.podspec
└── README.md
/SDWebImagePhotosPlugin/Assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/Cartfile:
--------------------------------------------------------------------------------
1 | github "SDWebImage/SDWebImage" ~> 5.10
--------------------------------------------------------------------------------
/Cartfile.resolved:
--------------------------------------------------------------------------------
1 | github "SDWebImage/SDWebImage" "5.8.3"
2 |
--------------------------------------------------------------------------------
/Example/Tests/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/en.lproj/InfoPlist.strings:
--------------------------------------------------------------------------------
1 | /* Localized versions of Info.plist keys */
2 |
3 |
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImage.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImage.gif
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImage.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImage.jpg
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImage.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImage.png
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImageStatic.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImageStatic.webp
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "version" : 1,
4 | "author" : "xcode"
5 | }
6 | }
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImageAnimated.apng:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImageAnimated.apng
--------------------------------------------------------------------------------
/Example/Tests/Images/TestImageAnimated.webp:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/SDWebImage/SDWebImagePhotosPlugin/HEAD/Example/Tests/Images/TestImageAnimated.webp
--------------------------------------------------------------------------------
/Example/Tests/Tests-Prefix.pch:
--------------------------------------------------------------------------------
1 | // The contents of this file are implicitly included at the beginning of every test case source file.
2 |
3 | #ifdef __OBJC__
4 |
5 |
6 |
7 | #endif
8 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Module/SDWebImagePhotosPlugin.modulemap:
--------------------------------------------------------------------------------
1 | framework module SDWebImagePhotosPlugin {
2 | umbrella header "SDWebImagePhotosPlugin.h"
3 |
4 | export *
5 | module * { export * }
6 | }
7 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | PreviewsEnabled
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2018/7/19.
6 | // Copyright © 2018年 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : NSViewController
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2018/7/19.
6 | // Copyright © 2018年 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | int main(int argc, const char * argv[]) {
12 | return NSApplicationMain(argc, argv);
13 | }
14 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2018/7/19.
6 | // Copyright © 2018年 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : NSObject
12 |
13 |
14 | @end
15 |
16 |
--------------------------------------------------------------------------------
/Package.resolved:
--------------------------------------------------------------------------------
1 | {
2 | "object": {
3 | "pins": [
4 | {
5 | "package": "SDWebImage",
6 | "repositoryURL": "https://github.com/SDWebImage/SDWebImage.git",
7 | "state": {
8 | "branch": null,
9 | "revision": "0a3cd255a655b73fb3b3437acf2ab506b5c0c9c6",
10 | "version": "5.1.0"
11 | }
12 | }
13 | ]
14 | },
15 | "version": 1
16 | }
17 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/MasterViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | @interface MasterViewController : UITableViewController
12 |
13 | @end
14 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/TestCollectionViewItem.h:
--------------------------------------------------------------------------------
1 | //
2 | // TestCollectionViewItem.h
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2019/4/3.
6 | // Copyright © 2019 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface TestCollectionViewItem : NSCollectionViewItem
12 |
13 | @property (weak) IBOutlet NSImageView *imageViewDisplay;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/SDWebImagePhotosPlugin-Prefix.pch:
--------------------------------------------------------------------------------
1 | //
2 | // Prefix header
3 | //
4 | // The contents of this file are implicitly included at the beginning of every source file.
5 | //
6 |
7 | #import
8 |
9 | #ifndef __IPHONE_5_0
10 | #warning "This project uses features only available in iOS SDK 5.0 and later."
11 | #endif
12 |
13 | #ifdef __OBJC__
14 | @import UIKit;
15 | @import Foundation;
16 | #endif
17 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDWebImagePhotosError.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDWebImagePhotosError.h"
10 |
11 | NSErrorDomain const _Nonnull SDWebImagePhotosErrorDomain = @"SDWebImagePhotosErrorDomain";
12 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // SDWebImagePhotosPlugin
4 | //
5 | // Created by DreamPiggy on 05/07/2018.
6 | // Copyright (c) 2018 DreamPiggy. All rights reserved.
7 | //
8 |
9 | @import UIKit;
10 | #import "SDAppDelegate.h"
11 |
12 | int main(int argc, char * argv[])
13 | {
14 | @autoreleasepool {
15 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([SDAppDelegate class]));
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/Example/Tests/SystemAlert.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImagePhotosPlugin package.
3 | *
4 | * For the full copyright and license information, please view the LICENSE
5 | * file that was distributed with this source code.
6 | */
7 |
8 | #import
9 |
10 | // Automation API to force tap current system alert
11 | @interface SystemAlert : NSObject
12 | + (void)tapLeftButton;
13 | + (void)tapRightButton;
14 | @end
15 |
--------------------------------------------------------------------------------
/Example/Podfile:
--------------------------------------------------------------------------------
1 | use_frameworks!
2 | inhibit_all_warnings!
3 |
4 | target 'SDWebImagePhotosPlugin_Example' do
5 | platform :ios, '9.0'
6 | pod 'SDWebImagePhotosPlugin', :path => '../'
7 |
8 | target 'SDWebImagePhotosPlugin_Tests' do
9 | inherit! :search_paths
10 | pod 'Expecta'
11 |
12 | end
13 | end
14 |
15 | target 'SDWebImagePhotosPlugin_Example macOS' do
16 | platform :osx, '10.13'
17 | pod 'SDWebImagePhotosPlugin', :path => '../'
18 | end
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.network.client
8 |
9 | com.apple.security.personal-information.photos-library
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/DetailViewController.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | @interface DetailViewController : UIViewController
12 |
13 | @property (strong, nonatomic) NSURL *imageURL;
14 |
15 | @end
16 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/TestCollectionViewItem.m:
--------------------------------------------------------------------------------
1 | //
2 | // TestCollectionViewItem.m
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2019/4/3.
6 | // Copyright © 2019 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import "TestCollectionViewItem.h"
10 |
11 | @interface TestCollectionViewItem ()
12 |
13 | @end
14 |
15 | @implementation TestCollectionViewItem
16 |
17 | - (void)viewDidLoad {
18 | [super viewDidLoad];
19 | }
20 |
21 | @end
22 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/SDWebImagePhotosPlugin_Example_macOS.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.user-selected.read-only
8 |
9 | com.apple.security.assets.pictures.read-write
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/SDAppDelegate.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | @import UIKit;
10 |
11 | @interface SDAppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 | @property (strong, nonatomic) UINavigationController *navigationController;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/PHAsset+SDWebImagePhotosPlugin.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "PHAsset+SDWebImagePhotosPlugin.h"
10 | #import "NSURL+SDWebImagePhotosPlugin.h"
11 |
12 | @implementation PHAsset (SDWebImagePhotosPlugin)
13 |
14 | - (NSURL *)sd_URLRepresentation {
15 | return [NSURL sd_URLWithAsset:self];
16 | }
17 |
18 | @end
19 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 |
5 | ---
6 |
7 | ### New Feature Request Checklist
8 |
9 | * [ ] I have checked the current documentations or APIs and does not find a solution
10 | * [ ] I have searched for a similar issue in the [project](https://github.com/SDWebImage/SDWebImagePhotosPlugin/issues) and found none
11 |
12 |
13 | ### Feature Request Description
14 |
15 | Please fill in the detailed description about feature request, including the feature use case (what you need) and the solution you want (like usage, demo code, ...)
16 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/PHAsset+SDWebImagePhotosPlugin.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | @interface PHAsset (SDWebImagePhotosPlugin)
12 |
13 | /// The convenience way to retrive the URL representation of PHAsset. The same as `+[NSURL sd_URLWithAsset:]`.
14 | /// @note This API always create and return new object in Objective-C/struct in Swift of URL. (which does not store the URL inside PHAssets, to avoid retain cycle)
15 | @property (nonatomic, strong, readonly, nonnull) NSURL *sd_URLRepresentation;
16 |
17 | @end
18 |
--------------------------------------------------------------------------------
/Example/Tests/Tests-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | ${EXECUTABLE_NAME}
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundlePackageType
14 | BNDL
15 | CFBundleShortVersionString
16 | 1.0
17 | CFBundleSignature
18 | ????
19 | CFBundleVersion
20 | 1
21 |
22 |
23 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Module/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | 1.2.1
19 | CFBundleVersion
20 | 1.2.1
21 | NSPrincipalClass
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Module/SDWebImagePhotosPlugin.h:
--------------------------------------------------------------------------------
1 | #ifdef __OBJC__
2 | #if __has_include()
3 | #import
4 | #endif
5 | #else
6 | #ifndef FOUNDATION_EXPORT
7 | #if defined(__cplusplus)
8 | #define FOUNDATION_EXPORT extern "C"
9 | #else
10 | #define FOUNDATION_EXPORT extern
11 | #endif
12 | #endif
13 | #endif
14 |
15 | #import
16 | #import
17 | #import
18 | #import
19 | #import
20 | #import
21 |
22 | FOUNDATION_EXPORT double SDWebImagePhotosPluginVersionNumber;
23 | FOUNDATION_EXPORT const unsigned char SDWebImagePhotosPluginVersionString[];
24 |
25 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/PHImageRequestOptions+SDWebImagePhotosPlugin.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | /// PHImageRequestOptions category to provide targetSize and contentMode when fetch Photos image asset
12 | @interface PHImageRequestOptions (SDWebImagePhotosPlugin)
13 |
14 | /**
15 | The `targetSize` value for image asset request. Defaults to `PHImageManagerMaximumSize`.
16 | */
17 | @property (nonatomic, assign) CGSize sd_targetSize;
18 |
19 | /**
20 | The `contentMode` value for image asset request. Defaults to `PHImageContentModeDefault`.
21 | */
22 | @property (nonatomic, assign) PHImageContentMode sd_contentMode;
23 |
24 | @end
25 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDWebImagePhotosError.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | FOUNDATION_EXPORT NSErrorDomain const SDWebImagePhotosErrorDomain;
12 |
13 | /// The error domain for SDWebImagePhotosPlugin's NSError
14 | typedef NS_ERROR_ENUM(SDWebImagePhotosErrorDomain, SDWebImagePhotosError) {
15 | /// Photos framework access is not authorized by user
16 | SDWebImagePhotosErrorNotAuthorized = 10001,
17 | /// Photos URL is not image asset type (like Video or Audio)
18 | SDWebImagePhotosErrorNotImageAsset = 10002,
19 | /// Photos local identifier failed to query PHAsset, is this valid ?
20 | SDWebImagePhotosErrorInvalidLocalIdentifier = 10003
21 | };
22 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OS X
2 | .DS_Store
3 |
4 | # Xcode
5 | build/
6 | *.pbxuser
7 | !default.pbxuser
8 | *.mode1v3
9 | !default.mode1v3
10 | *.mode2v3
11 | !default.mode2v3
12 | *.perspectivev3
13 | !default.perspectivev3
14 | xcuserdata/
15 | *.xccheckout
16 | profile
17 | *.moved-aside
18 | DerivedData
19 | *.hmap
20 | *.ipa
21 |
22 | # Bundler
23 | .bundle
24 |
25 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
26 | Carthage/Checkouts
27 | Carthage/Build
28 |
29 | # We recommend against adding the Pods directory to your .gitignore. However
30 | # you should judge for yourself, the pros and cons are mentioned at:
31 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
32 | #
33 | # Note: if you ignore the Pods directory, make sure to uncomment
34 | # `pod install` in .travis.yml
35 | #
36 | Example/Pods
37 | Example/Podfile.lock
38 |
39 | # SwiftPM
40 | .swiftpm
41 | .build
42 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDWebImagePhotosDefine.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDWebImagePhotosDefine.h"
10 |
11 | NSString * _Nonnull const SDWebImagePhotosScheme = @"ph";
12 | // PHImageManagerMaximumSize value is (-1.0, -1.0)
13 | const CGSize SDWebImagePhotosPixelSize = {.width = -2.0, .height = -2.0};
14 | const CGSize SDWebImagePhotosPointSize = {.width = -3.0, .height = -3.0};
15 | const int64_t SDWebImagePhotosProgressExpectedSize = 100LL;
16 |
17 | SDWebImageContextOption _Nonnull const SDWebImageContextPhotosFetchOptions = @"photosFetchOptions";
18 | SDWebImageContextOption _Nonnull const SDWebImageContextPhotosImageRequestOptions = @"photosImageRequestOptions";
19 | SDWebImageContextOption _Nonnull const SDWebImageContextPhotosRequestImageData = @"photosRequestImageData";
20 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2018/7/19.
6 | // Copyright © 2018年 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 | #import
11 |
12 | @interface AppDelegate ()
13 |
14 | @end
15 |
16 | @implementation AppDelegate
17 |
18 | - (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
19 | // Insert code here to initialize your application
20 | if (@available(macOS 11.0, *)) {
21 | [SDImageCodersManager.sharedManager addCoder:SDImageAWebPCoder.sharedCoder];
22 | }
23 | [SDImageCodersManager.sharedManager addCoder:SDImageHEICCoder.sharedCoder];
24 | }
25 |
26 |
27 | - (void)applicationWillTerminate:(NSNotification *)aNotification {
28 | // Insert code here to tear down your application
29 | }
30 |
31 | - (IBAction)reloadButtonDidTap:(NSMenuItem *)sender {
32 | // Menu item target-action
33 | }
34 |
35 | @end
36 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2018 DreamPiggy
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy
4 | of this software and associated documentation files (the "Software"), to deal
5 | in the Software without restriction, including without limitation the rights
6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7 | copies of the Software, and to permit persons to whom the Software is
8 | furnished to do so, subject to the following conditions:
9 |
10 | The above copyright notice and this permission notice shall be included in
11 | all copies or substantial portions of the Software.
12 |
13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19 | THE SOFTWARE.
20 |
--------------------------------------------------------------------------------
/Example/Tests/SDTestCase.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImagePhotosPlugin package.
3 | *
4 | * For the full copyright and license information, please view the LICENSE
5 | * file that was distributed with this source code.
6 | */
7 |
8 | #define EXP_SHORTHAND // required by Expecta
9 |
10 |
11 | #import
12 | #import
13 | #import
14 | #import
15 |
16 | FOUNDATION_EXPORT const int64_t kAsyncTestTimeout;
17 | FOUNDATION_EXPORT const int64_t kMinDelayNanosecond;
18 | FOUNDATION_EXPORT NSString * _Nonnull const kTestJPEGURL;
19 | FOUNDATION_EXPORT NSString * _Nonnull const kTestProgressiveJPEGURL;
20 | FOUNDATION_EXPORT NSString * _Nonnull const kTestPNGURL;
21 | FOUNDATION_EXPORT NSString * _Nonnull const kTestGIFURL;
22 | FOUNDATION_EXPORT NSString * _Nonnull const kTestWebPURL;
23 | FOUNDATION_EXPORT NSString * _Nonnull const kTestAPNGPURL;
24 |
25 | @interface SDTestCase : XCTestCase
26 |
27 | - (void)waitForExpectationsWithCommonTimeout;
28 | - (void)waitForExpectationsWithCommonTimeoutUsingHandler:(nullable XCWaitCompletionHandler)handler;
29 |
30 | @end
31 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "mac",
5 | "size" : "16x16",
6 | "scale" : "1x"
7 | },
8 | {
9 | "idiom" : "mac",
10 | "size" : "16x16",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "mac",
15 | "size" : "32x32",
16 | "scale" : "1x"
17 | },
18 | {
19 | "idiom" : "mac",
20 | "size" : "32x32",
21 | "scale" : "2x"
22 | },
23 | {
24 | "idiom" : "mac",
25 | "size" : "128x128",
26 | "scale" : "1x"
27 | },
28 | {
29 | "idiom" : "mac",
30 | "size" : "128x128",
31 | "scale" : "2x"
32 | },
33 | {
34 | "idiom" : "mac",
35 | "size" : "256x256",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "mac",
40 | "size" : "256x256",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "mac",
45 | "size" : "512x512",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "mac",
50 | "size" : "512x512",
51 | "scale" : "2x"
52 | }
53 | ],
54 | "info" : {
55 | "version" : 1,
56 | "author" : "xcode"
57 | }
58 | }
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 |
5 | ---
6 |
7 | ### New Issue Checklist
8 |
9 | * [ ] I have read the tutorial [usage](https://github.com/SDWebImage/SDWebImagePhotosPlugin#usage)
10 | * [ ] I have searched for a similar issue in the [project](https://github.com/SDWebImage/SDWebImagePhotosPlugin/issues) and found none
11 |
12 | ### Issue Info
13 |
14 | Info | Value |
15 | -------------------------|-------------------------------------|
16 | Platform Name | e.g. ios / macos / tvos
17 | Platform Version | e.g. 11.0 / 10.13.0 / 11.0
18 | Framework Version | e.g. 0.1.1
19 | Integration Method | e.g. carthage / cocoapods
20 | Xcode Version | e.g. Xcode 9
21 | Repro rate | e.g. all the time (100%) / sometimes x% / only once
22 | Repro with our demo prj | e.g. does it happen with our demo project?
23 | Demo project link | e.g. link to a demo project that highlights the issue
24 |
25 | ### Issue Description and Steps
26 |
27 | Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
28 |
--------------------------------------------------------------------------------
/Example/Tests/SystemAlert.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImagePhotosPlugin package.
3 | *
4 | * For the full copyright and license information, please view the LICENSE
5 | * file that was distributed with this source code.
6 | */
7 |
8 | #import "SystemAlert.h"
9 | #import "dlfcn.h"
10 |
11 | @interface SystemAlert (ForMethodCompletionOnly)
12 | + (id)localTarget;
13 | - (id)frontMostApp;
14 | - (id)alert;
15 | - (id)buttons;
16 | - (void)tap;
17 | @end
18 |
19 | @implementation SystemAlert
20 |
21 | + (void)load {
22 | dlopen([@"/Developer/Library/PrivateFrameworks/UIAutomation.framework/UIAutomation" fileSystemRepresentation], RTLD_LOCAL);
23 | }
24 |
25 | + (NSArray *)currentButtons {
26 | id localTarget = [NSClassFromString(@"UIATarget") localTarget];
27 | id app = [localTarget frontMostApp];
28 | id alert = [app alert];
29 | id buttons = [alert buttons];
30 | if (![buttons isKindOfClass:[NSArray class]]) {
31 | return nil;
32 | }
33 | return buttons;
34 | }
35 |
36 | + (void)tapLeftButton {
37 | id button = [self currentButtons].firstObject;
38 | [button tap];
39 | }
40 |
41 | + (void)tapRightButton {
42 | id button = [self currentButtons].lastObject;
43 | [button tap];
44 | }
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | $(DEVELOPMENT_LANGUAGE)
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIconFile
10 |
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | $(PRODUCT_NAME)
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleVersion
22 | 1
23 | LSMinimumSystemVersion
24 | $(MACOSX_DEPLOYMENT_TARGET)
25 | NSHumanReadableCopyright
26 | Copyright © 2018年 DreamPiggy. All rights reserved.
27 | NSMainStoryboardFile
28 | Main
29 | NSPhotoLibraryUsageDescription
30 | Allow SDWebImage Demo to show Photos Library images
31 | NSPrincipalClass
32 | NSApplication
33 |
34 |
35 |
--------------------------------------------------------------------------------
/Example/Tests/SDTestCase.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImagePhotosPlugin package.
3 | *
4 | * For the full copyright and license information, please view the LICENSE
5 | * file that was distributed with this source code.
6 | */
7 |
8 | #import "SDTestCase.h"
9 |
10 | const int64_t kAsyncTestTimeout = 5;
11 | const int64_t kMinDelayNanosecond = NSEC_PER_MSEC * 100; // 0.1s
12 | NSString *const kTestJPEGURL = @"http://via.placeholder.com/50x50.jpg";
13 | NSString *const kTestProgressiveJPEGURL = @"https://raw.githubusercontent.com/ibireme/YYImage/master/Demo/YYImageDemo/mew_progressive.jpg";
14 | NSString *const kTestPNGURL = @"http://via.placeholder.com/50x50.png";
15 | NSString *const kTestGIFURL = @"https://media.giphy.com/media/UEsrLdv7ugRTq/giphy.gif";
16 | NSString *const kTestWebPURL = @"http://littlesvr.ca/apng/images/SteamEngine.webp";
17 | NSString *const kTestAPNGPURL = @"https://upload.wikimedia.org/wikipedia/commons/1/14/Animated_PNG_example_bouncing_beach_ball.png";
18 |
19 | @implementation SDTestCase
20 |
21 | - (void)waitForExpectationsWithCommonTimeout {
22 | [self waitForExpectationsWithCommonTimeoutUsingHandler:nil];
23 | }
24 |
25 | - (void)waitForExpectationsWithCommonTimeoutUsingHandler:(XCWaitCompletionHandler)handler {
26 | [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:handler];
27 | }
28 |
29 | @end
30 |
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.0
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "SDWebImagePhotosPlugin",
8 | platforms: [
9 | .macOS(.v10_13), .iOS(.v9), .tvOS(.v10)
10 | ],
11 | products: [
12 | // Products define the executables and libraries produced by a package, and make them visible to other packages.
13 | .library(
14 | name: "SDWebImagePhotosPlugin",
15 | targets: ["SDWebImagePhotosPlugin"]),
16 | ],
17 | dependencies: [
18 | // Dependencies declare other packages that this package depends on.
19 | // .package(url: /* package url */, from: "1.0.0"),
20 | .package(url: "https://github.com/SDWebImage/SDWebImage.git", from: "5.10.0")
21 | ],
22 | targets: [
23 | // Targets are the basic building blocks of a package. A target can define a module or a test suite.
24 | // Targets can depend on other targets in this package, and on products in packages which this package depends on.
25 | .target(
26 | name: "SDWebImagePhotosPlugin",
27 | dependencies: ["SDWebImage"],
28 | path: ".",
29 | sources: ["SDWebImagePhotosPlugin/Classes"],
30 | publicHeadersPath: "SDWebImagePhotosPlugin/Classes"
31 | )
32 | ]
33 | )
34 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/NSURL+SDWebImagePhotosPlugin.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import
10 |
11 | @class PHAsset;
12 | /// NSURL category for Photos URL support
13 | @interface NSURL (SDWebImagePhotosPlugin)
14 |
15 | /**
16 | The localIdentifier value for Photos URL, or nil for other URL.
17 | */
18 | @property (nonatomic, copy, readonly, nullable) NSString *sd_assetLocalIdentifier;
19 |
20 | /**
21 | The `PHAsset` value for Photos URL, or nil for other URL, or the `PHAsset` is not availble.
22 | */
23 | @property (nonatomic, strong, readonly, nullable) PHAsset *sd_asset;
24 |
25 | /**
26 | Check whether the current URL represents Photos URL.
27 | */
28 | @property (nonatomic, assign, readonly) BOOL sd_isPhotosURL;
29 |
30 | /**
31 | Create a Photos URL with `PHAsset` 's local identifier
32 |
33 | @param identifier `PHAsset` 's local identifier
34 | @return A Photos URL
35 | */
36 | + (nonnull instancetype)sd_URLWithAssetLocalIdentifier:(nonnull NSString *)identifier;
37 |
38 | /**
39 | Create a Photos URL with `PHAsset`
40 |
41 | @param asset `PHAsset` object
42 | @return A Photos URL
43 | */
44 | + (nonnull instancetype)sd_URLWithAsset:(nonnull PHAsset *)asset;
45 |
46 | @end
47 |
--------------------------------------------------------------------------------
/.github/config.yml:
--------------------------------------------------------------------------------
1 | # Configuration for request-info - https://github.com/behaviorbot/request-info
2 |
3 | # *OPTIONAL* Comment to reply with
4 | # Can be either a string :
5 | requestInfoReplyComment: >
6 | Hi there! We found that the issue does not follow the issue template. Please fill it to provide the basic information for us to investigate the issue, thanks!
7 |
8 | # Or an array:
9 | # requestInfoReplyComment:
10 | # - Ah no! young blade! That was a trifle short!
11 | # - Tell me more !
12 | # - I am sure you can be more effusive
13 |
14 |
15 | # *OPTIONAL* default titles to check against for lack of descriptiveness
16 | # MUST BE ALL LOWERCASE
17 | # requestInfoDefaultTitles:
18 | # - update readme.md
19 | # - updates
20 |
21 | # *OPTIONAL* Label to be added to Issues and Pull Requests with insufficient information given
22 | requestInfoLabelToAdd: needs more info
23 |
24 | # *OPTIONAL* Require Pull Requests to contain more information than what is provided in the PR template
25 | # Will fail if the pull request's body is equal to the provided template
26 | checkPullRequestTemplate: true
27 |
28 | # *OPTIONAL* Only warn about insufficient information on these events type
29 | # Keys must be lowercase. Valid values are 'issue' and 'pullRequest'
30 | requestInfoOn:
31 | pullRequest: false
32 | issue: true
33 |
34 | # *OPTIONAL* Add a list of people whose Issues/PRs will not be commented on
35 | # keys must be GitHub usernames
36 | # requestInfoUserstoExclude:
37 | # - hiimbex
38 | # - bexo
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: objective-c
2 | osx_image: xcode11.2
3 |
4 | env:
5 | global:
6 | - LC_CTYPE=en_US.UTF-8
7 | - LANG=en_US.UTF-8
8 |
9 | addons:
10 | ssh_known_hosts: github.com
11 |
12 | notifications:
13 | email: false
14 |
15 | before_install:
16 | - env
17 | - locale
18 | - gem install cocoapods --no-document --quiet
19 | - gem install xcpretty --no-document --quiet
20 | - pod --version
21 | - pod repo update --silent
22 | - xcpretty --version
23 | - xcodebuild -version
24 | - xcodebuild -showsdks
25 |
26 | script:
27 | - set -o pipefail
28 |
29 | - echo Check if the library described by the podspec can be built
30 | - pod lib lint --allow-warnings
31 |
32 | - echo Build example
33 | - pod install --project-directory=Example
34 | - xcodebuild build -workspace Example/SDWebImagePhotosPlugin.xcworkspace -scheme SDWebImagePhotosPlugin-Example -destination 'platform=iOS Simulator,name=iPhone 11 Pro' -configuration Debug | xcpretty -c
35 |
36 | - echo Clean DerivedData
37 | - rm -rf ~/Library/Developer/Xcode/DerivedData/
38 | - mkdir DerivedData
39 |
40 | - echo Run the tests
41 | - xcodebuild test -workspace Example/SDWebImagePhotosPlugin.xcworkspace -scheme 'SDWebImagePhotosPlugin_Tests' -destination 'platform=iOS Simulator,name=iPhone 11 Pro' -configuration Debug | xcpretty -c
42 | - mv ~/Library/Developer/Xcode/DerivedData/ ./DerivedData/iOS
43 |
44 | after_success:
45 | - bash <(curl -s https://codecov.io/bash) -D './DerivedData/iOS' -J '^SDWebImagePhotosPlugin$' -F 'iOS'
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/PHImageRequestOptions+SDWebImagePhotosPlugin.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "PHImageRequestOptions+SDWebImagePhotosPlugin.h"
10 | #import "SDWebImagePhotosDefine.h"
11 | #import
12 |
13 | @implementation PHImageRequestOptions (SDWebImagePhotosPlugin)
14 |
15 | - (CGSize)sd_targetSize {
16 | NSValue *value = objc_getAssociatedObject(self, @selector(sd_targetSize));
17 | if (!value) {
18 | return PHImageManagerMaximumSize;
19 | }
20 | #if SD_MAC
21 | CGSize targetSize = value.sizeValue;
22 | #else
23 | CGSize targetSize = value.CGSizeValue;
24 | #endif
25 | return targetSize;
26 | }
27 |
28 | - (void)setSd_targetSize:(CGSize)sd_targetSize {
29 | objc_setAssociatedObject(self, @selector(sd_targetSize), @(sd_targetSize), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
30 | }
31 |
32 | - (PHImageContentMode)sd_contentMode {
33 | NSNumber *value = objc_getAssociatedObject(self, @selector(sd_contentMode));
34 | if (value != nil) {
35 | return PHImageContentModeDefault;
36 | }
37 | return value.integerValue;
38 | }
39 |
40 | - (void)setSd_contentMode:(PHImageContentMode)sd_contentMode {
41 | objc_setAssociatedObject(self, @selector(sd_contentMode), @(sd_contentMode), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
42 | }
43 |
44 | @end
45 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/MasterViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.podspec:
--------------------------------------------------------------------------------
1 | #
2 | # Be sure to run `pod lib lint SDWebImagePhotosPlugin.podspec' to ensure this is a
3 | # valid spec before submitting.
4 | #
5 | # Any lines starting with a # are optional, but their use is encouraged
6 | # To learn more about a Podspec see https://guides.cocoapods.org/syntax/podspec.html
7 | #
8 |
9 | Pod::Spec.new do |s|
10 | s.name = 'SDWebImagePhotosPlugin'
11 | s.version = '1.2.1'
12 | s.summary = 'A SDWebImage plugin to support Photos framework image loading.'
13 |
14 | s.description = <<-DESC
15 | This is a SDWebImage loader plugin to support Apple's Photos framework image asset.
16 | DESC
17 |
18 | s.homepage = 'https://github.com/SDWebImage/SDWebImagePhotosPlugin'
19 | # s.screenshots = 'www.example.com/screenshots_1', 'www.example.com/screenshots_2'
20 | s.license = { :type => 'MIT', :file => 'LICENSE' }
21 | s.author = { 'DreamPiggy' => 'lizhuoli1126@126.com' }
22 | s.source = { :git => 'https://github.com/SDWebImage/SDWebImagePhotosPlugin.git', :tag => s.version.to_s }
23 | # s.social_media_url = 'https://twitter.com/'
24 |
25 | s.osx.deployment_target = '10.13'
26 | s.ios.deployment_target = '9.0'
27 | s.tvos.deployment_target = '10.0'
28 |
29 | s.source_files = 'SDWebImagePhotosPlugin/Classes/**/*', 'SDWebImagePhotosPlugin/Module/SDWebImagePhotosPlugin.h'
30 | s.module_map = 'SDWebImagePhotosPlugin/Module/SDWebImagePhotosPlugin.modulemap'
31 |
32 | s.pod_target_xcconfig = {
33 | 'SUPPORTS_MACCATALYST' => 'YES',
34 | 'DERIVE_MACCATALYST_PRODUCT_BUNDLE_IDENTIFIER' => 'NO'
35 | }
36 |
37 | s.frameworks = 'Photos'
38 | s.dependency 'SDWebImage/Core', '~> 5.10'
39 | end
40 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/SDWebImagePhotosPlugin-Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleDisplayName
8 | ${PRODUCT_NAME}
9 | CFBundleExecutable
10 | ${EXECUTABLE_NAME}
11 | CFBundleIdentifier
12 | $(PRODUCT_BUNDLE_IDENTIFIER)
13 | CFBundleInfoDictionaryVersion
14 | 6.0
15 | CFBundleName
16 | ${PRODUCT_NAME}
17 | CFBundlePackageType
18 | APPL
19 | CFBundleShortVersionString
20 | 1.0
21 | CFBundleSignature
22 | ????
23 | CFBundleVersion
24 | 1.0
25 | LSRequiresIPhoneOS
26 |
27 | UILaunchStoryboardName
28 | LaunchScreen
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 | NSPhotoLibraryUsageDescription
47 | Allow SDWebImage Demo to show Photos Library images
48 |
49 |
50 |
--------------------------------------------------------------------------------
/.github/stale.yml:
--------------------------------------------------------------------------------
1 | # Configuration for probot-stale - https://github.com/probot/stale
2 |
3 | # Number of days of inactivity before an Issue or Pull Request becomes stale
4 | daysUntilStale: 60
5 |
6 | # Number of days of inactivity before an Issue or Pull Request with the stale label is closed.
7 | # Set to false to disable. If disabled, issues still need to be closed manually, but will remain marked as stale.
8 | daysUntilClose: 7
9 |
10 | # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
11 | exemptLabels:
12 | - crash
13 |
14 | # Set to true to ignore issues in a project (defaults to false)
15 | exemptProjects: false
16 |
17 | # Set to true to ignore issues in a milestone (defaults to false)
18 | exemptMilestones: false
19 |
20 | # Label to use when marking as stale
21 | staleLabel: wontfix
22 |
23 | # Comment to post when marking as stale. Set to `false` to disable
24 | markComment: >
25 | This issue has been automatically marked as stale because it has not had
26 | recent activity. It will be closed if no further activity occurs. Thank you
27 | for your contributions.
28 |
29 | # Comment to post when removing the stale label.
30 | # unmarkComment: >
31 | # Your comment here.
32 |
33 | # Comment to post when closing a stale Issue or Pull Request.
34 | # closeComment: >
35 | # Your comment here.
36 |
37 | # Limit the number of actions per hour, from 1-30. Default is 30
38 | limitPerRun: 30
39 |
40 | # Limit to only `issues` or `pulls`
41 | only: issues
42 |
43 | # Optionally, specify configuration settings that are specific to just 'issues' or 'pulls':
44 | # pulls:
45 | # daysUntilStale: 30
46 | # markComment: >
47 | # This pull request has been automatically marked as stale because it has not had
48 | # recent activity. It will be closed if no further activity occurs. Thank you
49 | # for your contributions.
50 |
51 | # issues:
52 | # exemptLabels:
53 | # - confirmed
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/Images.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "20x20",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "20x20",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "29x29",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "29x29",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "40x40",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "40x40",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "iphone",
35 | "size" : "60x60",
36 | "scale" : "2x"
37 | },
38 | {
39 | "idiom" : "iphone",
40 | "size" : "60x60",
41 | "scale" : "3x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "20x20",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "20x20",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "29x29",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "29x29",
61 | "scale" : "2x"
62 | },
63 | {
64 | "idiom" : "ipad",
65 | "size" : "40x40",
66 | "scale" : "1x"
67 | },
68 | {
69 | "idiom" : "ipad",
70 | "size" : "40x40",
71 | "scale" : "2x"
72 | },
73 | {
74 | "idiom" : "ipad",
75 | "size" : "76x76",
76 | "scale" : "1x"
77 | },
78 | {
79 | "idiom" : "ipad",
80 | "size" : "76x76",
81 | "scale" : "2x"
82 | },
83 | {
84 | "idiom" : "ipad",
85 | "size" : "83.5x83.5",
86 | "scale" : "2x"
87 | },
88 | {
89 | "idiom" : "ios-marketing",
90 | "size" : "1024x1024",
91 | "scale" : "1x"
92 | }
93 | ],
94 | "info" : {
95 | "version" : 1,
96 | "author" : "xcode"
97 | }
98 | }
99 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/NSURL+SDWebImagePhotosPlugin.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "NSURL+SDWebImagePhotosPlugin.h"
10 | #import "SDWebImagePhotosDefine.h"
11 | #import
12 | #import
13 |
14 | @implementation NSURL (SDWebImagePhotosPlugin)
15 |
16 | - (BOOL)sd_isPhotosURL {
17 | return [self.scheme isEqualToString:SDWebImagePhotosScheme];
18 | }
19 |
20 | - (NSString *)sd_assetLocalIdentifier {
21 | if (!self.sd_isPhotosURL) {
22 | return nil;
23 | }
24 | PHAsset *asset = self.sd_asset;
25 | if (asset) {
26 | return asset.localIdentifier;
27 | }
28 | NSString *urlString = self.absoluteString;
29 | NSString *prefix = [NSString stringWithFormat:@"%@://", SDWebImagePhotosScheme];
30 | if (urlString.length <= prefix.length) {
31 | return nil;
32 | }
33 | return [urlString stringByReplacingOccurrencesOfString:prefix withString:@""];
34 | }
35 |
36 | - (PHAsset *)sd_asset {
37 | return objc_getAssociatedObject(self, @selector(sd_asset));
38 | }
39 |
40 | - (void)setSd_asset:(PHAsset * _Nullable)sd_asset {
41 | objc_setAssociatedObject(self, @selector(sd_asset), sd_asset, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
42 | }
43 |
44 | + (instancetype)sd_URLWithAssetLocalIdentifier:(NSString *)identifier {
45 | NSParameterAssert(identifier);
46 | // ph://F2A9F582-BA45-4308-924E-6D146B784A09/L0/001
47 | NSString *prefix = [NSString stringWithFormat:@"%@://", SDWebImagePhotosScheme];
48 | return [NSURL URLWithString:[NSString stringWithFormat:@"%@%@", prefix, identifier]];
49 | }
50 |
51 | + (instancetype)sd_URLWithAsset:(PHAsset *)asset {
52 | NSParameterAssert(asset);
53 | NSString *localIdentifier = asset.localIdentifier;
54 | NSURL *url = [self sd_URLWithAssetLocalIdentifier:localIdentifier];
55 | url.sd_asset = asset;
56 |
57 | return url;
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin_Tests.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
16 |
18 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
40 |
41 |
42 |
43 |
49 |
50 |
52 |
53 |
56 |
57 |
58 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/DetailViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "DetailViewController.h"
10 | #import
11 | #import
12 |
13 | @interface DetailViewController ()
14 |
15 | @property (weak, nonatomic) IBOutlet UIImageView *imageView;
16 | @property (weak, nonatomic) IBOutlet UIScrollView *scrollView;
17 |
18 | @end
19 |
20 | @implementation DetailViewController
21 |
22 | - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
23 | return self.imageView;
24 | }
25 |
26 | - (void)scrollViewDidDoubleTapped:(UIGestureRecognizer *)gestureRecognizer {
27 | if (self.scrollView.zoomScale > self.scrollView.minimumZoomScale) {
28 | [self.scrollView setZoomScale:self.scrollView.minimumZoomScale animated:YES];
29 | } else {
30 | [self.scrollView setZoomScale:self.scrollView.maximumZoomScale animated:YES];
31 | }
32 | }
33 |
34 | - (void)configureView
35 | {
36 | self.scrollView.delegate = self;
37 | UITapGestureRecognizer *doubleTapGestureRecognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(scrollViewDidDoubleTapped:)];
38 | doubleTapGestureRecognizer.numberOfTapsRequired = 2;
39 | [self.scrollView addGestureRecognizer:doubleTapGestureRecognizer];
40 | if (!self.imageView.sd_imageIndicator) {
41 | self.imageView.sd_imageIndicator = SDWebImageProgressIndicator.defaultIndicator;
42 | }
43 | [self.imageView sd_setImageWithURL:self.imageURL
44 | placeholderImage:nil
45 | options:SDWebImageFromLoaderOnly
46 | context:@{SDWebImageContextStoreCacheType : @(SDImageCacheTypeNone)}];
47 | }
48 |
49 | - (void)viewDidLoad
50 | {
51 | [super viewDidLoad];
52 | if (@available(iOS 11.0, *)) {
53 | self.scrollView.contentInsetAdjustmentBehavior = UIScrollViewContentInsetAdjustmentNever;
54 | } else {
55 | self.automaticallyAdjustsScrollViewInsets = NO;
56 | }
57 | [self configureView];
58 | }
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/TestCollectionViewItem.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/DetailViewController.xib:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDImagePhotosLoader.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #if __has_include()
10 | #import
11 | #else
12 | @import SDWebImage;
13 | #endif
14 | #import
15 |
16 | /**
17 | The imgae loader to load image asset from Photos library. You need to register the loader into manager firstly. Use `@import SDWebImagePhotosPlugin` to import full framework instead of each header.
18 | @note To control single image request options, use the context option in `SDWebImagePhotosDefine.h`.
19 | @note Use `NSURL+SDWebImagePhotosPlugin.h` category to create Photos URL instead of string. Use `PHImageRequestOptions+SDWebImagePhotosPlugin.h` category to provide extra info for request options.
20 | @note And it's also strongly recommeded to totally disable memory cache if you want to query batch of Photos images frequently. You can do this by using `SDWebImageFromLoaderOnly` options during image request. And you can use `SDWebImageContextStoreCacheType` with `SDImageCacheTypeNone` to disable cache storing. This is because Photos framework manage the image cache by their own process outside your application process and can reduce memory usage.
21 | */
22 | @interface SDImagePhotosLoader : NSObject
23 |
24 | /**
25 | The global shared instance for Photos loader.
26 | */
27 | @property (nonatomic, class, readonly, nonnull) SDImagePhotosLoader *sharedLoader;
28 |
29 | /**
30 | The default `fetchOptions` used for PHAsset fetch with the localIdentifier.
31 | Defaults to nil.
32 | */
33 | @property (nonatomic, strong, nullable) PHFetchOptions *fetchOptions;
34 |
35 | /**
36 | The default `imageRequestOptions` used for image asset request.
37 | Defatuls value are these:
38 | networkAccessAllowed = YES;
39 | resizeMode = PHImageRequestOptionsResizeModeFast;
40 | deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
41 | version = PHImageRequestOptionsVersionCurrent;
42 | */
43 | @property (nonatomic, strong, nullable) PHImageRequestOptions *imageRequestOptions;
44 |
45 | /**
46 | Whether we request only `PHAssetMediaTypeImage` asset and ignore other types (video/audio/unknown).
47 | When we found other type, an error `SDWebImagePhotosErrorNotImageAsset` will be reported.
48 | Defaults to YES. If you prefer to load other type like video asset's poster image, set this value to NO.
49 | */
50 | @property (nonatomic, assign) BOOL requestImageAssetOnly;
51 |
52 | @end
53 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDWebImagePhotosDefine.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #if __has_include()
10 | #import
11 | #else
12 | @import SDWebImage;
13 | #endif
14 |
15 | /**
16 | * The scheme when identifing the URL is Photos URL
17 | */
18 | FOUNDATION_EXPORT NSString * _Nonnull const SDWebImagePhotosScheme;
19 |
20 | /**
21 | * Specify to use the exact size of image instead of original pixel size.
22 | * Use this size if you want full image that PHImageManagerMaximumSize can not provide. This is the designed behavior for PhotoKit.
23 | * @note SDWebImagePhotosPixelSize > PHImageManagerMaximumSize(default) > SDWebImagePhotosPointSize
24 | */
25 | FOUNDATION_EXPORT const CGSize SDWebImagePhotosPixelSize;
26 |
27 | /**
28 | * Specify to use the exact size of image instead of original point size.
29 | * The scale is from the custom scale factor, or using the device scale factor if not provide.
30 | */
31 | FOUNDATION_EXPORT const CGSize SDWebImagePhotosPointSize;
32 |
33 | /**
34 | * Because Photos Framework progressBlock does not contains the file size, only the progress. See `PHAssetImageProgressHandler`.
35 | * This value is used to represent the `exceptedSize`, and the `receivedSize` is calculated by multiplying with the progress value.
36 | */
37 | FOUNDATION_EXPORT const int64_t SDWebImagePhotosProgressExpectedSize; /* 100LL */
38 |
39 | /**
40 | A PHFetchOptions instance used in the Photos Library fetch process. If you do not provide, we will use the default options to fetch the asset. (PHFetchOptions)
41 | */
42 | FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPhotosFetchOptions;
43 |
44 | /**
45 | A PHImageRequestOptions instance used in the Photos Library image request process. If you do not provide, we will use the default options to fetch the image (PHImageRequestOptions)
46 | */
47 | FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPhotosImageRequestOptions;
48 |
49 | /**
50 | A Bool value specify whether or not, to use `requestImageDataForAsset:options:resultHandler:` instead of `requestImageForAsset:targetSize:contentMode:options:resultHandler:` API to request Asset's Image.
51 | By default, we automatically use `requestImageDataForAsset` for Animated Asset (GIF images), use `requestImageForAsset` for other Asset. If you provide a custom value, always using that value instead.
52 | If you care about the raw image data, you can enable this context option to get the raw image data in completion block.
53 | @note When query the raw image data, the `targetSize` and `contentMode` are ignored. You can use image transformer or other ways from your propose. See Apple's documentation for more details information. (NSNumber *)
54 | */
55 | FOUNDATION_EXPORT SDWebImageContextOption _Nonnull const SDWebImageContextPhotosRequestImageData;
56 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/SDAppDelegate.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDAppDelegate.h"
10 | #import "MasterViewController.h"
11 | #import
12 |
13 | @implementation SDAppDelegate
14 |
15 | @synthesize window = _window;
16 | @synthesize navigationController = _navigationController;
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
19 | {
20 | // Override point for customization after application launch.
21 | if (@available(iOS 14.0, *)) {
22 | [SDImageCodersManager.sharedManager addCoder:SDImageAWebPCoder.sharedCoder];
23 | }
24 | if (@available(iOS 13.0, *)) {
25 | [SDImageCodersManager.sharedManager addCoder:SDImageHEICCoder.sharedCoder];
26 | }
27 |
28 | self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
29 |
30 | MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
31 | self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
32 | self.window.rootViewController = self.navigationController;
33 | [self.window makeKeyAndVisible];
34 | return YES;
35 | }
36 |
37 | - (void)applicationWillResignActive:(UIApplication *)application
38 | {
39 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
40 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
41 | }
42 |
43 | - (void)applicationDidEnterBackground:(UIApplication *)application
44 | {
45 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
46 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
47 | }
48 |
49 | - (void)applicationWillEnterForeground:(UIApplication *)application
50 | {
51 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
52 | }
53 |
54 | - (void)applicationDidBecomeActive:(UIApplication *)application
55 | {
56 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
57 | }
58 |
59 | - (void)applicationWillTerminate:(UIApplication *)application
60 | {
61 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
62 | }
63 |
64 | @end
65 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin-tvOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin-macOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
34 |
35 |
45 |
46 |
52 |
53 |
54 |
55 |
56 |
57 |
63 |
64 |
70 |
71 |
72 |
73 |
75 |
76 |
79 |
80 |
81 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin_Example macOS.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
39 |
40 |
41 |
42 |
43 |
44 |
54 |
56 |
62 |
63 |
64 |
65 |
66 |
67 |
73 |
75 |
81 |
82 |
83 |
84 |
86 |
87 |
90 |
91 |
92 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin.xcodeproj/xcshareddata/xcschemes/SDWebImagePhotosPlugin-Example.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
33 |
39 |
40 |
41 |
42 |
43 |
49 |
50 |
51 |
52 |
53 |
54 |
64 |
66 |
72 |
73 |
74 |
75 |
76 |
77 |
83 |
85 |
91 |
92 |
93 |
94 |
96 |
97 |
100 |
101 |
102 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin_Example macOS/ViewController.m:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // SDWebImagePhotosPlugin_Example macOS
4 | //
5 | // Created by lizhuoli on 2018/7/19.
6 | // Copyright © 2018年 DreamPiggy. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | #import
11 | #import
12 | #import "TestCollectionViewItem.h"
13 |
14 | @interface ViewController ()
15 |
16 | @property (nonatomic, strong) NSMutableArray *objects;
17 | @property (weak) IBOutlet NSScrollView *scrollView;
18 | @property (weak) IBOutlet NSCollectionView *collectionView;
19 |
20 |
21 | @end
22 |
23 | @implementation ViewController
24 |
25 | - (instancetype)initWithCoder:(NSCoder *)coder {
26 | self = [super initWithCoder:coder];
27 | if (self) {
28 | self.objects = [NSMutableArray array];
29 | // Setup Photos Loader
30 | SDWebImageManager.defaultImageLoader = [SDImagePhotosLoader sharedLoader];
31 | // The original image size may be 4K, we only query the max view size :)
32 | SDImagePhotosLoader.sharedLoader.imageRequestOptions.sd_targetSize = CGSizeMake(500, 500);
33 |
34 | // Reload
35 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(menuItemDidTap:) name:NSMenuDidSendActionNotification object:nil];
36 | }
37 | return self;
38 | }
39 |
40 | - (void)viewDidLoad {
41 | [super viewDidLoad];
42 |
43 | // Photos Library Demo
44 | [self reloadData];
45 | }
46 |
47 | #pragma clang diagnostic push
48 | #pragma clang diagnostic ignored "-Wunguarded-availability"
49 | - (void)fetchAssets {
50 | [self.objects removeAllObjects];
51 | PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
52 | subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary
53 | options:nil];
54 | PHAssetCollection *collection = result.firstObject;
55 | PHFetchOptions *fetchOptions = [PHFetchOptions new];
56 | fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d", PHAssetMediaTypeImage];
57 | fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
58 | PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
59 | for (PHAsset *asset in assets) {
60 | // You can use local identifier of `PHAsset` to create URL
61 | // NSURL *url = [NSURL sd_URLWithAssetLocalIdentifier:asset.localIdentifier];
62 | // Or even `PHAsset` itself
63 | NSURL *url = [NSURL sd_URLWithAsset:asset];
64 | [self.objects addObject:url];
65 | }
66 | }
67 | #pragma clang diagnostic pop
68 |
69 | - (void)menuItemDidTap:(NSNotification *)notification {
70 | NSMenuItem *menuItem = notification.userInfo[@"MenuItem"];
71 | if ([menuItem.title isEqualToString:@"Reload"]) {
72 | [self reloadData];
73 | }
74 | }
75 |
76 | - (void)reloadData {
77 | [self fetchAssets];
78 | [self.collectionView reloadData];
79 | }
80 |
81 | - (NSCollectionViewItem *)collectionView:(NSCollectionView *)collectionView itemForRepresentedObjectAtIndexPath:(NSIndexPath *)indexPath {
82 | TestCollectionViewItem *cell = [collectionView makeItemWithIdentifier:@"TestCollectionViewItem" forIndexPath:indexPath];
83 | NSURL *photosURL = self.objects[indexPath.item];
84 | BOOL supportsHDR = NSScreen.mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1.0;
85 | SDWebImageMutableContext *context = [@{SDWebImageContextStoreCacheType: @(SDImageCacheTypeNone)} mutableCopy];
86 | if (supportsHDR) {
87 | if (@available (macOS 14.0, *)) {
88 | cell.imageViewDisplay.preferredImageDynamicRange = NSImageDynamicRangeHigh; // Enable Image View Level control for HDR
89 | }
90 | context[SDWebImageContextPhotosRequestImageData] = @(YES); // Photos Library only load HDR info when requestImageData
91 | context[SDWebImageContextImageDecodeToHDR] = @(YES); // When decoding HDR data, we need explicit enable HDR decoding
92 | }
93 | cell.imageViewDisplay.animates = YES;
94 | cell.imageViewDisplay.sd_imageTransition = SDWebImageTransition.fadeTransition;
95 | [cell.imageViewDisplay sd_setImageWithURL:photosURL placeholderImage:nil options:SDWebImageFromLoaderOnly context:context];
96 | return cell;
97 | }
98 |
99 | - (NSInteger)collectionView:(NSCollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
100 | return self.objects.count;
101 | }
102 |
103 | - (NSInteger)numberOfSectionsInCollectionView:(NSCollectionView *)collectionView {
104 | return 1;
105 | }
106 |
107 | @end
108 |
--------------------------------------------------------------------------------
/Example/SDWebImagePhotosPlugin/MasterViewController.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "MasterViewController.h"
10 | #import "DetailViewController.h"
11 | #import
12 | #import
13 |
14 | @interface MyCustomTableViewCell : UITableViewCell
15 |
16 | @property (nonatomic, strong) UILabel *customTextLabel;
17 | @property (nonatomic, strong) SDAnimatedImageView *customImageView;
18 |
19 | @end
20 |
21 | @implementation MyCustomTableViewCell
22 |
23 | - (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
24 | if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
25 | _customImageView = [[SDAnimatedImageView alloc] initWithFrame:CGRectMake(20.0, 2.0, 60.0, 40.0)];
26 | [self.contentView addSubview:_customImageView];
27 | _customTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(100.0, 12.0, 200, 20.0)];
28 | [self.contentView addSubview:_customTextLabel];
29 |
30 | _customImageView.clipsToBounds = YES;
31 | _customImageView.contentMode = UIViewContentModeScaleAspectFill;
32 | }
33 | return self;
34 | }
35 |
36 | @end
37 |
38 | @interface MasterViewController ()
39 |
40 | @property (nonatomic, strong) NSMutableArray *objects;
41 |
42 | @end
43 |
44 | @implementation MasterViewController
45 |
46 | - (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
47 | {
48 | self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
49 | if (self)
50 | {
51 | self.title = @"SDWebImage";
52 | self.navigationItem.rightBarButtonItem = [UIBarButtonItem.alloc initWithTitle:@"Reload"
53 | style:UIBarButtonItemStylePlain
54 | target:self
55 | action:@selector(reloadData)];
56 | self.objects = [NSMutableArray array];
57 | // Setup Photos Loader
58 | SDWebImageManager.defaultImageLoader = [SDImagePhotosLoader sharedLoader];
59 | // The original image size may be 4K, we only query the max view size :)
60 | SDImagePhotosLoader.sharedLoader.imageRequestOptions.sd_targetSize = CGSizeMake(500, 500);
61 | // Request Video Asset Poster as well
62 | SDImagePhotosLoader.sharedLoader.requestImageAssetOnly = NO;
63 | }
64 | return self;
65 | }
66 |
67 | - (void)viewDidLoad {
68 | [super viewDidLoad];
69 |
70 | // Photos Library Demo
71 | [self reloadData];
72 | }
73 |
74 | - (void)fetchAssets {
75 | [self.objects removeAllObjects];
76 | PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
77 | subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary
78 | options:nil];
79 | PHAssetCollection *collection = result.firstObject;
80 | PHFetchOptions *fetchOptions = [PHFetchOptions new];
81 | fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
82 | PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
83 | for (PHAsset *asset in assets) {
84 | // You can use local identifier of `PHAsset` to create URL
85 | // NSURL *url = [NSURL sd_URLWithAssetLocalIdentifier:asset.localIdentifier];
86 | // Or even `PHAsset` itself
87 | NSURL *url = [NSURL sd_URLWithAsset:asset];
88 | [self.objects addObject:url];
89 | }
90 | }
91 |
92 | - (void)reloadData
93 | {
94 | [self fetchAssets];
95 | [self.tableView reloadData];
96 | }
97 |
98 | #pragma mark - Table View
99 |
100 | - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
101 | {
102 | return 1;
103 | }
104 |
105 | - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
106 | {
107 | return self.objects.count;
108 | }
109 |
110 | - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
111 | {
112 | static NSString *CellIdentifier = @"Cell";
113 |
114 | static UIImage *placeholderImage = nil;
115 | if (!placeholderImage) {
116 | placeholderImage = [UIImage imageNamed:@"placeholder"];
117 | }
118 |
119 | MyCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
120 | if (cell == nil) {
121 | cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
122 | cell.customImageView.sd_imageTransition = SDWebImageTransition.fadeTransition;
123 | cell.customImageView.sd_imageIndicator = SDWebImageActivityIndicator.grayIndicator;
124 | }
125 |
126 | cell.customTextLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];
127 | SDWebImageMutableContext *context = [@{SDWebImageContextStoreCacheType : @(SDImageCacheTypeNone)} mutableCopy];
128 | BOOL supportsHDR = NO;
129 | if (@available(iOS 16.0, *)) {
130 | supportsHDR = UIScreen.mainScreen.potentialEDRHeadroom > 1.0;
131 | }
132 | if (supportsHDR) {
133 | if (@available(iOS 17.0, *)) {
134 | cell.customImageView.preferredImageDynamicRange = UIImageDynamicRangeHigh; // Enable Image View Level control for HDR
135 | }
136 | context[SDWebImageContextPhotosRequestImageData] = @(YES); // Photos Library only load HDR info when requestImageData
137 | context[SDWebImageContextImageDecodeToHDR] = @(YES); // When decoding HDR data, we need explicit enable HDR decoding
138 | }
139 | [cell.customImageView sd_setImageWithURL:self.objects[indexPath.row]
140 | placeholderImage:placeholderImage
141 | options:SDWebImageFromLoaderOnly
142 | context:context]; // Disable memory cache query/store
143 | return cell;
144 | }
145 |
146 | - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
147 | {
148 | NSURL *largeImageURL = self.objects[indexPath.row];
149 | DetailViewController *detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
150 | detailViewController.imageURL = largeImageURL;
151 | [self.navigationController pushViewController:detailViewController animated:YES];
152 | }
153 |
154 | @end
155 |
--------------------------------------------------------------------------------
/Example/Tests/SDPhotosPluginTests.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImagePhotosPlugin package.
3 | *
4 | * For the full copyright and license information, please view the LICENSE
5 | * file that was distributed with this source code.
6 | */
7 |
8 | #import "SDTestCase.h"
9 | #import "SystemAlert.h"
10 |
11 | @interface SDPhotosPluginTests : SDTestCase
12 |
13 | @end
14 |
15 | @implementation SDPhotosPluginTests
16 |
17 | + (void)setUp {
18 | XCTestExpectation *expectation = [[XCTestExpectation alloc] initWithDescription:@"Photos Library Permission"];
19 | // Request Photos Library access in advance
20 | [PHPhotoLibrary requestAuthorization:^(PHAuthorizationStatus status) {
21 | [expectation fulfill];
22 | }];
23 | // Auto grant access (OK button)
24 | [SystemAlert tapRightButton];
25 |
26 | __unused XCTWaiterResult result = [XCTWaiter waitForExpectations:@[expectation] timeout:kAsyncTestTimeout];
27 | }
28 |
29 | - (void)testUIImageViewSetImageWithAsset {
30 | XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithAsset"];
31 | SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:SDImageCache.sharedImageCache loader:SDImagePhotosLoader.sharedLoader];
32 | PHAsset *asset = [self smartAlbumAssets].firstObject;
33 | expect(asset).notTo.beNil();
34 | NSURL *originalImageURL = [NSURL sd_URLWithAsset:asset];
35 |
36 | UIImageView *imageView = [[UIImageView alloc] init];
37 | [imageView sd_setImageWithURL:originalImageURL
38 | placeholderImage:nil
39 | options:SDWebImageFromLoaderOnly
40 | context:@{SDWebImageContextCustomManager : manager}
41 | progress:nil
42 | completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
43 | expect(image).toNot.beNil();
44 | expect(error).to.beNil();
45 | expect(originalImageURL).to.equal(imageURL);
46 | expect(imageView.image).to.equal(image);
47 | [expectation fulfill];
48 | }];
49 | [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
50 | }
51 |
52 | - (void)testUIImageViewSetImageWithAssetLocalIdentifier {
53 | XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithAssetLocalIdentifier"];
54 | SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:SDImageCache.sharedImageCache loader:SDImagePhotosLoader.sharedLoader];
55 | NSString *localIdentifier = [self smartAlbumAssets].firstObject.localIdentifier;
56 | expect(localIdentifier).notTo.beNil();
57 | NSURL *originalImageURL = [NSURL sd_URLWithAssetLocalIdentifier:localIdentifier];
58 |
59 | UIImageView *imageView = [[UIImageView alloc] init];
60 | [imageView sd_setImageWithURL:originalImageURL
61 | placeholderImage:nil
62 | options:SDWebImageFromLoaderOnly
63 | context:@{SDWebImageContextCustomManager : manager}
64 | progress:nil
65 | completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
66 | expect(image).toNot.beNil();
67 | expect(error).to.beNil();
68 | expect(originalImageURL).to.equal(imageURL);
69 | expect(imageView.image).to.equal(image);
70 | [expectation fulfill];
71 | }];
72 | [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
73 | }
74 |
75 | - (void)testUIImageViewSetImageWithAssetAndThumbnailPixelSize {
76 | XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithAssetAndThumbnailPixelSize"];
77 | SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:SDImageCache.sharedImageCache loader:SDImagePhotosLoader.sharedLoader];
78 | PHAsset *asset = [self smartAlbumAssets].firstObject;
79 | expect(asset).notTo.beNil();
80 | NSURL *originalImageURL = [NSURL sd_URLWithAsset:asset];
81 | CGSize thumbnailPixelSize = CGSizeMake(1000, 1000);
82 |
83 | UIImageView *imageView = [[UIImageView alloc] init];
84 | [imageView sd_setImageWithURL:originalImageURL
85 | placeholderImage:nil
86 | options:0
87 | context:@{SDWebImageContextCustomManager : manager, SDWebImageContextImageThumbnailPixelSize : @(thumbnailPixelSize)}
88 | progress:nil
89 | completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
90 | expect(image).toNot.beNil();
91 | expect(error).to.beNil();
92 | expect(MAX(image.size.width, image.size.height), MAX(thumbnailPixelSize.width, thumbnailPixelSize.height)); // Aspect Fit
93 | expect(originalImageURL).to.equal(imageURL);
94 | expect(imageView.image).to.equal(image);
95 | [expectation fulfill];
96 | }];
97 | [self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
98 | }
99 |
100 | - (void)testUIImageViewSetImageWithGIFAsset {
101 | XCTestExpectation *expectation = [self expectationWithDescription:@"UIImageView setImageWithGIFAsset"];
102 |
103 | NSData *GIFData = [self testGIFData];
104 | __block NSString *localIdentifier = nil;
105 | // Write GIF image into Photos Library firstly
106 | [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
107 | PHAssetCreationRequest *request = [PHAssetCreationRequest creationRequestForAsset];
108 | localIdentifier = request.placeholderForCreatedAsset.localIdentifier;
109 | [request addResourceWithType:PHAssetResourceTypePhoto data:GIFData options:nil];
110 | } completionHandler:^(BOOL success, NSError * _Nullable error) {
111 | expect(success).to.beTruthy();
112 |
113 | dispatch_async(dispatch_get_main_queue(), ^{
114 | // Query the GIF image with localIdentifier
115 | SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:SDImageCache.sharedImageCache loader:SDImagePhotosLoader.sharedLoader];
116 | NSURL *originalImageURL = [NSURL sd_URLWithAssetLocalIdentifier:localIdentifier];
117 |
118 | UIImageView *imageView = [[UIImageView alloc] init];
119 | [imageView sd_setImageWithURL:originalImageURL
120 | placeholderImage:nil
121 | options:SDWebImageFromLoaderOnly
122 | context:@{SDWebImageContextCustomManager : manager}
123 | progress:nil
124 | completed:^(UIImage * _Nullable image, NSError * _Nullable error, SDImageCacheType cacheType, NSURL * _Nullable imageURL) {
125 | // Strong retain imageView to avoid immediatelly dealloc
126 | expect(imageView.image).equal(image);
127 | // Expect animated image
128 | expect(image.sd_isAnimated).to.beTruthy();
129 | [expectation fulfill];
130 | // The removal of temp GIF will cause a GUI dialog which is not suitable for running on CI machine :(
131 | // // Clean the temp GIF asset
132 | // [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
133 | // PHFetchResult *assets = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:nil];
134 | // [PHAssetChangeRequest deleteAssets:assets];
135 | // } completionHandler:^(BOOL success, NSError * _Nullable error) {
136 | // [expectation fulfill];
137 | // }];
138 | }];
139 | });
140 | }];
141 |
142 | [self waitForExpectationsWithTimeout:kAsyncTestTimeout * 2 handler:nil];
143 | }
144 |
145 | #pragma mark - Util
146 |
147 | - (PHFetchResult *)smartAlbumAssets {
148 | PHFetchResult *result = [PHAssetCollection fetchAssetCollectionsWithType:PHAssetCollectionTypeSmartAlbum
149 | subtype:PHAssetCollectionSubtypeSmartAlbumUserLibrary
150 | options:nil];
151 | PHAssetCollection *collection = result.firstObject;
152 | PHFetchOptions *fetchOptions = [PHFetchOptions new];
153 | fetchOptions.predicate = [NSPredicate predicateWithFormat:@"mediaType = %d", PHAssetMediaTypeImage];
154 | fetchOptions.sortDescriptors = @[[NSSortDescriptor sortDescriptorWithKey:@"creationDate" ascending:NO]];
155 | PHFetchResult *assets = [PHAsset fetchAssetsInAssetCollection:collection options:fetchOptions];
156 |
157 | return assets;
158 | }
159 |
160 | - (NSString *)testGIFPath {
161 | NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
162 | return [testBundle pathForResource:@"TestImage" ofType:@"gif"];
163 | }
164 |
165 | - (NSData *)testGIFData {
166 | NSData *testData = [NSData dataWithContentsOfFile:[self testGIFPath]];
167 | return testData;
168 | }
169 |
170 | @end
171 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # SDWebImagePhotosPlugin
2 |
3 | [](https://travis-ci.org/SDWebImage/SDWebImagePhotosPlugin)
4 | [](https://cocoapods.org/pods/SDWebImagePhotosPlugin)
5 | [](https://cocoapods.org/pods/SDWebImagePhotosPlugin)
6 | [](https://cocoapods.org/pods/SDWebImagePhotosPlugin)
7 | [](https://github.com/SDWebImage/SDWebImagePhotosPlugin)
8 | [](https://swift.org/package-manager/)
9 | [](https://codecov.io/gh/SDWebImage/SDWebImagePhotosPlugin)
10 |
11 | ## What it's for
12 | SDWebImagePhotosPlugin is a plugin for the [SDWebImage](https://github.com/rs/SDWebImage/) framework, which provides image loading support for the [Photos Library](https://developer.apple.com/documentation/photokit).
13 |
14 | This plugin allows you to use your familiar View Category method from SDWebImage, for loading Photos images with `PHAsset` or `localIdentifier`.
15 |
16 |
17 | ## Requirements
18 |
19 | + iOS 9+
20 | + macOS 10.13+
21 | + tvOS 10+
22 | + Xcode 10+
23 |
24 | ## Installation
25 |
26 | #### CocoaPods
27 |
28 | SDWebImagePhotosPlugin is available through [CocoaPods](https://cocoapods.org). To install
29 | it, simply add the following line to your Podfile:
30 |
31 | ```ruby
32 | pod 'SDWebImagePhotosPlugin'
33 | ```
34 |
35 | #### Carthage
36 |
37 | SDWebImagePhotosPlugin is available through [Carthage](https://github.com/Carthage/Carthage).
38 |
39 | ```
40 | github "SDWebImage/SDWebImagePhotosPlugin"
41 | ```
42 |
43 | #### Swift Package Manager (Xcode 11+)
44 |
45 | SDWebImagePhotosPlugin is available through [Swift Package Manager](https://swift.org/package-manager).
46 |
47 | ```swift
48 | let package = Package(
49 | dependencies: [
50 | .package(url: "https://github.com/SDWebImage/SDWebImagePhotosPlugin.git", from: "1.0")
51 | ]
52 | )
53 | ```
54 |
55 | ## Usage
56 | **Important!** To use this Photos Library plugin, you first need to register the photos loader to image manager.
57 |
58 | There are two ways to register the photos loader. One is for temporarily usage (when providing URL is definitely Photos URL but not HTTP URL), and another for global support (don't need any check, supports both HTTP URL as well as Photos URL).
59 |
60 | #### Use custom manager (temporarily)
61 | You can create a custom manager for temporary usage. When you use custom manager, be sure to specify `SDWebImageContextCustomManager` context option with your custom manager for View Category methods.
62 |
63 | + Objective-C
64 |
65 | ```objectivec
66 | // Assign loader to custom manager
67 | SDWebImageManager *manager = [[SDWebImageManager alloc] initWithCache:SDImageCache.sharedImageCache loader:SDImagePhotosLoader.sharedLoader];
68 | ```
69 |
70 | + Swift
71 |
72 | ```swift
73 | // Assign loader to custom manager
74 | let manager = SDWebImageManager(cache: SDImageCache.shared, loader: SDImagePhotosLoader.shared)
75 | ```
76 |
77 | #### Use loaders manager (globally)
78 | You can replace the default manager's loader implementation using [loaders manager](https://github.com/rs/SDWebImage/wiki/Advanced-Usage#loaders-manager) to support both HTTP && Photos URL globally. Put these code just at the application launch time (or some time just before `SDWebImageManager.sharedManager` is initialized).
79 |
80 | + Objective-C
81 |
82 | ```objectivec
83 | // Supports HTTP URL as well as Photos URL globally
84 | SDImageLoadersManager.sharedManager.loaders = @[SDWebImageDownloader.sharedDownloader, SDImagePhotosLoader.sharedLoader];
85 | // Replace default manager's loader implementation
86 | SDWebImageManager.defaultImageLoader = SDImageLoadersManager.sharedManager;
87 | ```
88 |
89 | + Swift
90 |
91 | ```swift
92 | // Supports HTTP URL as well as Photos URL globally
93 | SDImageLoadersManager.shared.loaders = [SDWebImageDownloader.shared, SDImagePhotosLoader.shared]
94 | // Replace default manager's loader implementation
95 | SDWebImageManager.defaultImageLoader = SDImageLoadersManager.shared
96 | ```
97 |
98 | #### Load Images
99 | To start loading the Photos Library image, use the `NSURL+SDWebImagePhotosPlugin` to create a Photos URL and call View Category method.
100 |
101 | + Objective-C
102 |
103 | ```objectivec
104 | // Create with `PHAsset`
105 | PHAsset *asset;
106 | NSURL *photosURL = asset.sd_URLRepresentation;
107 | // The same as `[NSURL sd_URLWithAsset:asset];`
108 | // Create with `localIdentifier`
109 | NSString *identifier;
110 | NSURL *potosURL = [NSURL sd_URLWithAssetLocalIdentifier:identifier];
111 |
112 | // Load image (assume using custom manager)
113 | [imageView sd_setImageWithURL:photosURL placeholderImage:nil context:@{SDWebImageContextCustomManager: manager}];
114 | ```
115 |
116 | + Swift
117 |
118 | ```swift
119 | // Create with `PHAsset`
120 | let asset: PHAsset
121 | let photosURL = asset.sd_URLRepresentation
122 | // The same as `NSURL.sd_URL(with: asset) as URL`
123 | // Create with `localIdentifier`
124 | let identifier: String
125 | let potosURL = NSURL.sd_URL(withAssetLocalIdentifier: identifier) as URL
126 |
127 | // Load image (assume using custom manager)
128 | imageView.sd_setImage(with: photosURL, placeholderImage: nil, context: [.customManager: manager])
129 | ```
130 |
131 | #### Animated Images
132 | SDWebImagePhotosPlugin supports GIF images stored in Photos Library as well. Just use the same API as normal images to query the asset. We will query the image data and decode the animated images (compatible with `UIImageView` as well as [SDAnimatedImageView](https://github.com/rs/SDWebImage/wiki/Advanced-Usage#animated-image-50))
133 |
134 |
135 | #### Video Assets
136 | SDWebImagePhotosPlugin supports loading Video Asset poster as well. By default, we don't allow non-image type assets, to avoid accidentally picking a wrong Asset. But you can disable this limit as well.
137 |
138 | + Objective-C
139 |
140 | ```objectivec
141 | SDImagePhotosLoader.sharedLoader.requestImageAssetOnly = NO;
142 | ```
143 |
144 | + Swift
145 |
146 | ```swift
147 | SDImagePhotosLoader.shared.requestImageAssetOnly = false
148 | ```
149 |
150 | Then just request the PHAssets or using the fetch options, which the media type is `.video`.
151 |
152 | #### HDR Photo Rendering
153 | To enable HDR decoding and rendering, upgrade SDWebImage to 5.21.0+, then, request the image data from Photos Library and turn on HDR decoding.
154 |
155 | + Objective-C
156 |
157 | ```objective-c
158 | #if TARGET_OS_OSX
159 | BOOL supportsHDR = NSScreen.mainScreen.maximumPotentialExtendedDynamicRangeColorComponentValue > 1.0;
160 | #else
161 | #define NSImageDynamicRangeHigh UIImageDynamicRangeHigh
162 | BOOL supportsHDR = UIScreen.mainScreen.potentialEDRHeadroom > 1.0;
163 | #endif
164 | SDWebImageMutableContext *context = [@{SDWebImageContextStoreCacheType: @(SDImageCacheTypeNone)} mutableCopy];
165 | if (supportsHDR) {
166 | if (@available (macOS 14.0, iOS 17, *)) {
167 | cell.imageViewDisplay.preferredImageDynamicRange = NSImageDynamicRangeHigh; // Enable Image View Level control for HDR
168 | }
169 | context[SDWebImageContextPhotosRequestImageData] = @(YES); // Photos Library only load HDR info when requestImageData
170 | context[SDWebImageContextImageDecodeToHDR] = @(YES); // When decoding HDR data, we need explicit enable HDR decoding
171 | }
172 | // Then loading HDR assets with context option
173 | [imageView sd_setImageWithURL:photosURL placeholderImage:nil context:context];
174 | ```
175 |
176 | + Swift
177 |
178 | ```swift
179 | #if os(macOS)
180 | let supportsHDR = NSScreen.main.maximumPotentialExtendedDynamicRangeColorComponentValue > 1.0
181 | #else
182 | let supportsHDR = UIScreen.main.potentialEDRHeadroom > 1.0
183 | #endif
184 | var context = [
185 | SDWebImageContextStoreCacheType: SDImageCacheType.none.rawValue
186 | ]
187 | if supportsHDR {
188 | if #available(macOS 14.0, iOS 17, *) {
189 | cell.imageViewDisplay.preferredImageDynamicRange = .high // Enable Image View Level control for HDR
190 | }
191 | context[.photosRequestImageData] = true // Photos Library only load HDR info when requestImageData
192 | context[.imageDecodeToHDR] = true // When decoding HDR data, we need explicit enable HDR decoding
193 | }
194 | // Then loading HDR assets with context option
195 | imageView.sd_setImage(with: photosURL, placeholderImage: nil, context:context)
196 | ```
197 |
198 | #### Fetch/Request Options
199 | To specify options like `PHFetchOptions` or `PHImageRequestOptions` for Photos Library. Either to change the correspond properties in loader, or provide a context options for each image request.
200 |
201 | + Objective-C
202 |
203 | ```objectivec
204 | // loader-level options
205 | // ignore iCloud Shared Album (`localIdentifier` Photos URL only)
206 | PHFetchOptions *fetchOptions = SDImagePhotosLoader.sharedLoader.fetchOptions;
207 | fetchOptions.predicate = [NSPredicate predicateWithFormat:@"sourceType != %d", PHAssetSourceTypeCloudShared];
208 |
209 | // request-level options
210 | // disable iCloud Photos Library (networkAccessAllowed defaults to YES)
211 | PHImageRequestOptions *requestOptions = [PHImageRequestOptions new];
212 | requestOptions.networkAccessAllowed = NO;
213 | [imageView sd_setImageWithURL:photosURL placeholderImage:nil context:@{SDWebImageContextPhotosImageRequestOptions: requestOptions, SDWebImageContextCustomManager: manager}];
214 | ```
215 |
216 | + Swift
217 |
218 | ```swift
219 | // loader-level options
220 | // ignore iCloud Shared Album (`localIdentifier` Photos URL only)
221 | let fetchOptions = SDImagePhotosLoader.shared.fetchOptions
222 | fetchOptions.predicate = NSPredicate(format: "sourceType != %d", PHAssetSourceType.typeCloudShared.rawValue)
223 |
224 | // request-level options
225 | // disable iCloud Photos Library (networkAccessAllowed defaults to YES)
226 | let requestOptions = PHImageRequestOptions()
227 | requestOptions.networkAccessAllowed = false
228 | imageView.sd_setImage(with: photosURL, placeholderImage: nil, context:[.photosImageRequestOptions: requestOptions, .customManager: manager])
229 | ```
230 |
231 | #### Control Query Image Size
232 | Photos taken by the iPhone camera may have a really large pixel size (4K+). So, if you want to load large Photos Library assets for rendering, you should specify target size with a limited size (for example, the size of the imageView that you are loading into).
233 |
234 | By default, we query the target size that matches the original image's largest size (see: [PHImageManagerMaximumSize](https://developer.apple.com/documentation/photokit/phimagemanagermaximumsize?language=objc)), which may consume too much memory on iOS devices. There are also two built-in dynamic values `SDWebImagePhotosPixelSize/SDWebImagePhotosPointSize` which are suitable for some cases.
235 |
236 | You can change the fetch image size by either using the `PHImageRequestOptions.sd_targetSize`, or [Thumbnail Decoding](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#thumbnail-decoding-550) via `.imageThumbnailPixelSize` context option.
237 |
238 | Control query image size limit in global:
239 |
240 | + Objective-C
241 |
242 | ```objective-c
243 | SDImagePhotosLoader.sharedLoader.imageRequestOptions.sd_targetSize = CGSizeMake(1000, 1000); // Limit 1000x1000 pixels
244 | ```
245 |
246 | + Swift
247 |
248 | ```swift
249 | SDImagePhotosLoader.shared.imageRequestOptions.sd_targetSize = CGSize(width: 1000, height: 1000) // Limit 1000x1000 pixels
250 | ```
251 |
252 | Control query image size for individual assets:
253 |
254 | + Objective-C
255 |
256 | ```objective-c
257 | UIImageView *imageView;
258 | PHAsset *asset;
259 | NSURL *url = asset.sd_URLRepresentation;
260 | [imageView.sd_setImageWithURL:url options:0 context:@{SDWebImageContextImageThumbnailPixelSize: @(imageView.bounds.size)}]; // Fetch image based on image view size
261 | ```
262 |
263 | + Swift
264 |
265 | ```swift
266 | let imageView: UIImageView
267 | let asset: PHAsset
268 | let url = asset.sd_URLRepresentation
269 | imageView.sd_setImage(with: url, context: [.imageThumbnailPixelSize : imageView.bounds.size]) // Fetch image based on image view size
270 | ```
271 |
272 | Note: You can also use `SDWebImageContextPhotosImageRequestOptions` as shown above. But the thumbnail pixel size can be used for normal Network URL as well, which can help you to unify the logic for HTTP URL and PHAsset URL.
273 |
274 |
275 | ## Tips
276 |
277 | 1. Images from the Photos Library are already stored on the device disk, and query speed is fast enough for small resolution images, so cache storage might be unnecessary. You can use `SDWebImageContextStoreCacheType` with `SDImageCacheTypeNone` to disable cache storage, and use `SDWebImageFromLoaderOnly` to disable cache queries.
278 | 2. If you use `PHImageRequestOptionsDeliveryModeOpportunistic` (default) to load the image, PhotosKit will return a degraded thumbnail image first and again with the full pixel image. When the image is degraded, the loader completion block will set `finished = NO`. However, this will not trigger the View Category completion block, and only trigger a image refresh (like progressive loading behavior for network image using `SDWebImageProgressiveLoad`)
279 | 3. By default, we will prefer using Photos [requestImageForAsset:targetSize:contentMode:options:resultHandler:](https://developer.apple.com/documentation/photokit/phimagemanager/1616964-requestimageforasset?language=objc) API for normal images, using [requestImageDataForAsset:options:resultHandler:](https://developer.apple.com/documentation/photokit/phimagemanager/1616957-requestimagedataforasset?language=objc) for animated images like GIF asset. If you need the raw image data for further image processing, you can always pass the `SDWebImageContextPhotosRequestImageData` context option to force using the request data API instead. Note that when requesting data, the `targetSize` and `contentMode` options are ignored. If you need smaller image sizes, consider using [Image Transformer](https://github.com/SDWebImage/SDWebImage/wiki/Advanced-Usage#image-transformer-50) feature from SDWebImage 5.0.
280 |
281 | ## Demo
282 |
283 | If you have some issue about usage, SDWebImagePhotosPlugin provide a demo for iOS & macOS platform. To run the demo, clone the repo and run the following command.
284 |
285 | ```bash
286 | cd Example/
287 | pod install
288 | open SDWebImagePhotosPlugin.xcworkspace
289 | ```
290 |
291 | After the Xcode project is opened, click Run to build and run the demo.
292 |
293 | ## Author
294 |
295 | DreamPiggy, lizhuoli1126@126.com
296 |
297 | ## License
298 |
299 | SDWebImagePhotosPlugin is available under the MIT license. See the LICENSE file for more info.
300 |
301 |
302 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin/Classes/SDImagePhotosLoader.m:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of the SDWebImage package.
3 | * (c) Olivier Poitrey
4 | *
5 | * For the full copyright and license information, please view the LICENSE
6 | * file that was distributed with this source code.
7 | */
8 |
9 | #import "SDImagePhotosLoader.h"
10 | #import "SDWebImagePhotosDefine.h"
11 | #import "NSURL+SDWebImagePhotosPlugin.h"
12 | #import "PHImageRequestOptions+SDWebImagePhotosPlugin.h"
13 | #import "SDWebImagePhotosError.h"
14 | #import
15 |
16 | // Compatible
17 | #if SD_UIKIT
18 | #import
19 | typedef UIImageOrientation SDImageOrientation;
20 | #else
21 | typedef CGImagePropertyOrientation SDImageOrientation;
22 | #endif
23 | // This protocol is used to fix the Xcode 11's API declaration for macOS. Which should be available on macOS 10.13
24 | @protocol PHImageManager
25 | - (PHImageRequestID)requestImageDataForAsset:(PHAsset *)asset options:(nullable PHImageRequestOptions *)options resultHandler:(void(^)(NSData *__nullable imageData, NSString *__nullable dataUTI, SDImageOrientation orientation, NSDictionary *__nullable info))resultHandler;
26 | @end
27 | @interface PHImageManager ()
28 | @end
29 |
30 | @interface SDImagePhotosLoaderOperation : NSObject
31 |
32 | @property (nonatomic, assign) PHImageRequestID requestID;
33 | @property (nonatomic, getter=isCancelled) BOOL cancelled;
34 |
35 | @end
36 |
37 | @implementation SDImagePhotosLoaderOperation
38 |
39 | - (void)cancel {
40 | [[PHImageManager defaultManager] cancelImageRequest:self.requestID];
41 | self.cancelled = YES;
42 | }
43 |
44 | @end
45 |
46 | @interface SDImagePhotosLoader ()
47 |
48 | @property (nonatomic, strong, nonnull) NSHashTable *operationsTable;
49 | @property (nonatomic, strong, nonnull) dispatch_queue_t fetchQueue;
50 |
51 | @end
52 |
53 | @implementation SDImagePhotosLoader
54 |
55 | - (void)dealloc {
56 | #if SD_UIKIT
57 | [[NSNotificationCenter defaultCenter] removeObserver:self];
58 | #endif
59 | }
60 |
61 | + (SDImagePhotosLoader *)sharedLoader {
62 | static dispatch_once_t onceToken;
63 | static SDImagePhotosLoader *loader;
64 | dispatch_once(&onceToken, ^{
65 | loader = [[SDImagePhotosLoader alloc] init];
66 | });
67 | return loader;
68 | }
69 |
70 | - (instancetype)init {
71 | self = [super init];
72 | if (self) {
73 | PHImageRequestOptions *requestOptions = [PHImageRequestOptions new];
74 | requestOptions.networkAccessAllowed = YES;
75 | requestOptions.resizeMode = PHImageRequestOptionsResizeModeFast;
76 | requestOptions.deliveryMode = PHImageRequestOptionsDeliveryModeOpportunistic;
77 | requestOptions.version = PHImageRequestOptionsVersionCurrent;
78 | self.imageRequestOptions = requestOptions;
79 | self.operationsTable = [NSHashTable weakObjectsHashTable];
80 | self.requestImageAssetOnly = YES;
81 | self.fetchQueue = dispatch_queue_create("SDImagePhotosLoader", DISPATCH_QUEUE_SERIAL);
82 | #if SD_UIKIT
83 | [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(didReceiveMemoryWarning:) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
84 | #endif
85 | }
86 | return self;
87 | }
88 |
89 | #if SD_UIKIT
90 | - (void)didReceiveMemoryWarning:(NSNotification *)notification {
91 | for (SDImagePhotosLoaderOperation *operation in self.operationsTable) {
92 | [operation cancel];
93 | }
94 | [self.operationsTable removeAllObjects];
95 | }
96 | #endif
97 |
98 | #pragma mark - Helper
99 | + (BOOL)isAnimatedImageWithUTType:(NSString *)UTType {
100 | if (!UTType) {
101 | return NO;
102 | }
103 | if ([UTType isEqualToString:(__bridge_transfer NSString *)kUTTypeGIF]) {
104 | return YES;
105 | }
106 |
107 | return NO;
108 | }
109 |
110 | + (BOOL)isPhotosStatusAuthorized {
111 | return [PHPhotoLibrary authorizationStatus] == PHAuthorizationStatusAuthorized;
112 | }
113 |
114 | #pragma mark - SDImageLoader
115 |
116 | - (BOOL)canRequestImageForURL:(NSURL *)url {
117 | return url.sd_isPhotosURL;
118 | }
119 |
120 | - (id)requestImageWithURL:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock {
121 | BOOL isPhotosURL = url.sd_isPhotosURL;
122 | if (!isPhotosURL) {
123 | if (completedBlock) {
124 | NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorInvalidURL userInfo:@{NSLocalizedDescriptionKey : @"Photos URL is nil"}];
125 | completedBlock(nil, nil, error, YES);
126 | }
127 | return nil;
128 | }
129 |
130 | if (![[self class] isPhotosStatusAuthorized]) {
131 | if (completedBlock) {
132 | NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorNotAuthorized userInfo:@{NSLocalizedDescriptionKey : @"Photos library access not authorized"}];
133 | completedBlock(nil, nil, error, YES);
134 | }
135 | return nil;
136 | }
137 |
138 | PHFetchOptions *fetchOptions;
139 | if ([context valueForKey:SDWebImageContextPhotosFetchOptions]) {
140 | fetchOptions = [context valueForKey:SDWebImageContextPhotosFetchOptions];
141 | } else {
142 | fetchOptions = self.fetchOptions;
143 | }
144 |
145 | // Begin fetch asset in fetcher queue because this block main queue
146 | SDImagePhotosLoaderOperation *operation = [[SDImagePhotosLoaderOperation alloc] init];
147 | dispatch_async(self.fetchQueue, ^{
148 | if (operation.isCancelled) {
149 | // Cancelled
150 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
151 | if (completedBlock) {
152 | completedBlock(nil, nil, error, YES);
153 | }
154 | return;
155 | }
156 | PHAsset *asset = url.sd_asset;
157 | if (!asset) {
158 | NSString *localIdentifier = url.sd_assetLocalIdentifier;
159 | PHFetchResult *fetchResult = [PHAsset fetchAssetsWithLocalIdentifiers:@[localIdentifier] options:fetchOptions];
160 | asset = fetchResult.firstObject;
161 | if (!asset) {
162 | NSString *desc = [NSString stringWithFormat:@"Invalid PHAsset localIdentifier: %@", localIdentifier];
163 | NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorInvalidLocalIdentifier userInfo:@{NSLocalizedDescriptionKey: desc}];
164 | if (completedBlock) {
165 | completedBlock(nil, nil, error, YES);
166 | }
167 | return;
168 | }
169 | }
170 | // Check whether we should request only image asset
171 | if (self.requestImageAssetOnly && asset.mediaType != PHAssetMediaTypeImage) {
172 | // Call error
173 | NSString *desc = [NSString stringWithFormat:@"Unsupported PHAsset localIdentifier: %d, PHAssetMediaType: %d", asset.localIdentifier, asset.mediaType];
174 | NSError *error = [NSError errorWithDomain:SDWebImagePhotosErrorDomain code:SDWebImagePhotosErrorNotImageAsset userInfo:@{NSLocalizedDescriptionKey: desc}];
175 | if (completedBlock) {
176 | completedBlock(nil, nil, error, YES);
177 | }
178 | return;
179 | }
180 |
181 | // Request image data instead of image
182 | BOOL requestImageData;
183 | if (context[SDWebImageContextPhotosRequestImageData]) {
184 | requestImageData = [context[SDWebImageContextPhotosRequestImageData] boolValue];
185 | } else {
186 | // Check UTType
187 | NSString *uniformTypeIdentifier;
188 | if ([asset respondsToSelector:@selector(uniformTypeIdentifier)]) {
189 | uniformTypeIdentifier = [asset valueForKey:NSStringFromSelector(@selector(uniformTypeIdentifier))];
190 | }
191 | // Check Animated Image, which need the original image data
192 | requestImageData = [[self class] isAnimatedImageWithUTType:uniformTypeIdentifier];
193 | }
194 |
195 | if (requestImageData) {
196 | [self fetchImageDataWithAsset:asset operation:operation url:url options:options context:context progress:progressBlock completed:completedBlock];
197 | } else {
198 | [self fetchImageWithAsset:asset operation:operation url:url options:options context:context progress:progressBlock completed:completedBlock];
199 | }
200 | });
201 | [self.operationsTable addObject:operation];
202 |
203 | return operation;
204 | }
205 |
206 | - (BOOL)shouldBlockFailedURLWithURL:(NSURL *)url error:(NSError *)error {
207 | BOOL shouldBlockFailedURL = NO;
208 | if ([error.domain isEqualToString:SDWebImageErrorDomain]) {
209 | shouldBlockFailedURL = error.code == SDWebImageErrorInvalidURL
210 | || error.code == SDWebImageErrorBadImageData;
211 | } else if ([error.domain isEqualToString:SDWebImagePhotosErrorDomain]) {
212 | shouldBlockFailedURL = error.code == SDWebImagePhotosErrorNotImageAsset;
213 | }
214 | return shouldBlockFailedURL;
215 | }
216 |
217 | // This is used for normal image loading (With `requestImage:` API)
218 | - (void)fetchImageWithAsset:(PHAsset *)asset operation:(SDImagePhotosLoaderOperation *)operation url:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock {
219 | PHImageRequestOptions *requestOptions;
220 | if ([context valueForKey:SDWebImageContextPhotosImageRequestOptions]) {
221 | requestOptions = [context valueForKey:SDWebImageContextPhotosImageRequestOptions];
222 | } else {
223 | requestOptions = self.imageRequestOptions;
224 | }
225 | CGSize targetSize;
226 | PHImageContentMode contentMode;
227 | // Check Thumbnail
228 | if ([context valueForKey:SDWebImageContextImageThumbnailPixelSize]) {
229 | NSValue *thumbnailSizeValue = [context valueForKey:SDWebImageContextImageThumbnailPixelSize];
230 | #if SD_MAC
231 | targetSize = thumbnailSizeValue.sizeValue;
232 | #else
233 | targetSize = thumbnailSizeValue.CGSizeValue;
234 | #endif
235 | BOOL preserveAspectRatio = YES;
236 | if ([context valueForKey:SDWebImageContextImagePreserveAspectRatio]) {
237 | preserveAspectRatio = [[context valueForKey:SDWebImageContextImagePreserveAspectRatio] boolValue];
238 | }
239 | contentMode = preserveAspectRatio ? PHImageContentModeAspectFit : PHImageContentModeAspectFill;
240 | } else {
241 | // Use request options
242 | targetSize = requestOptions.sd_targetSize;
243 | if (CGSizeEqualToSize(targetSize, SDWebImagePhotosPixelSize)) {
244 | targetSize = CGSizeMake(asset.pixelWidth, asset.pixelHeight);
245 | } else if (CGSizeEqualToSize(targetSize, SDWebImagePhotosPointSize)) {
246 | CGFloat scale = 1;
247 | NSNumber *scaleValue = [context valueForKey:SDWebImageContextImageScaleFactor];
248 | if (scaleValue) {
249 | scale = scaleValue.doubleValue;
250 | if (scale < 1) {
251 | scale = 1;
252 | }
253 | } else {
254 | #if SD_MAC
255 | scale = [NSScreen mainScreen].backingScaleFactor;
256 | #else
257 | scale = [UIScreen mainScreen].scale;
258 | #endif
259 | }
260 | targetSize = CGSizeMake(asset.pixelHeight * scale, asset.pixelHeight * scale);
261 | }
262 | contentMode = requestOptions.sd_contentMode;
263 | }
264 |
265 | // Progerss Handler
266 | if (progressBlock) {
267 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
268 | // Global queue, the same as us
269 | if (progressBlock) {
270 | progressBlock(progress * SDWebImagePhotosProgressExpectedSize, SDWebImagePhotosProgressExpectedSize, url);
271 | }
272 | };
273 | }
274 |
275 | __weak typeof(operation) weakOperation = operation;
276 | PHImageRequestID requestID = [[PHImageManager defaultManager] requestImageForAsset:asset targetSize:targetSize contentMode:contentMode options:requestOptions resultHandler:^(UIImage * _Nullable result, NSDictionary * _Nullable info) {
277 | if (weakOperation.isCancelled || [info[PHImageCancelledKey] boolValue]) {
278 | // Cancelled
279 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
280 | if (completedBlock) {
281 | completedBlock(nil, nil, error, YES);
282 | }
283 | return;
284 | }
285 | if (result) {
286 | BOOL isDegraded = [info[PHImageResultIsDegradedKey] boolValue];
287 | BOOL finished;
288 | if (requestOptions.deliveryMode == PHImageRequestOptionsDeliveryModeOpportunistic) {
289 | // The completion block may call multiple times. Only pass YES when `isDegraded` set to NO
290 | finished = !isDegraded;
291 | } else {
292 | finished = YES;
293 | }
294 | dispatch_main_async_safe(^{
295 | if (completedBlock) {
296 | completedBlock(result, nil, nil, finished);
297 | }
298 | });
299 | } else {
300 | NSError *error = info[PHImageErrorKey];
301 | dispatch_main_async_safe(^{
302 | if (completedBlock) {
303 | completedBlock(nil, nil, error, YES);
304 | }
305 | });
306 | }
307 | }];
308 |
309 | operation.requestID = requestID;
310 | }
311 |
312 | // This is used for animated image loading (With `requestImageData:` API)
313 | - (void)fetchImageDataWithAsset:(PHAsset *)asset operation:(SDImagePhotosLoaderOperation *)operation url:(NSURL *)url options:(SDWebImageOptions)options context:(SDWebImageContext *)context progress:(SDImageLoaderProgressBlock)progressBlock completed:(SDImageLoaderCompletedBlock)completedBlock {
314 | PHImageRequestOptions *requestOptions;
315 | if ([context valueForKey:SDWebImageContextPhotosImageRequestOptions]) {
316 | requestOptions = [context valueForKey:SDWebImageContextPhotosImageRequestOptions];
317 | } else {
318 | requestOptions = self.imageRequestOptions;
319 | }
320 |
321 | // Progerss Handler
322 | if (progressBlock) {
323 | requestOptions.progressHandler = ^(double progress, NSError * _Nullable error, BOOL * _Nonnull stop, NSDictionary * _Nullable info) {
324 | // Global queue, the same as us
325 | if (progressBlock) {
326 | progressBlock(progress * SDWebImagePhotosProgressExpectedSize, SDWebImagePhotosProgressExpectedSize, url);
327 | }
328 | };
329 | }
330 |
331 | __weak typeof(operation) weakOperation = operation;
332 | PHImageRequestID requestID = [(id)[PHImageManager defaultManager] requestImageDataForAsset:asset options:requestOptions resultHandler:^(NSData * _Nullable imageData, NSString * _Nullable dataUTI, SDImageOrientation orientation, NSDictionary * _Nullable info) {
333 | if (weakOperation.isCancelled || [info[PHImageCancelledKey] boolValue]) {
334 | // Cancelled
335 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
336 | if (completedBlock) {
337 | completedBlock(nil, nil, error, YES);
338 | }
339 | return;
340 | }
341 | if (imageData) {
342 | // Decode the image with data
343 | dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
344 | if (weakOperation.isCancelled) {
345 | // Cancelled
346 | NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorCancelled userInfo:nil];
347 | if (completedBlock) {
348 | completedBlock(nil, nil, error, YES);
349 | }
350 | return;
351 | }
352 | UIImage *image = SDImageLoaderDecodeImageData(imageData, url, options, context);
353 | NSError *error;
354 | if (!image) {
355 | error = [NSError errorWithDomain:SDWebImageErrorDomain code:SDWebImageErrorBadImageData userInfo:nil];
356 | }
357 | dispatch_async(dispatch_get_main_queue(), ^{
358 | if (completedBlock) {
359 | completedBlock(image, imageData, error, YES);
360 | }
361 | });
362 | });
363 | } else {
364 | NSError *error = info[PHImageErrorKey];
365 | dispatch_main_async_safe(^{
366 | if (completedBlock) {
367 | completedBlock(nil, nil, error, YES);
368 | }
369 | })
370 | }
371 | }];
372 |
373 | operation.requestID = requestID;
374 | }
375 |
376 | @end
377 |
--------------------------------------------------------------------------------
/SDWebImagePhotosPlugin.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 3235B28021FAD1E6008668C5 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3235B27F21FAD1E6008668C5 /* Photos.framework */; };
11 | 3235B28221FAD1ED008668C5 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3235B28121FAD1ED008668C5 /* Photos.framework */; };
12 | 3235B28421FAD1F5008668C5 /* Photos.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3235B28321FAD1F5008668C5 /* Photos.framework */; };
13 | 32380B5425B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32380B5225B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
14 | 32380B5525B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32380B5225B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
15 | 32380B5625B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32380B5225B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
16 | 32380B5725B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32380B5325B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m */; };
17 | 32380B5825B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32380B5325B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m */; };
18 | 32380B5925B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32380B5325B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m */; };
19 | 32CCEA13213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA12213E38CD00214381 /* SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
20 | 32CCEA14213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA12213E38CD00214381 /* SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
21 | 32CCEA15213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA12213E38CD00214381 /* SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
22 | 32CCEA25213E38F600214381 /* SDImagePhotosLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1B213E38F600214381 /* SDImagePhotosLoader.m */; };
23 | 32CCEA26213E38F600214381 /* SDImagePhotosLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1B213E38F600214381 /* SDImagePhotosLoader.m */; };
24 | 32CCEA27213E38F600214381 /* SDImagePhotosLoader.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1B213E38F600214381 /* SDImagePhotosLoader.m */; };
25 | 32CCEA28213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1C213E38F600214381 /* SDWebImagePhotosDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };
26 | 32CCEA29213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1C213E38F600214381 /* SDWebImagePhotosDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };
27 | 32CCEA2A213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1C213E38F600214381 /* SDWebImagePhotosDefine.h */; settings = {ATTRIBUTES = (Public, ); }; };
28 | 32CCEA2B213E38F600214381 /* SDWebImagePhotosError.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1D213E38F600214381 /* SDWebImagePhotosError.m */; };
29 | 32CCEA2C213E38F600214381 /* SDWebImagePhotosError.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1D213E38F600214381 /* SDWebImagePhotosError.m */; };
30 | 32CCEA2D213E38F600214381 /* SDWebImagePhotosError.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1D213E38F600214381 /* SDWebImagePhotosError.m */; };
31 | 32CCEA2E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m */; };
32 | 32CCEA2F213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m */; };
33 | 32CCEA30213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA1E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m */; };
34 | 32CCEA31213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1F213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
35 | 32CCEA32213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1F213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
36 | 32CCEA33213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA1F213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
37 | 32CCEA34213E38F600214381 /* SDImagePhotosLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA20213E38F600214381 /* SDImagePhotosLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
38 | 32CCEA35213E38F600214381 /* SDImagePhotosLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA20213E38F600214381 /* SDImagePhotosLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
39 | 32CCEA36213E38F600214381 /* SDImagePhotosLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA20213E38F600214381 /* SDImagePhotosLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
40 | 32CCEA37213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA21213E38F600214381 /* SDWebImagePhotosDefine.m */; };
41 | 32CCEA38213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA21213E38F600214381 /* SDWebImagePhotosDefine.m */; };
42 | 32CCEA39213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA21213E38F600214381 /* SDWebImagePhotosDefine.m */; };
43 | 32CCEA3A213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA22213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m */; };
44 | 32CCEA3B213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA22213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m */; };
45 | 32CCEA3C213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */ = {isa = PBXBuildFile; fileRef = 32CCEA22213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m */; };
46 | 32CCEA3D213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA23213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
47 | 32CCEA3E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA23213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
48 | 32CCEA3F213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA23213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
49 | 32CCEA40213E38F600214381 /* SDWebImagePhotosError.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA24213E38F600214381 /* SDWebImagePhotosError.h */; settings = {ATTRIBUTES = (Public, ); }; };
50 | 32CCEA41213E38F600214381 /* SDWebImagePhotosError.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA24213E38F600214381 /* SDWebImagePhotosError.h */; settings = {ATTRIBUTES = (Public, ); }; };
51 | 32CCEA42213E38F600214381 /* SDWebImagePhotosError.h in Headers */ = {isa = PBXBuildFile; fileRef = 32CCEA24213E38F600214381 /* SDWebImagePhotosError.h */; settings = {ATTRIBUTES = (Public, ); }; };
52 | 32CCEA45213E431000214381 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32CCEA44213E431000214381 /* SDWebImage.framework */; };
53 | 32CCEA47213E431E00214381 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32CCEA46213E431E00214381 /* SDWebImage.framework */; };
54 | 32CCEA49213E432A00214381 /* SDWebImage.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 32CCEA48213E432900214381 /* SDWebImage.framework */; };
55 | /* End PBXBuildFile section */
56 |
57 | /* Begin PBXFileReference section */
58 | 3235B27F21FAD1E6008668C5 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; };
59 | 3235B28121FAD1ED008668C5 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = Platforms/AppleTVOS.platform/Developer/SDKs/AppleTVOS12.1.sdk/System/Library/Frameworks/Photos.framework; sourceTree = DEVELOPER_DIR; };
60 | 3235B28321FAD1F5008668C5 /* Photos.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Photos.framework; path = System/Library/Frameworks/Photos.framework; sourceTree = SDKROOT; };
61 | 32380B5225B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "PHAsset+SDWebImagePhotosPlugin.h"; sourceTree = ""; };
62 | 32380B5325B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = "PHAsset+SDWebImagePhotosPlugin.m"; sourceTree = ""; };
63 | 32CCE9E8213E383E00214381 /* SDWebImagePhotosPlugin.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImagePhotosPlugin.framework; sourceTree = BUILT_PRODUCTS_DIR; };
64 | 32CCE9F8213E384500214381 /* SDWebImagePhotosPlugin_tvOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImagePhotosPlugin_tvOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65 | 32CCEA05213E385A00214381 /* SDWebImagePhotosPlugin_macOS.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = SDWebImagePhotosPlugin_macOS.framework; sourceTree = BUILT_PRODUCTS_DIR; };
66 | 32CCEA12213E38CD00214381 /* SDWebImagePhotosPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDWebImagePhotosPlugin.h; path = Module/SDWebImagePhotosPlugin.h; sourceTree = ""; };
67 | 32CCEA16213E38D000214381 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = Module/Info.plist; sourceTree = ""; };
68 | 32CCEA1B213E38F600214381 /* SDImagePhotosLoader.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImagePhotosLoader.m; sourceTree = ""; };
69 | 32CCEA1C213E38F600214381 /* SDWebImagePhotosDefine.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImagePhotosDefine.h; sourceTree = ""; };
70 | 32CCEA1D213E38F600214381 /* SDWebImagePhotosError.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImagePhotosError.m; sourceTree = ""; };
71 | 32CCEA1E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSURL+SDWebImagePhotosPlugin.m"; sourceTree = ""; };
72 | 32CCEA1F213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "PHImageRequestOptions+SDWebImagePhotosPlugin.h"; sourceTree = ""; };
73 | 32CCEA20213E38F600214381 /* SDImagePhotosLoader.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDImagePhotosLoader.h; sourceTree = ""; };
74 | 32CCEA21213E38F600214381 /* SDWebImagePhotosDefine.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImagePhotosDefine.m; sourceTree = ""; };
75 | 32CCEA22213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "PHImageRequestOptions+SDWebImagePhotosPlugin.m"; sourceTree = ""; };
76 | 32CCEA23213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSURL+SDWebImagePhotosPlugin.h"; sourceTree = ""; };
77 | 32CCEA24213E38F600214381 /* SDWebImagePhotosError.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDWebImagePhotosError.h; sourceTree = ""; };
78 | 32CCEA44213E431000214381 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/Mac/SDWebImage.framework; sourceTree = ""; };
79 | 32CCEA46213E431E00214381 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/tvOS/SDWebImage.framework; sourceTree = ""; };
80 | 32CCEA48213E432900214381 /* SDWebImage.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = SDWebImage.framework; path = Carthage/Build/iOS/SDWebImage.framework; sourceTree = ""; };
81 | /* End PBXFileReference section */
82 |
83 | /* Begin PBXFrameworksBuildPhase section */
84 | 32CCE9E4213E383E00214381 /* Frameworks */ = {
85 | isa = PBXFrameworksBuildPhase;
86 | buildActionMask = 2147483647;
87 | files = (
88 | 3235B28421FAD1F5008668C5 /* Photos.framework in Frameworks */,
89 | 32CCEA49213E432A00214381 /* SDWebImage.framework in Frameworks */,
90 | );
91 | runOnlyForDeploymentPostprocessing = 0;
92 | };
93 | 32CCE9F4213E384500214381 /* Frameworks */ = {
94 | isa = PBXFrameworksBuildPhase;
95 | buildActionMask = 2147483647;
96 | files = (
97 | 3235B28221FAD1ED008668C5 /* Photos.framework in Frameworks */,
98 | 32CCEA47213E431E00214381 /* SDWebImage.framework in Frameworks */,
99 | );
100 | runOnlyForDeploymentPostprocessing = 0;
101 | };
102 | 32CCEA01213E385A00214381 /* Frameworks */ = {
103 | isa = PBXFrameworksBuildPhase;
104 | buildActionMask = 2147483647;
105 | files = (
106 | 3235B28021FAD1E6008668C5 /* Photos.framework in Frameworks */,
107 | 32CCEA45213E431000214381 /* SDWebImage.framework in Frameworks */,
108 | );
109 | runOnlyForDeploymentPostprocessing = 0;
110 | };
111 | /* End PBXFrameworksBuildPhase section */
112 |
113 | /* Begin PBXGroup section */
114 | 32CCE9DE213E383E00214381 = {
115 | isa = PBXGroup;
116 | children = (
117 | 32CCE9EA213E383E00214381 /* SDWebImagePhotosPlugin */,
118 | 32CCE9E9213E383E00214381 /* Products */,
119 | 32CCEA43213E430F00214381 /* Frameworks */,
120 | );
121 | sourceTree = "";
122 | };
123 | 32CCE9E9213E383E00214381 /* Products */ = {
124 | isa = PBXGroup;
125 | children = (
126 | 32CCE9E8213E383E00214381 /* SDWebImagePhotosPlugin.framework */,
127 | 32CCE9F8213E384500214381 /* SDWebImagePhotosPlugin_tvOS.framework */,
128 | 32CCEA05213E385A00214381 /* SDWebImagePhotosPlugin_macOS.framework */,
129 | );
130 | name = Products;
131 | sourceTree = "";
132 | };
133 | 32CCE9EA213E383E00214381 /* SDWebImagePhotosPlugin */ = {
134 | isa = PBXGroup;
135 | children = (
136 | 32CCEA1A213E38F600214381 /* Classes */,
137 | 32CCEA12213E38CD00214381 /* SDWebImagePhotosPlugin.h */,
138 | 32CCEA16213E38D000214381 /* Info.plist */,
139 | );
140 | path = SDWebImagePhotosPlugin;
141 | sourceTree = "";
142 | };
143 | 32CCEA1A213E38F600214381 /* Classes */ = {
144 | isa = PBXGroup;
145 | children = (
146 | 32CCEA23213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h */,
147 | 32CCEA1E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m */,
148 | 32CCEA1F213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h */,
149 | 32CCEA22213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m */,
150 | 32CCEA1C213E38F600214381 /* SDWebImagePhotosDefine.h */,
151 | 32CCEA21213E38F600214381 /* SDWebImagePhotosDefine.m */,
152 | 32CCEA24213E38F600214381 /* SDWebImagePhotosError.h */,
153 | 32CCEA1D213E38F600214381 /* SDWebImagePhotosError.m */,
154 | 32CCEA20213E38F600214381 /* SDImagePhotosLoader.h */,
155 | 32CCEA1B213E38F600214381 /* SDImagePhotosLoader.m */,
156 | 32380B5225B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h */,
157 | 32380B5325B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m */,
158 | );
159 | path = Classes;
160 | sourceTree = "";
161 | };
162 | 32CCEA43213E430F00214381 /* Frameworks */ = {
163 | isa = PBXGroup;
164 | children = (
165 | 3235B27F21FAD1E6008668C5 /* Photos.framework */,
166 | 3235B28121FAD1ED008668C5 /* Photos.framework */,
167 | 3235B28321FAD1F5008668C5 /* Photos.framework */,
168 | 32CCEA48213E432900214381 /* SDWebImage.framework */,
169 | 32CCEA46213E431E00214381 /* SDWebImage.framework */,
170 | 32CCEA44213E431000214381 /* SDWebImage.framework */,
171 | );
172 | name = Frameworks;
173 | sourceTree = "";
174 | };
175 | /* End PBXGroup section */
176 |
177 | /* Begin PBXHeadersBuildPhase section */
178 | 32CCE9E5213E383E00214381 /* Headers */ = {
179 | isa = PBXHeadersBuildPhase;
180 | buildActionMask = 2147483647;
181 | files = (
182 | 32CCEA28213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */,
183 | 32380B5425B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */,
184 | 32CCEA31213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */,
185 | 32CCEA40213E38F600214381 /* SDWebImagePhotosError.h in Headers */,
186 | 32CCEA34213E38F600214381 /* SDImagePhotosLoader.h in Headers */,
187 | 32CCEA13213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */,
188 | 32CCEA3D213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */,
189 | );
190 | runOnlyForDeploymentPostprocessing = 0;
191 | };
192 | 32CCE9F5213E384500214381 /* Headers */ = {
193 | isa = PBXHeadersBuildPhase;
194 | buildActionMask = 2147483647;
195 | files = (
196 | 32CCEA29213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */,
197 | 32380B5525B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */,
198 | 32CCEA32213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */,
199 | 32CCEA41213E38F600214381 /* SDWebImagePhotosError.h in Headers */,
200 | 32CCEA35213E38F600214381 /* SDImagePhotosLoader.h in Headers */,
201 | 32CCEA14213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */,
202 | 32CCEA3E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */,
203 | );
204 | runOnlyForDeploymentPostprocessing = 0;
205 | };
206 | 32CCEA02213E385A00214381 /* Headers */ = {
207 | isa = PBXHeadersBuildPhase;
208 | buildActionMask = 2147483647;
209 | files = (
210 | 32CCEA2A213E38F600214381 /* SDWebImagePhotosDefine.h in Headers */,
211 | 32380B5625B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.h in Headers */,
212 | 32CCEA33213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.h in Headers */,
213 | 32CCEA42213E38F600214381 /* SDWebImagePhotosError.h in Headers */,
214 | 32CCEA36213E38F600214381 /* SDImagePhotosLoader.h in Headers */,
215 | 32CCEA15213E38CD00214381 /* SDWebImagePhotosPlugin.h in Headers */,
216 | 32CCEA3F213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.h in Headers */,
217 | );
218 | runOnlyForDeploymentPostprocessing = 0;
219 | };
220 | /* End PBXHeadersBuildPhase section */
221 |
222 | /* Begin PBXNativeTarget section */
223 | 32CCE9E7213E383E00214381 /* SDWebImagePhotosPlugin */ = {
224 | isa = PBXNativeTarget;
225 | buildConfigurationList = 32CCE9F0213E383E00214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin" */;
226 | buildPhases = (
227 | 32CCE9E3213E383E00214381 /* Sources */,
228 | 32CCE9E4213E383E00214381 /* Frameworks */,
229 | 32CCE9E5213E383E00214381 /* Headers */,
230 | 32CCE9E6213E383E00214381 /* Resources */,
231 | );
232 | buildRules = (
233 | );
234 | dependencies = (
235 | );
236 | name = SDWebImagePhotosPlugin;
237 | productName = SDWebImagePhotosPlugin;
238 | productReference = 32CCE9E8213E383E00214381 /* SDWebImagePhotosPlugin.framework */;
239 | productType = "com.apple.product-type.framework";
240 | };
241 | 32CCE9F7213E384500214381 /* SDWebImagePhotosPlugin-tvOS */ = {
242 | isa = PBXNativeTarget;
243 | buildConfigurationList = 32CCE9FD213E384600214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin-tvOS" */;
244 | buildPhases = (
245 | 32CCE9F3213E384500214381 /* Sources */,
246 | 32CCE9F4213E384500214381 /* Frameworks */,
247 | 32CCE9F5213E384500214381 /* Headers */,
248 | 32CCE9F6213E384500214381 /* Resources */,
249 | );
250 | buildRules = (
251 | );
252 | dependencies = (
253 | );
254 | name = "SDWebImagePhotosPlugin-tvOS";
255 | productName = "SDWebImagePhotosPlugin-tvOS";
256 | productReference = 32CCE9F8213E384500214381 /* SDWebImagePhotosPlugin_tvOS.framework */;
257 | productType = "com.apple.product-type.framework";
258 | };
259 | 32CCEA04213E385A00214381 /* SDWebImagePhotosPlugin-macOS */ = {
260 | isa = PBXNativeTarget;
261 | buildConfigurationList = 32CCEA0A213E385A00214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin-macOS" */;
262 | buildPhases = (
263 | 32CCEA00213E385A00214381 /* Sources */,
264 | 32CCEA01213E385A00214381 /* Frameworks */,
265 | 32CCEA02213E385A00214381 /* Headers */,
266 | 32CCEA03213E385A00214381 /* Resources */,
267 | );
268 | buildRules = (
269 | );
270 | dependencies = (
271 | );
272 | name = "SDWebImagePhotosPlugin-macOS";
273 | productName = "SDWebImagePhotosPlugin-macOS";
274 | productReference = 32CCEA05213E385A00214381 /* SDWebImagePhotosPlugin_macOS.framework */;
275 | productType = "com.apple.product-type.framework";
276 | };
277 | /* End PBXNativeTarget section */
278 |
279 | /* Begin PBXProject section */
280 | 32CCE9DF213E383E00214381 /* Project object */ = {
281 | isa = PBXProject;
282 | attributes = {
283 | LastUpgradeCheck = 0940;
284 | ORGANIZATIONNAME = SDWebImagePhotosPlugin;
285 | TargetAttributes = {
286 | 32CCE9E7213E383E00214381 = {
287 | CreatedOnToolsVersion = 9.4;
288 | };
289 | 32CCE9F7213E384500214381 = {
290 | CreatedOnToolsVersion = 9.4;
291 | };
292 | 32CCEA04213E385A00214381 = {
293 | CreatedOnToolsVersion = 9.4;
294 | };
295 | };
296 | };
297 | buildConfigurationList = 32CCE9E2213E383E00214381 /* Build configuration list for PBXProject "SDWebImagePhotosPlugin" */;
298 | compatibilityVersion = "Xcode 9.3";
299 | developmentRegion = en;
300 | hasScannedForEncodings = 0;
301 | knownRegions = (
302 | en,
303 | );
304 | mainGroup = 32CCE9DE213E383E00214381;
305 | productRefGroup = 32CCE9E9213E383E00214381 /* Products */;
306 | projectDirPath = "";
307 | projectRoot = "";
308 | targets = (
309 | 32CCE9E7213E383E00214381 /* SDWebImagePhotosPlugin */,
310 | 32CCE9F7213E384500214381 /* SDWebImagePhotosPlugin-tvOS */,
311 | 32CCEA04213E385A00214381 /* SDWebImagePhotosPlugin-macOS */,
312 | );
313 | };
314 | /* End PBXProject section */
315 |
316 | /* Begin PBXResourcesBuildPhase section */
317 | 32CCE9E6213E383E00214381 /* Resources */ = {
318 | isa = PBXResourcesBuildPhase;
319 | buildActionMask = 2147483647;
320 | files = (
321 | );
322 | runOnlyForDeploymentPostprocessing = 0;
323 | };
324 | 32CCE9F6213E384500214381 /* Resources */ = {
325 | isa = PBXResourcesBuildPhase;
326 | buildActionMask = 2147483647;
327 | files = (
328 | );
329 | runOnlyForDeploymentPostprocessing = 0;
330 | };
331 | 32CCEA03213E385A00214381 /* Resources */ = {
332 | isa = PBXResourcesBuildPhase;
333 | buildActionMask = 2147483647;
334 | files = (
335 | );
336 | runOnlyForDeploymentPostprocessing = 0;
337 | };
338 | /* End PBXResourcesBuildPhase section */
339 |
340 | /* Begin PBXSourcesBuildPhase section */
341 | 32CCE9E3213E383E00214381 /* Sources */ = {
342 | isa = PBXSourcesBuildPhase;
343 | buildActionMask = 2147483647;
344 | files = (
345 | 32CCEA25213E38F600214381 /* SDImagePhotosLoader.m in Sources */,
346 | 32CCEA3A213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */,
347 | 32CCEA2B213E38F600214381 /* SDWebImagePhotosError.m in Sources */,
348 | 32CCEA2E213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */,
349 | 32380B5725B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */,
350 | 32CCEA37213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */,
351 | );
352 | runOnlyForDeploymentPostprocessing = 0;
353 | };
354 | 32CCE9F3213E384500214381 /* Sources */ = {
355 | isa = PBXSourcesBuildPhase;
356 | buildActionMask = 2147483647;
357 | files = (
358 | 32CCEA26213E38F600214381 /* SDImagePhotosLoader.m in Sources */,
359 | 32CCEA3B213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */,
360 | 32CCEA2C213E38F600214381 /* SDWebImagePhotosError.m in Sources */,
361 | 32CCEA2F213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */,
362 | 32380B5825B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */,
363 | 32CCEA38213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */,
364 | );
365 | runOnlyForDeploymentPostprocessing = 0;
366 | };
367 | 32CCEA00213E385A00214381 /* Sources */ = {
368 | isa = PBXSourcesBuildPhase;
369 | buildActionMask = 2147483647;
370 | files = (
371 | 32CCEA27213E38F600214381 /* SDImagePhotosLoader.m in Sources */,
372 | 32CCEA3C213E38F600214381 /* PHImageRequestOptions+SDWebImagePhotosPlugin.m in Sources */,
373 | 32CCEA2D213E38F600214381 /* SDWebImagePhotosError.m in Sources */,
374 | 32CCEA30213E38F600214381 /* NSURL+SDWebImagePhotosPlugin.m in Sources */,
375 | 32380B5925B95E87002A50E1 /* PHAsset+SDWebImagePhotosPlugin.m in Sources */,
376 | 32CCEA39213E38F600214381 /* SDWebImagePhotosDefine.m in Sources */,
377 | );
378 | runOnlyForDeploymentPostprocessing = 0;
379 | };
380 | /* End PBXSourcesBuildPhase section */
381 |
382 | /* Begin XCBuildConfiguration section */
383 | 32CCE9EE213E383E00214381 /* Debug */ = {
384 | isa = XCBuildConfiguration;
385 | buildSettings = {
386 | ALWAYS_SEARCH_USER_PATHS = NO;
387 | CLANG_ANALYZER_NONNULL = YES;
388 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
389 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
390 | CLANG_CXX_LIBRARY = "libc++";
391 | CLANG_ENABLE_MODULES = YES;
392 | CLANG_ENABLE_OBJC_ARC = YES;
393 | CLANG_ENABLE_OBJC_WEAK = YES;
394 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
395 | CLANG_WARN_BOOL_CONVERSION = YES;
396 | CLANG_WARN_COMMA = YES;
397 | CLANG_WARN_CONSTANT_CONVERSION = YES;
398 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
399 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
400 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
401 | CLANG_WARN_EMPTY_BODY = YES;
402 | CLANG_WARN_ENUM_CONVERSION = YES;
403 | CLANG_WARN_INFINITE_RECURSION = YES;
404 | CLANG_WARN_INT_CONVERSION = YES;
405 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
406 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
407 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
408 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
409 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
410 | CLANG_WARN_STRICT_PROTOTYPES = YES;
411 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
412 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
413 | CLANG_WARN_UNREACHABLE_CODE = YES;
414 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
415 | CODE_SIGN_IDENTITY = "iPhone Developer";
416 | COPY_PHASE_STRIP = NO;
417 | CURRENT_PROJECT_VERSION = 1;
418 | DEBUG_INFORMATION_FORMAT = dwarf;
419 | ENABLE_STRICT_OBJC_MSGSEND = YES;
420 | ENABLE_TESTABILITY = YES;
421 | GCC_C_LANGUAGE_STANDARD = gnu11;
422 | GCC_DYNAMIC_NO_PIC = NO;
423 | GCC_NO_COMMON_BLOCKS = YES;
424 | GCC_OPTIMIZATION_LEVEL = 0;
425 | GCC_PREPROCESSOR_DEFINITIONS = (
426 | "DEBUG=1",
427 | "$(inherited)",
428 | );
429 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
430 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
431 | GCC_WARN_UNDECLARED_SELECTOR = YES;
432 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
433 | GCC_WARN_UNUSED_FUNCTION = YES;
434 | GCC_WARN_UNUSED_VARIABLE = YES;
435 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
436 | MACOSX_DEPLOYMENT_TARGET = 10.13;
437 | MTL_ENABLE_DEBUG_INFO = YES;
438 | ONLY_ACTIVE_ARCH = YES;
439 | SDKROOT = iphoneos;
440 | VERSIONING_SYSTEM = "apple-generic";
441 | VERSION_INFO_PREFIX = "";
442 | };
443 | name = Debug;
444 | };
445 | 32CCE9EF213E383E00214381 /* Release */ = {
446 | isa = XCBuildConfiguration;
447 | buildSettings = {
448 | ALWAYS_SEARCH_USER_PATHS = NO;
449 | CLANG_ANALYZER_NONNULL = YES;
450 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
451 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
452 | CLANG_CXX_LIBRARY = "libc++";
453 | CLANG_ENABLE_MODULES = YES;
454 | CLANG_ENABLE_OBJC_ARC = YES;
455 | CLANG_ENABLE_OBJC_WEAK = YES;
456 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
457 | CLANG_WARN_BOOL_CONVERSION = YES;
458 | CLANG_WARN_COMMA = YES;
459 | CLANG_WARN_CONSTANT_CONVERSION = YES;
460 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
461 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
462 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
463 | CLANG_WARN_EMPTY_BODY = YES;
464 | CLANG_WARN_ENUM_CONVERSION = YES;
465 | CLANG_WARN_INFINITE_RECURSION = YES;
466 | CLANG_WARN_INT_CONVERSION = YES;
467 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
468 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
469 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
470 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
471 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
472 | CLANG_WARN_STRICT_PROTOTYPES = YES;
473 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
474 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
475 | CLANG_WARN_UNREACHABLE_CODE = YES;
476 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
477 | CODE_SIGN_IDENTITY = "iPhone Developer";
478 | COPY_PHASE_STRIP = NO;
479 | CURRENT_PROJECT_VERSION = 1;
480 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
481 | ENABLE_NS_ASSERTIONS = NO;
482 | ENABLE_STRICT_OBJC_MSGSEND = YES;
483 | GCC_C_LANGUAGE_STANDARD = gnu11;
484 | GCC_NO_COMMON_BLOCKS = YES;
485 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
486 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
487 | GCC_WARN_UNDECLARED_SELECTOR = YES;
488 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
489 | GCC_WARN_UNUSED_FUNCTION = YES;
490 | GCC_WARN_UNUSED_VARIABLE = YES;
491 | IPHONEOS_DEPLOYMENT_TARGET = 9.0;
492 | MACOSX_DEPLOYMENT_TARGET = 10.13;
493 | MTL_ENABLE_DEBUG_INFO = NO;
494 | SDKROOT = iphoneos;
495 | VALIDATE_PRODUCT = YES;
496 | VERSIONING_SYSTEM = "apple-generic";
497 | VERSION_INFO_PREFIX = "";
498 | };
499 | name = Release;
500 | };
501 | 32CCE9F1213E383E00214381 /* Debug */ = {
502 | isa = XCBuildConfiguration;
503 | buildSettings = {
504 | CODE_SIGN_IDENTITY = "";
505 | CODE_SIGN_STYLE = Automatic;
506 | DEFINES_MODULE = YES;
507 | DYLIB_COMPATIBILITY_VERSION = 1;
508 | DYLIB_CURRENT_VERSION = 1;
509 | DYLIB_INSTALL_NAME_BASE = "@rpath";
510 | FRAMEWORK_SEARCH_PATHS = (
511 | "$(inherited)",
512 | "$(PROJECT_DIR)/Carthage/Build/iOS",
513 | );
514 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
515 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
516 | LD_RUNPATH_SEARCH_PATHS = (
517 | "$(inherited)",
518 | "@executable_path/Frameworks",
519 | "@loader_path/Frameworks",
520 | );
521 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.SDWebImagePhotosPlugin;
522 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
523 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
524 | SKIP_INSTALL = YES;
525 | TARGETED_DEVICE_FAMILY = "1,2";
526 | };
527 | name = Debug;
528 | };
529 | 32CCE9F2213E383E00214381 /* Release */ = {
530 | isa = XCBuildConfiguration;
531 | buildSettings = {
532 | CODE_SIGN_IDENTITY = "";
533 | CODE_SIGN_STYLE = Automatic;
534 | DEFINES_MODULE = YES;
535 | DYLIB_COMPATIBILITY_VERSION = 1;
536 | DYLIB_CURRENT_VERSION = 1;
537 | DYLIB_INSTALL_NAME_BASE = "@rpath";
538 | FRAMEWORK_SEARCH_PATHS = (
539 | "$(inherited)",
540 | "$(PROJECT_DIR)/Carthage/Build/iOS",
541 | );
542 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
543 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
544 | LD_RUNPATH_SEARCH_PATHS = (
545 | "$(inherited)",
546 | "@executable_path/Frameworks",
547 | "@loader_path/Frameworks",
548 | );
549 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.SDWebImagePhotosPlugin;
550 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
551 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
552 | SKIP_INSTALL = YES;
553 | TARGETED_DEVICE_FAMILY = "1,2";
554 | };
555 | name = Release;
556 | };
557 | 32CCE9FE213E384600214381 /* Debug */ = {
558 | isa = XCBuildConfiguration;
559 | buildSettings = {
560 | CODE_SIGN_IDENTITY = "";
561 | CODE_SIGN_STYLE = Automatic;
562 | DEFINES_MODULE = YES;
563 | DYLIB_COMPATIBILITY_VERSION = 1;
564 | DYLIB_CURRENT_VERSION = 1;
565 | DYLIB_INSTALL_NAME_BASE = "@rpath";
566 | FRAMEWORK_SEARCH_PATHS = (
567 | "$(inherited)",
568 | "$(PROJECT_DIR)/Carthage/Build/tvOS",
569 | );
570 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
571 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
572 | LD_RUNPATH_SEARCH_PATHS = (
573 | "$(inherited)",
574 | "@executable_path/Frameworks",
575 | "@loader_path/Frameworks",
576 | );
577 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.SDWebImagePhotosPlugin-tvOS";
578 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
579 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
580 | SDKROOT = appletvos;
581 | SKIP_INSTALL = YES;
582 | TARGETED_DEVICE_FAMILY = 3;
583 | TVOS_DEPLOYMENT_TARGET = 10.0;
584 | };
585 | name = Debug;
586 | };
587 | 32CCE9FF213E384600214381 /* Release */ = {
588 | isa = XCBuildConfiguration;
589 | buildSettings = {
590 | CODE_SIGN_IDENTITY = "";
591 | CODE_SIGN_STYLE = Automatic;
592 | DEFINES_MODULE = YES;
593 | DYLIB_COMPATIBILITY_VERSION = 1;
594 | DYLIB_CURRENT_VERSION = 1;
595 | DYLIB_INSTALL_NAME_BASE = "@rpath";
596 | FRAMEWORK_SEARCH_PATHS = (
597 | "$(inherited)",
598 | "$(PROJECT_DIR)/Carthage/Build/tvOS",
599 | );
600 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
601 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
602 | LD_RUNPATH_SEARCH_PATHS = (
603 | "$(inherited)",
604 | "@executable_path/Frameworks",
605 | "@loader_path/Frameworks",
606 | );
607 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.SDWebImagePhotosPlugin-tvOS";
608 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
609 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
610 | SDKROOT = appletvos;
611 | SKIP_INSTALL = YES;
612 | TARGETED_DEVICE_FAMILY = 3;
613 | TVOS_DEPLOYMENT_TARGET = 10.0;
614 | };
615 | name = Release;
616 | };
617 | 32CCEA0B213E385A00214381 /* Debug */ = {
618 | isa = XCBuildConfiguration;
619 | buildSettings = {
620 | CODE_SIGN_IDENTITY = "-";
621 | CODE_SIGN_STYLE = Automatic;
622 | COMBINE_HIDPI_IMAGES = YES;
623 | DEFINES_MODULE = YES;
624 | DYLIB_COMPATIBILITY_VERSION = 1;
625 | DYLIB_CURRENT_VERSION = 1;
626 | DYLIB_INSTALL_NAME_BASE = "@rpath";
627 | FRAMEWORK_SEARCH_PATHS = (
628 | "$(inherited)",
629 | "$(PROJECT_DIR)/Carthage/Build/Mac",
630 | );
631 | FRAMEWORK_VERSION = A;
632 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
633 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
634 | LD_RUNPATH_SEARCH_PATHS = (
635 | "$(inherited)",
636 | "@executable_path/../Frameworks",
637 | "@loader_path/Frameworks",
638 | );
639 | MACOSX_DEPLOYMENT_TARGET = 10.13;
640 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.SDWebImagePhotosPlugin-macOS";
641 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
642 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
643 | SDKROOT = macosx;
644 | SKIP_INSTALL = YES;
645 | };
646 | name = Debug;
647 | };
648 | 32CCEA0C213E385A00214381 /* Release */ = {
649 | isa = XCBuildConfiguration;
650 | buildSettings = {
651 | CODE_SIGN_IDENTITY = "-";
652 | CODE_SIGN_STYLE = Automatic;
653 | COMBINE_HIDPI_IMAGES = YES;
654 | DEFINES_MODULE = YES;
655 | DYLIB_COMPATIBILITY_VERSION = 1;
656 | DYLIB_CURRENT_VERSION = 1;
657 | DYLIB_INSTALL_NAME_BASE = "@rpath";
658 | FRAMEWORK_SEARCH_PATHS = (
659 | "$(inherited)",
660 | "$(PROJECT_DIR)/Carthage/Build/Mac",
661 | );
662 | FRAMEWORK_VERSION = A;
663 | INFOPLIST_FILE = "$(SRCROOT)/SDWebImagePhotosPlugin/Module/Info.plist";
664 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
665 | LD_RUNPATH_SEARCH_PATHS = (
666 | "$(inherited)",
667 | "@executable_path/../Frameworks",
668 | "@loader_path/Frameworks",
669 | );
670 | MACOSX_DEPLOYMENT_TARGET = 10.13;
671 | PRODUCT_BUNDLE_IDENTIFIER = "org.cocoapods.SDWebImagePhotosPlugin-macOS";
672 | PRODUCT_MODULE_NAME = SDWebImagePhotosPlugin;
673 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
674 | SDKROOT = macosx;
675 | SKIP_INSTALL = YES;
676 | };
677 | name = Release;
678 | };
679 | /* End XCBuildConfiguration section */
680 |
681 | /* Begin XCConfigurationList section */
682 | 32CCE9E2213E383E00214381 /* Build configuration list for PBXProject "SDWebImagePhotosPlugin" */ = {
683 | isa = XCConfigurationList;
684 | buildConfigurations = (
685 | 32CCE9EE213E383E00214381 /* Debug */,
686 | 32CCE9EF213E383E00214381 /* Release */,
687 | );
688 | defaultConfigurationIsVisible = 0;
689 | defaultConfigurationName = Release;
690 | };
691 | 32CCE9F0213E383E00214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin" */ = {
692 | isa = XCConfigurationList;
693 | buildConfigurations = (
694 | 32CCE9F1213E383E00214381 /* Debug */,
695 | 32CCE9F2213E383E00214381 /* Release */,
696 | );
697 | defaultConfigurationIsVisible = 0;
698 | defaultConfigurationName = Release;
699 | };
700 | 32CCE9FD213E384600214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin-tvOS" */ = {
701 | isa = XCConfigurationList;
702 | buildConfigurations = (
703 | 32CCE9FE213E384600214381 /* Debug */,
704 | 32CCE9FF213E384600214381 /* Release */,
705 | );
706 | defaultConfigurationIsVisible = 0;
707 | defaultConfigurationName = Release;
708 | };
709 | 32CCEA0A213E385A00214381 /* Build configuration list for PBXNativeTarget "SDWebImagePhotosPlugin-macOS" */ = {
710 | isa = XCConfigurationList;
711 | buildConfigurations = (
712 | 32CCEA0B213E385A00214381 /* Debug */,
713 | 32CCEA0C213E385A00214381 /* Release */,
714 | );
715 | defaultConfigurationIsVisible = 0;
716 | defaultConfigurationName = Release;
717 | };
718 | /* End XCConfigurationList section */
719 | };
720 | rootObject = 32CCE9DF213E383E00214381 /* Project object */;
721 | }
722 |
--------------------------------------------------------------------------------