merge of upstream
This commit is contained in:
commit
b232de666c
|
@ -0,0 +1 @@
|
|||
*.mdj binary
|
|
@ -6,7 +6,7 @@
|
|||
|
||||
* [ ] I have updated this branch with the latest master to avoid conflicts (via merge from master or rebase)
|
||||
* [ ] I have added the required tests to prove the fix/feature I am adding
|
||||
* [ ] I have updated the documentation (if necesarry)
|
||||
* [ ] I have updated the documentation (if necessary)
|
||||
* [ ] I have run the tests and they pass
|
||||
* [ ] I have run the lint and it passes (`pod lib lint`)
|
||||
|
||||
|
|
|
@ -1,3 +1,6 @@
|
|||
[submodule "Vendors/libwebp"]
|
||||
path = Vendors/libwebp
|
||||
url = https://github.com/webmproject/libwebp
|
||||
[submodule "Vendors/FLAnimatedImage"]
|
||||
path = Vendors/FLAnimatedImage
|
||||
url = https://github.com/Flipboard/FLAnimatedImage
|
||||
|
|
42
.travis.yml
42
.travis.yml
|
@ -1,27 +1,51 @@
|
|||
|
||||
language: objective-c
|
||||
osx_image: xcode7.3
|
||||
|
||||
env:
|
||||
global:
|
||||
- LC_CTYPE=en_US.UTF-8
|
||||
- LANG=en_US.UTF-8
|
||||
|
||||
osx_image: xcode7.1
|
||||
|
||||
before_install:
|
||||
|
||||
- export LANG=en_US.UTF-8
|
||||
- env
|
||||
- locale
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- gem install xcpretty --no-rdoc --no-ri --no-document --quiet
|
||||
- pod --version
|
||||
- pod setup --silent > /dev/null
|
||||
- pod repo update --silent
|
||||
- xcpretty --version
|
||||
- xcodebuild -version
|
||||
- xcodebuild -showsdks
|
||||
|
||||
script:
|
||||
- set -o pipefail
|
||||
|
||||
- echo Check if the library described by the podspec can be built
|
||||
- pod lib lint --allow-warnings
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator build
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+WebP' -sdk iphonesimulator build
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+MKAnnotation' -sdk iphonesimulator build
|
||||
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator build
|
||||
- echo Build as static library
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage iOS static' -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage watchOS static' -sdk watchsimulator -configuration Debug | xcpretty -c
|
||||
|
||||
- echo Build as dynamic framework
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage OSX' -sdk macosx -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage iOS' -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage tvOS' -sdk appletvsimulator -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage watchOS' -sdk watchsimulator -configuration Debug | xcpretty -c
|
||||
|
||||
- echo Build the Demo apps
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage OSX Demo' -sdk macosx -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage iOS Demo' -configuration Debug -destination 'name=iPhone 6s' | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage TV Demo' -sdk appletvsimulator -configuration Debug | xcpretty -c
|
||||
- xcodebuild clean build -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Watch Demo' -configuration Debug -destination 'name=iPhone 6s' | xcpretty -c
|
||||
|
||||
- echo Run the tests
|
||||
- pod install --project-directory=Tests
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator clean
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test
|
||||
- xcodebuild clean -workspace SDWebImage.xcworkspace -scheme 'SDWebImage iOS static' -sdk iphonesimulator PLATFORM_NAME=iphonesimulator -configuration Debug | xcpretty -c
|
||||
- xcodebuild test -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' -configuration Debug | xcpretty -c
|
||||
|
||||
after_success:
|
||||
- bash <(curl -s https://codecov.io/bash)
|
119
CHANGELOG.md
119
CHANGELOG.md
|
@ -1,3 +1,122 @@
|
|||
## [4.0.0 - New platforms (Mac OS X and watchOS) + refactoring, on Jan 28th, 2017](https://github.com/rs/SDWebImage/releases/tag/4.0.0)
|
||||
|
||||
See [all tickets marked for the 4.0.0 release](https://github.com/rs/SDWebImage/milestone/3)
|
||||
Versions 4.0.0-beta and 4.0.0-beta 2 list all the changes.
|
||||
|
||||
## [4.0.0 beta 2 - New platforms (Mac OS X and watchOS) + refactoring, on Oct 6th, 2016](https://github.com/rs/SDWebImage/releases/tag/4.0.0-beta2)
|
||||
|
||||
See [all tickets marked for the 4.0.0 release](https://github.com/rs/SDWebImage/milestone/3)
|
||||
|
||||
#### Features
|
||||
|
||||
- Add an option to scale down large images #787 00bf467 efad1e5 8d1a0ae. Fixed #538, #880 and #586. This one is a more robust solution than #884 or #894. Can be activated via `SDWebImageScaleDownLargeImages` or `SDWebImageDownloaderScaleDownLargeImages`
|
||||
|
||||
#### Fixes
|
||||
|
||||
- Fixed #1668 CGContextDrawImage: invalid context 0x0 - b366d84
|
||||
|
||||
## [4.0.0 beta - New platforms (Mac OS X and watchOS) + refactoring, on Oct 5th, 2016](https://github.com/rs/SDWebImage/releases/tag/4.0.0-beta)
|
||||
|
||||
See [all tickets marked for the 4.0.0 release](https://github.com/rs/SDWebImage/milestone/3)
|
||||
|
||||
#### Infrastructure:
|
||||
|
||||
- support for **watchOS** and **OS X** platforms #1595
|
||||
- the `SDWebImage xcodeproj` contains the following targets:
|
||||
- `SDWebImage iOS static` (iOS static lib)
|
||||
- `SDWebImage watchOS static` (watchOS static lib)
|
||||
- `SDWebImage OSX` (OSX dynamic framework)
|
||||
- `SDWebImage iOS` (iOS dynamic framework)
|
||||
- `SDWebImage tvOS` (tvOS dynamic framework)
|
||||
- `SDWebImage watchOS` (watchOS dynamic framework)
|
||||
- the `SDWebImage Demo xcodeproj` contains the following targets:
|
||||
- `SDWebImage OSX Demo`
|
||||
- `SDWebImage iOS Demo`
|
||||
- `SDWebImage TV Demo`
|
||||
- `SDWebImage Watch Demo`
|
||||
- bumped `libwep` version to `0.5.1`
|
||||
- improved unit testing code coverage (*35%* -> **77%**) and integrated [CodeCov](https://codecov.io/gh/rs/SDWebImage)
|
||||
|
||||
#### Backwards incompatible changes
|
||||
|
||||
- removed all deprecated methods (that we carried around for backwards compatibility in previous versions) #774
|
||||
- Renamed `SDWebImageManager` `downloadImageWithURL:options:progress:completed:` to `loadImageWithURL:options:progress:completed:` as it makes more sense, since we check the cache first and download only if needed a32a177
|
||||
- Deleted targets: `SDWebImage+MKAnnotation`, `SDWebImage+WebP`, `SDWebImageFramework`:
|
||||
- `SDWebImage `target that build as a static library (all subspecs included) -> `libSDWebImage.a`
|
||||
- `SDWebImageiOS` and `SDWebImagetvOS` targets that build as dynamic frameworks
|
||||
- Renamed the dynamic frameworks targets from `WebImage` to `SDWebImage`. Renamed the `WebImage.h` to `SDWebImage.h` to match the framework naming
|
||||
- Renamed the schemes for consistency. Updated the Tests Podfile + project.
|
||||
- For #883 Fix multiple requests for same image and then canceling one, several breaking changes were needed:
|
||||
- `SDWebImageDownloader` method `- downloadImageWithURL:options:progress:completed:` now returns a `SDWebImageDownloadToken *` instead of `id <SDWebImageOperation>` (give the ability to cancel downloads using the returned token)
|
||||
- `SDWebImageDownloaderOperation` initializer `- initWithRequest:options:progress:completed:cancelled` split into `- initWithRequest:options` and `addHandlersForProgress:completed:`. Note: there is no more cancel block
|
||||
- Modern Objective-C syntax done in 64382b9 includes:
|
||||
- initializers now return `instancetype` instead of `id`
|
||||
- explicit designated initializers (i.e. for `SDImageCache`)
|
||||
- For #1575 GIF support using FLAnimatedImage, several changes were needed:
|
||||
- replaced type `SDWebImageQueryCompletedBlock` with `SDCacheQueryCompletedBlock` and added an `NSData *` param
|
||||
- because of the change above, the `done` param of `SDImageCache` `queryDiskCacheForKey:done:` is now a `SDCacheQueryCompletedBlock` and those blocks must now include an `NSData *` param
|
||||
- replaced type `SDWebImageCompletionWithFinishedBlock` with `SDInternalCompletionBlock` and added an `NSData *` param
|
||||
- because of the change above, the `completed` param of `SDWebImageManager` `loadImageWithURL:options:progress:completed:` is now `SDInternalCompletionBlock` and those blocks must now include an `NSData *` param
|
||||
- for consistency with the previous change, also renamed `SDWebImageCompletionBlock` to `SDExternalCompletionBlock`
|
||||
- `UIImage` will no longer respond to `sd_animatedGIFNamed:` or `sd_animatedImageByScalingAndCroppingToSize:`
|
||||
- Xcode 7 Objective-C updates (Lightweight Generics and Nullability) #1581
|
||||
- breaks compatibility at least for Swift users of the framework
|
||||
- **watchOS** and **OS X** support #1595 required
|
||||
- renamed `SDWebImage` iOS static lib target to `SDWebImage iOS static` for clarity
|
||||
- improving the unit tests code coverage #1681 required
|
||||
- Refactored `NSData` `ImageContentType` category, instead of returning the contentType as a string, the new added method `sd_imageFormatForImageData` will return a `SDImageFormat` enum value
|
||||
- `SDImageCache` configuration properties moved into `SDImageCacheConfig` (which is now available via `config` property):
|
||||
- `shouldDecompressImages`
|
||||
- `shouldDisableiCloud`
|
||||
- `shouldCacheImagesInMemory`
|
||||
- `maxCacheAge`
|
||||
- `maxCacheSize`
|
||||
- The `storeImage:` methods from `SDImageCache` were async already, but declared as sync. Properly marked them as async + added completion. Got rid of the recalculate param. If the `NSData` is provided, use it. Otherwise, recalculate from the `UIImage`
|
||||
- Removed the synchronous methods `diskImageExistsForURL:` and `cachedImageExistsForURL:` from `SDWebImageManager`
|
||||
- Removed the synchronous method `diskImageExistsWithKey:` from `SDImageCache`
|
||||
- Get rid of the confusion caused by `cleanDisk` and `clearDisk` on `SDImageCache`. Renamed `cleanDisk` to `deleteOldFiles`. No longer expose the sync `clearDisk` and `deleteOldFiles`, just the async ones.
|
||||
- Renamed `SDImageCache` `queryDiskCacheForKey:done:` to `queryCacheOperationForKey:done:`
|
||||
- Another `SDImageCache` clarification: `imageFromDiskCacheForKey:` used to also check the memory cache which I think is misleading. Now `imageFromDiskCacheForKey` only checks the disk cache and the new method `imageFromCacheForKey` checks both caches
|
||||
- Got rid of `removeImageForKey:` and `removeImageForKey:fromDisk:` from `SDImageCache` that looked sync but were async. Left only the 2 async ones
|
||||
- Removed `UIImageView` `sd_cancelCurrentHighlightedImageLoad`
|
||||
- Added `sd_` prefix to the activity indicator related methods (`setShowActivityIndicatorView:`, `setIndicatorStyle:`, `showActivityIndicatorView`, `addActivityIndicator`, `removeActivityIndicator`) #1640
|
||||
- Use `dispatch_main_async_safe` for all the completion blocks on the main queue (used to be `dispatch_sync`) - avoiding locks.
|
||||
- Removed `dispatch_main_sync_safe` as it can be mistakenly used
|
||||
- Add `url` as param to progress block `SDWebImageDownloaderProgressBlock` - #984
|
||||
|
||||
#### Features:
|
||||
|
||||
- Switched our GIF support to a better implementation: [FLAnimatedImage by Flipboard](https://github.com/Flipboard/FLAnimatedImage) #1575
|
||||
- requires iOS 8+ (it's the only way due to FLAnimatedImage requirements)
|
||||
- the implementation relies on a `WebCache` category on top of `FLAnimatedImageView`
|
||||
- details in the [README](README.md#animated-images-gif-support)
|
||||
- Converted any remaining code to Modern Objective-C syntax - 64382b9
|
||||
- Xcode 7 Objective-C updates (Lightweight Generics and Nullability) #1581
|
||||
- via #1595 Clarified and simplified the usage of `TARGET_OS_*` macros. Added `SD_MAC`, `SD_UIKIT`, `SD_IOS`, `SD_TV`, `SD_WATCH`. The biggest issue here was `TARGET_OS_MAC` was 1 for all platforms and we couldn't rely on it.
|
||||
- Replaces #1398 Allow to customise cache and image downloader instances used with `SDWebImageManager` - added a new initializer (`initWithCache:downloader:`) 9112170
|
||||
- `UIImage` responds to `sd_imageData` and `sd_imageDataAsFormat:` via the `MultiFormat` category. Those methods transform a `UIImage` to the `NSData` representation 82d1f2e
|
||||
- Created `SDWebImageDownloaderOperationInterface` to describe the behavior of a downloader operation. Any custom operation must conform to this protocol df3b6a5
|
||||
- Refactored all the duplicate code from our `WebCache` categories into a `UIView` `WebCache` category. All the other categories will make calls to this one. Customization of setting the image is done via the `setImageBlock` and the `operationKey` e1840c3
|
||||
- Due to the change above, the activity indicator can now be added to `UIButton`, `MKAnnotationView`, `UIImageView`
|
||||
- Animated WebP support #1438
|
||||
- The shared objects (not really singletons) should allow subclassing, therefore the return type of the shared resource method should be `instancetype` and not a fixed type - c57cf7e
|
||||
- Allow to specify `NSURLSessionConfiguration` for `SDWebImageDownloader` #1654
|
||||
- Add `url` as param to progress block `SDWebImageDownloaderProgressBlock` - #984
|
||||
|
||||
#### Fixes:
|
||||
|
||||
- Fix multiple requests for same image and then canceling one #883 + 8a78586
|
||||
- Fixed #1444 and the master build thanks to [@kenmaz](https://github.com/kenmaz/SDWebImage/commit/5034c334be50765dfe4e97c48bcb74ef64175188)
|
||||
- Fixed an issue with the `SDWebImageDownloaderOperation` : `cancelInternal` was not called because of the old mechanism rellying on the `thread` property - probably because that thread did not have a runloop. Removed that and now cancelInternal is called as expected f4bdae6
|
||||
- Replaced #781 on replacing dispatch_sync with dispatch_async for the main queue 062e50a f7e8246 c77adf4 fdb8b2c 265ace4 0c47bc3. Check for main queue instead of main thread.
|
||||
- Fixed #1619 iOS 10 crash (`setObjectForKey: object cannot be nil`) - #1676 7940577
|
||||
- Fixed #1326 #1424 (`Carthage bitcode issue`) - #1593
|
||||
- Fixed #1639 via #1657 (`Add support for downloading images behind redirect`)
|
||||
- Replaced #1537 via 9cd6779 - fixed a potential retain cycle
|
||||
- Updated `dispatch_main_async_safe` macro in order to avoid redefinition when included as Pod
|
||||
- Fixed #1089 by updating the docs on the calling queue for the `progressBlock` (background queue)
|
||||
- Fixed a compilation issue on `FLAnimatedImageView+WebCache` - #1687
|
||||
|
||||
## [3.8.2 Patch release for 3.8.0 on Sep 5th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.2)
|
||||
|
||||
#### Fixes:
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
#### Using `UIImageView+WebCache` category with `UITableView`
|
||||
|
||||
Just import the `UIImageView+WebCache.h` header, and call the `sd_setImageWithURL:placeholderImage:`
|
||||
method from the `tableView:cellForRowAtIndexPath:` `UITableViewDataSource` method. Everything will be
|
||||
handled for you, from async downloads to caching management.
|
||||
|
||||
```objective-c
|
||||
#import <SDWebImage/UIImageView+WebCache.h>
|
||||
|
||||
...
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
static NSString *MyIdentifier = @"MyIdentifier";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:MyIdentifier] autorelease];
|
||||
}
|
||||
|
||||
// Here we use the new provided sd_setImageWithURL: method to load the web image
|
||||
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
|
||||
|
||||
cell.textLabel.text = @"My Text";
|
||||
return cell;
|
||||
}
|
||||
```
|
||||
|
||||
```swift
|
||||
import SDWebImage
|
||||
...
|
||||
func tableView(tableView: UITableView!, cellForRowAtIndexPath indexPath: NSIndexPath!) -> UITableViewCell! {
|
||||
static let myIdentifier = "MyIdentifier"
|
||||
let cell = tableView.dequeueReusableCellWithIdentifier(myIdentifier, forIndexPath: indexPath) as UITableViewCell
|
||||
|
||||
cell.imageView.sd_setImageWithURL(imageUrl, placeholderImage:placeholderImage)
|
||||
return cell
|
||||
```
|
||||
|
||||
### Using blocks
|
||||
|
||||
With blocks, you can be notified about the image download progress and whenever the image retrieval has completed with success or not:
|
||||
|
||||
```objective-c
|
||||
// Here we use the new provided sd_setImageWithURL: method to load the web image
|
||||
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
|
||||
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
|
||||
... completion code here ...
|
||||
}];
|
||||
```
|
||||
|
||||
Note: neither your success nor failure block will be call if your image request is canceled before completion.
|
||||
|
||||
### Using SDWebImageManager
|
||||
|
||||
The `SDWebImageManager` is the class behind the `UIImageView(WebCache)` category. It ties the asynchronous downloader with the image cache store. You can use this class directly to benefit from web image downloading with caching in another context than a `UIView` (ie: with Cocoa).
|
||||
|
||||
Here is a simple example of how to use `SDWebImageManager`:
|
||||
|
||||
```objective-c
|
||||
SDWebImageManager *manager = [SDWebImageManager sharedManager];
|
||||
[manager loadImageWithURL:imageURL
|
||||
options:0
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
// progression tracking code
|
||||
}
|
||||
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
|
||||
if (image) {
|
||||
// do something with image
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### Using Asynchronous Image Downloader Independently
|
||||
|
||||
It's also possible to use the async image downloader independently:
|
||||
|
||||
```objective-c
|
||||
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
|
||||
[downloader downloadImageWithURL:imageURL
|
||||
options:0
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
// progression tracking code
|
||||
}
|
||||
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
|
||||
if (image && finished) {
|
||||
// do something with image
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### Using Asynchronous Image Caching Independently
|
||||
|
||||
It is also possible to use the async based image cache store independently. SDImageCache
|
||||
maintains a memory cache and an optional disk cache. Disk cache write operations are performed
|
||||
asynchronous so it doesn't add unnecessary latency to the UI.
|
||||
|
||||
The SDImageCache class provides a singleton instance for convenience but you can create your own
|
||||
instance if you want to create separated cache namespace.
|
||||
|
||||
To lookup the cache, you use the `queryDiskCacheForKey:done:` method. If the method returns nil, it means the cache
|
||||
doesn't currently own the image. You are thus responsible for generating and caching it. The cache
|
||||
key is an application unique identifier for the image to cache. It is generally the absolute URL of
|
||||
the image.
|
||||
|
||||
```objective-c
|
||||
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"];
|
||||
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) {
|
||||
// image is not nil if image was found
|
||||
}];
|
||||
```
|
||||
|
||||
By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache.
|
||||
You can prevent this from happening by calling the alternative method `imageFromMemoryCacheForKey:`.
|
||||
|
||||
To store an image into the cache, you use the storeImage:forKey: method:
|
||||
|
||||
```objective-c
|
||||
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
|
||||
```
|
||||
|
||||
By default, the image will be stored in memory cache as well as on disk cache (asynchronously). If
|
||||
you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative
|
||||
third argument.
|
||||
|
||||
### Using cache key filter
|
||||
|
||||
Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic
|
||||
(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter that
|
||||
takes the NSURL as input, and output a cache key NSString.
|
||||
|
||||
The following example sets a filter in the application delegate that will remove any query-string from
|
||||
the URL before to use it as a cache key:
|
||||
|
||||
```objective-c
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
|
||||
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
|
||||
return [url absoluteString];
|
||||
};
|
||||
|
||||
// Your app init code...
|
||||
return YES;
|
||||
}
|
||||
```
|
|
@ -0,0 +1,33 @@
|
|||
### Installation by cloning the repository
|
||||
|
||||
In order to gain access to all the files from the repository, you should clone it.
|
||||
```
|
||||
git clone --recursive https://github.com/rs/SDWebImage.git
|
||||
```
|
||||
|
||||
... TO BE CHECKED AND DESCRIBED IN DETAIL
|
||||
|
||||
### Add dependencies
|
||||
|
||||
- In you application project app’s target settings, find the "Build Phases" section and open the "Link Binary With Libraries" block:
|
||||
- Click the "+" button again and select the "ImageIO.framework", this is needed by the progressive download feature:
|
||||
|
||||
### Add Linker Flag
|
||||
|
||||
Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag:
|
||||
|
||||
![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg)
|
||||
|
||||
Alternatively, if this causes compilation problems with frameworks that extend optional libraries, such as Parse, RestKit or opencv2, instead of the -ObjC flag use:
|
||||
```
|
||||
-force_load SDWebImage.framework/Versions/Current/SDWebImage
|
||||
```
|
||||
|
||||
If you're using Cocoa Pods and have any frameworks that extend optional libraries, such as Parsen RestKit or opencv2, instead of the -ObjC flag use:
|
||||
```
|
||||
-force_load $(TARGET_BUILD_DIR)/libPods.a
|
||||
```
|
||||
and this:
|
||||
```
|
||||
$(inherited)
|
||||
```
|
|
@ -0,0 +1,198 @@
|
|||
## SDWebImage 4.0 Migration Guide
|
||||
|
||||
SDWebImage 4.0 is the latest major release of SDWebImage, a top library for downloading and caching images.
|
||||
As a major release, following [Semantic Versioning](http://semver.org/) conventions, 4.0 introduces several API-breaking changes with its new architecture.
|
||||
|
||||
We've expanded the list of supported platforms and added to the existing **iOS** and **tvOS**, the long waited **watchOS** and **Mac OS X**.
|
||||
|
||||
Our support for animated images (especially GIFs) was not that great, so we decided to delegate this responsibility to [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage), a library created by Flipboard which has great results in working with animated images.
|
||||
|
||||
This guide is provided in order to ease the transition of existing applications using SDWebImage 3.X to the latest APIs, as well as explain the design and structure of new and changed functionality.
|
||||
|
||||
### Requirements: iOS 7, Mac OS X 10.8, watchOS 2, tvOS 9, Xcode 7.3
|
||||
|
||||
SDWebImage 4.0 officially supports iOS 7 and later, Mac OS X 10.8 and later, watchOS 2 and later and tvOS 9 and later.
|
||||
It needs Xcode 7.3 or later to be able to build everything properly.
|
||||
|
||||
For targeting previous versions of the SDKs, check [README - Backwards compatibility](https://github.com/rs/SDWebImage#backwards-compatibility)
|
||||
.
|
||||
|
||||
### Migration
|
||||
|
||||
#### Swift
|
||||
|
||||
Because the 4.0 version included #1581 - Lightweight Generics and Nullability, the Swift interface for all users has changed.
|
||||
For 3.x versions which did not have the Nullability specifiers, all params and vars where bridged as Implicitly Unwrapped Optionals.
|
||||
With 4.0, the ones marked as `nullable` will be regular optionals, as the `nonnull` ones are non-optionals.
|
||||
|
||||
For details, read [Nullability and Objective-C](https://developer.apple.com/swift/blog/?id=25).
|
||||
|
||||
#### Using the UI*View categories brings no change
|
||||
|
||||
SDWebImage 3.x
|
||||
```
|
||||
[imageView sd_setImageWithURL:url placeholderImage:placeholderImage];
|
||||
```
|
||||
|
||||
SDWebImage 4.x
|
||||
```
|
||||
[imageView sd_setImageWithURL:url placeholderImage:placeholderImage];
|
||||
```
|
||||
|
||||
#### Using directly SDWebImageManager
|
||||
|
||||
SDWebImage 3.x
|
||||
```
|
||||
[manager downloadImageWithURL:url options:options: progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { ... } ];
|
||||
```
|
||||
|
||||
SDWebImage 4.x
|
||||
```
|
||||
[manager loadImageWithURL:url options:options: progress:nil completed:^(UIImage *image, NSData *imageData, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { ... } ];
|
||||
```
|
||||
|
||||
### Entities
|
||||
|
||||
#### Added
|
||||
- `SDImageCacheConfig` class for `SDImageCache` config (`shouldDecompressImages`, `shouldDisableiCloud`, `shouldCacheImagesInMemory`, `maxCacheAge`, `maxCacheSize`)
|
||||
- `SDWebImageDownloadToken` class for the ability to cancel specific downloads (`url`, `downloadOperationCancelToken`)
|
||||
- `UIView (WebCache)` category because of DRY, with methods
|
||||
- `sd_imageURL`
|
||||
- `sd_internalSetImageWithURL:placeholderImage:options:operationKey:setImageBlock:progress:completed:`
|
||||
- `sd_cancelCurrentImageLoad`
|
||||
- `sd_showActivityIndicatorView`
|
||||
- `sd_addActivityIndicator`
|
||||
- `sd_removeActivityIndicator`
|
||||
- `SDWebImageDownloaderOperationInterface` protocol to describe the downloader operation behavior (in case one wants to customize)
|
||||
- `SDImageFormat` enum containing the formats supported by the library (jpeg, png, gif, tiff, webp)
|
||||
- `FLAnimatedImageView (WebCache)` category for `FLAnimatedImageView` from [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage)
|
||||
|
||||
#### UIImageView (WebCache)
|
||||
- moved to `UIView (WebCache)`,`UIImageView` objects still respond to those methods:
|
||||
- `sd_imageURL`
|
||||
- `sd_cancelCurrentImageLoad`
|
||||
- `setShowActivityIndicatorView:` renamed to `sd_setShowActivityIndicatorView:`
|
||||
- `setIndicatorStyle:` renamed to `sd_setIndicatorStyle:`
|
||||
- removed deprecated methods:
|
||||
- `imageURL`
|
||||
- `setImageWithURL:`
|
||||
- `setImageWithURL:placeholderImage:`
|
||||
- `setImageWithURL:placeholderImage:options:`
|
||||
- `setImageWithURL:completed:`
|
||||
- `setImageWithURL:placeholderImage:completed:`
|
||||
- `setImageWithURL:placeholderImage:options:completed:`
|
||||
- `setImageWithURL:placeholderImage:options:progress:completed:`
|
||||
- `sd_setImageWithPreviousCachedImageWithURL:andPlaceholderImage:options:progress:completed:`
|
||||
- `setAnimationImagesWithURLs:`
|
||||
- `cancelCurrentArrayLoad`
|
||||
- `cancelCurrentImageLoad`
|
||||
|
||||
#### UIButton (WebCache)
|
||||
- removed deprecated methods:
|
||||
- `currentImageURL`
|
||||
- `imageURLForState:`
|
||||
- `setImageWithURL:forState:`
|
||||
- `setImageWithURL:forState:placeholderImage:`
|
||||
- `setImageWithURL:forState:placeholderImage:options:`
|
||||
- `setImageWithURL:forState:completed:`
|
||||
- `setImageWithURL:forState:placeholderImage:completed:`
|
||||
- `setImageWithURL:forState:placeholderImage:options:completed:`
|
||||
- `setBackgroundImageWithURL:forState:`
|
||||
- `setBackgroundImageWithURL:forState:placeholderImage:`
|
||||
- `setBackgroundImageWithURL:forState:placeholderImage:options:`
|
||||
- `setBackgroundImageWithURL:forState:completed:`
|
||||
- `setBackgroundImageWithURL:forState:placeholderImage:completed:`
|
||||
- `setBackgroundImageWithURL:forState:placeholderImage:options:completed:`
|
||||
- `cancelCurrentImageLoad`
|
||||
- `cancelBackgroundImageLoadForState:`
|
||||
|
||||
#### MKAnnotationView (WebCache)
|
||||
- removed deprecated methods:
|
||||
- `imageURL`
|
||||
- `setImageWithURL:`
|
||||
- `setImageWithURL:placeholderImage:`
|
||||
- `setImageWithURL:placeholderImage:options:`
|
||||
- `setImageWithURL:completed:`
|
||||
- `setImageWithURL:placeholderImage:completed:`
|
||||
- `setImageWithURL:placeholderImage:options:completed:`
|
||||
- `cancelCurrentImageLoad`
|
||||
|
||||
#### UIImageView (HighlightedWebCache)
|
||||
- removed methods:
|
||||
- `sd_cancelCurrentHighlightedImageLoad`
|
||||
- removed deprecated methods:
|
||||
- `setHighlightedImageWithURL:`
|
||||
- `setHighlightedImageWithURL:options:`
|
||||
- `setHighlightedImageWithURL:completed:`
|
||||
- `setHighlightedImageWithURL:options:completed:`
|
||||
- `setHighlightedImageWithURL:options:progress:completed:`
|
||||
- `cancelCurrentHighlightedImageLoad`
|
||||
|
||||
#### SDWebImageManager
|
||||
- `initWithCache:downloader:` is now the designated initializer
|
||||
- added `SDWebImageScaleDownLargeImages` option for scaling large images
|
||||
- renamed `downloadImageWithURL:options:progress:completed` to `loadImageWithURL:options:progress:completed` just to make it clear what the method does
|
||||
- renamed `SDWebImageCompletionBlock` to `SDExternalCompletionBlock`
|
||||
- renamed `SDWebImageCompletionWithFinishedBlock` to `SDInternalCompletionBlock` and added extra `NSData` param
|
||||
- removed synchronous methods:
|
||||
- `cachedImageExistsForURL:`
|
||||
- `diskImageExistsForURL:`
|
||||
- removed deprecated methods:
|
||||
- `downloadWithURL:options:progress:completed:`
|
||||
- removed deprecated types:
|
||||
- `SDWebImageCompletedBlock`
|
||||
- `SDWebImageCompletedWithFinishedBlock`
|
||||
|
||||
#### SDWebImagePrefetcher
|
||||
- `initWithImageManager:` is now the designated initializer
|
||||
|
||||
#### SDWebImageDownloader
|
||||
- added `initWithSessionConfiguration:` which is now the designated initializer
|
||||
- added `SDWebImageDownloaderScaleDownLargeImages` option for scaling large images
|
||||
- added a `NSURL` param to `SDWebImageDownloaderProgressBlock`
|
||||
- `downloadImageWithURL:options:progress:completed:` now returns a `SDWebImageDownloadToken`
|
||||
- added method `cancel:` which takes a `SDWebImageDownloadToken`
|
||||
|
||||
#### SDWebImageDownloaderOperation
|
||||
- `initWithRequest:inSession:options:progress:completed:cancelled:` replaced by two methods: `initWithRequest:inSession:options:` and `addHandlersForProgress:completed:`
|
||||
- `initWithRequest:inSession:options:` is now the designated initializer
|
||||
- added `cancel:` method
|
||||
- removed deprecated methods:
|
||||
- `initWithRequest:options:progress:completed:cancelled:`
|
||||
|
||||
#### SDImageCache
|
||||
- moved the following properties to `SDImageCacheConfig`:
|
||||
- `shouldDecompressImages`
|
||||
- `shouldDisableiCloud`
|
||||
- `shouldCacheImagesInMemory`
|
||||
- `maxCacheAge`
|
||||
- `maxCacheSize`
|
||||
- added a `config` property (`SDImageCacheConfig`)
|
||||
- renamed `SDWebImageQueryCompletedBlock` to `SDCacheQueryCompletedBlock` and added `NSData` param
|
||||
- `initWithNamespace:diskCacheDirectory:` is now the designated initializer
|
||||
- the `storeImage:forKey:`, `storeImage:forKey:toDisk:`, `storeImage:recalculateFromImage:imageData:forKey:toDisk:` methods were async already, but declared as sync. Properly marked them as async + added `completion` param. Got rid of the `recalculate` param. If the `NSData` is provided, use it. Otherwise, recalculate it from the `UIImage`
|
||||
- `storeImage:forKey:` -> `storeImage:forKey:completion:`
|
||||
- `storeImage:forKey:toDisk:` -> `storeImage:forKey:toDisk:completion:`
|
||||
- `storeImage:recalculateFromImage:imageData:forKey:toDisk:` -> `storeImage:imageData:forKey:toDisk:completion:`
|
||||
- removed the synchronous method `diskImageExistsWithKey:`
|
||||
- got rid of the confusion caused by having `cleanDisk` and `clearDisk`. Renamed `cleanDiskWithCompletion:` to `deleteOldFilesWithCompletion:`.
|
||||
- removed the synchronous `clearDisk` and `deleteOldFiles`
|
||||
- renamed `queryDiskCacheForKey:done:` to `queryCacheOperationForKey:done:`
|
||||
- another clarification: `imageFromDiskCacheForKey:` used to also check the memory cache which I think is misleading. Now `imageFromDiskCacheForKey:` only checks the disk cache and the new method `imageFromCacheForKey:` checks both caches
|
||||
- removed `removeImageForKey:` and `removeImageForKey:fromDisk:` because they caused confusion (were calling the async ones with `nil` as `completion`)
|
||||
|
||||
#### NSData (ImageContentType)
|
||||
- renamed `sd_contentTypeForImageData:` to `sd_imageFormatForImageData:` and returns `SDImageFormat`
|
||||
- removed the deprecated method `contentTypeForImageData:`
|
||||
|
||||
#### SDWebImageCompat
|
||||
- removed `dispatch_main_sync_safe` as it could be mistakenly used
|
||||
- updated `dispatch_main_async_safe` so it checks for the main queue instead of the main thread
|
||||
|
||||
#### SDWebImageDecoder
|
||||
- added `decodedAndScaledDownImageWithImage:` that decodes the image and scales it down if it's too big (over 60MB in memory)
|
||||
|
||||
#### UIImage
|
||||
- removed `sd_animatedGIFNamed:` or `sd_animatedImageByScalingAndCroppingToSize:`
|
||||
- added `isGIF`
|
||||
- added `sd_imageData` and `sd_imageDataAsFormat:`. Those methods transform a `UIImage` to the `NSData` representation
|
File diff suppressed because it is too large
Load Diff
Binary file not shown.
After Width: | Height: | Size: 735 KiB |
Binary file not shown.
After Width: | Height: | Size: 129 KiB |
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629CE1D0DFD000089D7DD"
|
||||
BuildableName = "SDWebImage OSX Demo.app"
|
||||
BlueprintName = "SDWebImage OSX Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629CE1D0DFD000089D7DD"
|
||||
BuildableName = "SDWebImage OSX Demo.app"
|
||||
BlueprintName = "SDWebImage OSX Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629CE1D0DFD000089D7DD"
|
||||
BuildableName = "SDWebImage OSX Demo.app"
|
||||
BlueprintName = "SDWebImage OSX Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "OS_ACTIVITY_MODE"
|
||||
value = "disable"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629CE1D0DFD000089D7DD"
|
||||
BuildableName = "SDWebImage OSX Demo.app"
|
||||
BlueprintName = "SDWebImage OSX Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,98 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D1A51D0E1181004B36C9"
|
||||
BuildableName = "SDWebImage TV Demo.app"
|
||||
BlueprintName = "SDWebImage TV Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D1A51D0E1181004B36C9"
|
||||
BuildableName = "SDWebImage TV Demo.app"
|
||||
BlueprintName = "SDWebImage TV Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D1A51D0E1181004B36C9"
|
||||
BuildableName = "SDWebImage TV Demo.app"
|
||||
BlueprintName = "SDWebImage TV Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "OS_ACTIVITY_MODE"
|
||||
value = "disable"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<BuildableProductRunnable
|
||||
runnableDebuggingMode = "0">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D1A51D0E1181004B36C9"
|
||||
BuildableName = "SDWebImage TV Demo.app"
|
||||
BlueprintName = "SDWebImage TV Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,149 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629F91D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo Extension.appex"
|
||||
BlueprintName = "SDWebImage Watch Demo Extension"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761294155AB74D005750A4"
|
||||
BuildableName = "SDWebImage iOS Demo.app"
|
||||
BlueprintName = "SDWebImage iOS Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES"
|
||||
notificationPayloadFile = "SDWebImage Watch Demo Extension/PushNotificationPayload.apns">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.carousel"
|
||||
RemotePath = "/SDWebImage iOS Demo">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "OS_ACTIVITY_MODE"
|
||||
value = "disable"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<RemoteRunnable
|
||||
runnableDebuggingMode = "2"
|
||||
BundleIdentifier = "com.apple.carousel"
|
||||
RemotePath = "/SDWebImage iOS Demo">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</RemoteRunnable>
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "43A629ED1D0E07600089D7DD"
|
||||
BuildableName = "SDWebImage Watch Demo.app"
|
||||
BlueprintName = "SDWebImage Watch Demo"
|
||||
ReferencedContainer = "container:SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// AppDelegate.h
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// AppDelegate.m
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
|
@ -20,10 +20,10 @@
|
|||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
|
||||
{
|
||||
//Add a custom read-only cache path
|
||||
NSString *bundledPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CustomPathImages"];
|
||||
NSString *bundledPath = [[NSBundle mainBundle].resourcePath stringByAppendingPathComponent:@"CustomPathImages"];
|
||||
[[SDImageCache sharedImageCache] addReadOnlyCachePath:bundledPath];
|
||||
|
||||
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
self.window = [[UIWindow alloc] initWithFrame:[UIScreen mainScreen].bounds];
|
||||
// Override point for customization after application launch.
|
||||
|
||||
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// DetailViewController.h
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
@ -12,6 +12,4 @@
|
|||
|
||||
@property (strong, nonatomic) NSURL *imageURL;
|
||||
|
||||
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,16 +1,21 @@
|
|||
//
|
||||
// DetailViewController.m
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "DetailViewController.h"
|
||||
#import <SDWebImage/UIImageView+WebCache.h>
|
||||
#import <SDWebImage/FLAnimatedImageView+WebCache.h>
|
||||
|
||||
@interface DetailViewController ()
|
||||
|
||||
@property (strong, nonatomic) IBOutlet FLAnimatedImageView *imageView;
|
||||
|
||||
- (void)configureView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation DetailViewController
|
||||
|
@ -37,7 +42,7 @@
|
|||
[self.imageView sd_setImageWithURL:self.imageURL
|
||||
placeholderImage:nil
|
||||
options:SDWebImageProgressiveDownload
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL *targetURL) {
|
||||
if (!activityIndicator) {
|
||||
[weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]];
|
||||
activityIndicator.center = weakImageView.center;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// MasterViewController.h
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
|
|
@ -1,14 +1,45 @@
|
|||
//
|
||||
// MasterViewController.m
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "MasterViewController.h"
|
||||
#import <SDWebImage/UIImageView+WebCache.h>
|
||||
#import "DetailViewController.h"
|
||||
#import <SDWebImage/FLAnimatedImageView.h>
|
||||
#import <SDWebImage/FLAnimatedImageView+WebCache.h>
|
||||
#import <SDWebImage/UIView+WebCache.h>
|
||||
|
||||
|
||||
@interface MyCustomTableViewCell : UITableViewCell
|
||||
|
||||
@property (nonatomic, strong) UILabel *customTextLabel;
|
||||
@property (nonatomic, strong) FLAnimatedImageView *customImageView;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MyCustomTableViewCell
|
||||
|
||||
- (instancetype)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier {
|
||||
if (self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]) {
|
||||
_customImageView = [[FLAnimatedImageView alloc] initWithFrame:CGRectMake(20.0, 2.0, 60.0, 40.0)];
|
||||
[self.contentView addSubview:_customImageView];
|
||||
_customTextLabel = [[UILabel alloc] initWithFrame:CGRectMake(100.0, 12.0, 200, 20.0)];
|
||||
[self.contentView addSubview:_customTextLabel];
|
||||
|
||||
_customImageView.clipsToBounds = YES;
|
||||
_customImageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
||||
@interface MasterViewController () {
|
||||
NSMutableArray *_objects;
|
||||
|
@ -19,7 +50,7 @@
|
|||
|
||||
@synthesize detailViewController = _detailViewController;
|
||||
|
||||
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
- (instancetype)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
|
||||
{
|
||||
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
|
||||
if (self)
|
||||
|
@ -38,8 +69,12 @@
|
|||
_objects = [NSMutableArray arrayWithObjects:
|
||||
@"http://www.httpwatch.com/httpgallery/authentication/authenticatedimage/default.aspx?0.35786508303135633", // requires HTTP auth, used to demo the NTLM auth
|
||||
@"http://assets.sbnation.com/assets/2512203/dogflops.gif",
|
||||
@"https://raw.githubusercontent.com/liyong03/YLGIFImage/master/YLGIFImageDemo/YLGIFImageDemo/joy.gif",
|
||||
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp",
|
||||
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test9.webp",
|
||||
@"http://littlesvr.ca/apng/images/SteamEngine.webp",
|
||||
@"http://littlesvr.ca/apng/images/world-cup-2014-42.webp",
|
||||
@"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png",
|
||||
nil];
|
||||
|
||||
for (int i=0; i<100; i++) {
|
||||
|
@ -55,7 +90,7 @@
|
|||
- (void)flushCache
|
||||
{
|
||||
[SDWebImageManager.sharedManager.imageCache clearMemory];
|
||||
[SDWebImageManager.sharedManager.imageCache clearDisk];
|
||||
[SDWebImageManager.sharedManager.imageCache clearDiskOnCompletion:nil];
|
||||
}
|
||||
|
||||
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
|
||||
|
@ -79,20 +114,23 @@
|
|||
{
|
||||
static NSString *CellIdentifier = @"Cell";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil)
|
||||
{
|
||||
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
static UIImage *placeholderImage = nil;
|
||||
if (!placeholderImage) {
|
||||
placeholderImage = [UIImage imageNamed:@"placeholder"];
|
||||
}
|
||||
|
||||
[cell.imageView setShowActivityIndicatorView:YES];
|
||||
[cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
MyCustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[MyCustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
|
||||
}
|
||||
|
||||
cell.textLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];
|
||||
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
|
||||
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[_objects objectAtIndex:indexPath.row]]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
|
||||
[cell.customImageView sd_setShowActivityIndicatorView:YES];
|
||||
[cell.customImageView sd_setIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
|
||||
cell.customTextLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];
|
||||
[cell.customImageView sd_setImageWithURL:[NSURL URLWithString:_objects[indexPath.row]]
|
||||
placeholderImage:placeholderImage
|
||||
options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
|
||||
return cell;
|
||||
}
|
||||
|
||||
|
@ -102,7 +140,7 @@
|
|||
{
|
||||
self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
|
||||
}
|
||||
NSString *largeImageURL = [[_objects objectAtIndex:indexPath.row] stringByReplacingOccurrencesOfString:@"small" withString:@"source"];
|
||||
NSString *largeImageURL = [_objects[indexPath.row] stringByReplacingOccurrencesOfString:@"small" withString:@"source"];
|
||||
self.detailViewController.imageURL = [NSURL URLWithString:largeImageURL];
|
||||
[self.navigationController pushViewController:self.detailViewController animated:YES];
|
||||
}
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1.0</string>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
|
|
|
@ -1,164 +1,28 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1296</int>
|
||||
<string key="IBDocument.SystemVersion">11D50b</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.32</string>
|
||||
<string key="IBDocument.HIToolboxVersion">568.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">1181</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUIView</string>
|
||||
<string>IBUIImageView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="372490531">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="975951072">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUIView" id="191373211">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<array class="NSMutableArray" key="NSSubviews">
|
||||
<object class="IBUIImageView" id="268130440">
|
||||
<reference key="NSNextResponder" ref="191373211"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrameSize">{320, 460}</string>
|
||||
<reference key="NSSuperview" ref="191373211"/>
|
||||
<reference key="NSWindow"/>
|
||||
<string key="NSReuseIdentifierKey">_NS:9</string>
|
||||
<int key="IBUIContentMode">1</int>
|
||||
<bool key="IBUIUserInteractionEnabled">NO</bool>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
</array>
|
||||
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
<object class="NSColorSpace" key="NSCustomColorSpace">
|
||||
<int key="NSID">2</int>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="191373211"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">imageView</string>
|
||||
<reference key="source" ref="372490531"/>
|
||||
<reference key="destination" ref="268130440"/>
|
||||
</object>
|
||||
<int key="connectionID">8</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">1</int>
|
||||
<reference key="object" ref="191373211"/>
|
||||
<array class="NSMutableArray" key="children">
|
||||
<reference ref="268130440"/>
|
||||
</array>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="372490531"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="975951072"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">7</int>
|
||||
<reference key="object" ref="268130440"/>
|
||||
<reference key="parent" ref="191373211"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">DetailViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">8</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">DetailViewController</string>
|
||||
<string key="superclassName">UIViewController</string>
|
||||
<object class="NSMutableDictionary" key="outlets">
|
||||
<string key="NS.key.0">imageView</string>
|
||||
<string key="NS.object.0">UIImageView</string>
|
||||
</object>
|
||||
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
|
||||
<string key="NS.key.0">imageView</string>
|
||||
<object class="IBToOneOutletInfo" key="NS.object.0">
|
||||
<string key="name">imageView</string>
|
||||
<string key="candidateClassName">UIImageView</string>
|
||||
</object>
|
||||
</object>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/DetailViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
|
||||
<real value="1296" key="NS.object.0"/>
|
||||
</object>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">1181</string>
|
||||
</data>
|
||||
</archive>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="DetailViewController">
|
||||
<connections>
|
||||
<outlet property="imageView" destination="7" id="8"/>
|
||||
<outlet property="view" destination="1" id="3"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<view contentMode="scaleToFill" id="1">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleAspectFit" id="7" customClass="FLAnimatedImageView">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
</view>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -1,139 +1,25 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
|
||||
<data>
|
||||
<int key="IBDocument.SystemTarget">1280</int>
|
||||
<string key="IBDocument.SystemVersion">11C25</string>
|
||||
<string key="IBDocument.InterfaceBuilderVersion">1919</string>
|
||||
<string key="IBDocument.AppKitVersion">1138.11</string>
|
||||
<string key="IBDocument.HIToolboxVersion">566.00</string>
|
||||
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
|
||||
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="NS.object.0">916</string>
|
||||
</object>
|
||||
<array key="IBDocument.IntegratedClassDependencies">
|
||||
<string>IBProxyObject</string>
|
||||
<string>IBUITableView</string>
|
||||
</array>
|
||||
<array key="IBDocument.PluginDependencies">
|
||||
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</array>
|
||||
<object class="NSMutableDictionary" key="IBDocument.Metadata">
|
||||
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
|
||||
<integer value="1" key="NS.object.0"/>
|
||||
</object>
|
||||
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
|
||||
<object class="IBProxyObject" id="841351856">
|
||||
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBProxyObject" id="371349661">
|
||||
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
</object>
|
||||
<object class="IBUITableView" id="709618507">
|
||||
<reference key="NSNextResponder"/>
|
||||
<int key="NSvFlags">274</int>
|
||||
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
|
||||
<reference key="NSSuperview"/>
|
||||
<reference key="NSWindow"/>
|
||||
<object class="NSColor" key="IBUIBackgroundColor">
|
||||
<int key="NSColorSpace">3</int>
|
||||
<bytes key="NSWhite">MQA</bytes>
|
||||
</object>
|
||||
<bool key="IBUIClipsSubviews">YES</bool>
|
||||
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
|
||||
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBUIAlwaysBounceVertical">YES</bool>
|
||||
<int key="IBUISeparatorStyle">1</int>
|
||||
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
|
||||
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
|
||||
<float key="IBUIRowHeight">44</float>
|
||||
<float key="IBUISectionHeaderHeight">22</float>
|
||||
<float key="IBUISectionFooterHeight">22</float>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBObjectContainer" key="IBDocument.Objects">
|
||||
<array class="NSMutableArray" key="connectionRecords">
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">view</string>
|
||||
<reference key="source" ref="841351856"/>
|
||||
<reference key="destination" ref="709618507"/>
|
||||
</object>
|
||||
<int key="connectionID">3</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">dataSource</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">4</int>
|
||||
</object>
|
||||
<object class="IBConnectionRecord">
|
||||
<object class="IBCocoaTouchOutletConnection" key="connection">
|
||||
<string key="label">delegate</string>
|
||||
<reference key="source" ref="709618507"/>
|
||||
<reference key="destination" ref="841351856"/>
|
||||
</object>
|
||||
<int key="connectionID">5</int>
|
||||
</object>
|
||||
</array>
|
||||
<object class="IBMutableOrderedSet" key="objectRecords">
|
||||
<array key="orderedObjects">
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">0</int>
|
||||
<array key="object" id="0"/>
|
||||
<reference key="children" ref="1000"/>
|
||||
<nil key="parent"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-1</int>
|
||||
<reference key="object" ref="841351856"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
<string key="objectName">File's Owner</string>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">-2</int>
|
||||
<reference key="object" ref="371349661"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
<object class="IBObjectRecord">
|
||||
<int key="objectID">2</int>
|
||||
<reference key="object" ref="709618507"/>
|
||||
<reference key="parent" ref="0"/>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<dictionary class="NSMutableDictionary" key="flattenedProperties">
|
||||
<string key="-1.CustomClassName">MasterViewController</string>
|
||||
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="-2.CustomClassName">UIResponder</string>
|
||||
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
|
||||
</dictionary>
|
||||
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
|
||||
<nil key="activeLocalization"/>
|
||||
<dictionary class="NSMutableDictionary" key="localizations"/>
|
||||
<nil key="sourceID"/>
|
||||
<int key="maxID">5</int>
|
||||
</object>
|
||||
<object class="IBClassDescriber" key="IBDocument.Classes">
|
||||
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
|
||||
<object class="IBPartialClassDescription">
|
||||
<string key="className">MasterViewController</string>
|
||||
<string key="superclassName">UITableViewController</string>
|
||||
<object class="IBClassDescriptionSource" key="sourceIdentifier">
|
||||
<string key="majorKey">IBProjectSource</string>
|
||||
<string key="minorKey">./Classes/MasterViewController.h</string>
|
||||
</object>
|
||||
</object>
|
||||
</array>
|
||||
</object>
|
||||
<int key="IBDocument.localizationMode">0</int>
|
||||
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
|
||||
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
|
||||
<int key="IBDocument.defaultPropertyAccessControl">3</int>
|
||||
<string key="IBCocoaTouchPluginVersion">916</string>
|
||||
</data>
|
||||
</archive>
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="3.0" toolsVersion="10117" systemVersion="15E65" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none">
|
||||
<dependencies>
|
||||
<deployment identifier="iOS"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<objects>
|
||||
<placeholder placeholderIdentifier="IBFilesOwner" id="-1" userLabel="File's Owner" customClass="MasterViewController">
|
||||
<connections>
|
||||
<outlet property="view" destination="2" id="3"/>
|
||||
</connections>
|
||||
</placeholder>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="-2" customClass="UIResponder"/>
|
||||
<tableView clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="22" sectionFooterHeight="22" id="2">
|
||||
<rect key="frame" x="0.0" y="0.0" width="320" height="460"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<color key="backgroundColor" white="1" alpha="1" colorSpace="calibratedWhite"/>
|
||||
<freeformSimulatedSizeMetrics key="simulatedDestinationMetrics"/>
|
||||
<connections>
|
||||
<outlet property="dataSource" destination="-1" id="4"/>
|
||||
<outlet property="delegate" destination="-1" id="5"/>
|
||||
</connections>
|
||||
</tableView>
|
||||
</objects>
|
||||
</document>
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// main.m
|
||||
// SDWebImage Demo
|
||||
//
|
||||
// Created by Olivier Poitrey on 09/05/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate>
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,25 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
|
||||
// Insert code here to initialize your application
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(NSNotification *)aNotification {
|
||||
// Insert code here to tear down your application
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,58 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "16x16",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "32x32",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "128x128",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "256x256",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "mac",
|
||||
"size" : "512x512",
|
||||
"scale" : "2x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,706 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder3.Cocoa.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" initialViewController="B8D-0N-5wS">
|
||||
<dependencies>
|
||||
<deployment identifier="macosx"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="10117"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Application-->
|
||||
<scene sceneID="JPo-4y-FX3">
|
||||
<objects>
|
||||
<application id="hnw-xV-0zn" sceneMemberID="viewController">
|
||||
<menu key="mainMenu" title="Main Menu" systemMenu="main" id="AYu-sK-qS6">
|
||||
<items>
|
||||
<menuItem title="SDWebImage OSX Demo" id="1Xt-HY-uBw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="SDWebImage OSX Demo" systemMenu="apple" id="uQy-DD-JDr">
|
||||
<items>
|
||||
<menuItem title="About SDWebImage OSX Demo" id="5kV-Vb-QxS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontStandardAboutPanel:" target="Ady-hI-5gd" id="Exp-CZ-Vem"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="VOq-y0-SEH"/>
|
||||
<menuItem title="Preferences…" keyEquivalent="," id="BOF-NM-1cW"/>
|
||||
<menuItem isSeparatorItem="YES" id="wFC-TO-SCJ"/>
|
||||
<menuItem title="Services" id="NMo-om-nkz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Services" systemMenu="services" id="hz9-B4-Xy5"/>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4je-JR-u6R"/>
|
||||
<menuItem title="Hide SDWebImage OSX Demo" keyEquivalent="h" id="Olw-nP-bQN">
|
||||
<connections>
|
||||
<action selector="hide:" target="Ady-hI-5gd" id="PnN-Uc-m68"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Hide Others" keyEquivalent="h" id="Vdr-fp-XzO">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="hideOtherApplications:" target="Ady-hI-5gd" id="VT4-aY-XCT"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Show All" id="Kd2-mp-pUS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unhideAllApplications:" target="Ady-hI-5gd" id="Dhg-Le-xox"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="kCx-OE-vgT"/>
|
||||
<menuItem title="Quit SDWebImage OSX Demo" keyEquivalent="q" id="4sb-4s-VLi">
|
||||
<connections>
|
||||
<action selector="terminate:" target="Ady-hI-5gd" id="Te7-pn-YzF"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="File" id="dMs-cI-mzQ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="File" id="bib-Uj-vzu">
|
||||
<items>
|
||||
<menuItem title="New" keyEquivalent="n" id="Was-JA-tGl">
|
||||
<connections>
|
||||
<action selector="newDocument:" target="Ady-hI-5gd" id="4Si-XN-c54"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open…" keyEquivalent="o" id="IAo-SY-fd9">
|
||||
<connections>
|
||||
<action selector="openDocument:" target="Ady-hI-5gd" id="bVn-NM-KNZ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Open Recent" id="tXI-mr-wws">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Open Recent" systemMenu="recentDocuments" id="oas-Oc-fiZ">
|
||||
<items>
|
||||
<menuItem title="Clear Menu" id="vNY-rz-j42">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="clearRecentDocuments:" target="Ady-hI-5gd" id="Daa-9d-B3U"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="m54-Is-iLE"/>
|
||||
<menuItem title="Close" keyEquivalent="w" id="DVo-aG-piG">
|
||||
<connections>
|
||||
<action selector="performClose:" target="Ady-hI-5gd" id="HmO-Ls-i7Q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save…" keyEquivalent="s" id="pxx-59-PXV">
|
||||
<connections>
|
||||
<action selector="saveDocument:" target="Ady-hI-5gd" id="teZ-XB-qJY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Save As…" keyEquivalent="S" id="Bw7-FT-i3A">
|
||||
<connections>
|
||||
<action selector="saveDocumentAs:" target="Ady-hI-5gd" id="mDf-zr-I0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Revert to Saved" id="KaW-ft-85H">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="revertDocumentToSaved:" target="Ady-hI-5gd" id="iJ3-Pv-kwq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="aJh-i4-bef"/>
|
||||
<menuItem title="Page Setup…" keyEquivalent="P" id="qIS-W8-SiK">
|
||||
<modifierMask key="keyEquivalentModifierMask" shift="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="runPageLayout:" target="Ady-hI-5gd" id="Din-rz-gC5"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Print…" keyEquivalent="p" id="aTl-1u-JFS">
|
||||
<connections>
|
||||
<action selector="print:" target="Ady-hI-5gd" id="qaZ-4w-aoO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Edit" id="5QF-Oa-p0T">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Edit" id="W48-6f-4Dl">
|
||||
<items>
|
||||
<menuItem title="Undo" keyEquivalent="z" id="dRJ-4n-Yzg">
|
||||
<connections>
|
||||
<action selector="undo:" target="Ady-hI-5gd" id="M6e-cu-g7V"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Redo" keyEquivalent="Z" id="6dh-zS-Vam">
|
||||
<connections>
|
||||
<action selector="redo:" target="Ady-hI-5gd" id="oIA-Rs-6OD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="WRV-NI-Exz"/>
|
||||
<menuItem title="Cut" keyEquivalent="x" id="uRl-iY-unG">
|
||||
<connections>
|
||||
<action selector="cut:" target="Ady-hI-5gd" id="YJe-68-I9s"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy" keyEquivalent="c" id="x3v-GG-iWU">
|
||||
<connections>
|
||||
<action selector="copy:" target="Ady-hI-5gd" id="G1f-GL-Joy"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste" keyEquivalent="v" id="gVA-U4-sdL">
|
||||
<connections>
|
||||
<action selector="paste:" target="Ady-hI-5gd" id="UvS-8e-Qdg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste and Match Style" keyEquivalent="V" id="WeT-3V-zwk">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteAsPlainText:" target="Ady-hI-5gd" id="cEh-KX-wJQ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Delete" id="pa3-QI-u2k">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="delete:" target="Ady-hI-5gd" id="0Mk-Ml-PaM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Select All" keyEquivalent="a" id="Ruw-6m-B2m">
|
||||
<connections>
|
||||
<action selector="selectAll:" target="Ady-hI-5gd" id="VNm-Mi-diN"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="uyl-h8-XO2"/>
|
||||
<menuItem title="Find" id="4EN-yA-p0u">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Find" id="1b7-l0-nxx">
|
||||
<items>
|
||||
<menuItem title="Find…" tag="1" keyEquivalent="f" id="Xz5-n4-O0W">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="cD7-Qs-BN4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find and Replace…" tag="12" keyEquivalent="f" id="YEy-JH-Tfz">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="WD3-Gg-5AJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Next" tag="2" keyEquivalent="g" id="q09-fT-Sye">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="NDo-RZ-v9R"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Find Previous" tag="3" keyEquivalent="G" id="OwM-mh-QMV">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="HOh-sY-3ay"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use Selection for Find" tag="7" keyEquivalent="e" id="buJ-ug-pKt">
|
||||
<connections>
|
||||
<action selector="performFindPanelAction:" target="Ady-hI-5gd" id="U76-nv-p5D"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Jump to Selection" keyEquivalent="j" id="S0p-oC-mLd">
|
||||
<connections>
|
||||
<action selector="centerSelectionInVisibleArea:" target="Ady-hI-5gd" id="IOG-6D-g5B"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Spelling and Grammar" id="Dv1-io-Yv7">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Spelling" id="3IN-sU-3Bg">
|
||||
<items>
|
||||
<menuItem title="Show Spelling and Grammar" keyEquivalent=":" id="HFo-cy-zxI">
|
||||
<connections>
|
||||
<action selector="showGuessPanel:" target="Ady-hI-5gd" id="vFj-Ks-hy3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Document Now" keyEquivalent=";" id="hz2-CU-CR7">
|
||||
<connections>
|
||||
<action selector="checkSpelling:" target="Ady-hI-5gd" id="fz7-VC-reM"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="bNw-od-mp5"/>
|
||||
<menuItem title="Check Spelling While Typing" id="rbD-Rh-wIN">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleContinuousSpellChecking:" target="Ady-hI-5gd" id="7w6-Qz-0kB"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Check Grammar With Spelling" id="mK6-2p-4JG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleGrammarChecking:" target="Ady-hI-5gd" id="muD-Qn-j4w"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Correct Spelling Automatically" id="78Y-hA-62v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticSpellingCorrection:" target="Ady-hI-5gd" id="2lM-Qi-WAP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Substitutions" id="9ic-FL-obx">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Substitutions" id="FeM-D8-WVr">
|
||||
<items>
|
||||
<menuItem title="Show Substitutions" id="z6F-FW-3nz">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="orderFrontSubstitutionsPanel:" target="Ady-hI-5gd" id="oku-mr-iSq"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="gPx-C9-uUO"/>
|
||||
<menuItem title="Smart Copy/Paste" id="9yt-4B-nSM">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleSmartInsertDelete:" target="Ady-hI-5gd" id="3IJ-Se-DZD"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Quotes" id="hQb-2v-fYv">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticQuoteSubstitution:" target="Ady-hI-5gd" id="ptq-xd-QOA"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Dashes" id="rgM-f4-ycn">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDashSubstitution:" target="Ady-hI-5gd" id="oCt-pO-9gS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Smart Links" id="cwL-P1-jid">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticLinkDetection:" target="Ady-hI-5gd" id="Gip-E3-Fov"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Data Detectors" id="tRr-pd-1PS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticDataDetection:" target="Ady-hI-5gd" id="R1I-Nq-Kbl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Text Replacement" id="HFQ-gK-NFA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleAutomaticTextReplacement:" target="Ady-hI-5gd" id="DvP-Fe-Py6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Transformations" id="2oI-Rn-ZJC">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Transformations" id="c8a-y6-VQd">
|
||||
<items>
|
||||
<menuItem title="Make Upper Case" id="vmV-6d-7jI">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="uppercaseWord:" target="Ady-hI-5gd" id="sPh-Tk-edu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Make Lower Case" id="d9M-CD-aMd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowercaseWord:" target="Ady-hI-5gd" id="iUZ-b5-hil"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Capitalize" id="UEZ-Bs-lqG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="capitalizeWord:" target="Ady-hI-5gd" id="26H-TL-nsh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Speech" id="xrE-MZ-jX0">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Speech" id="3rS-ZA-NoH">
|
||||
<items>
|
||||
<menuItem title="Start Speaking" id="Ynk-f8-cLZ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="startSpeaking:" target="Ady-hI-5gd" id="654-Ng-kyl"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Stop Speaking" id="Oyz-dy-DGm">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="stopSpeaking:" target="Ady-hI-5gd" id="dX8-6p-jy9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Format" id="jxT-CU-nIS">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Format" id="GEO-Iw-cKr">
|
||||
<items>
|
||||
<menuItem title="Font" id="Gi5-1S-RQB">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Font" systemMenu="font" id="aXa-aM-Jaq">
|
||||
<items>
|
||||
<menuItem title="Show Fonts" keyEquivalent="t" id="Q5e-8K-NDq"/>
|
||||
<menuItem title="Bold" tag="2" keyEquivalent="b" id="GB9-OM-e27"/>
|
||||
<menuItem title="Italic" tag="1" keyEquivalent="i" id="Vjx-xi-njq"/>
|
||||
<menuItem title="Underline" keyEquivalent="u" id="WRG-CD-K1S">
|
||||
<connections>
|
||||
<action selector="underline:" target="Ady-hI-5gd" id="FYS-2b-JAY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="5gT-KC-WSO"/>
|
||||
<menuItem title="Bigger" tag="3" keyEquivalent="+" id="Ptp-SP-VEL"/>
|
||||
<menuItem title="Smaller" tag="4" keyEquivalent="-" id="i1d-Er-qST"/>
|
||||
<menuItem isSeparatorItem="YES" id="kx3-Dk-x3B"/>
|
||||
<menuItem title="Kern" id="jBQ-r6-VK2">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Kern" id="tlD-Oa-oAM">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="GUa-eO-cwY">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardKerning:" target="Ady-hI-5gd" id="6dk-9l-Ckg"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="cDB-IK-hbR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffKerning:" target="Ady-hI-5gd" id="U8a-gz-Maa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Tighten" id="46P-cB-AYj">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="tightenKerning:" target="Ady-hI-5gd" id="hr7-Nz-8ro"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Loosen" id="ogc-rX-tC1">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="loosenKerning:" target="Ady-hI-5gd" id="8i4-f9-FKE"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Ligatures" id="o6e-r0-MWq">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Ligatures" id="w0m-vy-SC9">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="agt-UL-0e3">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useStandardLigatures:" target="Ady-hI-5gd" id="7uR-wd-Dx6"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use None" id="J7y-lM-qPV">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="turnOffLigatures:" target="Ady-hI-5gd" id="iX2-gA-Ilz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Use All" id="xQD-1f-W4t">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="useAllLigatures:" target="Ady-hI-5gd" id="KcB-kA-TuK"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Baseline" id="OaQ-X3-Vso">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Baseline" id="ijk-EB-dga">
|
||||
<items>
|
||||
<menuItem title="Use Default" id="3Om-Ey-2VK">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="unscript:" target="Ady-hI-5gd" id="0vZ-95-Ywn"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Superscript" id="Rqc-34-cIF">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="superscript:" target="Ady-hI-5gd" id="3qV-fo-wpU"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Subscript" id="I0S-gh-46l">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="subscript:" target="Ady-hI-5gd" id="Q6W-4W-IGz"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Raise" id="2h7-ER-AoG">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="raiseBaseline:" target="Ady-hI-5gd" id="4sk-31-7Q9"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Lower" id="1tx-W0-xDw">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="lowerBaseline:" target="Ady-hI-5gd" id="OF1-bc-KW4"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="Ndw-q3-faq"/>
|
||||
<menuItem title="Show Colors" keyEquivalent="C" id="bgn-CT-cEk">
|
||||
<connections>
|
||||
<action selector="orderFrontColorPanel:" target="Ady-hI-5gd" id="mSX-Xz-DV3"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="iMs-zA-UFJ"/>
|
||||
<menuItem title="Copy Style" keyEquivalent="c" id="5Vv-lz-BsD">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyFont:" target="Ady-hI-5gd" id="GJO-xA-L4q"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Style" keyEquivalent="v" id="vKC-jM-MkH">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteFont:" target="Ady-hI-5gd" id="JfD-CL-leO"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Text" id="Fal-I4-PZk">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Text" id="d9c-me-L2H">
|
||||
<items>
|
||||
<menuItem title="Align Left" keyEquivalent="{" id="ZM1-6Q-yy1">
|
||||
<connections>
|
||||
<action selector="alignLeft:" target="Ady-hI-5gd" id="zUv-R1-uAa"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Center" keyEquivalent="|" id="VIY-Ag-zcb">
|
||||
<connections>
|
||||
<action selector="alignCenter:" target="Ady-hI-5gd" id="spX-mk-kcS"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Justify" id="J5U-5w-g23">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="alignJustified:" target="Ady-hI-5gd" id="ljL-7U-jND"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Align Right" keyEquivalent="}" id="wb2-vD-lq4">
|
||||
<connections>
|
||||
<action selector="alignRight:" target="Ady-hI-5gd" id="r48-bG-YeY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="4s2-GY-VfK"/>
|
||||
<menuItem title="Writing Direction" id="H1b-Si-o9J">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Writing Direction" id="8mr-sm-Yjd">
|
||||
<items>
|
||||
<menuItem title="Paragraph" enabled="NO" id="ZvO-Gk-QUH">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="YGs-j5-SAR">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionNatural:" target="Ady-hI-5gd" id="qtV-5e-UBP"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="Lbh-J2-qVU">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="S0X-9S-QSf"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="jFq-tB-4Kx">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeBaseWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="5fk-qB-AqJ"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="swp-gr-a21"/>
|
||||
<menuItem title="Selection" enabled="NO" id="cqv-fj-IhA">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
</menuItem>
|
||||
<menuItem id="Nop-cj-93Q">
|
||||
<string key="title"> Default</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionNatural:" target="Ady-hI-5gd" id="lPI-Se-ZHp"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="BgM-ve-c93">
|
||||
<string key="title"> Left to Right</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionLeftToRight:" target="Ady-hI-5gd" id="caW-Bv-w94"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem id="RB4-Sm-HuC">
|
||||
<string key="title"> Right to Left</string>
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="makeTextWritingDirectionRightToLeft:" target="Ady-hI-5gd" id="EXD-6r-ZUu"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="fKy-g9-1gm"/>
|
||||
<menuItem title="Show Ruler" id="vLm-3I-IUL">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="toggleRuler:" target="Ady-hI-5gd" id="FOx-HJ-KwY"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Copy Ruler" keyEquivalent="c" id="MkV-Pr-PK5">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="copyRuler:" target="Ady-hI-5gd" id="71i-fW-3W2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Paste Ruler" keyEquivalent="v" id="LVM-kO-fVI">
|
||||
<modifierMask key="keyEquivalentModifierMask" control="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="pasteRuler:" target="Ady-hI-5gd" id="cSh-wd-qM2"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="View" id="H8h-7b-M4v">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="View" id="HyV-fh-RgO">
|
||||
<items>
|
||||
<menuItem title="Show Toolbar" keyEquivalent="t" id="snW-S8-Cw5">
|
||||
<modifierMask key="keyEquivalentModifierMask" option="YES" command="YES"/>
|
||||
<connections>
|
||||
<action selector="toggleToolbarShown:" target="Ady-hI-5gd" id="BXY-wc-z0C"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Customize Toolbar…" id="1UK-8n-QPP">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="runToolbarCustomizationPalette:" target="Ady-hI-5gd" id="pQI-g3-MTW"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Window" id="aUF-d1-5bR">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Window" systemMenu="window" id="Td7-aD-5lo">
|
||||
<items>
|
||||
<menuItem title="Minimize" keyEquivalent="m" id="OY7-WF-poV">
|
||||
<connections>
|
||||
<action selector="performMiniaturize:" target="Ady-hI-5gd" id="VwT-WD-YPe"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem title="Zoom" id="R4o-n2-Eq4">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="performZoom:" target="Ady-hI-5gd" id="DIl-cC-cCs"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
<menuItem isSeparatorItem="YES" id="eu3-7i-yIM"/>
|
||||
<menuItem title="Bring All to Front" id="LE2-aR-0XJ">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<connections>
|
||||
<action selector="arrangeInFront:" target="Ady-hI-5gd" id="DRN-fu-gQh"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
<menuItem title="Help" id="wpr-3q-Mcd">
|
||||
<modifierMask key="keyEquivalentModifierMask"/>
|
||||
<menu key="submenu" title="Help" systemMenu="help" id="F2S-fz-NVQ">
|
||||
<items>
|
||||
<menuItem title="SDWebImage OSX Demo Help" keyEquivalent="?" id="FKE-Sm-Kum">
|
||||
<connections>
|
||||
<action selector="showHelp:" target="Ady-hI-5gd" id="y7X-2Q-9no"/>
|
||||
</connections>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
</menuItem>
|
||||
</items>
|
||||
</menu>
|
||||
<connections>
|
||||
<outlet property="delegate" destination="Voe-Tx-rLC" id="PrD-fu-P6m"/>
|
||||
</connections>
|
||||
</application>
|
||||
<customObject id="Voe-Tx-rLC" customClass="AppDelegate"/>
|
||||
<customObject id="Ady-hI-5gd" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="0.0"/>
|
||||
</scene>
|
||||
<!--Window Controller-->
|
||||
<scene sceneID="R2V-B0-nI4">
|
||||
<objects>
|
||||
<windowController id="B8D-0N-5wS" sceneMemberID="viewController">
|
||||
<window key="window" title="Window" allowsToolTipsWhenApplicationIsInactive="NO" autorecalculatesKeyViewLoop="NO" oneShot="NO" releasedWhenClosed="NO" showsToolbarButton="NO" visibleAtLaunch="NO" animationBehavior="default" id="IQv-IB-iLA">
|
||||
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
|
||||
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
|
||||
<rect key="contentRect" x="196" y="240" width="480" height="400"/>
|
||||
<rect key="screenRect" x="0.0" y="0.0" width="1680" height="1027"/>
|
||||
</window>
|
||||
<connections>
|
||||
<segue destination="XfG-lQ-9wD" kind="relationship" relationship="window.shadowedContentViewController" id="cq2-FE-JQM"/>
|
||||
</connections>
|
||||
</windowController>
|
||||
<customObject id="Oky-zY-oP4" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="250"/>
|
||||
</scene>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="hIz-AP-VOD">
|
||||
<objects>
|
||||
<viewController id="XfG-lQ-9wD" customClass="ViewController" sceneMemberID="viewController">
|
||||
<view key="view" id="m2S-Jp-Qdl">
|
||||
<rect key="frame" x="0.0" y="0.0" width="480" height="400"/>
|
||||
<autoresizingMask key="autoresizingMask"/>
|
||||
<subviews>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="nbD-Cx-g7b">
|
||||
<rect key="frame" x="20" y="252" width="204" height="128"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="vAn-1d-apO"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="kv0-67-hkh">
|
||||
<rect key="frame" x="256" y="252" width="204" height="128"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="f0P-c9-GMe"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="JIp-Or-vBM">
|
||||
<rect key="frame" x="20" y="116" width="204" height="128"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="NJq-m3-LlB"/>
|
||||
</imageView>
|
||||
<imageView horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="khI-tY-l0M">
|
||||
<rect key="frame" x="256" y="116" width="204" height="128"/>
|
||||
<imageCell key="cell" refusesFirstResponder="YES" alignment="left" imageScaling="proportionallyDown" id="WbV-Do-9qy"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="imageView1" destination="nbD-Cx-g7b" id="t2R-8w-ybH"/>
|
||||
<outlet property="imageView2" destination="kv0-67-hkh" id="i4k-5c-bno"/>
|
||||
<outlet property="imageView3" destination="JIp-Or-vBM" id="Qcf-og-59T"/>
|
||||
<outlet property="imageView4" destination="khI-tY-l0M" id="STy-c1-ihV"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<customObject id="rPt-NT-nkU" userLabel="First Responder" customClass="NSResponder" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="75" y="818"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string></string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSMinimumSystemVersion</key>
|
||||
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
|
||||
<key>NSHumanReadableCopyright</key>
|
||||
<string>Copyright © 2016 Dailymotion. All rights reserved.</string>
|
||||
<key>NSMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>NSPrincipalClass</key>
|
||||
<string>NSApplication</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface ViewController : NSViewController
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "ViewController.h"
|
||||
|
||||
@import SDWebImage;
|
||||
|
||||
@interface ViewController ()
|
||||
|
||||
@property (weak) IBOutlet NSImageView *imageView1;
|
||||
@property (weak) IBOutlet NSImageView *imageView2;
|
||||
@property (weak) IBOutlet NSImageView *imageView3;
|
||||
@property (weak) IBOutlet NSImageView *imageView4;
|
||||
|
||||
@end
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
|
||||
// NOTE: https links or authentication ones do not work (there is a crash)
|
||||
|
||||
// Do any additional setup after loading the view.
|
||||
[self.imageView1 sd_setImageWithURL:[NSURL URLWithString:@"http://assets.sbnation.com/assets/2512203/dogflops.gif"]];
|
||||
[self.imageView2 sd_setImageWithURL:[NSURL URLWithString:@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp"]];
|
||||
[self.imageView3 sd_setImageWithURL:[NSURL URLWithString:@"http://littlesvr.ca/apng/images/SteamEngine.webp"]];
|
||||
[self.imageView4 sd_setImageWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"]];
|
||||
}
|
||||
|
||||
- (void)setRepresentedObject:(id)representedObject {
|
||||
[super setRepresentedObject:representedObject];
|
||||
|
||||
// Update the view, if already loaded.
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
int main(int argc, const char * argv[]) {
|
||||
return NSApplicationMain(argc, argv);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||
|
||||
@property (strong, nonatomic) UIWindow *window;
|
||||
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "AppDelegate.h"
|
||||
|
||||
@interface AppDelegate ()
|
||||
|
||||
@end
|
||||
|
||||
@implementation AppDelegate
|
||||
|
||||
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
// Override point for customization after application launch.
|
||||
return YES;
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive:(UIApplication *)application {
|
||||
// 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.
|
||||
// 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.
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application {
|
||||
// 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.
|
||||
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application {
|
||||
// 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.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive:(UIApplication *)application {
|
||||
// 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.
|
||||
}
|
||||
|
||||
- (void)applicationWillTerminate:(UIApplication *)application {
|
||||
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"layers" : [
|
||||
{
|
||||
"filename" : "Front.imagestacklayer"
|
||||
},
|
||||
{
|
||||
"filename" : "Middle.imagestacklayer"
|
||||
},
|
||||
{
|
||||
"filename" : "Back.imagestacklayer"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"layers" : [
|
||||
{
|
||||
"filename" : "Front.imagestacklayer"
|
||||
},
|
||||
{
|
||||
"filename" : "Middle.imagestacklayer"
|
||||
},
|
||||
{
|
||||
"filename" : "Back.imagestacklayer"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"assets" : [
|
||||
{
|
||||
"size" : "1280x768",
|
||||
"idiom" : "tv",
|
||||
"filename" : "App Icon - Large.imagestack",
|
||||
"role" : "primary-app-icon"
|
||||
},
|
||||
{
|
||||
"size" : "400x240",
|
||||
"idiom" : "tv",
|
||||
"filename" : "App Icon - Small.imagestack",
|
||||
"role" : "primary-app-icon"
|
||||
},
|
||||
{
|
||||
"size" : "1920x720",
|
||||
"idiom" : "tv",
|
||||
"filename" : "Top Shelf Image.imageset",
|
||||
"role" : "top-shelf-image"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "tv",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"orientation" : "landscape",
|
||||
"idiom" : "tv",
|
||||
"extent" : "full-screen",
|
||||
"minimum-system-version" : "9.0",
|
||||
"scale" : "1x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.AppleTV.Storyboard" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="AppleTV" propertyAccessControl="none" useAutolayout="YES" initialViewController="BYZ-38-t0r">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--View Controller-->
|
||||
<scene sceneID="tne-QT-ifu">
|
||||
<objects>
|
||||
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
|
||||
<layoutGuides>
|
||||
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
|
||||
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
|
||||
</layoutGuides>
|
||||
<view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
|
||||
<rect key="frame" x="0.0" y="0.0" width="1920" height="1080"/>
|
||||
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
|
||||
<subviews>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xeq-iS-C6S" customClass="FLAnimatedImageView">
|
||||
<rect key="frame" x="20" y="20" width="300" height="200"/>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="c5h-Lg-aZx" customClass="FLAnimatedImageView">
|
||||
<rect key="frame" x="636" y="20" width="300" height="200"/>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="Udx-nH-mbX" customClass="FLAnimatedImageView">
|
||||
<rect key="frame" x="944" y="20" width="300" height="200"/>
|
||||
</imageView>
|
||||
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="xvm-ne-7D9" customClass="FLAnimatedImageView">
|
||||
<rect key="frame" x="328" y="20" width="300" height="200"/>
|
||||
</imageView>
|
||||
</subviews>
|
||||
<color key="backgroundColor" white="0.0" alpha="0.0" colorSpace="custom" customColorSpace="calibratedWhite"/>
|
||||
</view>
|
||||
<connections>
|
||||
<outlet property="imageView1" destination="xeq-iS-C6S" id="4gp-UN-VjW"/>
|
||||
<outlet property="imageView2" destination="xvm-ne-7D9" id="m95-tV-LXY"/>
|
||||
<outlet property="imageView3" destination="c5h-Lg-aZx" id="9Hg-WX-Sl2"/>
|
||||
<outlet property="imageView4" destination="Udx-nH-mbX" id="lEI-yT-cZa"/>
|
||||
</connections>
|
||||
</viewController>
|
||||
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
|
||||
</objects>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>LSRequiresIPhoneOS</key>
|
||||
<true/>
|
||||
<key>UIMainStoryboardFile</key>
|
||||
<string>Main</string>
|
||||
<key>UIRequiredDeviceCapabilities</key>
|
||||
<array>
|
||||
<string>arm64</string>
|
||||
</array>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
@interface ViewController : UIViewController
|
||||
|
||||
@end
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "ViewController.h"
|
||||
#import <SDWebImage/FLAnimatedImageView+WebCache.h>
|
||||
|
||||
@interface ViewController ()
|
||||
|
||||
@property (weak, nonatomic) IBOutlet FLAnimatedImageView *imageView1;
|
||||
@property (weak, nonatomic) IBOutlet FLAnimatedImageView *imageView2;
|
||||
@property (weak, nonatomic) IBOutlet FLAnimatedImageView *imageView3;
|
||||
@property (weak, nonatomic) IBOutlet FLAnimatedImageView *imageView4;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation ViewController
|
||||
|
||||
- (void)viewDidLoad {
|
||||
[super viewDidLoad];
|
||||
// Do any additional setup after loading the view, typically from a nib.
|
||||
|
||||
[self.imageView1 sd_setImageWithURL:[NSURL URLWithString:@"http://assets.sbnation.com/assets/2512203/dogflops.gif"]];
|
||||
[self.imageView2 sd_setImageWithURL:[NSURL URLWithString:@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp"]];
|
||||
[self.imageView3 sd_setImageWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage000.jpg"]];
|
||||
[self.imageView4 sd_setImageWithURL:[NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage001.jpg"]];
|
||||
}
|
||||
|
||||
- (void)didReceiveMemoryWarning {
|
||||
[super didReceiveMemoryWarning];
|
||||
// Dispose of any resources that can be recreated.
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,16 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
#import "AppDelegate.h"
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
@autoreleasepool {
|
||||
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
|
||||
}
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Did you know that git does not support storing empty directories?
|
|
@ -0,0 +1,13 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <WatchKit/WatchKit.h>
|
||||
|
||||
@interface ExtensionDelegate : NSObject <WKExtensionDelegate>
|
||||
|
||||
@end
|
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "ExtensionDelegate.h"
|
||||
|
||||
@implementation ExtensionDelegate
|
||||
|
||||
- (void)applicationDidFinishLaunching {
|
||||
// Perform any final initialization of your application.
|
||||
}
|
||||
|
||||
- (void)applicationDidBecomeActive {
|
||||
// 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.
|
||||
}
|
||||
|
||||
- (void)applicationWillResignActive {
|
||||
// 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.
|
||||
// Use this method to pause ongoing tasks, disable timers, etc.
|
||||
}
|
||||
|
||||
@end
|
|
@ -0,0 +1,43 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>NSAppTransportSecurity</key>
|
||||
<dict>
|
||||
<key>NSAllowsArbitraryLoads</key>
|
||||
<true/>
|
||||
</dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>SDWebImage Watch Demo Extension</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>XPC!</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>NSExtension</key>
|
||||
<dict>
|
||||
<key>NSExtensionAttributes</key>
|
||||
<dict>
|
||||
<key>WKAppBundleIdentifier</key>
|
||||
<string>com.dailymotion.SDWebImage-iOS-Demo.watchkitapp</string>
|
||||
</dict>
|
||||
<key>NSExtensionPointIdentifier</key>
|
||||
<string>com.apple.watchkit</string>
|
||||
</dict>
|
||||
<key>WKExtensionDelegateClassName</key>
|
||||
<string>ExtensionDelegate</string>
|
||||
</dict>
|
||||
</plist>
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <WatchKit/WatchKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface InterfaceController : WKInterfaceController
|
||||
|
||||
@end
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "InterfaceController.h"
|
||||
#import <SDWebImage/SDWebImageManager.h>
|
||||
|
||||
|
||||
@interface InterfaceController()
|
||||
|
||||
@property (weak) IBOutlet WKInterfaceImage *imageInterface;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation InterfaceController
|
||||
|
||||
- (void)awakeWithContext:(id)context {
|
||||
[super awakeWithContext:context];
|
||||
|
||||
// Configure interface objects here.
|
||||
}
|
||||
|
||||
- (void)willActivate {
|
||||
// This method is called when watch view controller is about to be visible to user
|
||||
[super willActivate];
|
||||
|
||||
NSString *urlString = @"https://nr-platform.s3.amazonaws.com/uploads/platform/published_extension/branding_icon/275/AmazonS3.png";
|
||||
[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:urlString] options:0 progress:nil completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
|
||||
self.imageInterface.image = image;
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)didDeactivate {
|
||||
// This method is called when watch view controller is no longer visible
|
||||
[super didDeactivate];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <WatchKit/WatchKit.h>
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface NotificationController : WKUserNotificationInterfaceController
|
||||
|
||||
@end
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "NotificationController.h"
|
||||
|
||||
|
||||
@interface NotificationController()
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NotificationController
|
||||
|
||||
- (instancetype)init {
|
||||
self = [super init];
|
||||
if (self){
|
||||
// Initialize variables here.
|
||||
// Configure interface objects here.
|
||||
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)willActivate {
|
||||
// This method is called when watch view controller is about to be visible to user
|
||||
[super willActivate];
|
||||
}
|
||||
|
||||
- (void)didDeactivate {
|
||||
// This method is called when watch view controller is no longer visible
|
||||
[super didDeactivate];
|
||||
}
|
||||
|
||||
/*
|
||||
- (void)didReceiveLocalNotification:(UILocalNotification *)localNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
|
||||
// This method is called when a local notification needs to be presented.
|
||||
// Implement it if you use a dynamic notification interface.
|
||||
// Populate your dynamic notification interface as quickly as possible.
|
||||
//
|
||||
// After populating your dynamic notification interface call the completion block.
|
||||
completionHandler(WKUserNotificationInterfaceTypeCustom);
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
- (void)didReceiveRemoteNotification:(NSDictionary *)remoteNotification withCompletion:(void (^)(WKUserNotificationInterfaceType))completionHandler {
|
||||
// This method is called when a remote notification needs to be presented.
|
||||
// Implement it if you use a dynamic notification interface.
|
||||
// Populate your dynamic notification interface as quickly as possible.
|
||||
//
|
||||
// After populating your dynamic notification interface call the completion block.
|
||||
completionHandler(WKUserNotificationInterfaceTypeCustom);
|
||||
}
|
||||
*/
|
||||
|
||||
@end
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"aps": {
|
||||
"alert": {
|
||||
"body": "Test message",
|
||||
"title": "Optional title"
|
||||
},
|
||||
"category": "myCategory"
|
||||
},
|
||||
|
||||
"WatchKit Simulator Actions": [
|
||||
{
|
||||
"title": "First Button",
|
||||
"identifier": "firstButtonAction"
|
||||
}
|
||||
],
|
||||
|
||||
"customKey": "Use this file to define a testing payload for your notifications. The aps dictionary specifies the category, alert text and title. The WatchKit Simulator Actions array can provide info for one or more action buttons in addition to the standard Dismiss button. Any other top level keys are custom payload. If you have multiple such JSON files in your project, you'll be able to select them when choosing to debug the notification interface of your Watch App."
|
||||
}
|
|
@ -0,0 +1,55 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"size" : "24x24",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "notificationCenter",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "27.5x27.5",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "notificationCenter",
|
||||
"subtype" : "42mm"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"size" : "29x29",
|
||||
"idiom" : "watch",
|
||||
"role" : "companionSettings",
|
||||
"scale" : "3x"
|
||||
},
|
||||
{
|
||||
"size" : "40x40",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "appLauncher",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "86x86",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "quickLook",
|
||||
"subtype" : "38mm"
|
||||
},
|
||||
{
|
||||
"size" : "98x98",
|
||||
"idiom" : "watch",
|
||||
"scale" : "2x",
|
||||
"role" : "quickLook",
|
||||
"subtype" : "42mm"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<document type="com.apple.InterfaceBuilder.WatchKit.Storyboard" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="watchKit" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="AgC-eL-Hgc">
|
||||
<dependencies>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
|
||||
<plugIn identifier="com.apple.InterfaceBuilder.IBWatchKitPlugin" version="10032"/>
|
||||
</dependencies>
|
||||
<scenes>
|
||||
<!--Interface Controller-->
|
||||
<scene sceneID="aou-V4-d1y">
|
||||
<objects>
|
||||
<controller id="AgC-eL-Hgc" customClass="InterfaceController">
|
||||
<items>
|
||||
<imageView height="150" alignment="left" id="tBV-Mv-OtJ"/>
|
||||
</items>
|
||||
<connections>
|
||||
<outlet property="imageInterface" destination="tBV-Mv-OtJ" id="uId-u2-it3"/>
|
||||
</connections>
|
||||
</controller>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="220" y="345"/>
|
||||
</scene>
|
||||
<!--Static Notification Interface Controller-->
|
||||
<scene sceneID="AEw-b0-oYE">
|
||||
<objects>
|
||||
<notificationController id="YCC-NB-fut">
|
||||
<items>
|
||||
<label alignment="left" text="Alert Label" id="IdU-wH-bcW"/>
|
||||
</items>
|
||||
<notificationCategory key="notificationCategory" identifier="myCategory" id="JfB-70-Muf"/>
|
||||
<connections>
|
||||
<outlet property="notificationAlertLabel" destination="IdU-wH-bcW" id="JKC-fr-R95"/>
|
||||
<segue destination="4sK-HA-Art" kind="relationship" relationship="dynamicNotificationInterface" id="kXh-Jw-8B1"/>
|
||||
</connections>
|
||||
</notificationController>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="220" y="643"/>
|
||||
</scene>
|
||||
<!--Notification Controller-->
|
||||
<scene sceneID="ZPc-GJ-vnh">
|
||||
<objects>
|
||||
<controller id="4sK-HA-Art" customClass="NotificationController"/>
|
||||
</objects>
|
||||
<point key="canvasLocation" x="468" y="643"/>
|
||||
</scene>
|
||||
</scenes>
|
||||
</document>
|
|
@ -0,0 +1,35 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>CFBundleDevelopmentRegion</key>
|
||||
<string>en</string>
|
||||
<key>CFBundleDisplayName</key>
|
||||
<string>SDWebImage iOS Demo</string>
|
||||
<key>CFBundleExecutable</key>
|
||||
<string>$(EXECUTABLE_NAME)</string>
|
||||
<key>CFBundleIdentifier</key>
|
||||
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
|
||||
<key>CFBundleInfoDictionaryVersion</key>
|
||||
<string>6.0</string>
|
||||
<key>CFBundleName</key>
|
||||
<string>$(PRODUCT_NAME)</string>
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>1.0</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>1</string>
|
||||
<key>UISupportedInterfaceOrientations</key>
|
||||
<array>
|
||||
<string>UIInterfaceOrientationPortrait</string>
|
||||
<string>UIInterfaceOrientationPortraitUpsideDown</string>
|
||||
</array>
|
||||
<key>WKCompanionAppBundleIdentifier</key>
|
||||
<string>com.dailymotion.SDWebImage-iOS-Demo</string>
|
||||
<key>WKWatchKitApp</key>
|
||||
<true/>
|
||||
</dict>
|
||||
</plist>
|
318
README.md
318
README.md
|
@ -1,185 +1,100 @@
|
|||
Web Image
|
||||
=========
|
||||
<p align="center" >
|
||||
<img src="SDWebImage_logo.png" title="SDWebImage logo" float=left>
|
||||
</p>
|
||||
|
||||
|
||||
[![Build Status](http://img.shields.io/travis/rs/SDWebImage/master.svg?style=flat)](https://travis-ci.org/rs/SDWebImage)
|
||||
[![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
[![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
[![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)
|
||||
[![Dependency Status](https://www.versioneye.com/objective-c/sdwebimage/3.3/badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/3.3)
|
||||
[![Dependency Status](https://www.versioneye.com/objective-c/sdwebimage/badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage)
|
||||
[![Reference Status](https://www.versioneye.com/objective-c/sdwebimage/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/references)
|
||||
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/rs/SDWebImage)
|
||||
[![codecov](https://codecov.io/gh/rs/SDWebImage/branch/master/graph/badge.svg)](https://codecov.io/gh/rs/SDWebImage)
|
||||
|
||||
This library provides a category for UIImageView with support for remote images coming from the web.
|
||||
This library provides an async image downloader with cache support. For convenience, we added categories for UI elements like `UIImageView`, `UIButton`, `MKAnnotationView`.
|
||||
|
||||
It provides:
|
||||
## Features
|
||||
|
||||
- An `UIImageView` category adding web image and cache management to the Cocoa Touch framework
|
||||
- An asynchronous image downloader
|
||||
- An asynchronous memory + disk image caching with automatic cache expiration handling
|
||||
- Animated GIF support
|
||||
- WebP format support
|
||||
- A background image decompression
|
||||
- A guarantee that the same URL won't be downloaded several times
|
||||
- A guarantee that bogus URLs won't be retried again and again
|
||||
- A guarantee that main thread will never be blocked
|
||||
- Performances!
|
||||
- Use GCD and ARC
|
||||
- Arm64 support
|
||||
- [x] Categories for `UIImageView`, `UIButton`, `MKAnnotationView` adding web image and cache management
|
||||
- [x] An asynchronous image downloader
|
||||
- [x] An asynchronous memory + disk image caching with automatic cache expiration handling
|
||||
- [x] A background image decompression
|
||||
- [x] A guarantee that the same URL won't be downloaded several times
|
||||
- [x] A guarantee that bogus URLs won't be retried again and again
|
||||
- [x] A guarantee that main thread will never be blocked
|
||||
- [x] Performances!
|
||||
- [x] Use GCD and ARC
|
||||
|
||||
NOTE: Version 3.8 of SDWebImage requires iOS 7 or later (because of NSURLSession).
|
||||
Versions 3.7 to 3.0 requires iOS 5.1.1. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat).
|
||||
## Supported Image Formats
|
||||
|
||||
[How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F)
|
||||
- Image formats supported by UIImage (JPEG, PNG, ...), including GIF
|
||||
- WebP format, including animated WebP (use the `WebP` subspec)
|
||||
|
||||
Who Uses It
|
||||
----------
|
||||
## Requirements
|
||||
|
||||
Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list.
|
||||
- iOS 7.0 or later
|
||||
- tvOS 9.0 or later
|
||||
- watchOS 2.0 or later
|
||||
- OS X 10.8 or later
|
||||
- Xcode 7.3 or later
|
||||
|
||||
How To Use
|
||||
----------
|
||||
#### Backwards compatibility
|
||||
|
||||
API documentation is available at [CocoaDocs - SDWebImage](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
- For iOS 5 and 6, use [any 3.x version up to 3.7.6](https://github.com/rs/SDWebImage/tree/3.7.6)
|
||||
- For iOS < 5.0, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat).
|
||||
|
||||
### Using UIImageView+WebCache category with UITableView
|
||||
## Getting Started
|
||||
|
||||
Just #import the UIImageView+WebCache.h header, and call the sd_setImageWithURL:placeholderImage:
|
||||
method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be
|
||||
handled for you, from async downloads to caching management.
|
||||
- Read this Readme doc
|
||||
- Read the [How to use section](https://github.com/rs/SDWebImage#how-to-use)
|
||||
- Read the [documentation @ CocoaDocs](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
- Read [How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F)
|
||||
- Try the example by downloading the project from Github or even easier using CocoaPods try `pod try SDWebImage`
|
||||
- Get to the [installation steps](https://github.com/rs/SDWebImage#installation)
|
||||
- Read the [SDWebImage 4.0 Migration Guide](Docs/SDWebImage-4.0-Migration-guide.md) to get an idea of the changes from 3.x to 4.x
|
||||
|
||||
## Who Uses It
|
||||
- Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list.
|
||||
|
||||
## Communication
|
||||
|
||||
- If you **need help**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage). (Tag 'sdwebimage')
|
||||
- If you'd like to **ask a general question**, use [Stack Overflow](http://stackoverflow.com/questions/tagged/sdwebimage).
|
||||
- If you **found a bug**, open an issue.
|
||||
- If you **have a feature request**, open an issue.
|
||||
- If you **want to contribute**, submit a pull request.
|
||||
|
||||
## Installation
|
||||
|
||||
## How To Use
|
||||
|
||||
```objective-c
|
||||
Objective-C:
|
||||
|
||||
#import <SDWebImage/UIImageView+WebCache.h>
|
||||
|
||||
...
|
||||
|
||||
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
|
||||
static NSString *MyIdentifier = @"MyIdentifier";
|
||||
|
||||
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
|
||||
if (cell == nil) {
|
||||
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
|
||||
reuseIdentifier:MyIdentifier] autorelease];
|
||||
}
|
||||
|
||||
// Here we use the new provided sd_setImageWithURL: method to load the web image
|
||||
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
|
||||
|
||||
cell.textLabel.text = @"My Text";
|
||||
return cell;
|
||||
}
|
||||
[imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
|
||||
```
|
||||
|
||||
### Using blocks
|
||||
```swift
|
||||
Swift:
|
||||
|
||||
With blocks, you can be notified about the image download progress and whenever the image retrieval
|
||||
has completed with success or not:
|
||||
@import SDWebImage
|
||||
|
||||
```objective-c
|
||||
// Here we use the new provided sd_setImageWithURL: method to load the web image
|
||||
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
|
||||
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
|
||||
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
|
||||
... completion code here ...
|
||||
}];
|
||||
imageView.sd_setImage(with: URL(string: "http://www.domain.com/path/to/image.jpg"), placeholderImage: UIImage(named: "placeholder.png"))
|
||||
```
|
||||
|
||||
Note: neither your success nor failure block will be call if your image request is canceled before completion.
|
||||
- For details about how to use the library and clear examples, see [The detailed How to use](Docs/HowToUse.md)
|
||||
|
||||
### Using SDWebImageManager
|
||||
|
||||
The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the
|
||||
asynchronous downloader with the image cache store. You can use this class directly to benefit
|
||||
from web image downloading with caching in another context than a UIView (ie: with Cocoa).
|
||||
|
||||
Here is a simple example of how to use SDWebImageManager:
|
||||
|
||||
```objective-c
|
||||
SDWebImageManager *manager = [SDWebImageManager sharedManager];
|
||||
[manager downloadImageWithURL:imageURL
|
||||
options:0
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
// progression tracking code
|
||||
}
|
||||
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
|
||||
if (image) {
|
||||
// do something with image
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### Using Asynchronous Image Downloader Independently
|
||||
|
||||
It's also possible to use the async image downloader independently:
|
||||
|
||||
```objective-c
|
||||
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
|
||||
[downloader downloadImageWithURL:imageURL
|
||||
options:0
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
// progression tracking code
|
||||
}
|
||||
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
|
||||
if (image && finished) {
|
||||
// do something with image
|
||||
}
|
||||
}];
|
||||
```
|
||||
|
||||
### Using Asynchronous Image Caching Independently
|
||||
|
||||
It is also possible to use the async based image cache store independently. SDImageCache
|
||||
maintains a memory cache and an optional disk cache. Disk cache write operations are performed
|
||||
asynchronous so it doesn't add unnecessary latency to the UI.
|
||||
|
||||
The SDImageCache class provides a singleton instance for convenience but you can create your own
|
||||
instance if you want to create separated cache namespace.
|
||||
|
||||
To lookup the cache, you use the `queryDiskCacheForKey:done:` method. If the method returns nil, it means the cache
|
||||
doesn't currently own the image. You are thus responsible for generating and caching it. The cache
|
||||
key is an application unique identifier for the image to cache. It is generally the absolute URL of
|
||||
the image.
|
||||
|
||||
```objective-c
|
||||
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"];
|
||||
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) {
|
||||
// image is not nil if image was found
|
||||
}];
|
||||
```
|
||||
|
||||
By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache.
|
||||
You can prevent this from happening by calling the alternative method `imageFromMemoryCacheForKey:`.
|
||||
|
||||
To store an image into the cache, you use the storeImage:forKey: method:
|
||||
|
||||
```objective-c
|
||||
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
|
||||
```
|
||||
|
||||
By default, the image will be stored in memory cache as well as on disk cache (asynchronously). If
|
||||
you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative
|
||||
third argument.
|
||||
|
||||
### Using cache key filter
|
||||
|
||||
Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic
|
||||
(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter that
|
||||
takes the NSURL as input, and output a cache key NSString.
|
||||
|
||||
The following example sets a filter in the application delegate that will remove any query-string from
|
||||
the URL before to use it as a cache key:
|
||||
|
||||
```objective-c
|
||||
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
|
||||
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
|
||||
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
|
||||
return [url absoluteString];
|
||||
};
|
||||
|
||||
// Your app init code...
|
||||
return YES;
|
||||
}
|
||||
```
|
||||
## Animated Images (GIF) support
|
||||
|
||||
- Starting with the 4.0 version, we rely on [FLAnimatedImage](https://github.com/Flipboard/FLAnimatedImage) to take care of our animated images.
|
||||
- If you use cocoapods, add `pod 'SDWebImage/GIF'` to your podfile.
|
||||
- To use it, simply make sure you use `FLAnimatedImageView` instead of `UIImageView`.
|
||||
- **Note**: there is a backwards compatible feature, so if you are still trying to load a GIF into a `UIImageView`, it will only show the 1st frame as a static image.
|
||||
- **Important**: FLAnimatedImage only works on the iOS platform, so for all the other platforms (OS X, tvOS, watchOS) we will fallback to the backwards compatibility feature described above
|
||||
|
||||
Common Problems
|
||||
---------------
|
||||
|
@ -201,21 +116,31 @@ If you don't control the image server you're using, you may not be able to chang
|
|||
|
||||
``` objective-c
|
||||
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
|
||||
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
|
||||
options:SDWebImageRefreshCached];
|
||||
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
|
||||
options:SDWebImageRefreshCached];
|
||||
```
|
||||
|
||||
### Add a progress indicator
|
||||
|
||||
See this category: https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage
|
||||
Add these before you call ```sd_setImageWithURL```
|
||||
|
||||
``` objective-c
|
||||
[imageView sd_setShowActivityIndicatorView:YES];
|
||||
[imageView sd_setIndicatorStyle:UIActivityIndicatorViewStyleGray];
|
||||
```
|
||||
|
||||
``` swift
|
||||
imageView.sd_setShowActivityIndicatorView(true)
|
||||
imageView.sd_setIndicatorStyle(.Gray)
|
||||
```
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
||||
There are three ways to use SDWebImage in your project:
|
||||
- using CocoaPods
|
||||
- copying all the files into your project
|
||||
- importing the project as a static library
|
||||
- using Carthage
|
||||
- by cloning the project into your repository
|
||||
|
||||
### Installation with CocoaPods
|
||||
|
||||
|
@ -235,7 +160,7 @@ use_frameworks!
|
|||
|
||||
#### Subspecs
|
||||
|
||||
There are 3 subspecs available now: `Core`, `MapKit` and `WebP` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `WebP`, you need to specify it).
|
||||
There are 4 subspecs available now: `Core`, `MapKit`, `GIF` and `WebP` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `WebP`, you need to specify it).
|
||||
|
||||
Podfile example:
|
||||
```
|
||||
|
@ -253,63 +178,8 @@ To install with carthage, follow the instruction on [Carthage](https://github.co
|
|||
github "rs/SDWebImage"
|
||||
```
|
||||
|
||||
#### Usage
|
||||
Swift
|
||||
|
||||
If you installed using CocoaPods:
|
||||
```
|
||||
import SDWebImage
|
||||
```
|
||||
|
||||
If you installed manually:
|
||||
```
|
||||
import WebImage
|
||||
```
|
||||
|
||||
Objective-C
|
||||
|
||||
```
|
||||
@import WebImage;
|
||||
```
|
||||
|
||||
### Installation by cloning the repository
|
||||
|
||||
In order to gain access to all the files from the repository, you should clone it.
|
||||
```
|
||||
git clone --recursive https://github.com/rs/SDWebImage.git
|
||||
```
|
||||
|
||||
### Add the SDWebImage project to your project
|
||||
|
||||
- Download and unzip the last version of the framework from the [download page](https://github.com/rs/SDWebImage/releases)
|
||||
- Right-click on the project navigator and select "Add Files to "Your Project":
|
||||
- In the dialog, select SDWebImage.framework:
|
||||
- Check the "Copy items into destination group's folder (if needed)" checkbox
|
||||
|
||||
### Add dependencies
|
||||
|
||||
- In you application project app’s target settings, find the "Build Phases" section and open the "Link Binary With Libraries" block:
|
||||
- Click the "+" button again and select the "ImageIO.framework", this is needed by the progressive download feature:
|
||||
|
||||
### Add Linker Flag
|
||||
|
||||
Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag:
|
||||
|
||||
![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg)
|
||||
|
||||
Alternatively, if this causes compilation problems with frameworks that extend optional libraries, such as Parse, RestKit or opencv2, instead of the -ObjC flag use:
|
||||
```
|
||||
-force_load SDWebImage.framework/Versions/Current/SDWebImage
|
||||
```
|
||||
|
||||
If you're using Cocoa Pods and have any frameworks that extend optional libraries, such as Parsen RestKit or opencv2, instead of the -ObjC flag use:
|
||||
```
|
||||
-force_load $(TARGET_BUILD_DIR)/libPods.a
|
||||
```
|
||||
and this:
|
||||
```
|
||||
$(inherited)
|
||||
```
|
||||
- see [Manual install](Docs/ManualInstallation.md)
|
||||
|
||||
### Import headers in your source files
|
||||
|
||||
|
@ -324,11 +194,23 @@ In the source files where you need to use the library, import the header file:
|
|||
At this point your workspace should build without error. If you are having problem, post to the Issue and the
|
||||
community can help you solve it.
|
||||
|
||||
Future Enhancements
|
||||
-------------------
|
||||
## Author
|
||||
- [Olivier Poitrey](https://github.com/rs)
|
||||
|
||||
- LRU memory cache cleanup instead of reset on memory warning
|
||||
## Collaborators
|
||||
- [Konstantinos K.](https://github.com/mythodeia)
|
||||
- [Bogdan Poplauschi](https://github.com/bpoplauschi)
|
||||
|
||||
## Licenses
|
||||
|
||||
All source code is licensed under the [MIT License](https://raw.github.com/rs/SDWebImage/master/LICENSE).
|
||||
|
||||
## Architecture
|
||||
|
||||
<p align="center" >
|
||||
<img src="Docs/SDWebImageClassDiagram.png" title="SDWebImage class diagram">
|
||||
</p>
|
||||
|
||||
<p align="center" >
|
||||
<img src="Docs/SDWebImageSequenceDiagram.png" title="SDWebImage sequence diagram">
|
||||
</p>
|
||||
|
|
|
@ -1,8 +1,12 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'SDWebImage'
|
||||
s.version = '3.8.2'
|
||||
s.version = '4.0.0'
|
||||
|
||||
s.osx.deployment_target = '10.8'
|
||||
s.ios.deployment_target = '7.0'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
s.watchos.deployment_target = '2.0'
|
||||
|
||||
s.license = 'MIT'
|
||||
s.summary = 'Asynchronous image downloader with cache support with an UIImageView category.'
|
||||
s.homepage = 'https://github.com/rs/SDWebImage'
|
||||
|
@ -29,18 +33,34 @@ Pod::Spec.new do |s|
|
|||
end
|
||||
|
||||
s.subspec 'MapKit' do |mk|
|
||||
mk.osx.deployment_target = '10.8'
|
||||
mk.ios.deployment_target = '7.0'
|
||||
mk.tvos.deployment_target = '9.0'
|
||||
mk.source_files = 'SDWebImage/MKAnnotationView+WebCache.*'
|
||||
mk.framework = 'MapKit'
|
||||
mk.dependency 'SDWebImage/Core'
|
||||
end
|
||||
|
||||
s.subspec 'GIF' do |gif|
|
||||
gif.ios.deployment_target = '7.0'
|
||||
gif.source_files = 'SDWebImage/FLAnimatedImage/*.{h,m}'
|
||||
gif.dependency 'SDWebImage/Core'
|
||||
gif.dependency 'FLAnimatedImage', '~> 1.0'
|
||||
gif.xcconfig = {
|
||||
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/FLAnimatedImage/FLAnimatedImage'
|
||||
}
|
||||
end
|
||||
|
||||
s.subspec 'WebP' do |webp|
|
||||
webp.source_files = 'SDWebImage/UIImage+WebP.{h,m}'
|
||||
webp.xcconfig = {
|
||||
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1',
|
||||
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
|
||||
}
|
||||
webp.watchos.xcconfig = {
|
||||
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1 WEBP_USE_INTRINSICS=1',
|
||||
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
|
||||
}
|
||||
webp.dependency 'SDWebImage/Core'
|
||||
webp.dependency 'libwebp'
|
||||
end
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -14,9 +14,9 @@
|
|||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BlueprintIdentifier = "4397D2761D0DDD8C00BB2784"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage OSX"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -45,9 +45,9 @@
|
|||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BlueprintIdentifier = "4397D2761D0DDD8C00BB2784"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage OSX"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -63,9 +63,9 @@
|
|||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BlueprintIdentifier = "4397D2761D0DDD8C00BB2784"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage OSX"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -15,8 +15,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761307155AD0D5005750A4"
|
||||
BuildableName = "libSDWebImage.a"
|
||||
BlueprintName = "SDWebImage"
|
||||
BuildableName = "libSDWebImage iOS static.a"
|
||||
BlueprintName = "SDWebImage iOS static"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -46,8 +46,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761307155AD0D5005750A4"
|
||||
BuildableName = "libSDWebImage.a"
|
||||
BlueprintName = "SDWebImage"
|
||||
BuildableName = "libSDWebImage iOS static.a"
|
||||
BlueprintName = "SDWebImage iOS static"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -15,8 +15,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage iOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -46,8 +46,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage iOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -64,8 +64,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage iOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -15,8 +15,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage tvOS"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage tvOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -46,8 +46,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage tvOS"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage tvOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -64,8 +64,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
|
||||
BuildableName = "WebImage.framework"
|
||||
BlueprintName = "WebImage tvOS"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage tvOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
|
@ -0,0 +1,80 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D11B1D0E0E3B004B36C9"
|
||||
BuildableName = "libSDWebImage watchOS static.a"
|
||||
BlueprintName = "SDWebImage watchOS static"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D11B1D0E0E3B004B36C9"
|
||||
BuildableName = "libSDWebImage watchOS static.a"
|
||||
BlueprintName = "SDWebImage watchOS static"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "4314D11B1D0E0E3B004B36C9"
|
||||
BuildableName = "libSDWebImage watchOS static.a"
|
||||
BlueprintName = "SDWebImage watchOS static"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -14,9 +14,9 @@
|
|||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "531041C2157EAFA400BBABC3"
|
||||
BuildableName = "libSDWebImage+MKAnnotation.a"
|
||||
BlueprintName = "SDWebImage+MKAnnotation"
|
||||
BlueprintIdentifier = "431BB6891D06D2C1006A3455"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage watchOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -45,9 +45,9 @@
|
|||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "531041C2157EAFA400BBABC3"
|
||||
BuildableName = "libSDWebImage+MKAnnotation.a"
|
||||
BlueprintName = "SDWebImage+MKAnnotation"
|
||||
BlueprintIdentifier = "431BB6891D06D2C1006A3455"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage watchOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -60,6 +60,15 @@
|
|||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "431BB6891D06D2C1006A3455"
|
||||
BuildableName = "SDWebImage.framework"
|
||||
BlueprintName = "SDWebImage watchOS"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
|
@ -19,6 +19,9 @@
|
|||
<FileRef
|
||||
location = "group:CHANGELOG.md">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Docs">
|
||||
</FileRef>
|
||||
<FileRef
|
||||
location = "group:Tests/Pods/Pods.xcodeproj">
|
||||
</FileRef>
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||
<plist version="1.0">
|
||||
<dict>
|
||||
<key>IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded</key>
|
||||
<false/>
|
||||
</dict>
|
||||
</plist>
|
|
@ -1,6 +1,6 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
LastUpgradeVersion = "0800"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
|
@ -15,8 +15,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761294155AB74D005750A4"
|
||||
BuildableName = "SDWebImage Demo.app"
|
||||
BlueprintName = "SDWebImage Demo"
|
||||
BuildableName = "SDWebImage iOS Demo.app"
|
||||
BlueprintName = "SDWebImage iOS Demo"
|
||||
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
|
@ -33,8 +33,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761294155AB74D005750A4"
|
||||
BuildableName = "SDWebImage Demo.app"
|
||||
BlueprintName = "SDWebImage Demo"
|
||||
BuildableName = "SDWebImage iOS Demo.app"
|
||||
BlueprintName = "SDWebImage iOS Demo"
|
||||
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
|
@ -56,11 +56,18 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761294155AB74D005750A4"
|
||||
BuildableName = "SDWebImage Demo.app"
|
||||
BlueprintName = "SDWebImage Demo"
|
||||
BuildableName = "SDWebImage iOS Demo.app"
|
||||
BlueprintName = "SDWebImage iOS Demo"
|
||||
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
||||
<EnvironmentVariables>
|
||||
<EnvironmentVariable
|
||||
key = "OS_ACTIVITY_MODE"
|
||||
value = "disable"
|
||||
isEnabled = "YES">
|
||||
</EnvironmentVariable>
|
||||
</EnvironmentVariables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
|
@ -75,8 +82,8 @@
|
|||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "53761294155AB74D005750A4"
|
||||
BuildableName = "SDWebImage Demo.app"
|
||||
BlueprintName = "SDWebImage Demo"
|
||||
BuildableName = "SDWebImage iOS Demo.app"
|
||||
BlueprintName = "SDWebImage iOS Demo"
|
||||
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildableProductRunnable>
|
|
@ -1,71 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537D957317ECC1FE0097C263"
|
||||
BuildableName = "libSDWebImage+WebP.a"
|
||||
BlueprintName = "SDWebImage+WebP"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "537D957317ECC1FE0097C263"
|
||||
BuildableName = "libSDWebImage+WebP.a"
|
||||
BlueprintName = "SDWebImage+WebP"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -1,71 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Scheme
|
||||
LastUpgradeVersion = "0710"
|
||||
version = "1.3">
|
||||
<BuildAction
|
||||
parallelizeBuildables = "YES"
|
||||
buildImplicitDependencies = "YES">
|
||||
<BuildActionEntries>
|
||||
<BuildActionEntry
|
||||
buildForTesting = "YES"
|
||||
buildForRunning = "YES"
|
||||
buildForProfiling = "YES"
|
||||
buildForArchiving = "YES"
|
||||
buildForAnalyzing = "YES">
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "539F912B16316D2D00160719"
|
||||
BuildableName = "SDWebImageFramework"
|
||||
BlueprintName = "SDWebImageFramework"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</BuildActionEntry>
|
||||
</BuildActionEntries>
|
||||
</BuildAction>
|
||||
<TestAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES">
|
||||
<Testables>
|
||||
</Testables>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</TestAction>
|
||||
<LaunchAction
|
||||
buildConfiguration = "Debug"
|
||||
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
|
||||
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
|
||||
launchStyle = "0"
|
||||
useCustomWorkingDirectory = "NO"
|
||||
ignoresPersistentStateOnLaunch = "NO"
|
||||
debugDocumentVersioning = "YES"
|
||||
debugServiceExtension = "internal"
|
||||
allowLocationSimulation = "YES">
|
||||
<MacroExpansion>
|
||||
<BuildableReference
|
||||
BuildableIdentifier = "primary"
|
||||
BlueprintIdentifier = "539F912B16316D2D00160719"
|
||||
BuildableName = "SDWebImageFramework"
|
||||
BlueprintName = "SDWebImageFramework"
|
||||
ReferencedContainer = "container:SDWebImage.xcodeproj">
|
||||
</BuildableReference>
|
||||
</MacroExpansion>
|
||||
<AdditionalOptions>
|
||||
</AdditionalOptions>
|
||||
</LaunchAction>
|
||||
<ProfileAction
|
||||
buildConfiguration = "Release"
|
||||
shouldUseLaunchSchemeArgsEnv = "YES"
|
||||
savedToolIdentifier = ""
|
||||
useCustomWorkingDirectory = "NO"
|
||||
debugDocumentVersioning = "YES">
|
||||
</ProfileAction>
|
||||
<AnalyzeAction
|
||||
buildConfiguration = "Debug">
|
||||
</AnalyzeAction>
|
||||
<ArchiveAction
|
||||
buildConfiguration = "Release"
|
||||
revealArchiveInOrganizer = "YES">
|
||||
</ArchiveAction>
|
||||
</Scheme>
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
#if SD_UIKIT
|
||||
|
||||
#if __has_include(<FLAnimatedImage/FLAnimatedImage.h>)
|
||||
#import <FLAnimatedImage/FLAnimatedImage.h>
|
||||
#else
|
||||
#import "FLAnimatedImageView.h"
|
||||
#endif
|
||||
|
||||
#import "SDWebImageManager.h"
|
||||
|
||||
|
||||
/**
|
||||
* A category for the FLAnimatedImage imageView class that hooks it to the SDWebImage system.
|
||||
* Very similar to the base class category (UIImageView (WebCache))
|
||||
*/
|
||||
@interface FLAnimatedImageView (WebCache)
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
* Uses a placeholder until the request finishes.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
* Uses a placeholder until the request finishes.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param completedBlock A block called when operation has been completed. This block has no return value
|
||||
* and takes the requested UIImage as first parameter. In case of error the image parameter
|
||||
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
|
||||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
* Uses a placeholder until the request finishes.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
* @param completedBlock A block called when operation has been completed. This block has no return value
|
||||
* and takes the requested UIImage as first parameter. In case of error the image parameter
|
||||
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
|
||||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
* Uses a placeholder until the request finishes.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
|
||||
* @param completedBlock A block called when operation has been completed. This block has no return value
|
||||
* and takes the requested UIImage as first parameter. In case of error the image parameter
|
||||
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
|
||||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Load the image at the given url (either from cache or download) and load it in this imageView. It works with both static and dynamic images
|
||||
* The download is asynchronous and cached.
|
||||
* Uses a placeholder until the request finishes.
|
||||
*
|
||||
* @param url The url for the image.
|
||||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
|
||||
* @param progressBlock A block called while image is downloading
|
||||
* @note the progress block is executed on a background queue
|
||||
* @param completedBlock A block called when operation has been completed. This block has no return value
|
||||
* and takes the requested UIImage as first parameter. In case of error the image parameter
|
||||
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
|
||||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options
|
||||
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "FLAnimatedImageView+WebCache.h"
|
||||
|
||||
#if SD_UIKIT
|
||||
#import "objc/runtime.h"
|
||||
#import "UIView+WebCacheOperation.h"
|
||||
#import "UIView+WebCache.h"
|
||||
#import "NSData+ImageContentType.h"
|
||||
#import "FLAnimatedImage.h"
|
||||
#import "UIImageView+WebCache.h"
|
||||
|
||||
@implementation FLAnimatedImageView (WebCache)
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options
|
||||
progress:(nullable SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
__weak typeof(self)weakSelf = self;
|
||||
[self sd_internalSetImageWithURL:url
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
operationKey:nil
|
||||
setImageBlock:^(UIImage *image, NSData *imageData) {
|
||||
SDImageFormat imageFormat = [NSData sd_imageFormatForImageData:imageData];
|
||||
if (imageFormat == SDImageFormatGIF) {
|
||||
weakSelf.animatedImage = [FLAnimatedImage animatedImageWithGIFData:imageData];
|
||||
weakSelf.image = nil;
|
||||
} else {
|
||||
weakSelf.image = image;
|
||||
weakSelf.animatedImage = nil;
|
||||
}
|
||||
}
|
||||
progress:progressBlock
|
||||
completed:completedBlock];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
|
@ -1,12 +1,16 @@
|
|||
//
|
||||
// MKAnnotationView+WebCache.h
|
||||
// SDWebImage
|
||||
//
|
||||
// Created by Olivier Poitrey on 14/03/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "MapKit/MapKit.h"
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
#if SD_UIKIT || SD_MAC
|
||||
|
||||
#import <MapKit/MapKit.h>
|
||||
#import "SDWebImageManager.h"
|
||||
|
||||
/**
|
||||
|
@ -14,14 +18,6 @@
|
|||
*/
|
||||
@interface MKAnnotationView (WebCache)
|
||||
|
||||
/**
|
||||
* Get the current image URL.
|
||||
*
|
||||
* Note that because of the limitations of categories this property can get out of sync
|
||||
* if you use sd_setImage: directly.
|
||||
*/
|
||||
- (NSURL *)sd_imageURL;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url`.
|
||||
*
|
||||
|
@ -29,7 +25,7 @@
|
|||
*
|
||||
* @param url The url for the image.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(NSURL *)url;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url` and a placeholder.
|
||||
|
@ -40,7 +36,8 @@
|
|||
* @param placeholder The image to be set initially, until the image request finishes.
|
||||
* @see sd_setImageWithURL:placeholderImage:options:
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url`, placeholder and custom options.
|
||||
|
@ -52,7 +49,9 @@
|
|||
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
|
||||
*/
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url`.
|
||||
|
@ -66,7 +65,8 @@
|
|||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url`, placeholder.
|
||||
|
@ -81,7 +81,9 @@
|
|||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Set the imageView `image` with an `url`, placeholder and custom options.
|
||||
|
@ -97,28 +99,11 @@
|
|||
* indicating if the image was retrieved from the local cache or from the network.
|
||||
* The fourth parameter is the original image url.
|
||||
*/
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
|
||||
|
||||
/**
|
||||
* Cancel the current download
|
||||
*/
|
||||
- (void)sd_cancelCurrentImageLoad;
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface MKAnnotationView (WebCacheDeprecated)
|
||||
|
||||
- (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`");
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`");
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`");
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:`");
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`");
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`");
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
|
||||
|
||||
- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`");
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
|
|
@ -1,135 +1,57 @@
|
|||
//
|
||||
// MKAnnotationView+WebCache.m
|
||||
// SDWebImage
|
||||
//
|
||||
// Created by Olivier Poitrey on 14/03/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "MKAnnotationView+WebCache.h"
|
||||
|
||||
#if SD_UIKIT || SD_MAC
|
||||
|
||||
#import "objc/runtime.h"
|
||||
#import "UIView+WebCacheOperation.h"
|
||||
|
||||
static char imageURLKey;
|
||||
#import "UIView+WebCache.h"
|
||||
|
||||
@implementation MKAnnotationView (WebCache)
|
||||
|
||||
- (NSURL *)sd_imageURL {
|
||||
return objc_getAssociatedObject(self, &imageURLKey);
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url {
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder options:(SDWebImageOptions)options {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url placeholderImage:(nullable UIImage *)placeholder completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
|
||||
[self sd_cancelCurrentImageLoad];
|
||||
|
||||
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
|
||||
self.image = placeholder;
|
||||
|
||||
if (url) {
|
||||
__weak __typeof(self)wself = self;
|
||||
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
|
||||
if (!wself) return;
|
||||
dispatch_main_sync_safe(^{
|
||||
__strong MKAnnotationView *sself = wself;
|
||||
if (!sself) return;
|
||||
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {
|
||||
completedBlock(image, error, cacheType, url);
|
||||
return;
|
||||
} else if (image) {
|
||||
wself.image = image;
|
||||
[wself setNeedsLayout];
|
||||
} else {
|
||||
if ((options & SDWebImageDelayPlaceholder)) {
|
||||
wself.image = placeholder;
|
||||
[wself setNeedsLayout];
|
||||
}
|
||||
}
|
||||
if (completedBlock && finished) {
|
||||
completedBlock(image, error, cacheType, url);
|
||||
}
|
||||
});
|
||||
}];
|
||||
[self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"];
|
||||
} else {
|
||||
dispatch_main_async_safe(^{
|
||||
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
|
||||
if (completedBlock) {
|
||||
completedBlock(nil, error, SDImageCacheTypeNone, url);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
- (void)sd_cancelCurrentImageLoad {
|
||||
[self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"];
|
||||
- (void)sd_setImageWithURL:(nullable NSURL *)url
|
||||
placeholderImage:(nullable UIImage *)placeholder
|
||||
options:(SDWebImageOptions)options
|
||||
completed:(nullable SDExternalCompletionBlock)completedBlock {
|
||||
__weak typeof(self)weakSelf = self;
|
||||
[self sd_internalSetImageWithURL:url
|
||||
placeholderImage:placeholder
|
||||
options:options
|
||||
operationKey:nil
|
||||
setImageBlock:^(UIImage *image, NSData *imageData) {
|
||||
weakSelf.image = image;
|
||||
}
|
||||
progress:nil
|
||||
completed:completedBlock];
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation MKAnnotationView (WebCacheDeprecated)
|
||||
|
||||
- (NSURL *)imageURL {
|
||||
return [self sd_imageURL];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
|
||||
if (completedBlock) {
|
||||
completedBlock(image, error, cacheType);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
|
||||
if (completedBlock) {
|
||||
completedBlock(image, error, cacheType);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
|
||||
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
|
||||
if (completedBlock) {
|
||||
completedBlock(image, error, cacheType);
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
- (void)cancelCurrentImageLoad {
|
||||
[self sd_cancelCurrentImageLoad];
|
||||
}
|
||||
|
||||
@end
|
||||
#endif
|
||||
|
|
|
@ -1,26 +1,33 @@
|
|||
//
|
||||
// Created by Fabrice Aneche on 06/01/14.
|
||||
// Copyright (c) 2014 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
* (c) Fabrice Aneche
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
typedef NS_ENUM(NSInteger, SDImageFormat) {
|
||||
SDImageFormatUndefined = -1,
|
||||
SDImageFormatJPEG = 0,
|
||||
SDImageFormatPNG,
|
||||
SDImageFormatGIF,
|
||||
SDImageFormatTIFF,
|
||||
SDImageFormatWebP
|
||||
};
|
||||
|
||||
@interface NSData (ImageContentType)
|
||||
|
||||
/**
|
||||
* Compute the content type for an image data
|
||||
* Return image format
|
||||
*
|
||||
* @param data the input data
|
||||
* @param data the input image data
|
||||
*
|
||||
* @return the content type as string (i.e. image/jpeg, image/gif)
|
||||
* @return the image format as `SDImageFormat` (enum)
|
||||
*/
|
||||
+ (NSString *)sd_contentTypeForImageData:(NSData *)data;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@interface NSData (ImageContentTypeDeprecated)
|
||||
|
||||
+ (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`");
|
||||
+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,49 +1,46 @@
|
|||
//
|
||||
// Created by Fabrice Aneche on 06/01/14.
|
||||
// Copyright (c) 2014 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
* (c) Fabrice Aneche
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "NSData+ImageContentType.h"
|
||||
|
||||
|
||||
@implementation NSData (ImageContentType)
|
||||
|
||||
+ (NSString *)sd_contentTypeForImageData:(NSData *)data {
|
||||
+ (SDImageFormat)sd_imageFormatForImageData:(nullable NSData *)data {
|
||||
if (!data) {
|
||||
return SDImageFormatUndefined;
|
||||
}
|
||||
|
||||
uint8_t c;
|
||||
[data getBytes:&c length:1];
|
||||
switch (c) {
|
||||
case 0xFF:
|
||||
return @"image/jpeg";
|
||||
return SDImageFormatJPEG;
|
||||
case 0x89:
|
||||
return @"image/png";
|
||||
return SDImageFormatPNG;
|
||||
case 0x47:
|
||||
return @"image/gif";
|
||||
return SDImageFormatGIF;
|
||||
case 0x49:
|
||||
case 0x4D:
|
||||
return @"image/tiff";
|
||||
return SDImageFormatTIFF;
|
||||
case 0x52:
|
||||
// R as RIFF for WEBP
|
||||
if ([data length] < 12) {
|
||||
return nil;
|
||||
if (data.length < 12) {
|
||||
return SDImageFormatUndefined;
|
||||
}
|
||||
|
||||
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
|
||||
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
|
||||
return @"image/webp";
|
||||
return SDImageFormatWebP;
|
||||
}
|
||||
|
||||
return nil;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@implementation NSData (ImageContentTypeDeprecated)
|
||||
|
||||
+ (NSString *)contentTypeForImageData:(NSData *)data {
|
||||
return [self sd_contentTypeForImageData:data];
|
||||
return SDImageFormatUndefined;
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
#if SD_MAC
|
||||
|
||||
#import <Cocoa/Cocoa.h>
|
||||
|
||||
@interface NSImage (WebCache)
|
||||
|
||||
- (CGImageRef)CGImage;
|
||||
- (NSArray<NSImage *> *)images;
|
||||
- (BOOL)isGIF;
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "NSImage+WebCache.h"
|
||||
|
||||
#if SD_MAC
|
||||
|
||||
@implementation NSImage (WebCache)
|
||||
|
||||
- (CGImageRef)CGImage {
|
||||
NSRect imageRect = NSMakeRect(0, 0, self.size.width, self.size.height);
|
||||
CGImageRef cgImage = [self CGImageForProposedRect:&imageRect context:NULL hints:nil];
|
||||
return cgImage;
|
||||
}
|
||||
|
||||
- (NSArray<NSImage *> *)images {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (BOOL)isGIF {
|
||||
return NO;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
#endif
|
||||
|
|
@ -9,6 +9,8 @@
|
|||
#import <Foundation/Foundation.h>
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
@class SDImageCacheConfig;
|
||||
|
||||
typedef NS_ENUM(NSInteger, SDImageCacheType) {
|
||||
/**
|
||||
* The image wasn't available the SDWebImage caches, but was downloaded from the web.
|
||||
|
@ -24,33 +26,25 @@ typedef NS_ENUM(NSInteger, SDImageCacheType) {
|
|||
SDImageCacheTypeMemory
|
||||
};
|
||||
|
||||
typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType);
|
||||
typedef void(^SDCacheQueryCompletedBlock)(UIImage * _Nullable image, NSData * _Nullable data, SDImageCacheType cacheType);
|
||||
|
||||
typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
|
||||
|
||||
typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
|
||||
|
||||
|
||||
/**
|
||||
* SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
|
||||
* asynchronous so it doesn’t add unnecessary latency to the UI.
|
||||
*/
|
||||
@interface SDImageCache : NSObject
|
||||
|
||||
/**
|
||||
* Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
|
||||
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldDecompressImages;
|
||||
#pragma mark - Properties
|
||||
|
||||
/**
|
||||
* disable iCloud backup [defaults to YES]
|
||||
* Cache Config object - storing all kind of settings
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldDisableiCloud;
|
||||
|
||||
/**
|
||||
* use memory cache [defaults to YES]
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;
|
||||
@property (nonatomic, nonnull, readonly) SDImageCacheConfig *config;
|
||||
|
||||
/**
|
||||
* The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
|
||||
|
@ -62,29 +56,21 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*/
|
||||
@property (assign, nonatomic) NSUInteger maxMemoryCountLimit;
|
||||
|
||||
/**
|
||||
* The maximum length of time to keep an image in the cache, in seconds
|
||||
*/
|
||||
@property (assign, nonatomic) NSInteger maxCacheAge;
|
||||
|
||||
/**
|
||||
* The maximum size of the cache, in bytes.
|
||||
*/
|
||||
@property (assign, nonatomic) NSUInteger maxCacheSize;
|
||||
#pragma mark - Singleton and initialization
|
||||
|
||||
/**
|
||||
* Returns global shared cache instance
|
||||
*
|
||||
* @return SDImageCache global instance
|
||||
*/
|
||||
+ (SDImageCache *)sharedImageCache;
|
||||
+ (nonnull instancetype)sharedImageCache;
|
||||
|
||||
/**
|
||||
* Init a new cache store with a specific namespace
|
||||
*
|
||||
* @param ns The namespace to use for this cache store
|
||||
*/
|
||||
- (id)initWithNamespace:(NSString *)ns;
|
||||
- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns;
|
||||
|
||||
/**
|
||||
* Init a new cache store with a specific namespace and directory
|
||||
|
@ -92,9 +78,12 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
* @param ns The namespace to use for this cache store
|
||||
* @param directory Directory to cache disk images in
|
||||
*/
|
||||
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory;
|
||||
- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns
|
||||
diskCacheDirectory:(nonnull NSString *)directory NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
-(NSString *)makeDiskCachePath:(NSString*)fullNamespace;
|
||||
#pragma mark - Cache paths
|
||||
|
||||
- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace;
|
||||
|
||||
/**
|
||||
* Add a read-only cache path to search for images pre-cached by SDImageCache
|
||||
|
@ -102,99 +91,123 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*
|
||||
* @param path The path to use for this read-only cache path
|
||||
*/
|
||||
- (void)addReadOnlyCachePath:(NSString *)path;
|
||||
- (void)addReadOnlyCachePath:(nonnull NSString *)path;
|
||||
|
||||
#pragma mark - Store Ops
|
||||
|
||||
/**
|
||||
* Store an image into memory and disk cache at the given key.
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
*
|
||||
* @param image The image to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param image The image to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param completionBlock A block executed after the operation is finished
|
||||
*/
|
||||
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Store an image into memory and optionally disk cache at the given key.
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
*
|
||||
* @param image The image to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param toDisk Store the image to disk cache if YES
|
||||
* @param image The image to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param toDisk Store the image to disk cache if YES
|
||||
* @param completionBlock A block executed after the operation is finished
|
||||
*/
|
||||
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Store an image into memory and optionally disk cache at the given key.
|
||||
* Asynchronously store an image into memory and disk cache at the given key.
|
||||
*
|
||||
* @param image The image to store
|
||||
* @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage
|
||||
* @param imageData The image data as returned by the server, this representation will be used for disk storage
|
||||
* instead of converting the given image object into a storable/compressed image format in order
|
||||
* to save quality and CPU
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param toDisk Store the image to disk cache if YES
|
||||
* @param image The image to store
|
||||
* @param imageData The image data as returned by the server, this representation will be used for disk storage
|
||||
* instead of converting the given image object into a storable/compressed image format in order
|
||||
* to save quality and CPU
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @param toDisk Store the image to disk cache if YES
|
||||
* @param completionBlock A block executed after the operation is finished
|
||||
*/
|
||||
- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk;
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Store image NSData into disk cache at the given key.
|
||||
* Synchronously store image NSData into disk cache at the given key.
|
||||
*
|
||||
* @param imageData The image data to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
* @warning This method is synchronous, make sure to call it from the ioQueue
|
||||
*
|
||||
* @param imageData The image data to store
|
||||
* @param key The unique image cache key, usually it's image absolute URL
|
||||
*/
|
||||
- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key;
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key;
|
||||
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
||||
/**
|
||||
* Query the disk cache asynchronously.
|
||||
* Async check if image exists in disk cache already (does not load the image)
|
||||
*
|
||||
* @param key The unique key used to store the wanted image
|
||||
* @param key the key describing the url
|
||||
* @param completionBlock the block to be executed when the check is done.
|
||||
* @note the completion block will be always executed on the main queue
|
||||
*/
|
||||
- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
|
||||
- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Operation that queries the cache asynchronously and call the completion when done.
|
||||
*
|
||||
* @param key The unique key used to store the wanted image
|
||||
* @param doneBlock The completion block. Will not get called if the operation is cancelled
|
||||
*
|
||||
* @return a NSOperation instance containing the cache op
|
||||
*/
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock;
|
||||
|
||||
/**
|
||||
* Query the memory cache synchronously.
|
||||
*
|
||||
* @param key The unique key used to store the wanted image
|
||||
* @param key The unique key used to store the image
|
||||
*/
|
||||
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;
|
||||
- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key;
|
||||
|
||||
/**
|
||||
* Query the disk cache synchronously after checking the memory cache.
|
||||
* Query the disk cache synchronously.
|
||||
*
|
||||
* @param key The unique key used to store the wanted image
|
||||
* @param key The unique key used to store the image
|
||||
*/
|
||||
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
|
||||
- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key;
|
||||
|
||||
/**
|
||||
* Remove the image from memory and disk cache asynchronously
|
||||
* Query the cache (memory and or disk) synchronously after checking the memory cache.
|
||||
*
|
||||
* @param key The unique image cache key
|
||||
* @param key The unique key used to store the image
|
||||
*/
|
||||
- (void)removeImageForKey:(NSString *)key;
|
||||
- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key;
|
||||
|
||||
#pragma mark - Remove Ops
|
||||
|
||||
/**
|
||||
* Remove the image from memory and disk cache asynchronously
|
||||
*
|
||||
* @param key The unique image cache key
|
||||
* @param completion An block that should be executed after the image has been removed (optional)
|
||||
* @param completion A block that should be executed after the image has been removed (optional)
|
||||
*/
|
||||
- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion;
|
||||
|
||||
/**
|
||||
* Remove the image from memory and optionally disk cache asynchronously
|
||||
*
|
||||
* @param key The unique image cache key
|
||||
* @param fromDisk Also remove cache entry from disk if YES
|
||||
*/
|
||||
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
|
||||
- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion;
|
||||
|
||||
/**
|
||||
* Remove the image from memory and optionally disk cache asynchronously
|
||||
*
|
||||
* @param key The unique image cache key
|
||||
* @param fromDisk Also remove cache entry from disk if YES
|
||||
* @param completion An block that should be executed after the image has been removed (optional)
|
||||
* @param completion A block that should be executed after the image has been removed (optional)
|
||||
*/
|
||||
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion;
|
||||
- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion;
|
||||
|
||||
#pragma mark - Cache clean Ops
|
||||
|
||||
/**
|
||||
* Clear all memory cached images
|
||||
|
@ -202,28 +215,18 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
- (void)clearMemory;
|
||||
|
||||
/**
|
||||
* Clear all disk cached images. Non-blocking method - returns immediately.
|
||||
* @param completion An block that should be executed after cache expiration completes (optional)
|
||||
* Async clear all disk cached images. Non-blocking method - returns immediately.
|
||||
* @param completion A block that should be executed after cache expiration completes (optional)
|
||||
*/
|
||||
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;
|
||||
- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion;
|
||||
|
||||
/**
|
||||
* Clear all disk cached images
|
||||
* @see clearDiskOnCompletion:
|
||||
* Async remove all expired cached image from disk. Non-blocking method - returns immediately.
|
||||
* @param completionBlock A block that should be executed after cache expiration completes (optional)
|
||||
*/
|
||||
- (void)clearDisk;
|
||||
- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Remove all expired cached image from disk. Non-blocking method - returns immediately.
|
||||
* @param completionBlock An block that should be executed after cache expiration completes (optional)
|
||||
*/
|
||||
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Remove all expired cached image from disk
|
||||
* @see cleanDiskWithCompletionBlock:
|
||||
*/
|
||||
- (void)cleanDisk;
|
||||
#pragma mark - Cache Info
|
||||
|
||||
/**
|
||||
* Get the size used by the disk cache
|
||||
|
@ -238,25 +241,9 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
/**
|
||||
* Asynchronously calculate the disk cache's size.
|
||||
*/
|
||||
- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock;
|
||||
- (void)calculateSizeWithCompletionBlock:(nullable SDWebImageCalculateSizeBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Async check if image exists in disk cache already (does not load the image)
|
||||
*
|
||||
* @param key the key describing the url
|
||||
* @param completionBlock the block to be executed when the check is done.
|
||||
* @note the completion block will be always executed on the main queue
|
||||
*/
|
||||
- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
|
||||
|
||||
/**
|
||||
* Check if image exists in disk cache already (does not load the image)
|
||||
*
|
||||
* @param key the key describing the url
|
||||
*
|
||||
* @return YES if an image exists for the given key
|
||||
*/
|
||||
- (BOOL)diskImageExistsWithKey:(NSString *)key;
|
||||
#pragma mark - Cache Paths
|
||||
|
||||
/**
|
||||
* Get the cache path for a certain key (needs the cache path root folder)
|
||||
|
@ -266,7 +253,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*
|
||||
* @return the cache path
|
||||
*/
|
||||
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;
|
||||
- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path;
|
||||
|
||||
/**
|
||||
* Get the default cache path for a certain key
|
||||
|
@ -275,6 +262,6 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*
|
||||
* @return the default cache path
|
||||
*/
|
||||
- (NSString *)defaultCachePathForKey:(NSString *)key;
|
||||
- (nullable NSString *)defaultCachePathForKey:(nullable NSString *)key;
|
||||
|
||||
@end
|
||||
|
|
|
@ -10,6 +10,10 @@
|
|||
#import "SDWebImageDecoder.h"
|
||||
#import "UIImage+MultiFormat.h"
|
||||
#import <CommonCrypto/CommonDigest.h>
|
||||
#import "UIImage+GIF.h"
|
||||
#import "NSData+ImageContentType.h"
|
||||
#import "NSImage+WebCache.h"
|
||||
#import "SDImageCacheConfig.h"
|
||||
|
||||
// See https://github.com/rs/SDWebImage/pull/1141 for discussion
|
||||
@interface AutoPurgeCache : NSCache
|
||||
|
@ -17,51 +21,40 @@
|
|||
|
||||
@implementation AutoPurgeCache
|
||||
|
||||
- (id)init
|
||||
{
|
||||
- (nonnull instancetype)init {
|
||||
self = [super init];
|
||||
if (self) {
|
||||
#if SD_UIKIT
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
|
||||
#endif
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
- (void)dealloc {
|
||||
#if SD_UIKIT
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week
|
||||
// PNG signature bytes and data (below)
|
||||
static unsigned char kPNGSignatureBytes[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
|
||||
static NSData *kPNGSignatureData = nil;
|
||||
|
||||
BOOL ImageDataHasPNGPreffix(NSData *data);
|
||||
|
||||
BOOL ImageDataHasPNGPreffix(NSData *data) {
|
||||
NSUInteger pngSignatureLength = [kPNGSignatureData length];
|
||||
if ([data length] >= pngSignatureLength) {
|
||||
if ([[data subdataWithRange:NSMakeRange(0, pngSignatureLength)] isEqualToData:kPNGSignatureData]) {
|
||||
return YES;
|
||||
}
|
||||
}
|
||||
|
||||
return NO;
|
||||
}
|
||||
|
||||
FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
||||
#if SD_MAC
|
||||
return image.size.height * image.size.width;
|
||||
#elif SD_UIKIT || SD_WATCH
|
||||
return image.size.height * image.size.width * image.scale * image.scale;
|
||||
#endif
|
||||
}
|
||||
|
||||
@interface SDImageCache ()
|
||||
|
||||
@property (strong, nonatomic) NSCache *memCache;
|
||||
@property (strong, nonatomic) NSString *diskCachePath;
|
||||
@property (strong, nonatomic) NSMutableArray *customPaths;
|
||||
@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue;
|
||||
#pragma mark - Properties
|
||||
@property (strong, nonatomic, nonnull) NSCache *memCache;
|
||||
@property (strong, nonatomic, nonnull) NSString *diskCachePath;
|
||||
@property (strong, nonatomic, nullable) NSMutableArray<NSString *> *customPaths;
|
||||
@property (SDDispatchQueueSetterSementics, nonatomic, nullable) dispatch_queue_t ioQueue;
|
||||
|
||||
@end
|
||||
|
||||
|
@ -70,7 +63,9 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
NSFileManager *_fileManager;
|
||||
}
|
||||
|
||||
+ (SDImageCache *)sharedImageCache {
|
||||
#pragma mark - Singleton, init, dealloc
|
||||
|
||||
+ (nonnull instancetype)sharedImageCache {
|
||||
static dispatch_once_t once;
|
||||
static id instance;
|
||||
dispatch_once(&once, ^{
|
||||
|
@ -79,27 +74,24 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
return instance;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
return [self initWithNamespace:@"default"];
|
||||
}
|
||||
|
||||
- (id)initWithNamespace:(NSString *)ns {
|
||||
- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns {
|
||||
NSString *path = [self makeDiskCachePath:ns];
|
||||
return [self initWithNamespace:ns diskCacheDirectory:path];
|
||||
}
|
||||
|
||||
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory {
|
||||
- (nonnull instancetype)initWithNamespace:(nonnull NSString *)ns
|
||||
diskCacheDirectory:(nonnull NSString *)directory {
|
||||
if ((self = [super init])) {
|
||||
NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns];
|
||||
|
||||
// initialise PNG signature data
|
||||
kPNGSignatureData = [NSData dataWithBytes:kPNGSignatureBytes length:8];
|
||||
|
||||
// Create IO serial queue
|
||||
_ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL);
|
||||
|
||||
// Init default values
|
||||
_maxCacheAge = kDefaultCacheMaxCacheAge;
|
||||
_config = [[SDImageCacheConfig alloc] init];
|
||||
|
||||
// Init the memory cache
|
||||
_memCache = [[AutoPurgeCache alloc] init];
|
||||
|
@ -113,20 +105,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
_diskCachePath = path;
|
||||
}
|
||||
|
||||
// Set decompression to YES
|
||||
_shouldDecompressImages = YES;
|
||||
|
||||
// memory cache enabled
|
||||
_shouldCacheImagesInMemory = YES;
|
||||
|
||||
// Disable iCloud
|
||||
_shouldDisableiCloud = YES;
|
||||
|
||||
dispatch_sync(_ioQueue, ^{
|
||||
_fileManager = [NSFileManager new];
|
||||
});
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#if SD_UIKIT
|
||||
// Subscribe to app events
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(clearMemory)
|
||||
|
@ -134,12 +117,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(cleanDisk)
|
||||
selector:@selector(deleteOldFiles)
|
||||
name:UIApplicationWillTerminateNotification
|
||||
object:nil];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(backgroundCleanDisk)
|
||||
selector:@selector(backgroundDeleteOldFiles)
|
||||
name:UIApplicationDidEnterBackgroundNotification
|
||||
object:nil];
|
||||
#endif
|
||||
|
@ -153,7 +136,17 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
SDDispatchQueueRelease(_ioQueue);
|
||||
}
|
||||
|
||||
- (void)addReadOnlyCachePath:(NSString *)path {
|
||||
- (void)checkIfQueueIsIOQueue {
|
||||
const char *currentQueueLabel = dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL);
|
||||
const char *ioQueueLabel = dispatch_queue_get_label(self.ioQueue);
|
||||
if (strcmp(currentQueueLabel, ioQueueLabel) != 0) {
|
||||
NSLog(@"This method should be called from the ioQueue");
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark - Cache paths
|
||||
|
||||
- (void)addReadOnlyCachePath:(nonnull NSString *)path {
|
||||
if (!self.customPaths) {
|
||||
self.customPaths = [NSMutableArray new];
|
||||
}
|
||||
|
@ -163,19 +156,17 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
}
|
||||
|
||||
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path {
|
||||
- (nullable NSString *)cachePathForKey:(nullable NSString *)key inPath:(nonnull NSString *)path {
|
||||
NSString *filename = [self cachedFileNameForKey:key];
|
||||
return [path stringByAppendingPathComponent:filename];
|
||||
}
|
||||
|
||||
- (NSString *)defaultCachePathForKey:(NSString *)key {
|
||||
- (nullable NSString *)defaultCachePathForKey:(nullable NSString *)key {
|
||||
return [self cachePathForKey:key inPath:self.diskCachePath];
|
||||
}
|
||||
|
||||
#pragma mark SDImageCache (private)
|
||||
|
||||
- (NSString *)cachedFileNameForKey:(NSString *)key {
|
||||
const char *str = [key UTF8String];
|
||||
- (nullable NSString *)cachedFileNameForKey:(nullable NSString *)key {
|
||||
const char *str = key.UTF8String;
|
||||
if (str == NULL) {
|
||||
str = "";
|
||||
}
|
||||
|
@ -183,25 +174,44 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
CC_MD5(str, (CC_LONG)strlen(str), r);
|
||||
NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@",
|
||||
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],
|
||||
r[11], r[12], r[13], r[14], r[15], [[key pathExtension] isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", [key pathExtension]]];
|
||||
r[11], r[12], r[13], r[14], r[15], [key.pathExtension isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", key.pathExtension]];
|
||||
|
||||
return filename;
|
||||
}
|
||||
|
||||
#pragma mark ImageCache
|
||||
|
||||
// Init the disk cache
|
||||
-(NSString *)makeDiskCachePath:(NSString*)fullNamespace{
|
||||
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
- (nullable NSString *)makeDiskCachePath:(nonnull NSString*)fullNamespace {
|
||||
NSArray<NSString *> *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
|
||||
return [paths[0] stringByAppendingPathComponent:fullNamespace];
|
||||
}
|
||||
|
||||
- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk {
|
||||
#pragma mark - Store Ops
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:YES completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
[self storeImage:image imageData:nil forKey:key toDisk:toDisk completion:completionBlock];
|
||||
}
|
||||
|
||||
- (void)storeImage:(nullable UIImage *)image
|
||||
imageData:(nullable NSData *)imageData
|
||||
forKey:(nullable NSString *)key
|
||||
toDisk:(BOOL)toDisk
|
||||
completion:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
if (!image || !key) {
|
||||
if (completionBlock) {
|
||||
completionBlock();
|
||||
}
|
||||
return;
|
||||
}
|
||||
// if memory cache is enabled
|
||||
if (self.shouldCacheImagesInMemory) {
|
||||
if (self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = SDCacheCostForImage(image);
|
||||
[self.memCache setObject:image forKey:key cost:cost];
|
||||
}
|
||||
|
@ -210,56 +220,32 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
dispatch_async(self.ioQueue, ^{
|
||||
NSData *data = imageData;
|
||||
|
||||
if (image && (recalculate || !data)) {
|
||||
#if TARGET_OS_IPHONE
|
||||
// We need to determine if the image is a PNG or a JPEG
|
||||
// PNGs are easier to detect because they have a unique signature (http://www.w3.org/TR/PNG-Structure.html)
|
||||
// The first eight bytes of a PNG file always contain the following (decimal) values:
|
||||
// 137 80 78 71 13 10 26 10
|
||||
|
||||
// If the imageData is nil (i.e. if trying to save a UIImage directly or the image was transformed on download)
|
||||
// and the image has an alpha channel, we will consider it PNG to avoid losing the transparency
|
||||
int alphaInfo = CGImageGetAlphaInfo(image.CGImage);
|
||||
BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone ||
|
||||
alphaInfo == kCGImageAlphaNoneSkipFirst ||
|
||||
alphaInfo == kCGImageAlphaNoneSkipLast);
|
||||
BOOL imageIsPng = hasAlpha;
|
||||
|
||||
// But if we have an image data, we will look at the preffix
|
||||
if ([imageData length] >= [kPNGSignatureData length]) {
|
||||
imageIsPng = ImageDataHasPNGPreffix(imageData);
|
||||
}
|
||||
|
||||
if (imageIsPng) {
|
||||
data = UIImagePNGRepresentation(image);
|
||||
}
|
||||
else {
|
||||
data = UIImageJPEGRepresentation(image, (CGFloat)1.0);
|
||||
}
|
||||
#else
|
||||
data = [NSBitmapImageRep representationOfImageRepsInArray:image.representations usingType: NSJPEGFileType properties:nil];
|
||||
#endif
|
||||
if (!data && image) {
|
||||
SDImageFormat imageFormatFromData = [NSData sd_imageFormatForImageData:data];
|
||||
data = [image sd_imageDataAsFormat:imageFormatFromData];
|
||||
}
|
||||
|
||||
[self storeImageDataToDisk:data forKey:key];
|
||||
if (completionBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionBlock();
|
||||
});
|
||||
}
|
||||
});
|
||||
} else {
|
||||
if (completionBlock) {
|
||||
completionBlock();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (void)storeImage:(UIImage *)image forKey:(NSString *)key {
|
||||
[self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:YES];
|
||||
}
|
||||
|
||||
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk {
|
||||
[self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk];
|
||||
}
|
||||
|
||||
- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key {
|
||||
|
||||
if (!imageData) {
|
||||
- (void)storeImageDataToDisk:(nullable NSData *)imageData forKey:(nullable NSString *)key {
|
||||
if (!imageData || !key) {
|
||||
return;
|
||||
}
|
||||
|
||||
[self checkIfQueueIsIOQueue];
|
||||
|
||||
if (![_fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
}
|
||||
|
@ -272,35 +258,21 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
[_fileManager createFileAtPath:cachePathForKey contents:imageData attributes:nil];
|
||||
|
||||
// disable iCloud backup
|
||||
if (self.shouldDisableiCloud) {
|
||||
[fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||
if (self.config.shouldDisableiCloud) {
|
||||
[fileURL setResourceValue:@YES forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)diskImageExistsWithKey:(NSString *)key {
|
||||
BOOL exists = NO;
|
||||
#pragma mark - Query and Retrieve Ops
|
||||
|
||||
// this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance
|
||||
// from apple docs on NSFileManager: The methods of the shared NSFileManager object can be called from multiple threads safely.
|
||||
exists = [[NSFileManager defaultManager] fileExistsAtPath:[self defaultCachePathForKey:key]];
|
||||
|
||||
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
|
||||
// checking the key with and without the extension
|
||||
if (!exists) {
|
||||
exists = [[NSFileManager defaultManager] fileExistsAtPath:[[self defaultCachePathForKey:key] stringByDeletingPathExtension]];
|
||||
}
|
||||
|
||||
return exists;
|
||||
}
|
||||
|
||||
- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock {
|
||||
- (void)diskImageExistsWithKey:(nullable NSString *)key completion:(nullable SDWebImageCheckCacheCompletionBlock)completionBlock {
|
||||
dispatch_async(_ioQueue, ^{
|
||||
BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]];
|
||||
|
||||
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
|
||||
// checking the key with and without the extension
|
||||
if (!exists) {
|
||||
exists = [_fileManager fileExistsAtPath:[[self defaultCachePathForKey:key] stringByDeletingPathExtension]];
|
||||
exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key].stringByDeletingPathExtension];
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
|
@ -311,21 +283,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
});
|
||||
}
|
||||
|
||||
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key {
|
||||
- (nullable UIImage *)imageFromMemoryCacheForKey:(nullable NSString *)key {
|
||||
return [self.memCache objectForKey:key];
|
||||
}
|
||||
|
||||
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key {
|
||||
|
||||
// First check the in-memory cache...
|
||||
UIImage *image = [self imageFromMemoryCacheForKey:key];
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// Second check the disk cache...
|
||||
- (nullable UIImage *)imageFromDiskCacheForKey:(nullable NSString *)key {
|
||||
UIImage *diskImage = [self diskImageForKey:key];
|
||||
if (diskImage && self.shouldCacheImagesInMemory) {
|
||||
if (diskImage && self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = SDCacheCostForImage(diskImage);
|
||||
[self.memCache setObject:diskImage forKey:key cost:cost];
|
||||
}
|
||||
|
@ -333,7 +297,19 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
return diskImage;
|
||||
}
|
||||
|
||||
- (NSData *)diskImageDataBySearchingAllPathsForKey:(NSString *)key {
|
||||
- (nullable UIImage *)imageFromCacheForKey:(nullable NSString *)key {
|
||||
// First check the in-memory cache...
|
||||
UIImage *image = [self imageFromMemoryCacheForKey:key];
|
||||
if (image) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// Second check the disk cache...
|
||||
image = [self imageFromDiskCacheForKey:key];
|
||||
return image;
|
||||
}
|
||||
|
||||
- (nullable NSData *)diskImageDataBySearchingAllPathsForKey:(nullable NSString *)key {
|
||||
NSString *defaultPath = [self defaultCachePathForKey:key];
|
||||
NSData *data = [NSData dataWithContentsOfFile:defaultPath];
|
||||
if (data) {
|
||||
|
@ -342,12 +318,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
|
||||
// checking the key with and without the extension
|
||||
data = [NSData dataWithContentsOfFile:[defaultPath stringByDeletingPathExtension]];
|
||||
data = [NSData dataWithContentsOfFile:defaultPath.stringByDeletingPathExtension];
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
NSArray *customPaths = [self.customPaths copy];
|
||||
NSArray<NSString *> *customPaths = [self.customPaths copy];
|
||||
for (NSString *path in customPaths) {
|
||||
NSString *filePath = [self cachePathForKey:key inPath:path];
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
|
||||
|
@ -357,7 +333,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
|
||||
// checking the key with and without the extension
|
||||
imageData = [NSData dataWithContentsOfFile:[filePath stringByDeletingPathExtension]];
|
||||
imageData = [NSData dataWithContentsOfFile:filePath.stringByDeletingPathExtension];
|
||||
if (imageData) {
|
||||
return imageData;
|
||||
}
|
||||
|
@ -366,12 +342,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
return nil;
|
||||
}
|
||||
|
||||
- (UIImage *)diskImageForKey:(NSString *)key {
|
||||
- (nullable UIImage *)diskImageForKey:(nullable NSString *)key {
|
||||
NSData *data = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
if (data) {
|
||||
UIImage *image = [UIImage sd_imageWithData:data];
|
||||
image = [self scaledImageForKey:key image:image];
|
||||
if (self.shouldDecompressImages) {
|
||||
if (self.config.shouldDecompressImages) {
|
||||
image = [UIImage decodedImageWithImage:image];
|
||||
}
|
||||
return image;
|
||||
|
@ -381,68 +357,69 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
}
|
||||
|
||||
- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image {
|
||||
- (nullable UIImage *)scaledImageForKey:(nullable NSString *)key image:(nullable UIImage *)image {
|
||||
return SDScaledImageForKey(key, image);
|
||||
}
|
||||
|
||||
- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock {
|
||||
if (!doneBlock) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (nullable NSOperation *)queryCacheOperationForKey:(nullable NSString *)key done:(nullable SDCacheQueryCompletedBlock)doneBlock {
|
||||
if (!key) {
|
||||
doneBlock(nil, SDImageCacheTypeNone);
|
||||
if (doneBlock) {
|
||||
doneBlock(nil, nil, SDImageCacheTypeNone);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
// First check the in-memory cache...
|
||||
UIImage *image = [self imageFromMemoryCacheForKey:key];
|
||||
if (image) {
|
||||
doneBlock(image, SDImageCacheTypeMemory);
|
||||
NSData *diskData = nil;
|
||||
if ([image isGIF]) {
|
||||
diskData = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
}
|
||||
if (doneBlock) {
|
||||
doneBlock(image, diskData, SDImageCacheTypeMemory);
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
NSOperation *operation = [NSOperation new];
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
if (operation.isCancelled) {
|
||||
// do not call the completion if cancelled
|
||||
return;
|
||||
}
|
||||
|
||||
@autoreleasepool {
|
||||
NSData *diskData = [self diskImageDataBySearchingAllPathsForKey:key];
|
||||
UIImage *diskImage = [self diskImageForKey:key];
|
||||
if (diskImage && self.shouldCacheImagesInMemory) {
|
||||
if (diskImage && self.config.shouldCacheImagesInMemory) {
|
||||
NSUInteger cost = SDCacheCostForImage(diskImage);
|
||||
[self.memCache setObject:diskImage forKey:key cost:cost];
|
||||
}
|
||||
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
doneBlock(diskImage, SDImageCacheTypeDisk);
|
||||
});
|
||||
if (doneBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
doneBlock(diskImage, diskData, SDImageCacheTypeDisk);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return operation;
|
||||
}
|
||||
|
||||
- (void)removeImageForKey:(NSString *)key {
|
||||
[self removeImageForKey:key withCompletion:nil];
|
||||
}
|
||||
#pragma mark - Remove Ops
|
||||
|
||||
- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion {
|
||||
- (void)removeImageForKey:(nullable NSString *)key withCompletion:(nullable SDWebImageNoParamsBlock)completion {
|
||||
[self removeImageForKey:key fromDisk:YES withCompletion:completion];
|
||||
}
|
||||
|
||||
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk {
|
||||
[self removeImageForKey:key fromDisk:fromDisk withCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion {
|
||||
|
||||
- (void)removeImageForKey:(nullable NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(nullable SDWebImageNoParamsBlock)completion {
|
||||
if (key == nil) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (self.shouldCacheImagesInMemory) {
|
||||
if (self.config.shouldCacheImagesInMemory) {
|
||||
[self.memCache removeObjectForKey:key];
|
||||
}
|
||||
|
||||
|
@ -462,6 +439,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
}
|
||||
|
||||
# pragma mark - Mem Cache settings
|
||||
|
||||
- (void)setMaxMemoryCost:(NSUInteger)maxMemoryCost {
|
||||
self.memCache.totalCostLimit = maxMemoryCost;
|
||||
}
|
||||
|
@ -478,16 +457,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
self.memCache.countLimit = maxCountLimit;
|
||||
}
|
||||
|
||||
#pragma mark - Cache clean Ops
|
||||
|
||||
- (void)clearMemory {
|
||||
[self.memCache removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)clearDisk {
|
||||
[self clearDiskOnCompletion:nil];
|
||||
}
|
||||
|
||||
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion
|
||||
{
|
||||
- (void)clearDiskOnCompletion:(nullable SDWebImageNoParamsBlock)completion {
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
[_fileManager removeItemAtPath:self.diskCachePath error:nil];
|
||||
[_fileManager createDirectoryAtPath:self.diskCachePath
|
||||
|
@ -503,14 +479,14 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
});
|
||||
}
|
||||
|
||||
- (void)cleanDisk {
|
||||
[self cleanDiskWithCompletionBlock:nil];
|
||||
- (void)deleteOldFiles {
|
||||
[self deleteOldFilesWithCompletionBlock:nil];
|
||||
}
|
||||
|
||||
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock {
|
||||
- (void)deleteOldFilesWithCompletionBlock:(nullable SDWebImageNoParamsBlock)completionBlock {
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
|
||||
NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
|
||||
NSArray<NSString *> *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
|
||||
|
||||
// This enumerator prefetches useful properties for our cache files.
|
||||
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
|
||||
|
@ -518,20 +494,21 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
options:NSDirectoryEnumerationSkipsHiddenFiles
|
||||
errorHandler:NULL];
|
||||
|
||||
NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
|
||||
NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary];
|
||||
NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.config.maxCacheAge];
|
||||
NSMutableDictionary<NSURL *, NSDictionary<NSString *, id> *> *cacheFiles = [NSMutableDictionary dictionary];
|
||||
NSUInteger currentCacheSize = 0;
|
||||
|
||||
// Enumerate all of the files in the cache directory. This loop has two purposes:
|
||||
//
|
||||
// 1. Removing files that are older than the expiration date.
|
||||
// 2. Storing file attributes for the size-based cleanup pass.
|
||||
NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init];
|
||||
NSMutableArray<NSURL *> *urlsToDelete = [[NSMutableArray alloc] init];
|
||||
for (NSURL *fileURL in fileEnumerator) {
|
||||
NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
|
||||
NSError *error;
|
||||
NSDictionary<NSString *, id> *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:&error];
|
||||
|
||||
// Skip directories.
|
||||
if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
|
||||
// Skip directories and errors.
|
||||
if (error || !resourceValues || [resourceValues[NSURLIsDirectoryKey] boolValue]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -544,8 +521,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
// Store a reference to this file and account for its total size.
|
||||
NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
|
||||
currentCacheSize += [totalAllocatedSize unsignedIntegerValue];
|
||||
[cacheFiles setObject:resourceValues forKey:fileURL];
|
||||
currentCacheSize += totalAllocatedSize.unsignedIntegerValue;
|
||||
cacheFiles[fileURL] = resourceValues;
|
||||
}
|
||||
|
||||
for (NSURL *fileURL in urlsToDelete) {
|
||||
|
@ -554,22 +531,22 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
|
||||
// If our remaining disk cache exceeds a configured maximum size, perform a second
|
||||
// size-based cleanup pass. We delete the oldest files first.
|
||||
if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) {
|
||||
if (self.config.maxCacheSize > 0 && currentCacheSize > self.config.maxCacheSize) {
|
||||
// Target half of our maximum cache size for this cleanup pass.
|
||||
const NSUInteger desiredCacheSize = self.maxCacheSize / 2;
|
||||
const NSUInteger desiredCacheSize = self.config.maxCacheSize / 2;
|
||||
|
||||
// Sort the remaining cache files by their last modification time (oldest first).
|
||||
NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
|
||||
usingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
|
||||
}];
|
||||
NSArray<NSURL *> *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
|
||||
usingComparator:^NSComparisonResult(id obj1, id obj2) {
|
||||
return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
|
||||
}];
|
||||
|
||||
// Delete files until we fall below our desired cache size.
|
||||
for (NSURL *fileURL in sortedFiles) {
|
||||
if ([_fileManager removeItemAtURL:fileURL error:nil]) {
|
||||
NSDictionary *resourceValues = cacheFiles[fileURL];
|
||||
NSDictionary<NSString *, id> *resourceValues = cacheFiles[fileURL];
|
||||
NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
|
||||
currentCacheSize -= [totalAllocatedSize unsignedIntegerValue];
|
||||
currentCacheSize -= totalAllocatedSize.unsignedIntegerValue;
|
||||
|
||||
if (currentCacheSize < desiredCacheSize) {
|
||||
break;
|
||||
|
@ -585,7 +562,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
});
|
||||
}
|
||||
|
||||
- (void)backgroundCleanDisk {
|
||||
#if SD_UIKIT
|
||||
- (void)backgroundDeleteOldFiles {
|
||||
Class UIApplicationClass = NSClassFromString(@"UIApplication");
|
||||
if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) {
|
||||
return;
|
||||
|
@ -599,11 +577,14 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}];
|
||||
|
||||
// Start the long-running task and return immediately.
|
||||
[self cleanDiskWithCompletionBlock:^{
|
||||
[self deleteOldFilesWithCompletionBlock:^{
|
||||
[application endBackgroundTask:bgTask];
|
||||
bgTask = UIBackgroundTaskInvalid;
|
||||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
#pragma mark - Cache Info
|
||||
|
||||
- (NSUInteger)getSize {
|
||||
__block NSUInteger size = 0;
|
||||
|
@ -611,7 +592,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
|
||||
for (NSString *fileName in fileEnumerator) {
|
||||
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
|
||||
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
|
||||
NSDictionary<NSString *, id> *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
|
||||
size += [attrs fileSize];
|
||||
}
|
||||
});
|
||||
|
@ -622,12 +603,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
__block NSUInteger count = 0;
|
||||
dispatch_sync(self.ioQueue, ^{
|
||||
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
|
||||
count = [[fileEnumerator allObjects] count];
|
||||
count = fileEnumerator.allObjects.count;
|
||||
});
|
||||
return count;
|
||||
}
|
||||
|
||||
- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock {
|
||||
- (void)calculateSizeWithCompletionBlock:(nullable SDWebImageCalculateSizeBlock)completionBlock {
|
||||
NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
|
||||
|
||||
dispatch_async(self.ioQueue, ^{
|
||||
|
@ -642,7 +623,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
for (NSURL *fileURL in fileEnumerator) {
|
||||
NSNumber *fileSize;
|
||||
[fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL];
|
||||
totalSize += [fileSize unsignedIntegerValue];
|
||||
totalSize += fileSize.unsignedIntegerValue;
|
||||
fileCount += 1;
|
||||
}
|
||||
|
||||
|
@ -655,3 +636,4 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
}
|
||||
|
||||
@end
|
||||
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
//
|
||||
// SDImageCacheConfig.h
|
||||
// SDWebImage
|
||||
//
|
||||
// Created by Bogdan on 09/09/16.
|
||||
// Copyright © 2016 Dailymotion. All rights reserved.
|
||||
//
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
@interface SDImageCacheConfig : NSObject
|
||||
|
||||
/**
|
||||
* Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
|
||||
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldDecompressImages;
|
||||
|
||||
/**
|
||||
* disable iCloud backup [defaults to YES]
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldDisableiCloud;
|
||||
|
||||
/**
|
||||
* use memory cache [defaults to YES]
|
||||
*/
|
||||
@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;
|
||||
|
||||
/**
|
||||
* The maximum length of time to keep an image in the cache, in seconds
|
||||
*/
|
||||
@property (assign, nonatomic) NSInteger maxCacheAge;
|
||||
|
||||
/**
|
||||
* The maximum size of the cache, in bytes.
|
||||
*/
|
||||
@property (assign, nonatomic) NSUInteger maxCacheSize;
|
||||
|
||||
@end
|
|
@ -0,0 +1,26 @@
|
|||
//
|
||||
// SDImageCacheConfig.m
|
||||
// SDWebImage
|
||||
//
|
||||
// Created by Bogdan on 09/09/16.
|
||||
// Copyright © 2016 Dailymotion. All rights reserved.
|
||||
//
|
||||
|
||||
#import "SDImageCacheConfig.h"
|
||||
|
||||
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week
|
||||
|
||||
@implementation SDImageCacheConfig
|
||||
|
||||
- (instancetype)init {
|
||||
if (self = [super init]) {
|
||||
_shouldDecompressImages = YES;
|
||||
_shouldDisableiCloud = YES;
|
||||
_shouldCacheImagesInMemory = YES;
|
||||
_maxCacheAge = kDefaultCacheMaxCacheAge;
|
||||
_maxCacheSize = 0;
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
@end
|
|
@ -10,25 +10,67 @@
|
|||
#import <TargetConditionals.h>
|
||||
|
||||
#ifdef __OBJC_GC__
|
||||
#error SDWebImage does not support Objective-C Garbage Collection
|
||||
#error SDWebImage does not support Objective-C Garbage Collection
|
||||
#endif
|
||||
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
|
||||
#error SDWebImage doesn't support Deployment Target version < 5.0
|
||||
#endif
|
||||
|
||||
#if !TARGET_OS_IPHONE
|
||||
#import <AppKit/AppKit.h>
|
||||
#ifndef UIImage
|
||||
#define UIImage NSImage
|
||||
#endif
|
||||
#ifndef UIImageView
|
||||
#define UIImageView NSImageView
|
||||
#endif
|
||||
// Apple's defines from TargetConditionals.h are a bit weird.
|
||||
// Seems like TARGET_OS_MAC is always defined (on all platforms).
|
||||
// To determine if we are running on OSX, we can only relly on TARGET_OS_IPHONE=0 and all the other platforms
|
||||
#if !TARGET_OS_IPHONE && !TARGET_OS_IOS && !TARGET_OS_TV && !TARGET_OS_WATCH
|
||||
#define SD_MAC 1
|
||||
#else
|
||||
#define SD_MAC 0
|
||||
#endif
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
// iOS and tvOS are very similar, UIKit exists on both platforms
|
||||
// Note: watchOS also has UIKit, but it's very limited
|
||||
#if TARGET_OS_IOS || TARGET_OS_TV
|
||||
#define SD_UIKIT 1
|
||||
#else
|
||||
#define SD_UIKIT 0
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_IOS
|
||||
#define SD_IOS 1
|
||||
#else
|
||||
#define SD_IOS 0
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_TV
|
||||
#define SD_TV 1
|
||||
#else
|
||||
#define SD_TV 0
|
||||
#endif
|
||||
|
||||
#if TARGET_OS_WATCH
|
||||
#define SD_WATCH 1
|
||||
#else
|
||||
#define SD_WATCH 0
|
||||
#endif
|
||||
|
||||
|
||||
#if SD_MAC
|
||||
#import <AppKit/AppKit.h>
|
||||
#ifndef UIImage
|
||||
#define UIImage NSImage
|
||||
#endif
|
||||
#ifndef UIImageView
|
||||
#define UIImageView NSImageView
|
||||
#endif
|
||||
#ifndef UIView
|
||||
#define UIView NSView
|
||||
#endif
|
||||
#else
|
||||
#if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
|
||||
#error SDWebImage doesn't support Deployment Target version < 5.0
|
||||
#endif
|
||||
|
||||
#if SD_UIKIT
|
||||
#import <UIKit/UIKit.h>
|
||||
#endif
|
||||
#if SD_WATCH
|
||||
#import <WatchKit/WatchKit.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef NS_ENUM
|
||||
|
@ -45,10 +87,10 @@
|
|||
#define SDDispatchQueueRelease(q)
|
||||
#define SDDispatchQueueSetterSementics strong
|
||||
#else
|
||||
#undef SDDispatchQueueRelease
|
||||
#undef SDDispatchQueueSetterSementics
|
||||
#define SDDispatchQueueRelease(q) (dispatch_release(q))
|
||||
#define SDDispatchQueueSetterSementics assign
|
||||
#undef SDDispatchQueueRelease
|
||||
#undef SDDispatchQueueSetterSementics
|
||||
#define SDDispatchQueueRelease(q) (dispatch_release(q))
|
||||
#define SDDispatchQueueSetterSementics assign
|
||||
#endif
|
||||
|
||||
extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image);
|
||||
|
@ -57,16 +99,13 @@ typedef void(^SDWebImageNoParamsBlock)();
|
|||
|
||||
extern NSString *const SDWebImageErrorDomain;
|
||||
|
||||
#define dispatch_main_sync_safe(block)\
|
||||
if ([NSThread isMainThread]) {\
|
||||
block();\
|
||||
} else {\
|
||||
dispatch_sync(dispatch_get_main_queue(), block);\
|
||||
}
|
||||
|
||||
#ifndef dispatch_main_async_safe
|
||||
#define dispatch_main_async_safe(block)\
|
||||
if ([NSThread isMainThread]) {\
|
||||
if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {\
|
||||
block();\
|
||||
} else {\
|
||||
dispatch_async(dispatch_get_main_queue(), block);\
|
||||
}
|
||||
#endif
|
||||
|
||||
static int64_t kAsyncTestTimeout = 5;
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
//
|
||||
// SDWebImageCompat.m
|
||||
// SDWebImage
|
||||
//
|
||||
// Created by Olivier Poitrey on 11/12/12.
|
||||
// Copyright (c) 2012 Dailymotion. All rights reserved.
|
||||
//
|
||||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
#import "SDWebImageCompat.h"
|
||||
|
||||
|
@ -12,13 +12,16 @@
|
|||
#error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
|
||||
#endif
|
||||
|
||||
inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
|
||||
inline UIImage *SDScaledImageForKey(NSString * _Nullable key, UIImage * _Nullable image) {
|
||||
if (!image) {
|
||||
return nil;
|
||||
}
|
||||
|
||||
if ([image.images count] > 0) {
|
||||
NSMutableArray *scaledImages = [NSMutableArray array];
|
||||
#if SD_MAC
|
||||
return image;
|
||||
#elif SD_UIKIT || SD_WATCH
|
||||
if ((image.images).count > 0) {
|
||||
NSMutableArray<UIImage *> *scaledImages = [NSMutableArray array];
|
||||
|
||||
for (UIImage *tempImage in image.images) {
|
||||
[scaledImages addObject:SDScaledImageForKey(key, tempImage)];
|
||||
|
@ -27,7 +30,11 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
|
|||
return [UIImage animatedImageWithImages:scaledImages duration:image.duration];
|
||||
}
|
||||
else {
|
||||
#if SD_WATCH
|
||||
if ([[WKInterfaceDevice currentDevice] respondsToSelector:@selector(screenScale)]) {
|
||||
#elif SD_UIKIT
|
||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
|
||||
#endif
|
||||
CGFloat scale = 1;
|
||||
if (key.length >= 8) {
|
||||
NSRange range = [key rangeOfString:@"@2x."];
|
||||
|
@ -46,6 +53,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
|
|||
}
|
||||
return image;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain";
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* Created by james <https://github.com/mystcolor> on 9/28/11.
|
||||
* (c) james <https://github.com/mystcolor>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -13,6 +12,8 @@
|
|||
|
||||
@interface UIImage (ForceDecode)
|
||||
|
||||
+ (UIImage *)decodedImageWithImage:(UIImage *)image;
|
||||
+ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image;
|
||||
|
||||
+ (nullable UIImage *)decodedAndScaledDownImageWithImage:(nullable UIImage *)image;
|
||||
|
||||
@end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
/*
|
||||
* This file is part of the SDWebImage package.
|
||||
* (c) Olivier Poitrey <rs@dailymotion.com>
|
||||
*
|
||||
* Created by james <https://github.com/mystcolor> on 9/28/11.
|
||||
* (c) james <https://github.com/mystcolor>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
|
@ -12,53 +11,25 @@
|
|||
|
||||
@implementation UIImage (ForceDecode)
|
||||
|
||||
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
|
||||
// while downloading huge amount of images
|
||||
// autorelease the bitmap context
|
||||
// and all vars to help system to free memory
|
||||
// when there are memory warning.
|
||||
// on iOS7, do not forget to call
|
||||
// [[SDImageCache sharedImageCache] clearMemory];
|
||||
#if SD_UIKIT || SD_WATCH
|
||||
static const size_t kBytesPerPixel = 4;
|
||||
static const size_t kBitsPerComponent = 8;
|
||||
|
||||
if (image == nil) { // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
|
||||
return nil;
|
||||
+ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image {
|
||||
if (![UIImage shouldDecodeImage:image]) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
|
||||
// on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
|
||||
@autoreleasepool{
|
||||
// do not decode animated images
|
||||
if (image.images != nil) {
|
||||
return image;
|
||||
}
|
||||
|
||||
CGImageRef imageRef = image.CGImage;
|
||||
|
||||
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
|
||||
BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
|
||||
alpha == kCGImageAlphaLast ||
|
||||
alpha == kCGImageAlphaPremultipliedFirst ||
|
||||
alpha == kCGImageAlphaPremultipliedLast);
|
||||
if (anyAlpha) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// current
|
||||
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
|
||||
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
|
||||
|
||||
BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelCMYK ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelIndexed);
|
||||
if (unsupportedColorSpace) {
|
||||
colorspaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
}
|
||||
CGColorSpaceRef colorspaceRef = [UIImage colorSpaceForImageRef:imageRef];
|
||||
|
||||
size_t width = CGImageGetWidth(imageRef);
|
||||
size_t height = CGImageGetHeight(imageRef);
|
||||
NSUInteger bytesPerPixel = 4;
|
||||
NSUInteger bytesPerRow = bytesPerPixel * width;
|
||||
NSUInteger bitsPerComponent = 8;
|
||||
|
||||
size_t bytesPerRow = kBytesPerPixel * width;
|
||||
|
||||
// kCGImageAlphaNone is not supported in CGBitmapContextCreate.
|
||||
// Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
|
||||
|
@ -66,10 +37,13 @@
|
|||
CGContextRef context = CGBitmapContextCreate(NULL,
|
||||
width,
|
||||
height,
|
||||
bitsPerComponent,
|
||||
kBitsPerComponent,
|
||||
bytesPerRow,
|
||||
colorspaceRef,
|
||||
kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
|
||||
if (context == NULL) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// Draw the image into the context and retrieve the new bitmap image without alpha
|
||||
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
|
||||
|
@ -78,10 +52,6 @@
|
|||
scale:image.scale
|
||||
orientation:image.imageOrientation];
|
||||
|
||||
if (unsupportedColorSpace) {
|
||||
CGColorSpaceRelease(colorspaceRef);
|
||||
}
|
||||
|
||||
CGContextRelease(context);
|
||||
CGImageRelease(imageRefWithoutAlpha);
|
||||
|
||||
|
@ -89,4 +59,221 @@
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Defines the maximum size in MB of the decoded image when the flag `SDWebImageScaleDownLargeImages` is set
|
||||
* Suggested value for iPad1 and iPhone 3GS: 60.
|
||||
* Suggested value for iPad2 and iPhone 4: 120.
|
||||
* Suggested value for iPhone 3G and iPod 2 and earlier devices: 30.
|
||||
*/
|
||||
static const CGFloat kDestImageSizeMB = 60.0f;
|
||||
|
||||
/*
|
||||
* Defines the maximum size in MB of a tile used to decode image when the flag `SDWebImageScaleDownLargeImages` is set
|
||||
* Suggested value for iPad1 and iPhone 3GS: 20.
|
||||
* Suggested value for iPad2 and iPhone 4: 40.
|
||||
* Suggested value for iPhone 3G and iPod 2 and earlier devices: 10.
|
||||
*/
|
||||
static const CGFloat kSourceImageTileSizeMB = 20.0f;
|
||||
|
||||
static const CGFloat kBytesPerMB = 1024.0f * 1024.0f;
|
||||
static const CGFloat kPixelsPerMB = kBytesPerMB / kBytesPerPixel;
|
||||
static const CGFloat kDestTotalPixels = kDestImageSizeMB * kPixelsPerMB;
|
||||
static const CGFloat kTileTotalPixels = kSourceImageTileSizeMB * kPixelsPerMB;
|
||||
|
||||
static const CGFloat kDestSeemOverlap = 2.0f; // the numbers of pixels to overlap the seems where tiles meet.
|
||||
|
||||
+ (nullable UIImage *)decodedAndScaledDownImageWithImage:(nullable UIImage *)image {
|
||||
if (![UIImage shouldDecodeImage:image]) {
|
||||
return image;
|
||||
}
|
||||
|
||||
if (![UIImage shouldScaleDownImage:image]) {
|
||||
return [UIImage decodedImageWithImage:image];
|
||||
}
|
||||
|
||||
CGContextRef destContext;
|
||||
|
||||
// autorelease the bitmap context and all vars to help system to free memory when there are memory warning.
|
||||
// on iOS7, do not forget to call [[SDImageCache sharedImageCache] clearMemory];
|
||||
@autoreleasepool {
|
||||
CGImageRef sourceImageRef = image.CGImage;
|
||||
|
||||
CGSize sourceResolution = CGSizeZero;
|
||||
sourceResolution.width = CGImageGetWidth(sourceImageRef);
|
||||
sourceResolution.height = CGImageGetHeight(sourceImageRef);
|
||||
float sourceTotalPixels = sourceResolution.width * sourceResolution.height;
|
||||
// Determine the scale ratio to apply to the input image
|
||||
// that results in an output image of the defined size.
|
||||
// see kDestImageSizeMB, and how it relates to destTotalPixels.
|
||||
float imageScale = kDestTotalPixels / sourceTotalPixels;
|
||||
CGSize destResolution = CGSizeZero;
|
||||
destResolution.width = (int)(sourceResolution.width*imageScale);
|
||||
destResolution.height = (int)(sourceResolution.height*imageScale);
|
||||
|
||||
// current color space
|
||||
CGColorSpaceRef colorspaceRef = [UIImage colorSpaceForImageRef:sourceImageRef];
|
||||
|
||||
size_t bytesPerRow = kBytesPerPixel * destResolution.width;
|
||||
|
||||
// Allocate enough pixel data to hold the output image.
|
||||
void* destBitmapData = malloc( bytesPerRow * destResolution.height );
|
||||
if (destBitmapData == NULL) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// kCGImageAlphaNone is not supported in CGBitmapContextCreate.
|
||||
// Since the original image here has no alpha info, use kCGImageAlphaNoneSkipLast
|
||||
// to create bitmap graphics contexts without alpha info.
|
||||
destContext = CGBitmapContextCreate(destBitmapData,
|
||||
destResolution.width,
|
||||
destResolution.height,
|
||||
kBitsPerComponent,
|
||||
bytesPerRow,
|
||||
colorspaceRef,
|
||||
kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
|
||||
|
||||
if (destContext == NULL) {
|
||||
free(destBitmapData);
|
||||
return image;
|
||||
}
|
||||
CGContextSetInterpolationQuality(destContext, kCGInterpolationHigh);
|
||||
|
||||
// Now define the size of the rectangle to be used for the
|
||||
// incremental blits from the input image to the output image.
|
||||
// we use a source tile width equal to the width of the source
|
||||
// image due to the way that iOS retrieves image data from disk.
|
||||
// iOS must decode an image from disk in full width 'bands', even
|
||||
// if current graphics context is clipped to a subrect within that
|
||||
// band. Therefore we fully utilize all of the pixel data that results
|
||||
// from a decoding opertion by achnoring our tile size to the full
|
||||
// width of the input image.
|
||||
CGRect sourceTile = CGRectZero;
|
||||
sourceTile.size.width = sourceResolution.width;
|
||||
// The source tile height is dynamic. Since we specified the size
|
||||
// of the source tile in MB, see how many rows of pixels high it
|
||||
// can be given the input image width.
|
||||
sourceTile.size.height = (int)(kTileTotalPixels / sourceTile.size.width );
|
||||
sourceTile.origin.x = 0.0f;
|
||||
// The output tile is the same proportions as the input tile, but
|
||||
// scaled to image scale.
|
||||
CGRect destTile;
|
||||
destTile.size.width = destResolution.width;
|
||||
destTile.size.height = sourceTile.size.height * imageScale;
|
||||
destTile.origin.x = 0.0f;
|
||||
// The source seem overlap is proportionate to the destination seem overlap.
|
||||
// this is the amount of pixels to overlap each tile as we assemble the ouput image.
|
||||
float sourceSeemOverlap = (int)((kDestSeemOverlap/destResolution.height)*sourceResolution.height);
|
||||
CGImageRef sourceTileImageRef;
|
||||
// calculate the number of read/write operations required to assemble the
|
||||
// output image.
|
||||
int iterations = (int)( sourceResolution.height / sourceTile.size.height );
|
||||
// If tile height doesn't divide the image height evenly, add another iteration
|
||||
// to account for the remaining pixels.
|
||||
int remainder = (int)sourceResolution.height % (int)sourceTile.size.height;
|
||||
if(remainder) {
|
||||
iterations++;
|
||||
}
|
||||
// Add seem overlaps to the tiles, but save the original tile height for y coordinate calculations.
|
||||
float sourceTileHeightMinusOverlap = sourceTile.size.height;
|
||||
sourceTile.size.height += sourceSeemOverlap;
|
||||
destTile.size.height += kDestSeemOverlap;
|
||||
for( int y = 0; y < iterations; ++y ) {
|
||||
@autoreleasepool {
|
||||
sourceTile.origin.y = y * sourceTileHeightMinusOverlap + sourceSeemOverlap;
|
||||
destTile.origin.y = destResolution.height - (( y + 1 ) * sourceTileHeightMinusOverlap * imageScale + kDestSeemOverlap);
|
||||
sourceTileImageRef = CGImageCreateWithImageInRect( sourceImageRef, sourceTile );
|
||||
if( y == iterations - 1 && remainder ) {
|
||||
float dify = destTile.size.height;
|
||||
destTile.size.height = CGImageGetHeight( sourceTileImageRef ) * imageScale;
|
||||
dify -= destTile.size.height;
|
||||
destTile.origin.y += dify;
|
||||
}
|
||||
CGContextDrawImage( destContext, destTile, sourceTileImageRef );
|
||||
CGImageRelease( sourceTileImageRef );
|
||||
}
|
||||
}
|
||||
|
||||
CGImageRef destImageRef = CGBitmapContextCreateImage(destContext);
|
||||
CGContextRelease(destContext);
|
||||
if (destImageRef == NULL) {
|
||||
return image;
|
||||
}
|
||||
UIImage *destImage = [UIImage imageWithCGImage:destImageRef scale:image.scale orientation:image.imageOrientation];
|
||||
CGImageRelease(destImageRef);
|
||||
if (destImage == nil) {
|
||||
return image;
|
||||
}
|
||||
return destImage;
|
||||
}
|
||||
}
|
||||
|
||||
+ (BOOL)shouldDecodeImage:(nullable UIImage *)image {
|
||||
// Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
|
||||
if (image == nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
// do not decode animated images
|
||||
if (image.images != nil) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
CGImageRef imageRef = image.CGImage;
|
||||
|
||||
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
|
||||
BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
|
||||
alpha == kCGImageAlphaLast ||
|
||||
alpha == kCGImageAlphaPremultipliedFirst ||
|
||||
alpha == kCGImageAlphaPremultipliedLast);
|
||||
// do not decode images with alpha
|
||||
if (anyAlpha) {
|
||||
return NO;
|
||||
}
|
||||
|
||||
return YES;
|
||||
}
|
||||
|
||||
+ (BOOL)shouldScaleDownImage:(nonnull UIImage *)image {
|
||||
BOOL shouldScaleDown = YES;
|
||||
|
||||
CGImageRef sourceImageRef = image.CGImage;
|
||||
CGSize sourceResolution = CGSizeZero;
|
||||
sourceResolution.width = CGImageGetWidth(sourceImageRef);
|
||||
sourceResolution.height = CGImageGetHeight(sourceImageRef);
|
||||
float sourceTotalPixels = sourceResolution.width * sourceResolution.height;
|
||||
float imageScale = kDestTotalPixels / sourceTotalPixels;
|
||||
if (imageScale < 1) {
|
||||
shouldScaleDown = YES;
|
||||
} else {
|
||||
shouldScaleDown = NO;
|
||||
}
|
||||
|
||||
return shouldScaleDown;
|
||||
}
|
||||
|
||||
+ (CGColorSpaceRef)colorSpaceForImageRef:(CGImageRef)imageRef {
|
||||
// current
|
||||
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
|
||||
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
|
||||
|
||||
BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelCMYK ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelIndexed);
|
||||
if (unsupportedColorSpace) {
|
||||
colorspaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
CFAutorelease(colorspaceRef);
|
||||
}
|
||||
return colorspaceRef;
|
||||
}
|
||||
#elif SD_MAC
|
||||
+ (nullable UIImage *)decodedImageWithImage:(nullable UIImage *)image {
|
||||
return image;
|
||||
}
|
||||
|
||||
+ (nullable UIImage *)decodedAndScaledDownImageWithImage:(nullable UIImage *)image {
|
||||
return image;
|
||||
}
|
||||
#endif
|
||||
|
||||
@end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue