Compare commits
73 Commits
| Author | SHA1 | Date |
|---|---|---|
|
|
53837dc070 | |
|
|
c012fc9bb2 | |
|
|
67329ac512 | |
|
|
de149aedaa | |
|
|
fc0de57066 | |
|
|
473054879c | |
|
|
5d42a2ac5e | |
|
|
1e412927cc | |
|
|
eab4279140 | |
|
|
1bf62d475a | |
|
|
d8dc6a25aa | |
|
|
335a437b2e | |
|
|
cb7a3db23c | |
|
|
6545a3aba1 | |
|
|
9137b65d3b | |
|
|
09a9e74eae | |
|
|
5580c78282 | |
|
|
af7b587936 | |
|
|
86fc47bf7b | |
|
|
e6e5c5156b | |
|
|
cc510a6a4e | |
|
|
0dc2c41112 | |
|
|
f8a7b6bac7 | |
|
|
8e300c92a4 | |
|
|
44eac986bb | |
|
|
afaf306222 | |
|
|
5ac4e308c7 | |
|
|
f1a471e93f | |
|
|
11840d1313 | |
|
|
1f165b48ee | |
|
|
edb4bc3554 | |
|
|
990f85bce2 | |
|
|
b40124c95d | |
|
|
371533549c | |
|
|
d4d11ef0b0 | |
|
|
d6d9a5c233 | |
|
|
1fba8d99f3 | |
|
|
5cc5abae03 | |
|
|
19041b44c2 | |
|
|
d2b648e8ff | |
|
|
29c9c5d68a | |
|
|
4709774dc2 | |
|
|
0979d5b5f7 | |
|
|
11521aa040 | |
|
|
83240bd781 | |
|
|
32787175ac | |
|
|
0da78a4ce6 | |
|
|
09556f2d21 | |
|
|
ed7df926ea | |
|
|
16e1862afc | |
|
|
1ef791bad9 | |
|
|
32ca18b523 | |
|
|
1189f74c00 | |
|
|
469d8bbfd8 | |
|
|
2489074417 | |
|
|
b39fab3180 | |
|
|
974141f5a2 | |
|
|
e7fa11058b | |
|
|
8fe7ed5ca7 | |
|
|
cbb50e986e | |
|
|
68ae502797 | |
|
|
6e1b2aa8f0 | |
|
|
9c4fcfa844 | |
|
|
e41af47e2f | |
|
|
070cbc63ee | |
|
|
3b039d5910 | |
|
|
64f621081c | |
|
|
b426975b9f | |
|
|
fca618fb61 | |
|
|
9ecf488aff | |
|
|
a8fca6584f | |
|
|
47115e2593 | |
|
|
ee50027b88 |
|
|
@ -0,0 +1,42 @@
|
|||
# Contributing to SDWebImage
|
||||
|
||||
We want to make contributing to this project as easy and transparent as possible. Here are a few guidelines for making all our lives easier.
|
||||
|
||||
## Asking questions
|
||||
|
||||
We don't use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com/) instead. By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
A great way to contribute to the project is to send a detailed issue when you encounter an problem.
|
||||
It is very important to check for the same problem or suggestion in the project's issue list first. If you find a match, just add a small comment there.
|
||||
Doing this helps prioritize the most common problems and requests.
|
||||
|
||||
When reporting issues, please include the following:
|
||||
|
||||
- The platform name and version (e.g. iOS 8.1)
|
||||
- The library version
|
||||
- The integration method (e.g. CocoaPods/Carthage/manually)
|
||||
- The version of Xcode you're using
|
||||
- The full output of any stack trace or compiler error
|
||||
- A small demo project that replicates the issue (especially if the way to reproduce the issue is not straight-forward)
|
||||
- Any other details that would be useful in understanding the problem
|
||||
|
||||
This information will help us review and fix your issue faster.
|
||||
|
||||
|
||||
Please do not be offended if we close your issue and reference this document.
|
||||
If you believe the issue is truely a fault in the project’s codebase, re-open it.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
We gladly accept any PR's assuming they are well written, documented ( if necessary ) and preferably have test code.
|
||||
If you're unsure if we'll accept a new feature please open an issue requesting it and we can have a discussion before you code and submit a PR.
|
||||
|
||||
Checklist:
|
||||
- Fork the repo and create your branch from the latest master (to minimize the conflicts)
|
||||
- If you've added code that should be tested, add tests.
|
||||
- If you've changed APIs, update the documentation.
|
||||
- Ensure the test suite passes.
|
||||
- Make sure your code lints (pod lib lint)
|
||||
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
### New Issue Checklist
|
||||
|
||||
* [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/rs/SDWebImage/blob/master/.github/CONTRIBUTING.md)
|
||||
* [ ] I have read the [Documentation](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
* [ ] I have searched for a similar issue in the [project](https://github.com/rs/SDWebImage/issues) and found none
|
||||
|
||||
### Issue Info
|
||||
|
||||
Info | Value |
|
||||
-------------------------|-------------------------------------|
|
||||
Platform Name | e.g. ios / tvos
|
||||
Platform Version | e.g. 8.0
|
||||
SDWebImage Version | e.g. 3.7.6
|
||||
Integration Method | e.g. carthage / cocoapods / manually
|
||||
Xcode Version | e.g. Xcode 7.3
|
||||
Repro rate | e.g. all the time (100%) / sometimes x% / only once
|
||||
Repro with our demo prj | e.g. does it happen with our demo project?
|
||||
Demo project link | e.g. link to a demo project that highlights the issue
|
||||
|
||||
### Issue Description and Steps
|
||||
|
||||
Please fill in the detailed description of the issue (full output of any stack trace, compiler error, ...) and the steps to reproduce the issue.
|
||||
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
### New Pull Request Checklist
|
||||
|
||||
* [ ] I have read and understood the [CONTRIBUTING guide](https://github.com/rs/SDWebImage/blob/master/.github/CONTRIBUTING.md)
|
||||
* [ ] I have read the [Documentation](http://cocoadocs.org/docsets/SDWebImage/)
|
||||
* [ ] I have searched for a similar pull request in the [project](https://github.com/rs/SDWebImage/pulls) and found none
|
||||
|
||||
* [ ] 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 run the tests and they pass
|
||||
* [ ] I have run the lint and it passes (`pod lib lint`)
|
||||
|
||||
This merge request fixes / reffers to the following issues: ...
|
||||
|
||||
### Pull Request Description
|
||||
|
||||
...
|
||||
|
||||
|
|
@ -1,3 +1,3 @@
|
|||
[submodule "Vendors/libwebp"]
|
||||
path = Vendors/libwebp
|
||||
url = https://chromium.googlesource.com/webm/libwebp
|
||||
url = https://github.com/webmproject/libwebp
|
||||
|
|
|
|||
15
.travis.yml
15
.travis.yml
|
|
@ -8,19 +8,20 @@ before_install:
|
|||
- export LANG=en_US.UTF-8
|
||||
- env
|
||||
- locale
|
||||
- gem install cocoapods --quiet
|
||||
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
|
||||
- pod --version
|
||||
- pod setup --silent
|
||||
- pod setup --silent > /dev/null
|
||||
- pod repo update --silent
|
||||
|
||||
script:
|
||||
|
||||
- pod lib lint --allow-warnings
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator -arch i386 build
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+WebP' -sdk iphonesimulator -arch i386 build
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+MKAnnotation' -sdk iphonesimulator -arch i386 build
|
||||
- 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 -arch i386 build
|
||||
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator build
|
||||
|
||||
- pod install --project-directory=Tests
|
||||
- xcodebuild -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test
|
||||
- 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
|
||||
48
CHANGELOG.md
48
CHANGELOG.md
|
|
@ -1,3 +1,51 @@
|
|||
## [3.8.1 Patch release for 3.8.0 on Jun 7th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.1)
|
||||
|
||||
#### Fixes:
|
||||
|
||||
- SDWebImage 3.8.0 get wrong image #1589 - the issue was caused by the changes in 3.8.0 (Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1553 #1583 #1585) - Reverted.
|
||||
- Note: The solution for those issues (i.e. #1433 #1553) is to set the `SDWebImageManager` `cacheKeyFilter` block and do their own calculations there.
|
||||
|
||||
## [3.8.0 Minor release - Replaces NSURLConnection (deprecated) with NSURLSession - on Jun 6th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.0)
|
||||
|
||||
#### Infrastructure:
|
||||
|
||||
- Had to update the iOS deployment target to 7.0 from 5 - 6545a3a
|
||||
|
||||
#### Features:
|
||||
|
||||
- Replace deprecated `NSURLConnection` with `NSURLSession` #1578 #1586 - fixes #1291 #1318 #823 #1566 #1515
|
||||
- Allow to customise cache and image downloader instances used with `SDWebImageManager` 86fc47bf7b - fixes #1398 #870
|
||||
|
||||
#### Fixes:
|
||||
|
||||
- Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1553 #1583 #1585
|
||||
- Fixed the WebP build with the official 1.0.0 CocoaPods release f1a471e - fixes #1444
|
||||
- Updated doc: `removeImageForKey:` not synchronous e6e5c51 - fixes #1379 #1415
|
||||
|
||||
## [3.7.6 Patch release for 3.7.0 on May 8th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.7.6)
|
||||
|
||||
#### Infrastructure:
|
||||
- Changed the **libwebp git url** so that people from China can access it - #1390 (from `https://chromium.googlesource.com/webm/libwebp` to `https://github.com/webmproject/libwebp`)
|
||||
|
||||
#### Features:
|
||||
- Added `cancelAllDownloads` method to `SDWebImageDownloader` #1504
|
||||
- Added API to save image `NSData` to disk cache: `[SDImageCache storeImageDataToDisk:forKey:]` #1453
|
||||
|
||||
#### Fixes:
|
||||
- Fix #1449: Version 3.7.5 breaks semantic versioning (removes public API). Re-added `sd_setImageWithPreviousCachedImageWithURL:andPlaceholderImage:options:progress:completed:` and deprecated it. Will remove it in 4.0.0 b40124c
|
||||
- Fix `CGContextDrawImage: invalid context 0x0` - #1496 (fixes #1401 #1454 #1457)
|
||||
- Fix `CGBitmapContextCreateImage: invalid context 0x0` - #1464 (fixes #1423)
|
||||
- Fix changed image size when loading from disk #1540 (fixes #1437)
|
||||
- Repair memory release in the iPad environment #1549 (had to switch `#if TARGET_OS_IPHONE` to `#if TARGET_OS_IOS`)
|
||||
- Fixed completion logic in `MKAnnotationView+WebCache` #1547
|
||||
- Optimize the decoder to avoid unwanted blended layer - #1527 (fixes #1524)
|
||||
- Protect against malformed frame for GIFs - #1447
|
||||
- updated doc: #1462 #1466 #1486 #1532 #1461
|
||||
|
||||
## [3.7.5 Patch release for 3.7.0 on Jan 21st, 2016](https://github.com/rs/SDWebImage/releases/tag/3.7.5)
|
||||
- fixed #1425 and #1426 - Continuation of Fix #1366, addresses #1350 and reverts a part of #1221 - from commit 6406d8e, the wrong usage of `dispatch_apply`
|
||||
- fixed #1422 - Added a fallback for #976 so that if there are images saved with the old format (no extension), they can still be loaded
|
||||
|
||||
## [3.7.4 Patch release for 3.7.0 with tvOS support on Jan 8th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.7.4)
|
||||
|
||||
#### Updates
|
||||
|
|
|
|||
|
|
@ -33,6 +33,13 @@
|
|||
remoteGlobalIDString = 4A2CADFF1AB4BB5300B6BC39;
|
||||
remoteInfo = WebImage;
|
||||
};
|
||||
43AEAFA91D008FEE005B41A8 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
|
||||
proxyType = 2;
|
||||
remoteGlobalIDString = 00733A4C1BC487C000A5A117;
|
||||
remoteInfo = "WebImage tvOS";
|
||||
};
|
||||
DA248D731954841D00390AB0 /* PBXContainerItemProxy */ = {
|
||||
isa = PBXContainerItemProxy;
|
||||
containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
|
||||
|
|
@ -165,6 +172,7 @@
|
|||
DA248D761954841D00390AB0 /* libSDWebImage+WebP.a */,
|
||||
DA248D781954841D00390AB0 /* libSDWebImage+MKAnnotation.a */,
|
||||
43A0FAAF1BDD16AC00B7582B /* WebImage.framework */,
|
||||
43AEAFAA1D008FEE005B41A8 /* WebImage.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -229,6 +237,13 @@
|
|||
remoteRef = 43A0FAAE1BDD16AC00B7582B /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
43AEAFAA1D008FEE005B41A8 /* WebImage.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = wrapper.framework;
|
||||
path = WebImage.framework;
|
||||
remoteRef = 43AEAFA91D008FEE005B41A8 /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
DA248D741954841D00390AB0 /* libSDWebImage.a */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
|
|
@ -322,7 +337,7 @@
|
|||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
};
|
||||
|
|
@ -340,7 +355,7 @@
|
|||
GCC_WARN_ABOUT_RETURN_TYPE = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
|
||||
SDKROOT = iphoneos;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@
|
|||
#import "DetailViewController.h"
|
||||
|
||||
@interface MasterViewController () {
|
||||
NSArray *_objects;
|
||||
NSMutableArray *_objects;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
@ -35,311 +35,17 @@
|
|||
[SDWebImageManager sharedManager].imageDownloader.username = @"httpwatch";
|
||||
[SDWebImageManager sharedManager].imageDownloader.password = @"httpwatch01";
|
||||
|
||||
_objects = [NSArray arrayWithObjects:
|
||||
_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",
|
||||
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test2.webp",
|
||||
@"http://www.ioncannon.net/wp-content/uploads/2011/06/test9.webp",
|
||||
@"http://static2.dmcdn.net/static/video/656/177/44771656:jpeg_preview_small.jpg?20120509154705",
|
||||
@"http://static2.dmcdn.net/static/video/629/228/44822926:jpeg_preview_small.jpg?20120509181018",
|
||||
@"http://static2.dmcdn.net/static/video/116/367/44763611:jpeg_preview_small.jpg?20120509101749",
|
||||
@"http://static2.dmcdn.net/static/video/340/086/44680043:jpeg_preview_small.jpg?20120509180118",
|
||||
@"http://static2.dmcdn.net/static/video/666/645/43546666:jpeg_preview_small.jpg?20120412153140",
|
||||
@"http://static2.dmcdn.net/static/video/771/577/44775177:jpeg_preview_small.jpg?20120509183230",
|
||||
@"http://static2.dmcdn.net/static/video/810/508/44805018:jpeg_preview_small.jpg?20120508125339",
|
||||
@"http://static2.dmcdn.net/static/video/152/008/44800251:jpeg_preview_small.jpg?20120508103336",
|
||||
@"http://static2.dmcdn.net/static/video/694/741/35147496:jpeg_preview_small.jpg?20120508111445",
|
||||
@"http://static2.dmcdn.net/static/video/988/667/44766889:jpeg_preview_small.jpg?20120508130425",
|
||||
@"http://static2.dmcdn.net/static/video/282/467/44764282:jpeg_preview_small.jpg?20120507130637",
|
||||
@"http://static2.dmcdn.net/static/video/754/657/44756457:jpeg_preview_small.jpg?20120507093012",
|
||||
@"http://static2.dmcdn.net/static/video/831/107/44701138:jpeg_preview_small.jpg?20120506133917",
|
||||
@"http://static2.dmcdn.net/static/video/411/057/44750114:jpeg_preview_small.jpg?20120507014914",
|
||||
@"http://static2.dmcdn.net/static/video/894/547/44745498:jpeg_preview_small.jpg?20120509183004",
|
||||
@"http://static2.dmcdn.net/static/video/082/947/44749280:jpeg_preview_small.jpg?20120507015022",
|
||||
@"http://static2.dmcdn.net/static/video/833/347/44743338:jpeg_preview_small.jpg?20120509183004",
|
||||
@"http://static2.dmcdn.net/static/video/683/666/44666386:jpeg_preview_small.jpg?20120505111208",
|
||||
@"http://static2.dmcdn.net/static/video/595/946/44649595:jpeg_preview_small.jpg?20120507194104",
|
||||
@"http://static2.dmcdn.net/static/video/984/935/44539489:jpeg_preview_small.jpg?20120501184650",
|
||||
@"http://static2.dmcdn.net/static/video/440/416/44614044:jpeg_preview_small.jpg?20120505174152",
|
||||
@"http://static2.dmcdn.net/static/video/561/977/20779165:jpeg_preview_small.jpg?20120423161805",
|
||||
@"http://static2.dmcdn.net/static/video/104/546/44645401:jpeg_preview_small.jpg?20120507185246",
|
||||
@"http://static2.dmcdn.net/static/video/671/636/44636176:jpeg_preview_small.jpg?20120504021339",
|
||||
@"http://static2.dmcdn.net/static/video/142/746/44647241:jpeg_preview_small.jpg?20120504104451",
|
||||
@"http://static2.dmcdn.net/static/video/776/860/44068677:jpeg_preview_small.jpg?20120507185251",
|
||||
@"http://static2.dmcdn.net/static/video/026/626/44626620:jpeg_preview_small.jpg?20120503203036",
|
||||
@"http://static2.dmcdn.net/static/video/364/663/39366463:jpeg_preview_small.jpg?20120509163505",
|
||||
@"http://static2.dmcdn.net/static/video/392/895/44598293:jpeg_preview_small.jpg?20120503165252",
|
||||
@"http://static2.dmcdn.net/static/video/620/865/44568026:jpeg_preview_small.jpg?20120507185121",
|
||||
@"http://static2.dmcdn.net/static/video/031/395/44593130:jpeg_preview_small.jpg?20120507185139",
|
||||
@"http://static2.dmcdn.net/static/video/676/495/44594676:jpeg_preview_small.jpg?20120503121341",
|
||||
@"http://static2.dmcdn.net/static/video/025/195/44591520:jpeg_preview_small.jpg?20120503132132",
|
||||
@"http://static2.dmcdn.net/static/video/993/665/44566399:jpeg_preview_small.jpg?20120503182623",
|
||||
@"http://static2.dmcdn.net/static/video/137/635/44536731:jpeg_preview_small.jpg?20120501165940",
|
||||
@"http://static2.dmcdn.net/static/video/611/794/44497116:jpeg_preview_small.jpg?20120507184954",
|
||||
@"http://static2.dmcdn.net/static/video/732/790/44097237:jpeg_preview_small.jpg?20120430162348",
|
||||
@"http://static2.dmcdn.net/static/video/064/991/44199460:jpeg_preview_small.jpg?20120430101250",
|
||||
@"http://static2.dmcdn.net/static/video/404/094/44490404:jpeg_preview_small.jpg?20120507184948",
|
||||
@"http://static2.dmcdn.net/static/video/413/120/44021314:jpeg_preview_small.jpg?20120507180850",
|
||||
@"http://static2.dmcdn.net/static/video/200/584/44485002:jpeg_preview_small.jpg?20120507184941",
|
||||
@"http://static2.dmcdn.net/static/video/551/318/42813155:jpeg_preview_small.jpg?20120412153202",
|
||||
@"http://static2.dmcdn.net/static/video/524/750/44057425:jpeg_preview_small.jpg?20120501220912",
|
||||
@"http://static2.dmcdn.net/static/video/124/843/44348421:jpeg_preview_small.jpg?20120507184551",
|
||||
@"http://static2.dmcdn.net/static/video/496/394/42493694:jpeg_preview_small.jpg?20120430105337",
|
||||
@"http://static2.dmcdn.net/static/video/548/883/44388845:jpeg_preview_small.jpg?20120428212713",
|
||||
@"http://static2.dmcdn.net/static/video/282/533/44335282:jpeg_preview_small.jpg?20120427102844",
|
||||
@"http://static2.dmcdn.net/static/video/257/132/44231752:jpeg_preview_small.jpg?20120428212609",
|
||||
@"http://static2.dmcdn.net/static/video/480/193/44391084:jpeg_preview_small.jpg?20120501143214",
|
||||
@"http://static2.dmcdn.net/static/video/903/432/44234309:jpeg_preview_small.jpg?20120427200002",
|
||||
@"http://static2.dmcdn.net/static/video/646/573/44375646:jpeg_preview_small.jpg?20120507184652",
|
||||
@"http://static2.dmcdn.net/static/video/709/573/44375907:jpeg_preview_small.jpg?20120507184652",
|
||||
@"http://static2.dmcdn.net/static/video/885/633/44336588:jpeg_preview_small.jpg?20120507184540",
|
||||
@"http://static2.dmcdn.net/static/video/732/523/44325237:jpeg_preview_small.jpg?20120426110308",
|
||||
@"http://static2.dmcdn.net/static/video/935/132/44231539:jpeg_preview_small.jpg?20120426115744",
|
||||
@"http://static2.dmcdn.net/static/video/941/129/43921149:jpeg_preview_small.jpg?20120426094640",
|
||||
@"http://static2.dmcdn.net/static/video/775/942/44249577:jpeg_preview_small.jpg?20120425011228",
|
||||
@"http://static2.dmcdn.net/static/video/868/332/44233868:jpeg_preview_small.jpg?20120429152901",
|
||||
@"http://static2.dmcdn.net/static/video/959/732/44237959:jpeg_preview_small.jpg?20120425133534",
|
||||
@"http://static2.dmcdn.net/static/video/383/402/44204383:jpeg_preview_small.jpg?20120424185842",
|
||||
@"http://static2.dmcdn.net/static/video/971/932/44239179:jpeg_preview_small.jpg?20120424154419",
|
||||
@"http://static2.dmcdn.net/static/video/096/991/44199690:jpeg_preview_small.jpg?20120423162001",
|
||||
@"http://static2.dmcdn.net/static/video/661/450/44054166:jpeg_preview_small.jpg?20120507180921",
|
||||
@"http://static2.dmcdn.net/static/video/419/322/44223914:jpeg_preview_small.jpg?20120424112858",
|
||||
@"http://static2.dmcdn.net/static/video/673/391/44193376:jpeg_preview_small.jpg?20120507181450",
|
||||
@"http://static2.dmcdn.net/static/video/907/781/44187709:jpeg_preview_small.jpg?20120423103507",
|
||||
@"http://static2.dmcdn.net/static/video/446/571/44175644:jpeg_preview_small.jpg?20120423033122",
|
||||
@"http://static2.dmcdn.net/static/video/146/671/44176641:jpeg_preview_small.jpg?20120428235503",
|
||||
@"http://static2.dmcdn.net/static/video/463/571/44175364:jpeg_preview_small.jpg?20120428235503",
|
||||
@"http://static2.dmcdn.net/static/video/442/471/44174244:jpeg_preview_small.jpg?20120428235502",
|
||||
@"http://static2.dmcdn.net/static/video/523/471/44174325:jpeg_preview_small.jpg?20120422205107",
|
||||
@"http://static2.dmcdn.net/static/video/977/159/43951779:jpeg_preview_small.jpg?20120420182100",
|
||||
@"http://static2.dmcdn.net/static/video/875/880/40088578:jpeg_preview_small.jpg?20120501131026",
|
||||
@"http://static2.dmcdn.net/static/video/434/992/38299434:jpeg_preview_small.jpg?20120503193356",
|
||||
@"http://static2.dmcdn.net/static/video/448/798/42897844:jpeg_preview_small.jpg?20120418155203",
|
||||
@"http://static2.dmcdn.net/static/video/374/690/44096473:jpeg_preview_small.jpg?20120507181124",
|
||||
@"http://static2.dmcdn.net/static/video/284/313/43313482:jpeg_preview_small.jpg?20120420184511",
|
||||
@"http://static2.dmcdn.net/static/video/682/060/44060286:jpeg_preview_small.jpg?20120421122436",
|
||||
@"http://static2.dmcdn.net/static/video/701/750/44057107:jpeg_preview_small.jpg?20120420112918",
|
||||
@"http://static2.dmcdn.net/static/video/790/850/44058097:jpeg_preview_small.jpg?20120424114522",
|
||||
@"http://static2.dmcdn.net/static/video/153/617/43716351:jpeg_preview_small.jpg?20120419190650",
|
||||
@"http://static2.dmcdn.net/static/video/394/633/37336493:jpeg_preview_small.jpg?20111109151109",
|
||||
@"http://static2.dmcdn.net/static/video/893/330/44033398:jpeg_preview_small.jpg?20120419123322",
|
||||
@"http://static2.dmcdn.net/static/video/395/046/42640593:jpeg_preview_small.jpg?20120418103546",
|
||||
@"http://static2.dmcdn.net/static/video/913/040/44040319:jpeg_preview_small.jpg?20120419164908",
|
||||
@"http://static2.dmcdn.net/static/video/090/020/44020090:jpeg_preview_small.jpg?20120418185934",
|
||||
@"http://static2.dmcdn.net/static/video/349/299/43992943:jpeg_preview_small.jpg?20120418112749",
|
||||
@"http://static2.dmcdn.net/static/video/530/189/43981035:jpeg_preview_small.jpg?20120419013834",
|
||||
@"http://static2.dmcdn.net/static/video/763/469/43964367:jpeg_preview_small.jpg?20120425111931",
|
||||
@"http://static2.dmcdn.net/static/video/961/455/43554169:jpeg_preview_small.jpg?20120418110127",
|
||||
@"http://static2.dmcdn.net/static/video/666/889/43988666:jpeg_preview_small.jpg?20120507180735",
|
||||
@"http://static2.dmcdn.net/static/video/160/459/43954061:jpeg_preview_small.jpg?20120501202847",
|
||||
@"http://static2.dmcdn.net/static/video/352/069/43960253:jpeg_preview_small.jpg?20120503175747",
|
||||
@"http://static2.dmcdn.net/static/video/096/502/43205690:jpeg_preview_small.jpg?20120417142655",
|
||||
@"http://static2.dmcdn.net/static/video/257/119/43911752:jpeg_preview_small.jpg?20120416101238",
|
||||
@"http://static2.dmcdn.net/static/video/874/098/43890478:jpeg_preview_small.jpg?20120415193608",
|
||||
@"http://static2.dmcdn.net/static/video/406/148/43841604:jpeg_preview_small.jpg?20120416123145",
|
||||
@"http://static2.dmcdn.net/static/video/463/885/43588364:jpeg_preview_small.jpg?20120409130206",
|
||||
@"http://static2.dmcdn.net/static/video/176/845/38548671:jpeg_preview_small.jpg?20120414200742",
|
||||
@"http://static2.dmcdn.net/static/video/447/848/51848744:jpeg_preview_small.jpg?20121105223446",
|
||||
@"http://static2.dmcdn.net/static/video/337/848/51848733:jpeg_preview_small.jpg?20121105223433",
|
||||
@"http://static2.dmcdn.net/static/video/707/848/51848707:jpeg_preview_small.jpg?20121105223428",
|
||||
@"http://static2.dmcdn.net/static/video/102/848/51848201:jpeg_preview_small.jpg?20121105223411",
|
||||
@"http://static2.dmcdn.net/static/video/817/848/51848718:jpeg_preview_small.jpg?20121105223402",
|
||||
@"http://static2.dmcdn.net/static/video/007/848/51848700:jpeg_preview_small.jpg?20121105223345",
|
||||
@"http://static2.dmcdn.net/static/video/696/848/51848696:jpeg_preview_small.jpg?20121105223355",
|
||||
@"http://static2.dmcdn.net/static/video/296/848/51848692:jpeg_preview_small.jpg?20121105223337",
|
||||
@"http://static2.dmcdn.net/static/video/080/848/51848080:jpeg_preview_small.jpg?20121105223653",
|
||||
@"http://static2.dmcdn.net/static/video/386/848/51848683:jpeg_preview_small.jpg?20121105223343",
|
||||
@"http://static2.dmcdn.net/static/video/876/848/51848678:jpeg_preview_small.jpg?20121105223301",
|
||||
@"http://static2.dmcdn.net/static/video/866/848/51848668:jpeg_preview_small.jpg?20121105223244",
|
||||
@"http://static2.dmcdn.net/static/video/572/548/51845275:jpeg_preview_small.jpg?20121105223229",
|
||||
@"http://static2.dmcdn.net/static/video/972/548/51845279:jpeg_preview_small.jpg?20121105223227",
|
||||
@"http://static2.dmcdn.net/static/video/112/548/51845211:jpeg_preview_small.jpg?20121105223226",
|
||||
@"http://static2.dmcdn.net/static/video/549/448/51844945:jpeg_preview_small.jpg?20121105223223",
|
||||
@"http://static2.dmcdn.net/static/video/166/848/51848661:jpeg_preview_small.jpg?20121105223228",
|
||||
@"http://static2.dmcdn.net/static/video/856/848/51848658:jpeg_preview_small.jpg?20121105223223",
|
||||
@"http://static2.dmcdn.net/static/video/746/848/51848647:jpeg_preview_small.jpg?20121105223204",
|
||||
@"http://static2.dmcdn.net/static/video/446/848/51848644:jpeg_preview_small.jpg?20121105223204",
|
||||
@"http://static2.dmcdn.net/static/video/726/848/51848627:jpeg_preview_small.jpg?20121105223221",
|
||||
@"http://static2.dmcdn.net/static/video/436/848/51848634:jpeg_preview_small.jpg?20121105223445",
|
||||
@"http://static2.dmcdn.net/static/video/836/848/51848638:jpeg_preview_small.jpg?20121105223144",
|
||||
@"http://static2.dmcdn.net/static/video/036/848/51848630:jpeg_preview_small.jpg?20121105223125",
|
||||
@"http://static2.dmcdn.net/static/video/026/848/51848620:jpeg_preview_small.jpg?20121105223102",
|
||||
@"http://static2.dmcdn.net/static/video/895/848/51848598:jpeg_preview_small.jpg?20121105223112",
|
||||
@"http://static2.dmcdn.net/static/video/116/848/51848611:jpeg_preview_small.jpg?20121105223052",
|
||||
@"http://static2.dmcdn.net/static/video/006/848/51848600:jpeg_preview_small.jpg?20121105223043",
|
||||
@"http://static2.dmcdn.net/static/video/432/548/51845234:jpeg_preview_small.jpg?20121105223022",
|
||||
@"http://static2.dmcdn.net/static/video/785/848/51848587:jpeg_preview_small.jpg?20121105223031",
|
||||
@"http://static2.dmcdn.net/static/video/975/848/51848579:jpeg_preview_small.jpg?20121105223012",
|
||||
@"http://static2.dmcdn.net/static/video/965/848/51848569:jpeg_preview_small.jpg?20121105222952",
|
||||
@"http://static2.dmcdn.net/static/video/365/848/51848563:jpeg_preview_small.jpg?20121105222943",
|
||||
@"http://static2.dmcdn.net/static/video/755/848/51848557:jpeg_preview_small.jpg?20121105222943",
|
||||
@"http://static2.dmcdn.net/static/video/722/248/51842227:jpeg_preview_small.jpg?20121105222908",
|
||||
@"http://static2.dmcdn.net/static/video/155/848/51848551:jpeg_preview_small.jpg?20121105222913",
|
||||
@"http://static2.dmcdn.net/static/video/345/848/51848543:jpeg_preview_small.jpg?20121105222907",
|
||||
@"http://static2.dmcdn.net/static/video/535/848/51848535:jpeg_preview_small.jpg?20121105222848",
|
||||
@"http://static2.dmcdn.net/static/video/035/848/51848530:jpeg_preview_small.jpg?20121105222837",
|
||||
@"http://static2.dmcdn.net/static/video/525/848/51848525:jpeg_preview_small.jpg?20121105222826",
|
||||
@"http://static2.dmcdn.net/static/video/233/848/51848332:jpeg_preview_small.jpg?20121105223414",
|
||||
@"http://static2.dmcdn.net/static/video/125/848/51848521:jpeg_preview_small.jpg?20121105222809",
|
||||
@"http://static2.dmcdn.net/static/video/005/848/51848500:jpeg_preview_small.jpg?20121105222802",
|
||||
@"http://static2.dmcdn.net/static/video/015/848/51848510:jpeg_preview_small.jpg?20121105222755",
|
||||
@"http://static2.dmcdn.net/static/video/121/548/51845121:jpeg_preview_small.jpg?20121105222850",
|
||||
@"http://static2.dmcdn.net/static/video/205/848/51848502:jpeg_preview_small.jpg?20121105222737",
|
||||
@"http://static2.dmcdn.net/static/video/697/448/51844796:jpeg_preview_small.jpg?20121105222818",
|
||||
@"http://static2.dmcdn.net/static/video/494/848/51848494:jpeg_preview_small.jpg?20121105222724",
|
||||
@"http://static2.dmcdn.net/static/video/806/448/51844608:jpeg_preview_small.jpg?20121105222811",
|
||||
@"http://static2.dmcdn.net/static/video/729/348/51843927:jpeg_preview_small.jpg?20121105222805",
|
||||
@"http://static2.dmcdn.net/static/video/865/148/51841568:jpeg_preview_small.jpg?20121105222803",
|
||||
@"http://static2.dmcdn.net/static/video/481/548/51845184:jpeg_preview_small.jpg?20121105222700",
|
||||
@"http://static2.dmcdn.net/static/video/190/548/51845091:jpeg_preview_small.jpg?20121105222656",
|
||||
@"http://static2.dmcdn.net/static/video/128/448/51844821:jpeg_preview_small.jpg?20121105222656",
|
||||
@"http://static2.dmcdn.net/static/video/784/848/51848487:jpeg_preview_small.jpg?20121105222704",
|
||||
@"http://static2.dmcdn.net/static/video/182/448/51844281:jpeg_preview_small.jpg?20121105222652",
|
||||
@"http://static2.dmcdn.net/static/video/801/848/51848108:jpeg_preview_small.jpg?20121105222907",
|
||||
@"http://static2.dmcdn.net/static/video/974/848/51848479:jpeg_preview_small.jpg?20121105222657",
|
||||
@"http://static2.dmcdn.net/static/video/274/848/51848472:jpeg_preview_small.jpg?20121105222644",
|
||||
@"http://static2.dmcdn.net/static/video/954/848/51848459:jpeg_preview_small.jpg?20121105222637",
|
||||
@"http://static2.dmcdn.net/static/video/554/848/51848455:jpeg_preview_small.jpg?20121105222615",
|
||||
@"http://static2.dmcdn.net/static/video/944/848/51848449:jpeg_preview_small.jpg?20121105222558",
|
||||
@"http://static2.dmcdn.net/static/video/144/848/51848441:jpeg_preview_small.jpg?20121105222556",
|
||||
@"http://static2.dmcdn.net/static/video/134/848/51848431:jpeg_preview_small.jpg?20121105222539",
|
||||
@"http://static2.dmcdn.net/static/video/624/848/51848426:jpeg_preview_small.jpg?20121105222523",
|
||||
@"http://static2.dmcdn.net/static/video/281/448/51844182:jpeg_preview_small.jpg?20121105222502",
|
||||
@"http://static2.dmcdn.net/static/video/414/848/51848414:jpeg_preview_small.jpg?20121105222516",
|
||||
@"http://static2.dmcdn.net/static/video/171/848/51848171:jpeg_preview_small.jpg?20121105223449",
|
||||
@"http://static2.dmcdn.net/static/video/904/848/51848409:jpeg_preview_small.jpg?20121105222514",
|
||||
@"http://static2.dmcdn.net/static/video/004/848/51848400:jpeg_preview_small.jpg?20121105222443",
|
||||
@"http://static2.dmcdn.net/static/video/693/848/51848396:jpeg_preview_small.jpg?20121105222439",
|
||||
@"http://static2.dmcdn.net/static/video/401/848/51848104:jpeg_preview_small.jpg?20121105222832",
|
||||
@"http://static2.dmcdn.net/static/video/957/648/51846759:jpeg_preview_small.jpg?20121105223109",
|
||||
@"http://static2.dmcdn.net/static/video/603/848/51848306:jpeg_preview_small.jpg?20121105222324",
|
||||
@"http://static2.dmcdn.net/static/video/990/848/51848099:jpeg_preview_small.jpg?20121105222807",
|
||||
@"http://static2.dmcdn.net/static/video/929/448/51844929:jpeg_preview_small.jpg?20121105222216",
|
||||
@"http://static2.dmcdn.net/static/video/320/548/51845023:jpeg_preview_small.jpg?20121105222214",
|
||||
@"http://static2.dmcdn.net/static/video/387/448/51844783:jpeg_preview_small.jpg?20121105222212",
|
||||
@"http://static2.dmcdn.net/static/video/833/248/51842338:jpeg_preview_small.jpg?20121105222209",
|
||||
@"http://static2.dmcdn.net/static/video/993/348/51843399:jpeg_preview_small.jpg?20121105222012",
|
||||
@"http://static2.dmcdn.net/static/video/660/848/51848066:jpeg_preview_small.jpg?20121105222754",
|
||||
@"http://static2.dmcdn.net/static/video/471/848/51848174:jpeg_preview_small.jpg?20121105223419",
|
||||
@"http://static2.dmcdn.net/static/video/255/748/51847552:jpeg_preview_small.jpg?20121105222420",
|
||||
@"http://static2.dmcdn.net/static/video/257/448/51844752:jpeg_preview_small.jpg?20121105221728",
|
||||
@"http://static2.dmcdn.net/static/video/090/848/51848090:jpeg_preview_small.jpg?20121105223020",
|
||||
@"http://static2.dmcdn.net/static/video/807/448/51844708:jpeg_preview_small.jpg?20121105221654",
|
||||
@"http://static2.dmcdn.net/static/video/196/448/51844691:jpeg_preview_small.jpg?20121105222110",
|
||||
@"http://static2.dmcdn.net/static/video/406/448/51844604:jpeg_preview_small.jpg?20121105221647",
|
||||
@"http://static2.dmcdn.net/static/video/865/348/51843568:jpeg_preview_small.jpg?20121105221644",
|
||||
@"http://static2.dmcdn.net/static/video/932/448/51844239:jpeg_preview_small.jpg?20121105221309",
|
||||
@"http://static2.dmcdn.net/static/video/967/438/51834769:jpeg_preview_small.jpg?20121105221020",
|
||||
@"http://static2.dmcdn.net/static/video/362/348/51843263:jpeg_preview_small.jpg?20121105220855",
|
||||
@"http://static2.dmcdn.net/static/video/777/448/51844777:jpeg_preview_small.jpg?20121105220715",
|
||||
@"http://static2.dmcdn.net/static/video/567/348/51843765:jpeg_preview_small.jpg?20121105220708",
|
||||
@"http://static2.dmcdn.net/static/video/905/248/51842509:jpeg_preview_small.jpg?20121105220640",
|
||||
@"http://static2.dmcdn.net/static/video/857/748/51847758:jpeg_preview_small.jpg?20121105221003",
|
||||
@"http://static2.dmcdn.net/static/video/578/348/51843875:jpeg_preview_small.jpg?20121105220350",
|
||||
@"http://static2.dmcdn.net/static/video/214/448/51844412:jpeg_preview_small.jpg?20121105220415",
|
||||
@"http://static2.dmcdn.net/static/video/264/748/51847462:jpeg_preview_small.jpg?20121105220635",
|
||||
@"http://static2.dmcdn.net/static/video/817/748/51847718:jpeg_preview_small.jpg?20121105220233",
|
||||
@"http://static2.dmcdn.net/static/video/784/848/51848487:jpeg_preview_small.jpg?20121105222704",
|
||||
@"http://static2.dmcdn.net/static/video/182/448/51844281:jpeg_preview_small.jpg?20121105222652",
|
||||
@"http://static2.dmcdn.net/static/video/801/848/51848108:jpeg_preview_small.jpg?20121105222907",
|
||||
@"http://static2.dmcdn.net/static/video/974/848/51848479:jpeg_preview_small.jpg?20121105222657",
|
||||
@"http://static2.dmcdn.net/static/video/274/848/51848472:jpeg_preview_small.jpg?20121105222644",
|
||||
@"http://static2.dmcdn.net/static/video/954/848/51848459:jpeg_preview_small.jpg?20121105222637",
|
||||
@"http://static2.dmcdn.net/static/video/554/848/51848455:jpeg_preview_small.jpg?20121105222615",
|
||||
@"http://static2.dmcdn.net/static/video/944/848/51848449:jpeg_preview_small.jpg?20121105222558",
|
||||
@"http://static2.dmcdn.net/static/video/144/848/51848441:jpeg_preview_small.jpg?20121105222556",
|
||||
@"http://static2.dmcdn.net/static/video/134/848/51848431:jpeg_preview_small.jpg?20121105222539",
|
||||
@"http://static2.dmcdn.net/static/video/624/848/51848426:jpeg_preview_small.jpg?20121105222523",
|
||||
@"http://static2.dmcdn.net/static/video/281/448/51844182:jpeg_preview_small.jpg?20121105222502",
|
||||
@"http://static2.dmcdn.net/static/video/414/848/51848414:jpeg_preview_small.jpg?20121105222516",
|
||||
@"http://static2.dmcdn.net/static/video/171/848/51848171:jpeg_preview_small.jpg?20121105223449",
|
||||
@"http://static2.dmcdn.net/static/video/904/848/51848409:jpeg_preview_small.jpg?20121105222514",
|
||||
@"http://static2.dmcdn.net/static/video/004/848/51848400:jpeg_preview_small.jpg?20121105222443",
|
||||
@"http://static2.dmcdn.net/static/video/693/848/51848396:jpeg_preview_small.jpg?20121105222439",
|
||||
@"http://static2.dmcdn.net/static/video/401/848/51848104:jpeg_preview_small.jpg?20121105222832",
|
||||
@"http://static2.dmcdn.net/static/video/957/648/51846759:jpeg_preview_small.jpg?20121105223109",
|
||||
@"http://static2.dmcdn.net/static/video/603/848/51848306:jpeg_preview_small.jpg?20121105222324",
|
||||
@"http://static2.dmcdn.net/static/video/990/848/51848099:jpeg_preview_small.jpg?20121105222807",
|
||||
@"http://static2.dmcdn.net/static/video/929/448/51844929:jpeg_preview_small.jpg?20121105222216",
|
||||
@"http://static2.dmcdn.net/static/video/320/548/51845023:jpeg_preview_small.jpg?20121105222214",
|
||||
@"http://static2.dmcdn.net/static/video/387/448/51844783:jpeg_preview_small.jpg?20121105222212",
|
||||
@"http://static2.dmcdn.net/static/video/833/248/51842338:jpeg_preview_small.jpg?20121105222209",
|
||||
@"http://static2.dmcdn.net/static/video/993/348/51843399:jpeg_preview_small.jpg?20121105222012",
|
||||
@"http://static2.dmcdn.net/static/video/660/848/51848066:jpeg_preview_small.jpg?20121105222754",
|
||||
@"http://static2.dmcdn.net/static/video/471/848/51848174:jpeg_preview_small.jpg?20121105223419",
|
||||
@"http://static2.dmcdn.net/static/video/255/748/51847552:jpeg_preview_small.jpg?20121105222420",
|
||||
@"http://static2.dmcdn.net/static/video/257/448/51844752:jpeg_preview_small.jpg?20121105221728",
|
||||
@"http://static2.dmcdn.net/static/video/090/848/51848090:jpeg_preview_small.jpg?20121105224514",
|
||||
@"http://static2.dmcdn.net/static/video/807/448/51844708:jpeg_preview_small.jpg?20121105221654",
|
||||
@"http://static2.dmcdn.net/static/video/196/448/51844691:jpeg_preview_small.jpg?20121105222110",
|
||||
@"http://static2.dmcdn.net/static/video/406/448/51844604:jpeg_preview_small.jpg?20121105221647",
|
||||
@"http://static2.dmcdn.net/static/video/865/348/51843568:jpeg_preview_small.jpg?20121105221644",
|
||||
@"http://static2.dmcdn.net/static/video/932/448/51844239:jpeg_preview_small.jpg?20121105221309",
|
||||
@"http://static2.dmcdn.net/static/video/967/438/51834769:jpeg_preview_small.jpg?20121105221020",
|
||||
@"http://static2.dmcdn.net/static/video/362/348/51843263:jpeg_preview_small.jpg?20121105220855",
|
||||
@"http://static2.dmcdn.net/static/video/777/448/51844777:jpeg_preview_small.jpg?20121105220715",
|
||||
@"http://static2.dmcdn.net/static/video/567/348/51843765:jpeg_preview_small.jpg?20121105220708",
|
||||
@"http://static2.dmcdn.net/static/video/905/248/51842509:jpeg_preview_small.jpg?20121105220640",
|
||||
@"http://static2.dmcdn.net/static/video/857/748/51847758:jpeg_preview_small.jpg?20121105221003",
|
||||
@"http://static2.dmcdn.net/static/video/578/348/51843875:jpeg_preview_small.jpg?20121105220350",
|
||||
@"http://static2.dmcdn.net/static/video/214/448/51844412:jpeg_preview_small.jpg?20121105220415",
|
||||
@"http://static2.dmcdn.net/static/video/264/748/51847462:jpeg_preview_small.jpg?20121105220635",
|
||||
@"http://static2.dmcdn.net/static/video/817/748/51847718:jpeg_preview_small.jpg?20121105220233",
|
||||
@"http://static2.dmcdn.net/static/video/807/748/51847708:jpeg_preview_small.jpg?20121105220241",
|
||||
@"http://static2.dmcdn.net/static/video/199/838/51838991:jpeg_preview_small.jpg?20121105220605",
|
||||
@"http://static2.dmcdn.net/static/video/776/748/51847677:jpeg_preview_small.jpg?20121105220150",
|
||||
@"http://static2.dmcdn.net/static/video/986/748/51847689:jpeg_preview_small.jpg?20121105224514",
|
||||
@"http://static2.dmcdn.net/static/video/915/748/51847519:jpeg_preview_small.jpg?20121105222216",
|
||||
@"http://static2.dmcdn.net/static/video/983/448/51844389:jpeg_preview_small.jpg?20121105220116",
|
||||
@"http://static2.dmcdn.net/static/video/751/348/51843157:jpeg_preview_small.jpg?20121105220104",
|
||||
@"http://static2.dmcdn.net/static/video/192/538/51835291:jpeg_preview_small.jpg?20121105220103",
|
||||
@"http://static2.dmcdn.net/static/video/596/448/51844695:jpeg_preview_small.jpg?20121105220033",
|
||||
@"http://static2.dmcdn.net/static/video/750/648/51846057:jpeg_preview_small.jpg?20121105221259",
|
||||
@"http://static2.dmcdn.net/static/video/441/148/51841144:jpeg_preview_small.jpg?20121105215911",
|
||||
@"http://static2.dmcdn.net/static/video/860/448/51844068:jpeg_preview_small.jpg?20121105215905",
|
||||
@"http://static2.dmcdn.net/static/video/995/748/51847599:jpeg_preview_small.jpg?20121105215939",
|
||||
@"http://static2.dmcdn.net/static/video/774/748/51847477:jpeg_preview_small.jpg?20121105223414",
|
||||
@"http://static2.dmcdn.net/static/video/498/648/51846894:jpeg_preview_small.jpg?20121105221807",
|
||||
@"http://static2.dmcdn.net/static/video/011/748/51847110:jpeg_preview_small.jpg?20121105221118",
|
||||
@"http://static2.dmcdn.net/static/video/794/748/51847497:jpeg_preview_small.jpg?20121105220829",
|
||||
@"http://static2.dmcdn.net/static/video/988/648/51846889:jpeg_preview_small.jpg?20121105222149",
|
||||
@"http://static2.dmcdn.net/static/video/769/548/51845967:jpeg_preview_small.jpg?20121105215601",
|
||||
@"http://static2.dmcdn.net/static/video/225/448/51844522:jpeg_preview_small.jpg?20121105215552",
|
||||
@"http://static2.dmcdn.net/static/video/172/308/51803271:jpeg_preview_small.jpg?20121105215455",
|
||||
@"http://static2.dmcdn.net/static/video/994/748/51847499:jpeg_preview_small.jpg?20121105220343",
|
||||
@"http://static2.dmcdn.net/static/video/852/748/51847258:jpeg_preview_small.jpg?20121105221031",
|
||||
@"http://static2.dmcdn.net/static/video/671/838/51838176:jpeg_preview_small.jpg?20121105215421",
|
||||
@"http://static2.dmcdn.net/static/video/172/448/51844271:jpeg_preview_small.jpg?20121105215420",
|
||||
@"http://static2.dmcdn.net/static/video/735/448/51844537:jpeg_preview_small.jpg?20121105215437",
|
||||
@"http://static2.dmcdn.net/static/video/834/448/51844438:jpeg_preview_small.jpg?20121105215431",
|
||||
@"http://static2.dmcdn.net/static/video/613/448/51844316:jpeg_preview_small.jpg?20121105215431",
|
||||
@"http://static2.dmcdn.net/static/video/581/748/51847185:jpeg_preview_small.jpg?20121105220637",
|
||||
@"http://static2.dmcdn.net/static/video/407/648/51846704:jpeg_preview_small.jpg?20121105220316",
|
||||
@"http://static2.dmcdn.net/static/video/460/448/51844064:jpeg_preview_small.jpg?20121105215245",
|
||||
@"http://static2.dmcdn.net/static/video/298/648/51846892:jpeg_preview_small.jpg?20121105220953",
|
||||
@"http://static2.dmcdn.net/static/video/053/748/51847350:jpeg_preview_small.jpg?20121105221113",
|
||||
@"http://static2.dmcdn.net/static/video/996/448/51844699:jpeg_preview_small.jpg?20121105222807",
|
||||
@"http://static2.dmcdn.net/static/video/451/448/51844154:jpeg_preview_small.jpg?20121105221955",
|
||||
@"http://static2.dmcdn.net/static/video/049/648/51846940:jpeg_preview_small.jpg?20121105215910",
|
||||
@"http://static2.dmcdn.net/static/video/091/748/51847190:jpeg_preview_small.jpg?20121105215617",
|
||||
@"http://static2.dmcdn.net/static/video/573/748/51847375:jpeg_preview_small.jpg?20121105223420",
|
||||
@"http://static2.dmcdn.net/static/video/103/248/51842301:jpeg_preview_small.jpg?20121105215014",
|
||||
@"http://static2.dmcdn.net/static/video/991/548/51845199:jpeg_preview_small.jpg?20121105215407",
|
||||
@"http://static2.dmcdn.net/static/video/872/648/51846278:jpeg_preview_small.jpg?20121105220635",
|
||||
@"http://static2.dmcdn.net/static/video/813/748/51847318:jpeg_preview_small.jpg?20121105214729",
|
||||
@"http://static2.dmcdn.net/static/video/153/448/51844351:jpeg_preview_small.jpg?20121105214622",
|
||||
@"http://static2.dmcdn.net/static/video/328/648/51846823:jpeg_preview_small.jpg?20121105214944",
|
||||
@"http://static2.dmcdn.net/static/video/892/748/51847298:jpeg_preview_small.jpg?20121105224514",
|
||||
@"http://static2.dmcdn.net/static/video/640/048/51840046:jpeg_preview_small.jpg?20121105214430",
|
||||
@"http://static2.dmcdn.net/static/video/153/648/51846351:jpeg_preview_small.jpg?20121105214426",
|
||||
@"http://static2.dmcdn.net/static/video/769/248/51842967:jpeg_preview_small.jpg?20121105214255",
|
||||
@"http://static2.dmcdn.net/static/video/720/448/51844027:jpeg_preview_small.jpg?20121105214248",
|
||||
@"http://static2.dmcdn.net/static/video/895/048/51840598:jpeg_preview_small.jpg?20121105214234",
|
||||
@"http://static2.dmcdn.net/static/video/893/348/51843398:jpeg_preview_small.jpg?20121105214157",
|
||||
@"http://static2.dmcdn.net/static/video/351/748/51847153:jpeg_preview_small.jpg?20121105214106",
|
||||
@"http://static2.dmcdn.net/static/video/364/648/51846463:jpeg_preview_small.jpg?20121105215005",
|
||||
@"http://static2.dmcdn.net/static/video/269/938/51839962:jpeg_preview_small.jpg?20121105214014",
|
||||
nil];
|
||||
|
||||
for (int i=0; i<100; i++) {
|
||||
[_objects addObject:[NSString stringWithFormat:@"https://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage%03d.jpg", i]];
|
||||
}
|
||||
|
||||
}
|
||||
[SDWebImageManager.sharedManager.imageDownloader setValue:@"SDWebImage Demo" forHTTPHeaderField:@"AppName"];
|
||||
SDWebImageManager.sharedManager.imageDownloader.executionOrder = SDWebImageDownloaderLIFOExecutionOrder;
|
||||
|
|
|
|||
2
LICENSE
2
LICENSE
|
|
@ -1,4 +1,4 @@
|
|||
Copyright (c) 2009 Olivier Poitrey <rs@dailymotion.com>
|
||||
Copyright (c) 2016 Olivier Poitrey rs@dailymotion.com
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
|
|
|||
12
README.md
12
README.md
|
|
@ -25,12 +25,12 @@ It provides:
|
|||
- Use GCD and ARC
|
||||
- Arm64 support
|
||||
|
||||
NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 2.0 and requires iOS 5.1.1
|
||||
minimum deployment version. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat).
|
||||
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).
|
||||
|
||||
[How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F)
|
||||
|
||||
Who Use It
|
||||
Who Uses It
|
||||
----------
|
||||
|
||||
Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list.
|
||||
|
|
@ -213,7 +213,7 @@ Installation
|
|||
------------
|
||||
|
||||
There are three ways to use SDWebImage in your project:
|
||||
- using Cocoapods
|
||||
- using CocoaPods
|
||||
- copying all the files into your project
|
||||
- importing the project as a static library
|
||||
|
||||
|
|
@ -223,8 +223,8 @@ There are three ways to use SDWebImage in your project:
|
|||
|
||||
#### Podfile
|
||||
```
|
||||
platform :ios, '6.1'
|
||||
pod 'SDWebImage', '~>3.7'
|
||||
platform :ios, '7.0'
|
||||
pod 'SDWebImage', '~>3.8'
|
||||
```
|
||||
|
||||
If you are using Swift, be sure to add `use_frameworks!` and set your target to iOS 8+:
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
Pod::Spec.new do |s|
|
||||
s.name = 'SDWebImage'
|
||||
s.version = '3.7.4'
|
||||
s.ios.deployment_target = '5.0'
|
||||
s.version = '3.8.1'
|
||||
s.ios.deployment_target = '7.0'
|
||||
s.tvos.deployment_target = '9.0'
|
||||
s.license = 'MIT'
|
||||
s.summary = 'Asynchronous image downloader with cache support with an UIImageView category.'
|
||||
|
|
@ -29,7 +29,7 @@ Pod::Spec.new do |s|
|
|||
end
|
||||
|
||||
s.subspec 'MapKit' do |mk|
|
||||
mk.ios.deployment_target = '5.0'
|
||||
mk.ios.deployment_target = '7.0'
|
||||
mk.source_files = 'SDWebImage/MKAnnotationView+WebCache.*'
|
||||
mk.framework = 'MapKit'
|
||||
mk.dependency 'SDWebImage/Core'
|
||||
|
|
@ -37,7 +37,10 @@ Pod::Spec.new do |s|
|
|||
|
||||
s.subspec 'WebP' do |webp|
|
||||
webp.source_files = 'SDWebImage/UIImage+WebP.{h,m}'
|
||||
webp.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1' }
|
||||
webp.xcconfig = {
|
||||
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1',
|
||||
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
|
||||
}
|
||||
webp.dependency 'SDWebImage/Core'
|
||||
webp.dependency 'libwebp'
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1409,7 +1409,6 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
ONLY_ACTIVE_ARCH = NO;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "SDWebImage+MKAnnotation";
|
||||
|
|
@ -1433,7 +1432,6 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "SDWebImage+MKAnnotation";
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
@ -1457,7 +1455,6 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)";
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SDWebImage;
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
@ -1481,7 +1478,6 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "";
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = SDWebImage;
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
@ -1508,7 +1504,6 @@
|
|||
"$(inherited)",
|
||||
);
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "SDWebImage+WebP";
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
@ -1531,7 +1526,6 @@
|
|||
GCC_PREFIX_HEADER = "";
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "SD_WEBP=1";
|
||||
INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "SDWebImage+WebP";
|
||||
SKIP_INSTALL = YES;
|
||||
|
|
@ -1567,7 +1561,7 @@
|
|||
GCC_WARN_UNUSED_PARAMETER = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = Vendors/libwebp/src;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = include/SDWebImage;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
|
|
@ -1596,7 +1590,7 @@
|
|||
GCC_WARN_UNUSED_PARAMETER = NO;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
HEADER_SEARCH_PATHS = Vendors/libwebp/src;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
|
||||
PUBLIC_HEADERS_FOLDER_PATH = include/SDWebImage;
|
||||
RUN_CLANG_STATIC_ANALYZER = YES;
|
||||
SDKROOT = iphoneos;
|
||||
|
|
@ -1607,7 +1601,6 @@
|
|||
539F912D16316D2D00160719 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
|
|
@ -1615,7 +1608,6 @@
|
|||
539F912E16316D2D00160719 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
|
|
|
|||
|
|
@ -51,8 +51,17 @@ static char imageURLKey;
|
|||
dispatch_main_sync_safe(^{
|
||||
__strong MKAnnotationView *sself = wself;
|
||||
if (!sself) return;
|
||||
if (image) {
|
||||
sself.image = image;
|
||||
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);
|
||||
|
|
|
|||
|
|
@ -134,6 +134,14 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
*/
|
||||
- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk;
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* Query the disk cache asynchronously.
|
||||
*
|
||||
|
|
@ -156,7 +164,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
|
|||
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
|
||||
|
||||
/**
|
||||
* Remove the image from memory and disk cache synchronously
|
||||
* Remove the image from memory and disk cache asynchronously
|
||||
*
|
||||
* @param key The unique image cache key
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -126,7 +126,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
_fileManager = [NSFileManager new];
|
||||
});
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
#if TARGET_OS_IOS
|
||||
// Subscribe to app events
|
||||
[[NSNotificationCenter defaultCenter] addObserver:self
|
||||
selector:@selector(clearMemory)
|
||||
|
|
@ -241,23 +241,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
#endif
|
||||
}
|
||||
|
||||
if (data) {
|
||||
if (![_fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
}
|
||||
|
||||
// get cache Path for image key
|
||||
NSString *cachePathForKey = [self defaultCachePathForKey:key];
|
||||
// transform to NSUrl
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey];
|
||||
|
||||
[_fileManager createFileAtPath:cachePathForKey contents:data attributes:nil];
|
||||
|
||||
// disable iCloud backup
|
||||
if (self.shouldDisableiCloud) {
|
||||
[fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||
}
|
||||
}
|
||||
[self storeImageDataToDisk:data forKey:key];
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -270,12 +254,41 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
[self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk];
|
||||
}
|
||||
|
||||
- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key {
|
||||
|
||||
if (!imageData) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (![_fileManager fileExistsAtPath:_diskCachePath]) {
|
||||
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
|
||||
}
|
||||
|
||||
// get cache Path for image key
|
||||
NSString *cachePathForKey = [self defaultCachePathForKey:key];
|
||||
// transform to NSUrl
|
||||
NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey];
|
||||
|
||||
[_fileManager createFileAtPath:cachePathForKey contents:imageData attributes:nil];
|
||||
|
||||
// disable iCloud backup
|
||||
if (self.shouldDisableiCloud) {
|
||||
[fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)diskImageExistsWithKey:(NSString *)key {
|
||||
BOOL exists = NO;
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
|
@ -283,6 +296,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
- (void)diskImageExistsWithKey:(NSString *)key completion:(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]];
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
completionBlock(exists);
|
||||
|
|
@ -320,6 +340,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
return data;
|
||||
}
|
||||
|
||||
// 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]];
|
||||
if (data) {
|
||||
return data;
|
||||
}
|
||||
|
||||
NSArray *customPaths = [self.customPaths copy];
|
||||
for (NSString *path in customPaths) {
|
||||
NSString *filePath = [self cachePathForKey:key inPath:path];
|
||||
|
|
@ -327,6 +354,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
if (imageData) {
|
||||
return imageData;
|
||||
}
|
||||
|
||||
// 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]];
|
||||
if (imageData) {
|
||||
return imageData;
|
||||
}
|
||||
}
|
||||
|
||||
return nil;
|
||||
|
|
@ -496,8 +530,8 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
|
|||
for (NSURL *fileURL in fileEnumerator) {
|
||||
NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
|
||||
|
||||
// Skip directories.
|
||||
if ([resourceValues[NSURLIsDirectoryKey] boolValue]) {
|
||||
// Skip nil or directories.
|
||||
if (!resourceValues || [resourceValues[NSURLIsDirectoryKey] boolValue]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -28,7 +28,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
|
|||
}
|
||||
else {
|
||||
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
|
||||
CGFloat scale = [UIScreen mainScreen].scale;
|
||||
CGFloat scale = 1;
|
||||
if (key.length >= 8) {
|
||||
NSRange range = [key rangeOfString:@"@2x."];
|
||||
if (range.location != NSNotFound) {
|
||||
|
|
|
|||
|
|
@ -19,50 +19,73 @@
|
|||
// when there are memory warning.
|
||||
// on iOS7, do not forget to call
|
||||
// [[SDImageCache sharedImageCache] clearMemory];
|
||||
|
||||
if (image == nil) { // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
|
||||
return nil;
|
||||
}
|
||||
|
||||
@autoreleasepool{
|
||||
// do not decode animated images
|
||||
if (image.images) { return image; }
|
||||
|
||||
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; }
|
||||
|
||||
size_t width = CGImageGetWidth(imageRef);
|
||||
size_t height = CGImageGetHeight(imageRef);
|
||||
|
||||
if (anyAlpha) {
|
||||
return image;
|
||||
}
|
||||
|
||||
// current
|
||||
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
|
||||
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
|
||||
|
||||
bool unsupportedColorSpace = (imageColorSpaceModel == 0 || imageColorSpaceModel == -1 || imageColorSpaceModel == kCGColorSpaceModelCMYK || imageColorSpaceModel == kCGColorSpaceModelIndexed);
|
||||
if (unsupportedColorSpace)
|
||||
BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelCMYK ||
|
||||
imageColorSpaceModel == kCGColorSpaceModelIndexed);
|
||||
if (unsupportedColorSpace) {
|
||||
colorspaceRef = CGColorSpaceCreateDeviceRGB();
|
||||
|
||||
CGContextRef context = CGBitmapContextCreate(NULL, width,
|
||||
}
|
||||
|
||||
size_t width = CGImageGetWidth(imageRef);
|
||||
size_t height = CGImageGetHeight(imageRef);
|
||||
NSUInteger bytesPerPixel = 4;
|
||||
NSUInteger bytesPerRow = bytesPerPixel * width;
|
||||
NSUInteger bitsPerComponent = 8;
|
||||
|
||||
|
||||
// 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.
|
||||
CGContextRef context = CGBitmapContextCreate(NULL,
|
||||
width,
|
||||
height,
|
||||
CGImageGetBitsPerComponent(imageRef),
|
||||
0,
|
||||
bitsPerComponent,
|
||||
bytesPerRow,
|
||||
colorspaceRef,
|
||||
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
|
||||
|
||||
// Draw the image into the context and retrieve the new image, which will now have an alpha layer
|
||||
kCGBitmapByteOrderDefault|kCGImageAlphaNoneSkipLast);
|
||||
|
||||
// Draw the image into the context and retrieve the new bitmap image without alpha
|
||||
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
|
||||
CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(context);
|
||||
UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha scale:image.scale orientation:image.imageOrientation];
|
||||
|
||||
if (unsupportedColorSpace)
|
||||
CGImageRef imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
|
||||
UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
|
||||
scale:image.scale
|
||||
orientation:image.imageOrientation];
|
||||
|
||||
if (unsupportedColorSpace) {
|
||||
CGColorSpaceRelease(colorspaceRef);
|
||||
}
|
||||
|
||||
CGContextRelease(context);
|
||||
CGImageRelease(imageRefWithAlpha);
|
||||
CGImageRelease(imageRefWithoutAlpha);
|
||||
|
||||
return imageWithAlpha;
|
||||
return imageWithoutAlpha;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
|
|||
SDWebImageDownloaderProgressiveDownload = 1 << 1,
|
||||
|
||||
/**
|
||||
* By default, request prevent the of NSURLCache. With this flag, NSURLCache
|
||||
* By default, request prevent the use of NSURLCache. With this flag, NSURLCache
|
||||
* is used with default policies.
|
||||
*/
|
||||
SDWebImageDownloaderUseNSURLCache = 1 << 2,
|
||||
|
|
@ -188,4 +188,9 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
|
|||
*/
|
||||
- (void)setSuspended:(BOOL)suspended;
|
||||
|
||||
/**
|
||||
* Cancels all download operations in the queue
|
||||
*/
|
||||
- (void)cancelAllDownloads;
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
static NSString *const kProgressCallbackKey = @"progress";
|
||||
static NSString *const kCompletedCallbackKey = @"completed";
|
||||
|
||||
@interface SDWebImageDownloader ()
|
||||
@interface SDWebImageDownloader () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
|
||||
|
||||
@property (strong, nonatomic) NSOperationQueue *downloadQueue;
|
||||
@property (weak, nonatomic) NSOperation *lastAddedOperation;
|
||||
|
|
@ -23,6 +23,9 @@ static NSString *const kCompletedCallbackKey = @"completed";
|
|||
// This queue is used to serialize the handling of the network responses of all the download operation in a single queue
|
||||
@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue;
|
||||
|
||||
// The session in which data tasks will run
|
||||
@property (strong, nonatomic) NSURLSession *session;
|
||||
|
||||
@end
|
||||
|
||||
@implementation SDWebImageDownloader
|
||||
|
|
@ -74,11 +77,26 @@ static NSString *const kCompletedCallbackKey = @"completed";
|
|||
#endif
|
||||
_barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT);
|
||||
_downloadTimeout = 15.0;
|
||||
|
||||
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
sessionConfig.timeoutIntervalForRequest = _downloadTimeout;
|
||||
|
||||
/**
|
||||
* Create the session for this task
|
||||
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
|
||||
* method calls and completion handler calls.
|
||||
*/
|
||||
self.session = [NSURLSession sessionWithConfiguration:sessionConfig
|
||||
delegate:self
|
||||
delegateQueue:nil];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
[self.session invalidateAndCancel];
|
||||
self.session = nil;
|
||||
|
||||
[self.downloadQueue cancelAllOperations];
|
||||
SDDispatchQueueRelease(_barrierQueue);
|
||||
}
|
||||
|
|
@ -133,6 +151,7 @@ static NSString *const kCompletedCallbackKey = @"completed";
|
|||
request.allHTTPHeaderFields = wself.HTTPHeaders;
|
||||
}
|
||||
operation = [[wself.operationClass alloc] initWithRequest:request
|
||||
inSession:self.session
|
||||
options:options
|
||||
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
|
||||
SDWebImageDownloader *sself = wself;
|
||||
|
|
@ -229,4 +248,70 @@ static NSString *const kCompletedCallbackKey = @"completed";
|
|||
[self.downloadQueue setSuspended:suspended];
|
||||
}
|
||||
|
||||
- (void)cancelAllDownloads {
|
||||
[self.downloadQueue cancelAllOperations];
|
||||
}
|
||||
|
||||
#pragma mark Helper methods
|
||||
|
||||
- (SDWebImageDownloaderOperation *)operationWithTask:(NSURLSessionTask *)task {
|
||||
SDWebImageDownloaderOperation *returnOperation = nil;
|
||||
for (SDWebImageDownloaderOperation *operation in self.downloadQueue.operations) {
|
||||
if (operation.dataTask.taskIdentifier == task.taskIdentifier) {
|
||||
returnOperation = operation;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return returnOperation;
|
||||
}
|
||||
|
||||
#pragma mark NSURLSessionDataDelegate
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
dataTask:(NSURLSessionDataTask *)dataTask
|
||||
didReceiveResponse:(NSURLResponse *)response
|
||||
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
|
||||
|
||||
// Identify the operation that runs this task and pass it the delegate method
|
||||
SDWebImageDownloaderOperation *dataOperation = [self operationWithTask:dataTask];
|
||||
|
||||
[dataOperation URLSession:session dataTask:dataTask didReceiveResponse:response completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
|
||||
|
||||
// Identify the operation that runs this task and pass it the delegate method
|
||||
SDWebImageDownloaderOperation *dataOperation = [self operationWithTask:dataTask];
|
||||
|
||||
[dataOperation URLSession:session dataTask:dataTask didReceiveData:data];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
dataTask:(NSURLSessionDataTask *)dataTask
|
||||
willCacheResponse:(NSCachedURLResponse *)proposedResponse
|
||||
completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler {
|
||||
|
||||
// Identify the operation that runs this task and pass it the delegate method
|
||||
SDWebImageDownloaderOperation *dataOperation = [self operationWithTask:dataTask];
|
||||
|
||||
[dataOperation URLSession:session dataTask:dataTask willCacheResponse:proposedResponse completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
#pragma mark NSURLSessionTaskDelegate
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||
// Identify the operation that runs this task and pass it the delegate method
|
||||
SDWebImageDownloaderOperation *dataOperation = [self operationWithTask:task];
|
||||
|
||||
[dataOperation URLSession:session task:task didCompleteWithError:error];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
|
||||
|
||||
// Identify the operation that runs this task and pass it the delegate method
|
||||
SDWebImageDownloaderOperation *dataOperation = [self operationWithTask:task];
|
||||
|
||||
[dataOperation URLSession:session task:task didReceiveChallenge:challenge completionHandler:completionHandler];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -15,22 +15,26 @@ extern NSString *const SDWebImageDownloadReceiveResponseNotification;
|
|||
extern NSString *const SDWebImageDownloadStopNotification;
|
||||
extern NSString *const SDWebImageDownloadFinishNotification;
|
||||
|
||||
@interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation>
|
||||
@interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
|
||||
|
||||
/**
|
||||
* The request used by the operation's connection.
|
||||
* The request used by the operation's task.
|
||||
*/
|
||||
@property (strong, nonatomic, readonly) NSURLRequest *request;
|
||||
|
||||
/**
|
||||
* The operation's task
|
||||
*/
|
||||
@property (strong, nonatomic, readonly) NSURLSessionTask *dataTask;
|
||||
|
||||
|
||||
@property (assign, nonatomic) BOOL shouldDecompressImages;
|
||||
|
||||
/**
|
||||
* Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default.
|
||||
*
|
||||
* This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`.
|
||||
* Was used to determine whether the URL connection should consult the credential storage for authenticating the connection.
|
||||
* @deprecated Not used for a couple of versions
|
||||
*/
|
||||
@property (nonatomic, assign) BOOL shouldUseCredentialStorage;
|
||||
@property (nonatomic, assign) BOOL shouldUseCredentialStorage __deprecated_msg("Property deprecated. Does nothing. Kept only for backwards compatibility");
|
||||
|
||||
/**
|
||||
* The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
|
||||
|
|
@ -60,6 +64,7 @@ extern NSString *const SDWebImageDownloadFinishNotification;
|
|||
* @see SDWebImageDownloaderOperation
|
||||
*
|
||||
* @param request the URL request
|
||||
* @param session the URL session in which this operation will run
|
||||
* @param options downloader options
|
||||
* @param progressBlock the block executed when a new chunk of data arrives.
|
||||
* @note the progress block is executed on a background queue
|
||||
|
|
@ -70,9 +75,32 @@ extern NSString *const SDWebImageDownloadFinishNotification;
|
|||
* @return the initialized instance
|
||||
*/
|
||||
- (id)initWithRequest:(NSURLRequest *)request
|
||||
inSession:(NSURLSession *)session
|
||||
options:(SDWebImageDownloaderOptions)options
|
||||
progress:(SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
|
||||
cancelled:(SDWebImageNoParamsBlock)cancelBlock;
|
||||
|
||||
/**
|
||||
* Initializes a `SDWebImageDownloaderOperation` object
|
||||
*
|
||||
* @see SDWebImageDownloaderOperation
|
||||
*
|
||||
* @param request the URL request
|
||||
* @param options downloader options
|
||||
* @param progressBlock the block executed when a new chunk of data arrives.
|
||||
* @note the progress block is executed on a background queue
|
||||
* @param completedBlock the block executed when the download is done.
|
||||
* @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue
|
||||
* @param cancelBlock the block executed if the download (operation) is cancelled
|
||||
*
|
||||
* @return the initialized instance. The operation will run in a separate session created for this operation
|
||||
*/
|
||||
- (id)initWithRequest:(NSURLRequest *)request
|
||||
options:(SDWebImageDownloaderOptions)options
|
||||
progress:(SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
|
||||
cancelled:(SDWebImageNoParamsBlock)cancelBlock
|
||||
__deprecated_msg("Method deprecated. Use `initWithRequest:inSession:options:progress:completed:cancelled`");
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ NSString *const SDWebImageDownloadReceiveResponseNotification = @"SDWebImageDown
|
|||
NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification";
|
||||
NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinishNotification";
|
||||
|
||||
@interface SDWebImageDownloaderOperation () <NSURLConnectionDataDelegate>
|
||||
@interface SDWebImageDownloaderOperation ()
|
||||
|
||||
@property (copy, nonatomic) SDWebImageDownloaderProgressBlock progressBlock;
|
||||
@property (copy, nonatomic) SDWebImageDownloaderCompletedBlock completedBlock;
|
||||
|
|
@ -26,7 +26,15 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
@property (assign, nonatomic, getter = isExecuting) BOOL executing;
|
||||
@property (assign, nonatomic, getter = isFinished) BOOL finished;
|
||||
@property (strong, nonatomic) NSMutableData *imageData;
|
||||
@property (strong, nonatomic) NSURLConnection *connection;
|
||||
|
||||
// This is weak because it is injected by whoever manages this session. If this gets nil-ed out, we won't be able to run
|
||||
// the task associated with this operation
|
||||
@property (weak, nonatomic) NSURLSession *unownedSession;
|
||||
// This is set if we're using not using an injected NSURLSession. We're responsible of invalidating this one
|
||||
@property (strong, nonatomic) NSURLSession *ownedSession;
|
||||
|
||||
@property (strong, nonatomic, readwrite) NSURLSessionTask *dataTask;
|
||||
|
||||
@property (strong, atomic) NSThread *thread;
|
||||
|
||||
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
|
||||
|
|
@ -49,10 +57,24 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
progress:(SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
|
||||
cancelled:(SDWebImageNoParamsBlock)cancelBlock {
|
||||
|
||||
return [self initWithRequest:request
|
||||
inSession:nil
|
||||
options:options
|
||||
progress:progressBlock
|
||||
completed:completedBlock
|
||||
cancelled:cancelBlock];
|
||||
}
|
||||
|
||||
- (id)initWithRequest:(NSURLRequest *)request
|
||||
inSession:(NSURLSession *)session
|
||||
options:(SDWebImageDownloaderOptions)options
|
||||
progress:(SDWebImageDownloaderProgressBlock)progressBlock
|
||||
completed:(SDWebImageDownloaderCompletedBlock)completedBlock
|
||||
cancelled:(SDWebImageNoParamsBlock)cancelBlock {
|
||||
if ((self = [super init])) {
|
||||
_request = request;
|
||||
_shouldDecompressImages = YES;
|
||||
_shouldUseCredentialStorage = YES;
|
||||
_options = options;
|
||||
_progressBlock = [progressBlock copy];
|
||||
_completedBlock = [completedBlock copy];
|
||||
|
|
@ -60,7 +82,8 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
_executing = NO;
|
||||
_finished = NO;
|
||||
_expectedSize = 0;
|
||||
responseFromCached = YES; // Initially wrong until `connection:willCacheResponse:` is called or not called
|
||||
_unownedSession = session;
|
||||
responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
|
@ -91,36 +114,36 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
}];
|
||||
}
|
||||
#endif
|
||||
|
||||
NSURLSession *session = self.unownedSession;
|
||||
if (!self.unownedSession) {
|
||||
NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration];
|
||||
sessionConfig.timeoutIntervalForRequest = 15;
|
||||
|
||||
/**
|
||||
* Create the session for this task
|
||||
* We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate
|
||||
* method calls and completion handler calls.
|
||||
*/
|
||||
self.ownedSession = [NSURLSession sessionWithConfiguration:sessionConfig
|
||||
delegate:self
|
||||
delegateQueue:nil];
|
||||
session = self.ownedSession;
|
||||
}
|
||||
|
||||
self.dataTask = [session dataTaskWithRequest:self.request];
|
||||
self.executing = YES;
|
||||
self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO];
|
||||
self.thread = [NSThread currentThread];
|
||||
}
|
||||
|
||||
[self.dataTask resume];
|
||||
|
||||
[self.connection start];
|
||||
|
||||
if (self.connection) {
|
||||
if (self.dataTask) {
|
||||
if (self.progressBlock) {
|
||||
self.progressBlock(0, NSURLResponseUnknownLength);
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self];
|
||||
});
|
||||
|
||||
if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) {
|
||||
// Make sure to run the runloop in our background thread so it can process downloaded data
|
||||
// Note: we use a timeout to work around an issue with NSURLConnection cancel under iOS 5
|
||||
// not waking up the runloop, leading to dead threads (see https://github.com/rs/SDWebImage/issues/466)
|
||||
CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false);
|
||||
}
|
||||
else {
|
||||
CFRunLoopRun();
|
||||
}
|
||||
|
||||
if (!self.isFinished) {
|
||||
[self.connection cancel];
|
||||
[self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:@{NSURLErrorFailingURLErrorKey : self.request.URL}]];
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (self.completedBlock) {
|
||||
|
|
@ -155,7 +178,6 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
- (void)cancelInternalAndStop {
|
||||
if (self.isFinished) return;
|
||||
[self cancelInternal];
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
}
|
||||
|
||||
- (void)cancelInternal {
|
||||
|
|
@ -163,8 +185,8 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
[super cancel];
|
||||
if (self.cancelBlock) self.cancelBlock();
|
||||
|
||||
if (self.connection) {
|
||||
[self.connection cancel];
|
||||
if (self.dataTask) {
|
||||
[self.dataTask cancel];
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||
});
|
||||
|
|
@ -188,9 +210,13 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
self.cancelBlock = nil;
|
||||
self.completedBlock = nil;
|
||||
self.progressBlock = nil;
|
||||
self.connection = nil;
|
||||
self.dataTask = nil;
|
||||
self.imageData = nil;
|
||||
self.thread = nil;
|
||||
if (self.ownedSession) {
|
||||
[self.ownedSession invalidateAndCancel];
|
||||
self.ownedSession = nil;
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setFinished:(BOOL)finished {
|
||||
|
|
@ -209,9 +235,12 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
return YES;
|
||||
}
|
||||
|
||||
#pragma mark NSURLConnection (delegate)
|
||||
#pragma mark NSURLSessionDataDelegate
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
dataTask:(NSURLSessionDataTask *)dataTask
|
||||
didReceiveResponse:(NSURLResponse *)response
|
||||
completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler {
|
||||
|
||||
//'304 Not Modified' is an exceptional one
|
||||
if (![response respondsToSelector:@selector(statusCode)] || ([((NSHTTPURLResponse *)response) statusCode] < 400 && [((NSHTTPURLResponse *)response) statusCode] != 304)) {
|
||||
|
|
@ -220,7 +249,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
if (self.progressBlock) {
|
||||
self.progressBlock(0, expected);
|
||||
}
|
||||
|
||||
|
||||
self.imageData = [[NSMutableData alloc] initWithCapacity:expected];
|
||||
self.response = response;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
|
|
@ -235,21 +264,24 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
if (code == 304) {
|
||||
[self cancelInternal];
|
||||
} else {
|
||||
[self.connection cancel];
|
||||
[self.dataTask cancel];
|
||||
}
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||
});
|
||||
|
||||
|
||||
if (self.completedBlock) {
|
||||
self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES);
|
||||
}
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
[self done];
|
||||
}
|
||||
|
||||
if (completionHandler) {
|
||||
completionHandler(NSURLSessionResponseAllow);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
|
||||
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
|
||||
[self.imageData appendData:data];
|
||||
|
||||
if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock) {
|
||||
|
|
@ -277,7 +309,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
// When we draw to Core Graphics, we lose orientation information,
|
||||
// which means the image below born of initWithCGIImage will be
|
||||
// oriented incorrectly sometimes. (Unlike the image born of initWithData
|
||||
// in connectionDidFinishLoading.) So save it here and pass it on later.
|
||||
// in didCompleteWithError.) So save it here and pass it on later.
|
||||
orientation = [[self class] orientationFromPropertyValue:(orientationValue == -1 ? 1 : orientationValue)];
|
||||
}
|
||||
|
||||
|
|
@ -334,6 +366,110 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
}
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session
|
||||
dataTask:(NSURLSessionDataTask *)dataTask
|
||||
willCacheResponse:(NSCachedURLResponse *)proposedResponse
|
||||
completionHandler:(void (^)(NSCachedURLResponse *cachedResponse))completionHandler {
|
||||
|
||||
responseFromCached = NO; // If this method is called, it means the response wasn't read from cache
|
||||
NSCachedURLResponse *cachedResponse = proposedResponse;
|
||||
|
||||
if (self.request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData) {
|
||||
// Prevents caching of responses
|
||||
cachedResponse = nil;
|
||||
}
|
||||
if (completionHandler) {
|
||||
completionHandler(cachedResponse);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark NSURLSessionTaskDelegate
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error {
|
||||
@synchronized(self) {
|
||||
self.thread = nil;
|
||||
self.dataTask = nil;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||
if (!error) {
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:self];
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
if (error) {
|
||||
if (self.completedBlock) {
|
||||
self.completedBlock(nil, nil, error, YES);
|
||||
}
|
||||
} else {
|
||||
SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;
|
||||
|
||||
if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) {
|
||||
responseFromCached = NO;
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) {
|
||||
completionBlock(nil, nil, nil, YES);
|
||||
} else if (self.imageData) {
|
||||
UIImage *image = [UIImage sd_imageWithData:self.imageData];
|
||||
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
|
||||
image = [self scaledImageForKey:key image:image];
|
||||
|
||||
// Do not force decoding animated GIFs
|
||||
if (!image.images) {
|
||||
if (self.shouldDecompressImages) {
|
||||
image = [UIImage decodedImageWithImage:image];
|
||||
}
|
||||
}
|
||||
if (CGSizeEqualToSize(image.size, CGSizeZero)) {
|
||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES);
|
||||
}
|
||||
else {
|
||||
completionBlock(image, self.imageData, nil, YES);
|
||||
}
|
||||
} else {
|
||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
self.completionBlock = nil;
|
||||
[self done];
|
||||
}
|
||||
|
||||
- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler {
|
||||
|
||||
NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling;
|
||||
__block NSURLCredential *credential = nil;
|
||||
|
||||
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||
if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates)) {
|
||||
disposition = NSURLSessionAuthChallengePerformDefaultHandling;
|
||||
} else {
|
||||
credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
|
||||
disposition = NSURLSessionAuthChallengeUseCredential;
|
||||
}
|
||||
} else {
|
||||
if ([challenge previousFailureCount] == 0) {
|
||||
if (self.credential) {
|
||||
credential = self.credential;
|
||||
disposition = NSURLSessionAuthChallengeUseCredential;
|
||||
} else {
|
||||
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
|
||||
}
|
||||
} else {
|
||||
disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge;
|
||||
}
|
||||
}
|
||||
|
||||
if (completionHandler) {
|
||||
completionHandler(disposition, credential);
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark Helper methods
|
||||
|
||||
+ (UIImageOrientation)orientationFromPropertyValue:(NSInteger)value {
|
||||
switch (value) {
|
||||
case 1:
|
||||
|
|
@ -361,106 +497,8 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis
|
|||
return SDScaledImageForKey(key, image);
|
||||
}
|
||||
|
||||
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection {
|
||||
SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock;
|
||||
@synchronized(self) {
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
self.thread = nil;
|
||||
self.connection = nil;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) {
|
||||
responseFromCached = NO;
|
||||
}
|
||||
|
||||
if (completionBlock) {
|
||||
if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) {
|
||||
completionBlock(nil, nil, nil, YES);
|
||||
} else if (self.imageData) {
|
||||
UIImage *image = [UIImage sd_imageWithData:self.imageData];
|
||||
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
|
||||
image = [self scaledImageForKey:key image:image];
|
||||
|
||||
// Do not force decoding animated GIFs
|
||||
if (!image.images) {
|
||||
if (self.shouldDecompressImages) {
|
||||
image = [UIImage decodedImageWithImage:image];
|
||||
}
|
||||
}
|
||||
if (CGSizeEqualToSize(image.size, CGSizeZero)) {
|
||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES);
|
||||
}
|
||||
else {
|
||||
completionBlock(image, self.imageData, nil, YES);
|
||||
}
|
||||
} else {
|
||||
completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES);
|
||||
}
|
||||
}
|
||||
self.completionBlock = nil;
|
||||
[self done];
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
|
||||
@synchronized(self) {
|
||||
CFRunLoopStop(CFRunLoopGetCurrent());
|
||||
self.thread = nil;
|
||||
self.connection = nil;
|
||||
dispatch_async(dispatch_get_main_queue(), ^{
|
||||
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
|
||||
});
|
||||
}
|
||||
|
||||
if (self.completedBlock) {
|
||||
self.completedBlock(nil, nil, error, YES);
|
||||
}
|
||||
self.completionBlock = nil;
|
||||
[self done];
|
||||
}
|
||||
|
||||
- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse {
|
||||
responseFromCached = NO; // If this method is called, it means the response wasn't read from cache
|
||||
if (self.request.cachePolicy == NSURLRequestReloadIgnoringLocalCacheData) {
|
||||
// Prevents caching of responses
|
||||
return nil;
|
||||
}
|
||||
else {
|
||||
return cachedResponse;
|
||||
}
|
||||
}
|
||||
|
||||
- (BOOL)shouldContinueWhenAppEntersBackground {
|
||||
return self.options & SDWebImageDownloaderContinueInBackground;
|
||||
}
|
||||
|
||||
- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection {
|
||||
return self.shouldUseCredentialStorage;
|
||||
}
|
||||
|
||||
- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{
|
||||
if ([challenge.protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
|
||||
if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates) &&
|
||||
[challenge.sender respondsToSelector:@selector(performDefaultHandlingForAuthenticationChallenge:)]) {
|
||||
[challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust];
|
||||
[[challenge sender] useCredential:credential forAuthenticationChallenge:challenge];
|
||||
}
|
||||
} else {
|
||||
if ([challenge previousFailureCount] == 0) {
|
||||
if (self.credential) {
|
||||
[[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge];
|
||||
} else {
|
||||
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
|
||||
}
|
||||
} else {
|
||||
[[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -64,9 +64,8 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
|
|||
SDWebImageAllowInvalidSSLCertificates = 1 << 7,
|
||||
|
||||
/**
|
||||
* By default, image are loaded in the order they were queued. This flag move them to
|
||||
* the front of the queue and is loaded immediately instead of waiting for the current queue to be loaded (which
|
||||
* could take a while).
|
||||
* By default, images are loaded in the order in which they were queued. This flag moves them to
|
||||
* the front of the queue.
|
||||
*/
|
||||
SDWebImageHighPriority = 1 << 8,
|
||||
|
||||
|
|
@ -182,6 +181,12 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
|
|||
*/
|
||||
+ (SDWebImageManager *)sharedManager;
|
||||
|
||||
/**
|
||||
* Allows to specify instance of cache and image downloader used with image manager.
|
||||
* @return new instance of `SDWebImageManager` with specified cache and downloader.
|
||||
*/
|
||||
- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader;
|
||||
|
||||
/**
|
||||
* Downloads the image at the given URL if not present in cache or return the cached version otherwise.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -37,25 +37,30 @@
|
|||
return instance;
|
||||
}
|
||||
|
||||
- (id)init {
|
||||
- (instancetype)init {
|
||||
SDImageCache *cache = [SDImageCache sharedImageCache];
|
||||
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
|
||||
return [self initWithCache:cache downloader:downloader];
|
||||
}
|
||||
|
||||
- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader {
|
||||
if ((self = [super init])) {
|
||||
_imageCache = [self createCache];
|
||||
_imageDownloader = [SDWebImageDownloader sharedDownloader];
|
||||
_imageCache = cache;
|
||||
_imageDownloader = downloader;
|
||||
_failedURLs = [NSMutableSet new];
|
||||
_runningOperations = [NSMutableArray new];
|
||||
}
|
||||
return self;
|
||||
}
|
||||
|
||||
- (SDImageCache *)createCache {
|
||||
return [SDImageCache sharedImageCache];
|
||||
}
|
||||
|
||||
- (NSString *)cacheKeyForURL:(NSURL *)url {
|
||||
if (!url) {
|
||||
return @"";
|
||||
}
|
||||
|
||||
if (self.cacheKeyFilter) {
|
||||
return self.cacheKeyFilter(url);
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
return [url absoluteString];
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -80,7 +80,11 @@
|
|||
totalCount:self.prefetchURLs.count
|
||||
];
|
||||
}
|
||||
else if (self.finishedCount == self.requestedCount) {
|
||||
if (self.prefetchURLs.count > self.requestedCount) {
|
||||
dispatch_async(self.prefetcherQueue, ^{
|
||||
[self startPrefetchingAtIndex:self.requestedCount];
|
||||
});
|
||||
} else if (self.finishedCount == self.requestedCount) {
|
||||
[self reportStatus];
|
||||
if (self.completionBlock) {
|
||||
self.completionBlock(self.finishedCount, self.skippedCount);
|
||||
|
|
|
|||
|
|
@ -57,8 +57,8 @@ static char imageURLStorageKey;
|
|||
[self.imageURLStorage removeObjectForKey:@(state)];
|
||||
|
||||
dispatch_main_async_safe(^{
|
||||
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
|
||||
if (completedBlock) {
|
||||
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
|
||||
completedBlock(nil, error, SDImageCacheTypeNone, url);
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -32,6 +32,9 @@
|
|||
|
||||
for (size_t i = 0; i < count; i++) {
|
||||
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
|
||||
if (!image) {
|
||||
continue;
|
||||
}
|
||||
|
||||
duration += [self sd_frameDurationAtIndex:i source:source];
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@
|
|||
#if !COCOAPODS
|
||||
#import "webp/decode.h"
|
||||
#else
|
||||
#import "libwebp/webp/decode.h"
|
||||
#import "webp/decode.h"
|
||||
#endif
|
||||
|
||||
// Callback for CGDataProviderRelease
|
||||
|
|
|
|||
|
|
@ -204,6 +204,8 @@
|
|||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
|
||||
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:progress:completed:`");
|
||||
|
||||
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithPreviousCachedImageWithURL:placeholderImage:options:progress:completed:`");
|
||||
|
||||
- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs __deprecated_msg("Use `sd_setAnimationImagesWithURLs:`");
|
||||
|
||||
- (void)cancelCurrentArrayLoad __deprecated_msg("Use `sd_cancelCurrentAnimationImagesLoad`");
|
||||
|
|
|
|||
|
|
@ -87,8 +87,8 @@ static char TAG_ACTIVITY_SHOW;
|
|||
} else {
|
||||
dispatch_main_async_safe(^{
|
||||
[self removeActivityIndicator];
|
||||
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
|
||||
if (completedBlock) {
|
||||
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
|
||||
completedBlock(nil, error, SDImageCacheTypeNone, url);
|
||||
}
|
||||
});
|
||||
|
|
@ -262,6 +262,10 @@ static char TAG_ACTIVITY_SHOW;
|
|||
}];
|
||||
}
|
||||
|
||||
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
|
||||
[self sd_setImageWithPreviousCachedImageWithURL:url placeholderImage:placeholder options:options progress:progressBlock completed:completedBlock];
|
||||
}
|
||||
|
||||
- (void)cancelCurrentArrayLoad {
|
||||
[self sd_cancelCurrentAnimationImagesLoad];
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,13 +3,9 @@ source 'https://github.com/CocoaPods/Specs.git'
|
|||
xcodeproj 'SDWebImage Tests'
|
||||
workspace '../SDWebImage'
|
||||
|
||||
def import_pods
|
||||
pod 'Expecta', '<=0.3.1' # A Matcher Framework for Objective-C/Cocoa
|
||||
target 'Tests' do
|
||||
platform :ios, '7.0'
|
||||
pod 'Expecta', '<=0.3.1'
|
||||
pod 'SDWebImage', :path => '../'
|
||||
end
|
||||
|
||||
target :ios do
|
||||
platform :ios, '5.0'
|
||||
link_with 'Tests'
|
||||
import_pods
|
||||
end
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@
|
|||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
2278D185E97AF851CF3F9A07 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */; };
|
||||
5F7F38AD1AE2A77A00B0E330 /* TestImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */; };
|
||||
ABC8501F672447AA91C788DA /* libPods-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */; };
|
||||
DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D56195472AA00390AB0 /* XCTest.framework */; };
|
||||
DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D58195472AA00390AB0 /* Foundation.framework */; };
|
||||
DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D5A195472AA00390AB0 /* UIKit.framework */; };
|
||||
|
|
@ -19,9 +19,9 @@
|
|||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.debug.xcconfig"; sourceTree = "<group>"; };
|
||||
2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Tests.release.xcconfig"; path = "Pods/Target Support Files/Pods-Tests/Pods-Tests.release.xcconfig"; sourceTree = "<group>"; };
|
||||
5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = TestImage.jpg; sourceTree = "<group>"; };
|
||||
CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.release.xcconfig"; sourceTree = "<group>"; };
|
||||
DA248D53195472AA00390AB0 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
DA248D56195472AA00390AB0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; };
|
||||
DA248D58195472AA00390AB0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||
|
|
@ -32,7 +32,7 @@
|
|||
DA248D68195475D800390AB0 /* SDImageCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCacheTests.m; sourceTree = "<group>"; };
|
||||
DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManagerTests.m; sourceTree = "<group>"; };
|
||||
DA91BEBB19795BC9006F2536 /* UIImageMultiFormatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIImageMultiFormatTests.m; sourceTree = "<group>"; };
|
||||
EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
|
|
@ -43,7 +43,7 @@
|
|||
DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */,
|
||||
DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */,
|
||||
DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */,
|
||||
ABC8501F672447AA91C788DA /* libPods-ios.a in Frameworks */,
|
||||
2278D185E97AF851CF3F9A07 /* libPods-Tests.a in Frameworks */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
|
@ -53,8 +53,8 @@
|
|||
8D1A343B1A6D91E95D7795EF /* Pods */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */,
|
||||
CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */,
|
||||
0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */,
|
||||
2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */,
|
||||
);
|
||||
name = Pods;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -83,7 +83,7 @@
|
|||
DA248D56195472AA00390AB0 /* XCTest.framework */,
|
||||
DA248D58195472AA00390AB0 /* Foundation.framework */,
|
||||
DA248D5A195472AA00390AB0 /* UIKit.framework */,
|
||||
EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */,
|
||||
F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */,
|
||||
);
|
||||
name = Frameworks;
|
||||
sourceTree = "<group>";
|
||||
|
|
@ -117,11 +117,12 @@
|
|||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = DA248D67195472AA00390AB0 /* Build configuration list for PBXNativeTarget "Tests" */;
|
||||
buildPhases = (
|
||||
FBC8982311CD4ED9A3006D45 /* Check Pods Manifest.lock */,
|
||||
FBC8982311CD4ED9A3006D45 /* 📦 Check Pods Manifest.lock */,
|
||||
DA248D4F195472AA00390AB0 /* Sources */,
|
||||
DA248D50195472AA00390AB0 /* Frameworks */,
|
||||
DA248D51195472AA00390AB0 /* Resources */,
|
||||
D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */,
|
||||
D6347736BDF64FC5A4D078A4 /* 📦 Copy Pods Resources */,
|
||||
4B51E412BA3594400947AC71 /* 📦 Embed Pods Frameworks */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
|
|
@ -170,29 +171,44 @@
|
|||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */ = {
|
||||
4B51E412BA3594400947AC71 /* 📦 Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Copy Pods Resources";
|
||||
name = "📦 Embed Pods Frameworks";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-resources.sh\"\n";
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FBC8982311CD4ED9A3006D45 /* Check Pods Manifest.lock */ = {
|
||||
D6347736BDF64FC5A4D078A4 /* 📦 Copy Pods Resources */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "Check Pods Manifest.lock";
|
||||
name = "📦 Copy Pods Resources";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
FBC8982311CD4ED9A3006D45 /* 📦 Check Pods Manifest.lock */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputPaths = (
|
||||
);
|
||||
name = "📦 Check Pods Manifest.lock";
|
||||
outputPaths = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
|
@ -241,7 +257,7 @@
|
|||
};
|
||||
DA248D65195472AA00390AB0 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = 1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */;
|
||||
baseConfigurationReference = 0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
|
|
@ -258,7 +274,6 @@
|
|||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
|
|
@ -289,7 +304,7 @@
|
|||
};
|
||||
DA248D66195472AA00390AB0 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
baseConfigurationReference = CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */;
|
||||
baseConfigurationReference = 2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
|
|
@ -307,7 +322,6 @@
|
|||
COPY_PHASE_STRIP = YES;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
FRAMEWORK_SEARCH_PATHS = (
|
||||
"$(SDKROOT)/Developer/Library/Frameworks",
|
||||
"$(inherited)",
|
||||
"$(DEVELOPER_FRAMEWORKS_DIR)",
|
||||
);
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@
|
|||
|
||||
#import "SDImageCache.h"
|
||||
|
||||
NSString *kImageTestKey = @"TestImageKey";
|
||||
NSString *kImageTestKey = @"TestImageKey.jpg";
|
||||
|
||||
@interface SDImageCacheTests : XCTestCase
|
||||
@property (strong, nonatomic) SDImageCache *sharedImageCache;
|
||||
|
|
@ -185,6 +185,25 @@ NSString *kImageTestKey = @"TestImageKey";
|
|||
expect(path).notTo.beNil;
|
||||
}
|
||||
|
||||
// TODO -- Testing image data insertion
|
||||
|
||||
- (void)testInsertionOfImageData {
|
||||
|
||||
NSData *imageData = [NSData dataWithContentsOfFile:[self testImagePath]];
|
||||
[self.sharedImageCache storeImageDataToDisk:imageData forKey:kImageTestKey];
|
||||
|
||||
UIImage *storedImageFromMemory = [self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey];
|
||||
expect(storedImageFromMemory).to.equal(nil);
|
||||
|
||||
NSString *cachePath = [self.sharedImageCache defaultCachePathForKey:kImageTestKey];
|
||||
NSData *storedImageData = [NSData dataWithContentsOfFile:cachePath];
|
||||
expect([storedImageData isEqualToData:imageData]).will.beTruthy;
|
||||
|
||||
[self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) {
|
||||
expect(isInCache).to.equal(YES);
|
||||
}];
|
||||
}
|
||||
|
||||
#pragma mark Helper methods
|
||||
|
||||
- (void)clearAllCaches{
|
||||
|
|
@ -193,9 +212,14 @@ NSString *kImageTestKey = @"TestImageKey";
|
|||
}
|
||||
|
||||
- (UIImage *)imageForTesting{
|
||||
NSBundle *testBundle=[NSBundle bundleForClass:[self class]];
|
||||
NSString *testBundlePath=[testBundle pathForResource:@"TestImage" ofType:@"jpg"];
|
||||
return [UIImage imageWithContentsOfFile:testBundlePath];
|
||||
|
||||
return [UIImage imageWithContentsOfFile:[self testImagePath]];
|
||||
}
|
||||
|
||||
@end
|
||||
- (NSString *)testImagePath {
|
||||
|
||||
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
|
||||
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
|
||||
}
|
||||
|
||||
@end
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ static int64_t kAsyncTestTimeout = 5;
|
|||
- (void)testThatDownloadInvokesCompletionBlockWithCorrectParamsAsync {
|
||||
__block XCTestExpectation *expectation = [self expectationWithDescription:@"Image download completes"];
|
||||
|
||||
NSURL *originalImageURL = [NSURL URLWithString:@"https://www.google.gr/images/srpr/logo11w.png"];
|
||||
NSURL *originalImageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage000.jpg"];
|
||||
|
||||
[[SDWebImageManager sharedManager] downloadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
|
||||
expect(image).toNot.beNil();
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
<key>CFBundlePackageType</key>
|
||||
<string>FMWK</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>3.7.4</string>
|
||||
<string>3.8.1</string>
|
||||
<key>CFBundleSignature</key>
|
||||
<string>????</string>
|
||||
<key>CFBundleVersion</key>
|
||||
|
|
|
|||
Loading…
Reference in New Issue