Compare commits

...

964 Commits
2.0 ... master

Author SHA1 Message Date
Anton 53837dc070 iOS 10 crash fix 2016-08-22 16:29:48 +03:00
Bogdan Poplauschi c012fc9bb2 Updated the changelog 2016-06-07 12:00:00 +03:00
Bogdan Poplauschi 67329ac512 Bumped the version 2016-06-07 11:57:03 +03:00
Bogdan Poplauschi de149aedaa Reverted all the changes for "Removed the URL query params from the filename (key)" fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1553 #1583 #1585
This is a deal breaker for people. The solution for those issues (i.e. very long urls) is to set the SDWebImageManager cacheKeyFilter block and do their own calculations there.
2016-06-07 11:56:31 +03:00
Bogdan Poplauschi fc0de57066 Readded `shouldUseCredentialStorage` to preserve backwards compatibility 2016-06-06 21:24:11 +03:00
Bogdan Poplauschi 473054879c Updated the changelog 2016-06-06 21:08:17 +03:00
Bogdan Poplauschi 5d42a2ac5e Merge pull request #1586 from oanapopescu/nsurlsession
Updated image downloader with a single session that manages all tasks
2016-06-06 21:00:34 +03:00
Oana Popescu 1e412927cc Keeping both owned and unowned sessions around as part of the operation.
We need different ownership for both because we need to invalidate the owned session upon completion.
The unowned session is wet to avoid cyclical references.
2016-06-06 20:09:43 +03:00
Oana Popescu eab4279140 Updated image downloader with a single session that manages all tasks
- the URL session is created and maintained y the image downloader
- the session will be injected to each operation and it will use it to create the data task
- when delegate callbacks are called, the downloader will call the same delegate methods on the appropriate operation
- if no session is injected upon creating a operation, it will create its own session for backwards compatibility.
2016-06-06 19:12:56 +03:00
Bogdan Poplauschi 1bf62d475a Fixed #1583 crash in `SDWebImageManager cacheKeyForURL:` when url is nil - replaced #1585 2016-06-06 07:32:34 +03:00
Bogdan Poplauschi d8dc6a25aa Merge pull request #1584 from minsOne/master
fixed crash on ios7 user device
2016-06-06 07:25:00 +03:00
Ahn Jung Min 335a437b2e fixed crash on ios7 user device
fixed that string property of NSURLComponents can`t use on iOS7
2016-06-06 04:42:02 +09:00
Bogdan Poplauschi cb7a3db23c Updated the changelog 2016-06-02 19:19:42 +03:00
Bogdan Poplauschi 6545a3aba1 Bumped the deployment target to iOS 7 (due to NSURLSession) and also incremented the library version to 3.8.0 2016-06-02 19:10:31 +03:00
Bogdan Poplauschi 9137b65d3b Merge pull request #1578 from oanapopescu/nsurlsession
Replace deprecated NSURLConnection with NSURLSession
2016-06-02 18:59:05 +03:00
Oana Popescu 09a9e74eae Removed dealloc method and added comment regarding sending nil for delegateQueue 2016-06-02 18:23:49 +03:00
Oana Popescu 5580c78282 Replace deprecated NSURLConnection with NSURLSession. See #1291 #1318 #823 #1566
- one session per operation to preserve the ordering and priority functionalities
- removed all the runloop code that was only used to keep the operation running. I am relying on non-setting the isFinished property to keep the operation running
- todo: check deallocation, test background tasks
2016-06-02 09:02:03 +03:00
Bogdan Poplauschi af7b587936 Fixed #1573 - Update to cc510a6 - Cached file name with path extension UIWebView issue - for iOS 7 and above, remove the query from the url (prior to iOS 7 the behavior remains the same). 2016-05-31 14:51:33 +03:00
Bogdan Poplauschi 86fc47bf7b Replaces #1398 Allow to customise cache and image downloader instances used with SDWebImageManager - added a new initializer (`initWithCache:downloader:`) 2016-05-30 07:31:01 +03:00
Bogdan Poplauschi e6e5c5156b Fixed #1415 documentation was not updated when `removeImageForKey:` became async 2016-05-29 22:32:15 +03:00
Bogdan Poplauschi cc510a6a4e Fixed #1553 Cached file name with path extension UIWebView issue - for iOS 7 and above, remove the query from the url (prior to iOS 7 the behavior remains the same). 2016-05-29 16:25:31 +03:00
Bogdan Poplauschi 0dc2c41112 Trying to get around this last build error "The certificate for this server is invalid. You might be connecting to a server that is pretending to be “www.google.gr” which could put your confidential information at risk." by using a different image 2016-05-29 12:49:06 +03:00
Bogdan Poplauschi f8a7b6bac7 The pod setup output is huge with CocoaPods 1.0.0 (10.000+ lines), causes Travis to "This log is too long to be displayed. Please reduce the verbosity of your build or download the raw log." 2016-05-29 12:48:26 +03:00
Bogdan Poplauschi 8e300c92a4 Need to clean the SDWebImage scheme to allow the tests to rebuild it using their required platform. 2016-05-29 00:50:24 +03:00
Bogdan Poplauschi 44eac986bb Another attempt at the build 2016-05-29 00:44:02 +03:00
Bogdan Poplauschi afaf306222 This should fix the build (the tests project) 2016-05-29 00:00:33 +03:00
Bogdan Poplauschi 5ac4e308c7 Fixed the Tests/Podfile, the Target ios was not to be found, so took advantage of this change to simplify it 2016-05-28 23:00:16 +03:00
Bogdan Poplauschi f1a471e93f Fixed #1444 and the master build thanks to 5034c334be 2016-05-28 22:50:53 +03:00
Bogdan Poplauschi 11840d1313 Attempt to fix the latest build (failed because of Invalid `Podfile` file: [!] The specification of `link_with` in the Podfile is now unsupported, please use target blocks instead.) 2016-05-28 22:07:18 +03:00
Bogdan Poplauschi 1f165b48ee Added CONTRIBUTING, ISSUE and PULL_REQUEST TEMPLATE 2016-05-28 21:46:40 +03:00
Bogdan Poplauschi edb4bc3554 Updated the changelog 2016-05-08 19:49:06 +03:00
Bogdan Poplauschi 990f85bce2 Bumped version to 3.7.6 2016-05-08 19:32:10 +03:00
Bogdan Poplauschi b40124c95d Fixed #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 2016-05-08 19:00:39 +03:00
Bogdan Poplauschi 371533549c Merge pull request #1453 from Mutix/master
Added API to save image NSData to disk cache.
2016-05-08 18:53:26 +03:00
Bogdan Poplauschi d4d11ef0b0 Merge pull request #1461 from jawwad/patch-1
Improve documentation for SDWebImageHighPriority
2016-05-08 18:43:52 +03:00
Bogdan Poplauschi d6d9a5c233 Merge pull request #1504 from siburb/master
Added "cancelAllDownloads" method to SDWebImageDownloader.
2016-05-08 18:41:36 +03:00
Bogdan Poplauschi 1fba8d99f3 Merge pull request #1549 from iOSPandaLee/master
Repair memory release in the iPad environment
2016-05-08 18:35:47 +03:00
iOSPandaLee 5cc5abae03 Repair memory release in the iPad environment
In the iPad environment, NSCache lead to anonymous VM very high, if reaches a certain value, app will be crash. Because of SDImageCache don't clear memory when receive memory warning notification, modify define TARGET_OS_IPHONE to TARGET_OS_IOS can resolve this issue.
2016-05-05 11:51:19 +08:00
Konstantinos K 19041b44c2 Merge pull request #1547 from maxoly/master
Fixed completion logic in MKAnnotationView+WebCache
2016-05-04 20:04:15 +03:00
Massimo Oliviero d2b648e8ff Fixed completion logic in MKAnnotationView+WebCache 2016-05-04 17:23:05 +02:00
Konstantinos K 29c9c5d68a Merge pull request #1540 from futuretap/fix-1437
Fixed changed image size (#1437)
2016-04-25 20:31:18 +03:00
Ortwin Gentz 4709774dc2 Revert dcde40fc01
fixes #1437
2016-04-25 16:16:00 +02:00
Konstantinos K 0979d5b5f7 Merge pull request #1532 from Sethathi/patch-1
Update README.md
2016-04-18 21:49:53 +03:00
Sethathi Morokole 11521aa040 Update README.md
Minor grammar fix
2016-04-18 16:03:39 +02:00
Konstantinos K 83240bd781 Merge pull request #1527 from yebw/master
Fix #1524
2016-04-12 21:14:14 +03:00
yebw 32787175ac Optimize the decoder to avoid of unwanted blended layer 2016-04-12 17:27:33 +08:00
Bogdan Poplauschi 0da78a4ce6 Merge pull request #1486 from bestswifter/master
typo fix
2016-03-27 18:54:37 +03:00
Konstantinos K 09556f2d21 Merge pull request #1464 from Brain89/fixDecodedImageWithImage(1423)
[fix] Issue #1423
2016-03-25 12:47:52 +02:00
Simon Burbidge ed7df926ea Added "cancelAllDownloads" method to SDWebImageDownloader. 2016-03-21 13:16:05 +08:00
Konstantinos K 16e1862afc Merge pull request #1390 from ttgb/patch-1
Update .gitmodules
2016-03-17 09:50:03 +02:00
Konstantinos K 1ef791bad9 Merge pull request #1496 from yamasakitomohiro/master
fixes  CGContextDrawImage: invalid context 0x0
https://github.com/rs/SDWebImage/issues/1401
https://github.com/rs/SDWebImage/issues/1454
https://github.com/rs/SDWebImage/issues/1457
2016-03-17 09:46:40 +02:00
山崎友弘 32ca18b523 To and modify the "Downloaded image has 0 pixels" error exits bug download a file of the png format 2016-03-15 18:41:35 +09:00
张星宇 1189f74c00 typo fix 2016-03-09 09:46:02 +08:00
Bogdan Poplauschi 469d8bbfd8 Merge pull request #1466 from toshi0383/fix-license
Remove XML special characters from LICENSE
2016-02-17 15:43:34 +02:00
toshi0383 2489074417 Also update copyright year 2016-02-17 20:18:49 +09:00
Toshihiro Suzuki b39fab3180 Remove XML special characters from LICENSE 2016-02-17 20:16:32 +09:00
Aleksandr Sychev 974141f5a2 [fix] Issue #1423 2016-02-15 18:45:57 +03:00
Bogdan Poplauschi e7fa11058b Merge pull request #1462 from ReadmeCritic/master
Correct the spelling of CocoaPods in README
2016-02-11 11:44:38 +02:00
ReadmeCritic 8fe7ed5ca7 Correct the spelling of CocoaPods in README 2016-02-10 13:38:58 -08:00
Jawwad Ahmad cbb50e986e Improve documentation for SDWebImageHighPriority
- Fixed grammar issues in the first sentence.
- Removed the second sentence since it is redundant. Moving to the front of the queue implies that they will be loaded first. Also doesn't seem necessary to inform the user that the queued images might take a while to download.
2016-02-11 01:24:14 +05:00
Martin Oppetit 68ae502797 Adhering to coding style
- also added new line at the end of SDImageCacheTests.m file
2016-02-04 10:14:53 +00:00
Mutix 6e1b2aa8f0 Merge pull request #1 from Mutix/feature/store-NSData
Added API to save image NSData to disk cache
2016-02-01 15:20:28 +00:00
Martin Oppetit 9c4fcfa844 Added API to save image NSData to disk cache
- exposing new `- (void)storeImageDataToDisk:(NSData *)imageData
forKey:(NSString *)key` function on SDImageCache
- added unit tests for this new API
- added file extension to kImageTestKey to ensure cache path is valid
for creating NSData
2016-02-01 15:19:59 +00:00
Olivier Poitrey e41af47e2f Merge pull request #1447 from slackhq/master
Protect against malformed frame
2016-01-30 02:54:23 +01:00
sukeban 070cbc63ee Add braces 2016-01-25 14:27:41 -08:00
sukeban 3b039d5910 Protect against malformed image
Don’t add nil to the array, just skip the frame.
2016-01-25 14:21:17 -08:00
Bogdan Poplauschi 64f621081c Bumped version to 3.7.5 and added to changelog 2016-01-21 16:34:36 +02:00
Bogdan Poplauschi b426975b9f Replaced the demo images from static2.dmcdn.net that were no longer working with the demo images from FastImageCache 2016-01-21 15:36:36 +02:00
Bogdan Poplauschi fca618fb61 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. Not the greatest way to fix it, but the simplest one. 2016-01-21 15:14:16 +02:00
Bogdan Poplauschi 9ecf488aff Merge pull request #1439 from Moral-Piggy/master
Without creating a NSError instance when completedBlock is nil
2016-01-20 17:28:44 +02:00
Bogdan Poplauschi a8fca6584f Continuation of Fix #1366, addresses #1350 and reverts a part of #1221 - from commit 6406d8e, the wrong usage of dispatch_apply
This one fixes: #1425 and #1426
2016-01-19 19:08:18 +02:00
liushuaikobe 47115e2593 If the sd_imageURL of the UIImageView or UIButton is nil, won't create a NSError Instance 2016-01-18 16:29:28 +08:00
Bogdan Poplauschi 6a623cd58f Updated Changelog and added Changelod to workspace 2016-01-08 17:44:08 +02:00
Bogdan Poplauschi a45b222e70 Bump version to 3.7.4 2016-01-08 17:17:58 +02:00
Bogdan Poplauschi aa3598f3e0 Merge pull request #1348 from yirenjun/master
Create a strong ref of weakOperation in the entry of The image downlo…
2016-01-08 16:53:15 +02:00
Bogdan Poplauschi 8aca4ca1b3 Merge pull request #1363 from muer2000/patch-3
Fixed #1361 sd_cancelBackgroundImageLoadForState
2016-01-08 16:50:00 +02:00
Bogdan Poplauschi cac21e106d Fix #1366, addresses #1350 and reverts a part of #1221 - from commit 6406d8e, the wrong usage of dispatch_apply 2016-01-08 16:50:35 +02:00
Bogdan Poplauschi ee49d49d35 Bumped the libwebp reference to 0.4.4 2016-01-08 16:34:18 +02:00
Konstantinos K 6c650f910e Merge pull request #1412 from valeriomazzeo/1382-CMYK-ColorSpace
added CMYK unsupported color space model
2015-12-31 09:46:02 +02:00
Valerio Mazzeo e709a04e89 added CMYK unsupported color space model 2015-12-30 15:45:14 +00:00
Aaron ttgb ee50027b88 Update .gitmodules
Modify the libwebp url to github mirror
2015-12-07 10:57:02 +08:00
Konstantinos K 740cd7f090 Merge pull request #1367 from Shayanzadeh/master
Fixes a bug where image scale & orientation are ignored when decoding / decompressing an image.
2015-11-17 21:33:13 +02:00
Shayan Yousefizadeh 95468315fc Fixes a bug where image scale & orientation are ignored when decoding / decompressing an image. 2015-11-17 18:24:48 +00:00
muer2000 40ad58571b Fixed #1361 sd_cancelBackgroundImageLoadForState
Fixed sd_cancelBackgroundImageLoadForState in sd_setBackgroundImageWithURL method
2015-11-12 15:45:47 +08:00
Bogdan Poplauschi 30e9e0b516 Merge pull request #1358 from hoseking/master
Add CocoaPods support for tvOS
2015-10-30 20:36:28 +02:00
hoseking 11c7efb6e1 Add CocoaPods support for tvOS 2015-10-30 10:50:33 -07:00
Bogdan Poplauschi a090531604 Updated Readme 2015-10-29 22:02:22 +02:00
Bogdan Poplauschi f9abff8988 Merge pull request #1350 from eikemeier/master
Fix compilation error introduced in commit 6406d8e
2015-10-27 15:32:00 +02:00
Oliver Eikemeier 92e38160d6 Fix compilation error introduced in commit 6406d8e526 2015-10-27 13:44:19 +01:00
Bogdan Poplauschi 8dcc5b5ae7 Updated Readme - fixed type 2015-10-26 11:39:19 +02:00
yirenjun 2b57abd44a Create a strong ref of weakOperation in the entry of The image download subOperation, use the strong ref instead weakOperation 2015-10-26 14:45:36 +08:00
Bogdan Poplauschi 6b5f3236a8 Updated .gitignore 2015-10-25 20:44:35 +02:00
Bogdan Poplauschi c8c00810dd Merge pull request #1221 from harishkashyap/master 2015-10-25 19:37:13 +02:00
Bogdan Poplauschi 04a0431ae9 Making sure all access to self.runningOperations is synchronized 2015-10-25 19:35:26 +02:00
Bogdan Poplauschi ac98896099 Code style 2015-10-25 19:32:31 +02:00
Harish Krishnamurthy 6406d8e526 Modifies SDWebImagePrefetcher prefetching logic.
- Removes recursive calls to startPrefetchingAtIndex.
- Uses dispatch_apply with striding to optimize the performance.
2015-10-25 19:30:29 +02:00
Bogdan Poplauschi 5b05d6c3cc Replaced #1258 - Removing "and" from method names per https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CodingGuidelines/Articles/NamingMethods.html 2015-10-25 19:24:50 +02:00
Bogdan Poplauschi 53ef2dc3c3 Merge pull request #1340 from lagapollo/lagapollo-patch-1
Memory usage upgrade
2015-10-25 19:19:45 +02:00
Bogdan Poplauschi 0e4dbe1f24 Merge pull request #1327 from hoseking/tvOS
Add support for tvOS
2015-10-25 16:05:45 +02:00
Bogdan Poplauschi 32923fa2e8 Xcode 7.1 updates 2015-10-25 15:58:45 +02:00
Bogdan Poplauschi dcb7985c5c Replaced #1345 - Added urlCredential property to SDWebImageDownloader 2015-10-25 15:57:52 +02:00
Bogdan Poplauschi 3b9c09142a Updated Readme 2015-10-24 14:08:56 +03:00
hoseking 07fe1f0dfe Update project settings for Xcode 7 2015-10-16 11:23:28 -07:00
hoseking 4068b93386 Add tvOS Framework target 2015-10-16 11:23:28 -07:00
Konstantinos K. 0ecd13667d Merge pull request #1341 from mihaiserban/master
iOS 9 App Transport Security Demo Target
2015-10-15 18:12:19 +03:00
Serban Mihai 7ba8208f17 iOS 9 App Transport Security Demo Target
fixed ios 9 load images caused by new App Transport Security feature
2015-10-15 16:46:40 +03:00
Bogdan Poplauschi bf899e222f Fixed the error that was causing the Travis builds to fail
The issue was: since CocoaPods 0.38.0, the way pod headers are created on disk changed (see for example https://github.com/core-plot/core-plot/issues/204). This caused the webp/decode.h file to be unaccessible from CocoaPods installations. We could not change the import to libwebp/webp/decode.h since our git clone installation would then fail (as the path for that is Vendors/libwebp/src/webp). The solution was to rely on the COCOAPODS macro to make 2 different imports for Cocoapods and the other installation type.
2015-10-13 14:38:15 +03:00
Bogdan Poplauschi c1f6aecd8b Added CHANGELOG.md 2015-10-13 12:01:22 +03:00
Bogdan Poplauschi 782c682187 Merge pull request #1331 from 102errors/master
spelling
2015-10-08 13:33:28 +03:00
102errors 233b6c2607 spelling 2015-10-09 18:21:44 +08:00
lagapollo 65fbc3b85a Memory usage upgrade
autorelease the bitmap context for clearing cache when memory warnings
2015-10-07 17:20:45 +02:00
Bogdan Poplauschi eec1b67497 Updated Readme (subspecs) 2015-10-06 16:59:48 +03:00
Bogdan Poplauschi a16d007622 Updated #976 according to comments via review 2015-09-30 18:56:33 +03:00
Bogdan Poplauschi 577fefa26e Merge pull request #976 from ghazel/file-extension
append the original path extension to the hash filename. closes #967
2015-09-30 18:51:06 +03:00
Konstantinos K. 7a48ca6dad Merge pull request #1323 from initlifeinc/master
don't to perform download if url is "" but not nil
2015-09-30 08:39:19 +03:00
initlife 20c77af44c Merge pull request #1 from initlifeinc/initlifeinc-patch-1
don't to perform download if url is "" but not nil
2015-09-30 10:59:02 +08:00
initlife 5f0594f043 don't to perform download if url is "" but not nil
sometimes user may pass @"" as url to sdwebimage to download, now it will also run NSURLConnection and try to download, actually there is no need to do this. I think maybe use url.absoluteString.length == 0 to avoid that url is not nil but a empty string will be better
2015-09-30 10:58:17 +08:00
Konstantinos K. 2d748f1e2f Merge pull request #1321 from mythodeia/master
Added a new constructor to SDWebImagePrefetcher
2015-09-29 10:27:51 +03:00
KonstantinosK 944fd77965 Added a new constructor to SDWebImagePrefetcher
that allows it to be instantiated with any image manager
2015-09-29 10:27:09 +03:00
Konstantinos K. 3af1a30ebb Merge pull request #1280 from atsusy/fix-uiimage-gif
```UIGraphicsBeginImageContextWithOptions``` and ```UIGraphicsEndImageContext``` should be inside the loop for each image
2015-09-29 09:18:33 +03:00
Konstantinos K. 996fea9e5b Merge pull request #1308 from adrianmacneil/patch-2
Add Swift installation tips
2015-09-29 08:41:49 +03:00
Konstantinos K. 6a28dc7ae9 Merge pull request #1276 from arielelkin/patch-2
SDWebImagePrefetcher: remove logging
2015-09-29 08:38:33 +03:00
Konstantinos K. 7e6bd60176 Merge pull request #1297 from mythodeia/master
cleaner implementation of failedUrl error handling
2015-09-29 08:38:13 +03:00
Konstantinos K. b185621812 Merge pull request #1310 from xzenon/patch
Added support for SDWebImageAvoidAutoSetImage option to UIButton and highlighted UIImageView categories
2015-09-23 09:01:54 +03:00
Xenon 05ce156764 Added support for SDWebImageAvoidAutoSetImage option to UIButton and highlighted UIImageView 2015-09-23 04:23:11 +03:00
Adrian Macneil 4786e98605 Add Swift installation tips
Refs #993
2015-09-21 20:10:14 -07:00
Konstantinos K. 60cab8b74c cleaner implementation of failedUrl error handling 2015-09-16 23:26:45 +03:00
Olivier Poitrey 14842f65f7 Merge pull request #1290 from adrianmacneil/patch-1
Fix typo
2015-09-11 12:08:07 -07:00
Adrian Macneil 4d1abffb32 Fix typo 2015-09-11 11:59:51 -07:00
Atsushi Kataoka 46c59183aa Fix sd_animatedImageByScalingAndCroppingToSize: 2015-09-02 11:12:59 +09:00
Ariel Elkin 6814af4ade SDWebImagePrefetcher: remove logging
Remove macro that checks for DEBUG, SD_VERBOSE, and SD_LOG_NONE
Remove calls to NSLog
2015-08-31 10:49:33 +02:00
Konstantinos K. 5a5c65d799 Merge pull request #1268 from izackp/patch-1
Fix unsupported colorspace issue.
2015-08-21 18:53:35 +03:00
Isaac Paul d00d368cdb Fix unsupported colorspace issue.
Without this fix, this url: https://abs.twimg.com/sticky/default_profile_images/default_profile_3_normal.png isn't correctly decoded and the method returns a nil image.. perhaps there should be a failsafe that checks the return value and returns the input image instead if the return value is nil.
2015-08-21 10:59:07 -04:00
Konstantinos K. 49f6e532b5 Merge pull request #1257 from Coeur/spelling
spelling
2015-08-16 18:29:54 +03:00
Konstantinos K. 5f6287e535 Merge pull request #1256 from esteluk/patch-1
Fix typo "timeElasped" -> "timeElapsed"
2015-08-16 18:29:44 +03:00
Antoine Cœur c011d1a88b spelling 2015-08-16 22:09:08 +08:00
Nathan Wong 6edface2c3 Fix typo "timeElasped" -> "timeElapsed" 2015-08-14 15:45:32 +01:00
Bogdan Poplauschi 0df58e4995 Merge pull request #1236 from mythodeia/master
better handling of colorspace models
2015-07-31 09:54:49 +03:00
mythodeia fb62c3fde1 better handling of colorspace models 2015-07-17 00:11:54 +03:00
Bogdan Poplauschi a45c722fc8 Merge pull request #1218 from mythodeia/master
progress callbacks now report on main thread
2015-07-16 00:11:12 +03:00
mythodeia 25b4c178d9 progress reports on main thread 2015-07-15 23:56:05 +03:00
Bogdan Poplauschi be560a4090 Merge pull request #1217 from mythodeia/master
Import fixes from @mythodeia 's fork
2015-07-15 23:42:00 +03:00
mythodeia df751e737b added option to disable memory cache
use this:
```shouldDisableMemoryCache``` to toggle memory cache
2015-07-15 11:35:03 +03:00
mythodeia a9ea132874 disable iCloud backup 2015-07-15 11:04:44 +03:00
mythodeia c68d585e49 activity indicator added
```
[cell.imageView setShowActivityIndicatorView:YES];
[cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray];
```
2015-07-15 10:50:04 +03:00
mythodeia 4cfb12c01c fix unsupported parameter combination issues
when CGBitmapContextCreate is called
2015-07-15 10:45:31 +03:00
mythodeia dcde40fc01 set as default the device's screen scale 2015-07-15 10:43:29 +03:00
Konstantinos K. ae11cf7e43 Update README.md 2015-07-15 09:39:25 +03:00
Bogdan Poplauschi 0373b97f71 Merge pull request #1125 from pauruiz/CacheTests
Cache tests
2015-07-14 16:39:47 +03:00
Bogdan Poplauschi 5c7dc8c2e5 Bumped podspec version 2015-07-13 23:02:15 +03:00
Bogdan Poplauschi ba335fc7d5 Merge pull request #1153 from LukeDurrant/CustomDiskCachePath
Custom disk cache path
2015-07-13 22:18:55 +03:00
Bogdan Poplauschi 33c13e79ca Coding style updates 2015-07-13 22:18:33 +03:00
Bogdan Poplauschi f611d5e52b Merge pull request #1188 from bill350/master
Add an option called "SDWebImageAvoidAutoImageFill" to avoid automati…
2015-07-02 18:07:44 +03:00
Jean-Charles SORIN 4d6693c813 Rename SDWebImageAvoidAutoImageFill option to SDWebImageAvoidAutoSetImage 2015-07-01 10:11:35 +02:00
Bogdan Poplauschi ef578240b3 Merge pull request #1199 from keslcod/master
A minor thing: Avoid compiler warning about the missing new line at the end of the file
2015-06-29 14:36:09 +03:00
Florian Buerger d107a80189 Add newline to avoid compiler warning 2015-06-29 11:48:49 +02:00
Bogdan Poplauschi b111d6246a Revert "Fixing casing for #import "webp/decode.h" (#import "WebP/decode.h") not"
This reverts commit 48d4adc210.
2015-06-29 11:41:32 +03:00
Bogdan Poplauschi 511ce9992e Merge pull request #1196 from unlucio/webp-case
Fixing casing for #import "webp/decode.h"
2015-06-25 10:38:04 +03:00
unLucio 48d4adc210 Fixing casing for #import "webp/decode.h" (#import "WebP/decode.h") not
working on case sensitive HDs
2015-06-25 11:04:55 +04:00
Bogdan Poplauschi 7e160e34a2 Merge pull request #1158 from akmarinov/master
Fixed an issue that causes URLs with trailing parameters to be assign…
2015-06-25 01:33:39 +03:00
Bogdan Poplauschi 466e4011d0 Merge pull request #1138 from KoCMoHaBTa/KoCMoHaBTa-patch-1074
Applied patch for issue #1074
2015-06-25 01:15:01 +03:00
Konstantinos K. 08e9962b5e Merge pull request #1167 from jiangmingz/patch-2
fix ImageIO: CGImageSourceCreateWithData data parameter is nil
2015-06-24 19:34:50 +03:00
Konstantinos K. 7692bd2610 Merge pull request #1178 from marciomeschini/marco/fix_accept_header
add webp accepted content type only if WebP enabled
2015-06-24 19:24:47 +03:00
Konstantinos K. 2ee4bfe24b Merge pull request #1159 from stephanecopin/errorCodeFailedURLs
Add handling for additional error codes that shouldn't be considered a permanent failure
2015-06-24 19:12:09 +03:00
Konstantinos K. 8021ddd313 Merge pull request #1121 from archfear/transparancy_fix
Fix for transparency being lost in transformed images.
2015-06-24 19:10:02 +03:00
stephane-fueled db4f3fc9b6 fix(): simplify logic for failed URLs error code on iOS6/7 2015-06-24 10:57:16 -04:00
stephane-fueled 4499441661 feat(failedURLs): add additional error codes that shouldn't be considered as a permanent failure 2015-06-24 10:54:58 -04:00
Marco Meschini e622b290c9 fix directive
apologies. yeah, #elseif was quite inappropriate for this case
2015-06-24 09:58:19 +01:00
Konstantinos K. 0e761f4aa7 404 image url was causing the test to fail 2015-06-24 10:37:31 +03:00
Konstantinos K. 43115af147 Merge pull request #1177 from aschuch/master
libwebp submodule moved to another location
2015-06-24 09:56:35 +03:00
Konstantinos K. 01a5cfb86b Merge pull request #1193 from rs/revert-1175-master
Revert "Fixes http://git.chromium.org/webm/libwebp.git/info/refs not …
2015-06-24 09:52:53 +03:00
Konstantinos K ef1a1c3c47 Revert "Fixes http://git.chromium.org/webm/libwebp.git/info/refs not valid" 2015-06-24 09:47:14 +03:00
Jean-Charles SORIN 5d2963ac73 Add an option called "SDWebImageAvoidAutoImageFill" to avoid automatic image addition in UIImageView and let developer to do it himself 2015-06-18 19:18:45 +02:00
Marco Meschini 26698f9da0 add webp accepted content type only if WebP enabled
Send WebP as accepted content type only if it is enabled. In case it's not, stick with the standard formats in order to avoid the server sending us back WebP images.
2015-06-12 17:04:33 +01:00
Konstantinos K. 48d10c1773 Merge pull request #1175 from joelchen/master
Fixes http://git.chromium.org/webm/libwebp.git/info/refs not valid
2015-06-12 18:13:56 +03:00
Alexander Schuch 1f65ca773f Update .gitmodules 2015-06-12 16:48:10 +02:00
Joel dfc57ac94c Fix http://git.chromium.org/webm/libwebp.git/info/refs not valid 2015-06-11 15:14:23 +08:00
Konstantinos K. 8f3b5e9330 fixed typ in method description
should say asynchronously in methods ```removeImageForKey...```
2015-06-08 10:05:58 +03:00
拔萝卜的☂Tank be0791233c Update UIImage+MultiFormat.m
fix <Error>: ImageIO: CGImageSourceCreateWithData data parameter is nil bug
2015-06-02 20:23:40 +08:00
Andrey Marinov 8f309e194e Fixed an issue that causes URLs with trailing parameters to be assigned an incorrect image scale value 2015-05-25 19:48:23 +03:00
Luke Durrant d7bc2c0036 Improved by using makeDiskCachePath 2015-05-20 17:30:23 +10:00
Luke Durrant 737140d4cb Added support for custom disk cache folder with fall back for caches directory 2015-05-20 17:28:06 +10:00
Olivier Poitrey 91b4251115 Merge pull request #1085 from flovilmart/AppExtensionSafe
Determines at runtime is UIApplication is available as per #1082
2015-05-17 21:06:19 -07:00
Olivier Poitrey 393d4f1601 Merge pull request #1143 from rromanchuk/feature/auto-purge-on-memory-event
Purge nscache on system memory notifications
2015-05-13 12:14:50 -07:00
Ryan Romanchuk 78be42ee3b Use subclassed NSCache 2015-05-13 11:03:13 -07:00
Ryan Romanchuk 4756d5dcbe Purge nscache on system memory notifications 2015-05-12 16:24:23 -07:00
Konstantinos K. a51688168d Merge pull request #1111 from molon/master
failedURLs can be removed at the appropriate time.
2015-05-12 08:37:14 +03:00
Olivier Poitrey 98989d9524 Merge pull request #1140 from rromanchuk/feature/add-count-limits
Add NSCache countLimit property
2015-05-11 12:48:37 -07:00
Ryan Romanchuk f72f4c183d Add NSCache countLimit property in attempts to get better control of cache eviction. 2015-05-11 11:02:33 -07:00
Milen Halachev 9f719ca2f9 Applied patch for issue #1074
When the code is copied within a swift module, or when a target is linked against the static library or when using from cocoapods - the debugger not longer gets broken.
2015-05-08 02:56:08 +03:00
Pau Ruiz 79eb6e77c5 Added all methods of the cache module, almost all directly and some of them indirectly used
Unable to test sync call to diskImageExistsWithKey, hoped due to problems with the file manager and the test bundle being different from the main bundle
2015-04-19 10:01:35 +01:00
Pau Ruiz 66ddb23593 Added image for testing cache 2015-04-19 09:24:34 +01:00
molon 9ae8f97425 failedURLs can be removed at the appropriate time. 2015-04-08 18:24:52 +08:00
Dan Dofter 38a6edb02a Only store an image with unknown format as PNG if it has an alpha channel. 2015-04-02 17:50:20 -07:00
Pete Callaway 7e50d78c80 Don’t pass the original image data to be cached if the image has been transformed as transparency may have been added 2015-04-02 17:41:16 -07:00
Bogdan Poplauschi 704c630567 Merge pull request #1104 from pollarm/master
Fix parenthesis to avoid crashes
2015-03-31 12:32:37 +03:00
Mike Pollard 4dd5a6681a Fix parenthesis to avoid crashes 2015-03-30 21:30:16 +01:00
Bogdan Poplauschi 6690de8ccf Merge pull request #1101 from samritchie/master
Carthage build fails in Xcode 6.2
2015-03-30 12:04:02 +03:00
Sam Ritchie 9c00f5cd7b Changed deployment target to 8.0 2015-03-29 12:29:25 +08:00
Florent Vilmart a897811eb5 Lowers deployment target to 8.0 2015-03-22 16:40:44 -04:00
Florent Vilmart a66a790eb2 Replaces direct calls to UIApplication by peformSelector 2015-03-20 18:37:55 -04:00
Florent Vilmart 17a4803661 Determines at runtime is UIApplication is available as per #1082 2015-03-20 15:29:28 -04:00
Bogdan Poplauschi 70dfe15144 Merge pull request #1081 from flovilmart/Carthage
Adds shared scheme for WebImage in SDWebImage.xcodeproj
2015-03-20 08:28:49 +02:00
Florent Vilmart f2252b3499 Adds shared scheme for WebImage in SDWebImage.xcodeproj 2015-03-19 21:15:53 -04:00
Bogdan Poplauschi 9620fffa64 @3x support - replaced #1005 2015-03-19 23:44:25 +02:00
Bogdan Poplauschi 4f97897a41 Merge pull request #1045 from mariusschulz/patch-1
Updates Podfile entry to v3.7
2015-03-19 23:38:13 +02:00
Bogdan Poplauschi cd0c57f43e Merge pull request #1071 from flovilmart/Carthage
Adds support for iOS 8+ Framework and Carthage
2015-03-19 23:33:06 +02:00
Florent Vilmart c0c5e0d714 Adds Carthage WebImage scheme to workspace 2015-03-19 14:14:11 -04:00
Bogdan Poplauschi 2b68869927 Merge pull request #1075 from ikesyo/refactor-image-cache-cost
[Refactor] Implement cache cost calculation as a inline function
2015-03-19 14:23:33 +02:00
Bogdan Poplauschi d56c4f3d22 Merge pull request #1054 from heistings/develop
Use __typeof(self) when assigning weak reference for block.
2015-03-19 14:19:58 +02:00
Bogdan Poplauschi eac0b816f8 Merge pull request #1041 from john-07/master
allow override diskCachePath
2015-03-19 14:13:34 +02:00
Bogdan Poplauschi 85dde52173 Merge pull request #1038 from rounak/patch-1
fixed typo
2015-03-19 14:10:13 +02:00
Bogdan Poplauschi 88ee3c6774 Replacing #1018 - avoid warning "<Error>: ImageIO: CGImageSourceCreateWithData data parameter is nil" if imageData is nil 2015-03-19 13:52:44 +02:00
Bogdan Poplauschi 6e947240a0 Merge pull request #1017 from warld-limited/prefetcher_patch
[Memory Issue] Clear SDWebImagePrefetcher progressBlock when it has completed
2015-03-19 13:47:17 +02:00
Bogdan Poplauschi 7f99c01804 Replaces #1016 2015-03-19 12:10:59 +02:00
Bogdan Poplauschi 72ed897c53 Formatting in the readme.md 2015-03-19 12:09:45 +02:00
Bogdan Poplauschi 843148139b Added some files to the workspace so they are easier to edit 2015-03-19 12:06:55 +02:00
Bogdan Poplauschi fb2063086d Merge pull request #985 from songfrank/master
Bug fix:Collection <__NSArrayM: > was mutated while being enumerated
2015-03-19 11:57:15 +02:00
Bogdan Poplauschi beabb1842b Merge pull request #988 from wantedly/improve-operation-behavior
Improve operation behavior
2015-03-19 11:54:01 +02:00
Bogdan Poplauschi 0ef0e07f77 Merge pull request #1011 from mattjgalloway/error_domain
Make a constant for the error domain
2015-03-19 10:55:59 +02:00
Bogdan Poplauschi 27e3038ec3 Merge pull request #1076 from ikesyo/faild-urls-nsset
[Refactor] Use NSMutableSet for failed URLs' storage instead of array
2015-03-18 11:24:55 +02:00
Syo Ikeda 210c13d124 [Refactor] Use NSMutableSet for failed URLs' storage instead of array 2015-03-18 12:33:28 +09:00
Syo Ikeda 021607a845 [Refactor] Implement cache cost calculation as a inline function 2015-03-18 12:27:23 +09:00
Bogdan Poplauschi d41bfaf8c8 Fix: xcodebuild: error: -destination implies architecture, -arch must not also be specified. 2015-03-17 16:53:00 +02:00
Bogdan Poplauschi 6c29c8b009 Another try to fix the travis builds 2015-03-17 16:36:50 +02:00
Bogdan Poplauschi b3ad18ea56 Updated travis.yml 2015-03-17 16:14:33 +02:00
Bogdan Poplauschi fd34a9a0fa Revert "Fixed #774 - remove deprecated methods. Since 4.0 is a major release, we don't need the backwards compatible methods"
This reverts commit 62a8ee1ab6.
2015-03-17 15:55:16 +02:00
Bogdan Poplauschi 36f5b1e4e9 The latest libwebp library has some warnings that cause our pod spec lint to fail 2015-03-17 15:43:11 +02:00
Bogdan Poplauschi 76ed37636f Updated libwebp submodule hash to 0.4.3 2015-03-17 15:29:07 +02:00
Florent Vilmart 9ee89474ed Adds support for iOS 8+ Framework and Carthage
Adds Instructions for Carthage installation
2015-03-15 12:06:27 -04:00
Olivier Poitrey 962bcb0323 Merge pull request #1059 from thedrick/thedrick-bump-podspec
Bumping podspec version
2015-03-09 15:34:01 -07:00
Tyler Hedrick 9b8aa8a12d Bumping podspec version 2015-03-09 14:50:45 -07:00
Olivier Poitrey 904f552e01 Merge pull request #1057 from heistings/dev_updateReadMe
Update README.md.
2015-03-08 20:20:51 -07:00
庞博 56e2c6283c Update README.md.
Signed-off-by: 庞博 <bopang@sohu-inc.com>
2015-03-09 10:14:43 +08:00
庞博 f83abb578a Use __typeof(self) when assigning weak reference for block.
Signed-off-by: 庞博 <bopang@sohu-inc.com>
2015-03-06 16:37:38 +08:00
Olivier Poitrey 9cc8269dcd Merge pull request #1049 from hoppenichu/fix_donwloader_2
Make sure callbacksForURL won't be modified
2015-02-25 17:04:13 -08:00
Takeru Chuganji 62e2320f2d make sure inmutable 2015-02-26 09:23:08 +09:00
Olivier Poitrey 17c3cf3aa0 Merge pull request #996 from harishkashyap/fix-memory-issues
Adds option to decompress images and select prefetcher Queue
2015-02-25 07:54:44 -08:00
Olivier Poitrey 0f157d4332 Merge pull request #1046 from hoppenichu/fix_downloader
Fix SDWebImageDownloader threading issue
2015-02-24 21:53:57 -08:00
Takeru Chuganji f8c7b9014c Specify Expecta Version 2015-02-25 10:50:08 +09:00
Takeru Chuganji ffa3962992 fix threading issue 2015-02-25 02:45:37 +09:00
Marius Schulz 4445bb2e47 Updates Podfile entry to v3.7 2015-02-24 10:49:22 +01:00
Evgeny Petrov 6468a92f32 allow override diskCachePath 2015-02-16 15:56:30 +03:00
Rounak dadb740c47 fixed typo
aync -> async
2015-02-10 17:54:33 +05:30
Naoki Morita ce73619640 Merge branch 'master' of github.com:rs/SDWebImage 2015-01-31 22:34:54 +09:00
Katsuma Ito 0e047941e9 Clear SDWebImagePrefetcher progressBlock when it has completed
If progressblock captures objects, captured objects remain until next SDWebImagePrefetcher works.
So, nil clear progressBlock as well as completionBlock.
2015-01-20 18:33:10 +08:00
Matt Galloway 761b00553b Make a constant for the error domain 2015-01-13 19:34:05 +00:00
Bogdan Poplauschi feca1e8d0d Merge pull request #987 from wantedly/fix-notification-dispatch
Fix NSNotificationCenter dispatch on subthreads.
2015-01-07 10:33:01 +02:00
Harish Krishnamurthy c59160e6da Reverts queue property to assign 2014-12-23 17:37:27 -05:00
Harish Krishnamurthy e97fea7233 Changes property of queue from weak to strong 2014-12-23 16:34:27 -05:00
Harish Krishnamurthy 4ceb6665b2 * Adds Queue options to SDWebImagePrefetcher.
* Adds option to decompress images in cache and post download.
2014-12-22 16:03:45 -05:00
Bogdan Poplauschi 21656fad68 Merge pull request #994 from initlifeinc/master
duplicate failed urls are added into failedURLs
2014-12-22 11:12:36 +02:00
Dick cded20c736 duplicate failed urls are added into failedURLs
fix bug when download image with option SDWebImageRetryFailed
2014-12-22 16:58:16 +08:00
Olivier Poitrey 0db489b32e Merge pull request #991 from sammcd/patch-1
Update README.md
2014-12-19 11:11:42 -08:00
Sam McDonald 0ae0e34642 Update README.md
Picky spelling fix.
2014-12-19 10:14:08 -08:00
Bogdan Poplauschi 6b137fb8ba Merge pull request #981 from mythodeia/master
initialise kPNGSignatureData data
2014-12-17 10:52:23 +02:00
Naoki Morita 22750a18b2 Merge branch 'improve-operation-behavior' 2014-12-16 12:35:44 +09:00
Naoki Morita f7a2321107 Fix typo. 2014-12-16 12:35:17 +09:00
Naoki Morita d90d115893 Fix notification name. 2014-12-16 12:24:57 +09:00
Naoki Morita 327c444322 Fix notification name. 2014-12-16 12:23:41 +09:00
Naoki Morita cd977d70a4 Improve operation behavior to get more information of it. 2014-12-16 11:48:26 +09:00
Naoki Morita 3d3471e490 Fix NSNotificationCenter dispatch on subthreads. 2014-12-16 10:52:34 +09:00
sfeng dad2a9254b Bug fix:Collection <__NSArrayM: > was mutated while being enumerated 2014-12-15 03:20:39 +08:00
Konstantinos K b271cbb371 initialise kPNGSignatureData data
in SDImageCache initWithNamespace method.
This ensures the kPNGSignatureData is always initialised even if the we
alloc SDImageCache without using the sharedImageCache singleton
2014-12-10 14:42:43 +02:00
Greg Hazel 9af7460f2b append the original path extension to the hash filename. closes #967 2014-12-06 13:06:29 -08:00
Bogdan Poplauschi 6698910fe1 Revert "Loading Indicator view with 2 lines of code"
This reverts commit 2cfa5ccb88.
2014-11-06 19:59:27 +02:00
mythodeia 2cfa5ccb88 Loading Indicator view with 2 lines of code
added support for UIActivityIndicatorView while the image is
downloaded, without adding extra ‘setImageWithUrl’ methods to the
UIImageView+WebCache category.
I used [this pull
request](https://github.com/mythodeia/UIActivityIndicator-for-SDWebImage
), original author is [JJSaccolo](https://github.com/JJSaccolo), and
modded it a bit to support loading indicator while the image is
downloading.

the usage is basically this right before the usual sd_setImage...
methods:
```
        // show activity indicator
        [cell.imageView setShowActivityIndicatorView:YES];
        // choose indicator style
        [cell.imageView
setIndicatorStyle:UIActivityIndicatorViewStyleGray];
```
2014-11-06 19:26:44 +02:00
Bogdan Poplauschi afd1931c52 Updated Readme with git clone command 2014-11-06 14:20:35 +02:00
Bogdan Poplauschi 0aa9b61bcc Everything worked except the tests, trying using xcodebuild instead of xctool 2014-11-04 13:52:11 +02:00
Bogdan Poplauschi 542fc29808 Another try with Travis CI, this time no clean action, as it fails with
xcodebuild build clean
Scheme Tests is not currently configured for the clean action.
2014-11-04 13:44:45 +02:00
Bogdan Poplauschi 87384290a4 Moved all schemes to the workspace container plus created scheme for Tests 2014-11-04 12:45:04 +02:00
Bogdan Poplauschi 0b50b57c13 Reverted last change, doesn't work with Travis CI 2014-11-04 12:28:49 +02:00
Bogdan Poplauschi 55f4beade5 Updated Travis CI config, making sure xctool is installed 2014-11-04 12:22:59 +02:00
Bogdan Poplauschi ef9a2798a7 Updated Travis CI script, replaced xcpretty with xctool 2014-11-04 12:16:25 +02:00
Bogdan Poplauschi 01931d1d89 Updated libwebp reference to 0.4.2 2014-11-04 10:55:59 +02:00
Bogdan Poplauschi 914ed45a44 Merge pull request #941 from mishagray/cost_compute_fix
Cost compute fix
2014-11-02 23:55:23 +02:00
Bogdan Poplauschi b596c9c120 Merge pull request #942 from Krivoblotsky/master
'304 Not Modified' HTTP status code handling.
2014-11-02 23:52:10 +02:00
Bogdan Poplauschi 7f39e5e60e The code from SDWebImageDownloaderOperation connection:didFailWithError: should match the code from connectionDidFinishLoading:. This fixes #872 2014-11-02 23:20:16 +02:00
Bogdan Poplauschi 936f47c005 Added Travis CI configuration file 2014-11-02 22:53:45 +02:00
Bogdan Poplauschi d9d9ceedf4 Updated the Tests project after updating to CocoaPods 0.34.4 2014-11-02 22:53:32 +02:00
Bogdan Poplauschi 759f0b9a3e Merge pull request #897 from MrAlek/fix/max-concurrency-count
Increased default maxConcurrentOperationCount, fixes #527
2014-11-02 19:33:11 +02:00
Alek Åström 09b6ee941a Increased default maxConcurrentOperationCount, fixing issue #527 2014-11-02 18:06:17 +01:00
Serg Krivoblotsky 3d94e34415 304 http status code handling 2014-10-31 23:30:27 +02:00
Michael Gray dfd2e2a2f1 Merge commit '7d9337406760603ddee47d5515e1e4835618b6b2' into cost_compute_fix 2014-10-31 14:32:51 -04:00
Bogdan Poplauschi 1a3ccc2e8d Merge pull request #840 from foxling/master
fix #610 display progressive jpeg issue
2014-10-31 20:12:38 +02:00
Bogdan Poplauschi 125515d7f1 Merge pull request #876 from matias-pequeno/custom_operations
Allows user to override default SDWebImageDownloaderOperation
2014-10-31 20:08:45 +02:00
Bogdan Poplauschi a4c213ecbd Merge pull request #886 from hsoi/fix-implicit-atomicity-declaration
Fix implicit atomicity declaration of the SDWebImageManager.cacheKeyFilter
2014-10-31 20:05:25 +02:00
Bogdan Poplauschi b0ff8516ab Merge pull request #898 from mattjgalloway/xctest_async
Switch to built in XCTest async
2014-10-31 20:02:42 +02:00
Bogdan Poplauschi c3c55784cb Merge pull request #936 from flexih/master
Decoding webp, depends on source image data alpha status.
2014-10-31 20:00:55 +02:00
Bogdan Poplauschi 52b2b70abf Merge pull request #937 from pavelosipov/master
Implement 'SDWebImageDownloaderAllowInvalidSSLCertificates' option.
2014-10-31 19:59:31 +02:00
Bogdan Poplauschi 62a8ee1ab6 Fixed #774 - remove deprecated methods. Since 4.0 is a major release, we don't need the backwards compatible methods 2014-10-31 19:12:42 +02:00
Pavel Osipov 75944258f0 Implement 'SDWebImageDownloaderAllowInvalidSSLCertificates' option. 2014-10-23 17:16:28 +04:00
flexih 83ad6fa977 Decoding webp, depends on source image data alpha status. 2014-10-23 12:14:43 +08:00
Olivier Poitrey d2da4d0df4 Merge pull request #929 from kirualex/patch-2
Handle empty urls NSArray
2014-10-14 07:14:45 -07:00
Alexis Creuzot 98082a6791 Handle empty urls NSArray
In some cases the user may end up with an empty urls NSArray, in which case the completion block is never called.
This commit handle such case to call immediately the completion block (if any)
2014-10-14 11:16:58 +02:00
Bogdan Poplauschi 2233b5e77d Merge pull request #896 from skrew/master
Update UIImageView+WebCache.m
2014-09-22 22:23:19 +03:00
Bogdan Poplauschi ee3c351abd Fixed #900 by adding a new flag SD_LOG_NONE that allows silencing the SD logs from the Prefetcher 2014-09-22 22:15:45 +03:00
Matt Galloway 66a6873b2c Switch to built in XCTest async 2014-09-15 12:06:11 +01:00
eric@skrobs 54a772ebb9 Update UIImageView+WebCache.m
Can cause animation losing or crash if you are in a thread.
2014-09-12 20:03:34 +02:00
Bogdan Poplauschi 5f4d7f44b4 Merge pull request #893 from asparagui/sp_fixes
minor spelling (forth->fourth)
2014-09-12 09:45:33 +03:00
Brett Koonce 5284ac6623 minor spelling (forth->fourth) 2014-09-11 19:24:54 -07:00
Bogdan Poplauschi 43af50c555 Merge pull request #890 from kyleclegg/master
Updated key filter sample code
2014-09-11 09:41:42 +03:00
Kyle Clegg 013ccba57b Updated code sample to not use deprecated api 2014-09-10 12:51:25 -06:00
John C. Daub 3c82278727 atomicity was implicit (compiler complained). Declared 'nonatomic' as that's fairly standard on iOS 2014-09-04 09:08:47 -05:00
Bogdan Poplauschi 11125c4379 Merge pull request #879 from dulgan/patch-1
Adding a flag for Cocoa Pods users
2014-09-01 16:09:36 +03:00
dulgan 249adae4f0 Adding a flag for Cocoa Pods users
Using the Parse framework and SDWebImage frameworks installed via Cocoa Pods gives the same error as described in the Alternatively section of the Add Linker Flag section in this Readme.
I found a solution here : http://www.deanmao.com/2012/12/31/linker-error-using-cocoapods/
2014-08-27 14:10:27 +02:00
Matias Pequeno 3671cdde0f Adds setter to override default SDWebImageDownloaderOperation. 2014-08-14 18:12:37 -07:00
Bogdan Poplauschi 6dfec7ccd9 Updated README.md with CocoaDocs link 2014-08-12 13:59:40 +03:00
Bogdan Poplauschi 15cda1b561 Merge pull request #854 from Gabro/patch-1
More explicit error message in case of nil completedBlock
2014-08-12 12:26:01 +03:00
Gabriele Petronella ec6b6e7267 More explicit error message in case of nil completedBlock
NSParameterAssert doesn't provide enough information for understanding the API misuse.
Pointing the API user to SDWebImagePrefetcher makes more sense, as a nil completedBlock most likely signifies the intention of prefetching the image.
2014-08-12 11:23:31 +02:00
Bogdan Poplauschi 16eea9f104 Updated references to libwebp files after the changes from their latest release (0.4.1) 2014-08-11 15:00:19 +03:00
Bogdan Poplauschi 8bf39a9263 Merge pull request #850 from tonyarnold/fix-comment-documentation
Fix misnamed parameters in comment documentation
2014-08-11 10:31:45 +03:00
Tony Arnold a31b9d46a1 Fix misnamed parameters in comment documentation 2014-08-11 17:27:05 +10:00
Bogdan Poplauschi f1041856d0 Updated libwebp reference to 0.4.1 (this fixed the arm64 build issues) 2014-08-08 18:12:59 +03:00
Bogdan Poplauschi 044abf402d Merge pull request #838 from justjimmy/master
fix cancelAll crash (Issue #809)
2014-08-06 19:20:47 +03:00
Bogdan Poplauschi 55c7c6c8e1 Merge pull request #703 from talklittle/master
Flag to transform animated images
2014-08-04 11:47:06 +03:00
Andrew Shu a8c4fa48b7 Flag to transform animated images
Using a new SDWebImageOptions flag: SDWebImageTransformAnimatedImage
2014-08-04 01:42:12 -07:00
foxling b2909fb2da fix #610 2014-08-04 15:17:58 +08:00
Jimmy Lee 3587b8d1e0 fix cancelAll crash 2014-07-31 10:10:52 +10:00
Bogdan Poplauschi 2eef774eae Merge pull request #836 from reiz/master
Add Reference & Dependency Badges
2014-07-28 13:47:42 +03:00
Robert Reiz bf6be426f3 Add References Badge to Readme 2014-07-26 10:45:46 +02:00
Robert Reiz 934c9cc96d Add Dependency Badge 2014-07-26 10:44:56 +02:00
Bogdan Poplauschi 7815923c48 Fixed other misspells from appledoc (additions to #829) 2014-07-23 16:15:16 +03:00
Bogdan Poplauschi 101ee70d94 Merge pull request #829 from davemess/master
Fix documentation spelling
2014-07-23 16:12:02 +03:00
David Messing 3bb13ef34a Merge branch 'branch-misspell' 2014-07-23 09:00:03 -04:00
David Messing b9d9456e21 Fixed documentation spelling. 2014-07-23 08:59:52 -04:00
Bogdan Poplauschi 959e8db914 Bumped podspec version 2014-07-23 08:17:14 +03:00
Bogdan Poplauschi e95224bf5f Temporary fix for #809, until we can figure out the cause of the crash 2014-07-23 08:13:25 +03:00
Bogdan Poplauschi f96302b427 Merge pull request #827 from BB9z/fix/pargma-mark
Missing mark.
2014-07-22 12:17:09 +03:00
BB9z f6d7d60b98 Missing mark. 2014-07-22 16:58:08 +08:00
Bogdan Poplauschi 222e6bca0d Merge pull request #795 from xlchen/master
fix duplicate symbols when using with webp via pods
2014-07-21 15:32:45 +03:00
Bogdan Poplauschi 28109c4c70 Fixed SDWebImageCombinedOperation cancel crash (#798 #809) 2014-07-21 15:27:16 +03:00
mishagray 7d93374067 Modified the cost calculuations to appropriately compute the 'scale' of an image 2014-07-20 18:10:02 -04:00
Bogdan Poplauschi c8df858f75 Added test for the UIImage+MultiFormat crash 2014-07-18 16:56:32 +03:00
Bogdan Poplauschi 681a7c4222 Merge pull request #819 from n13/master
guarding against image source == NULL
2014-07-18 16:21:16 +03:00
Nikolaus Heger 9faee5356c guarding against image source == NULL 2014-07-18 11:07:13 +07:00
Bogdan Poplauschi b88a552fba Updated all block params and properties, using defined blocks that have var names (for proper autocomplete). Created a SDWebImageNoParamsBlock to distinguish easier from other no params blocks. Fixes #810 2014-07-16 15:17:08 +03:00
Bogdan Poplauschi cd4b925448 Update to #732 to fix misspell (completion instead of completition) 2014-07-14 18:29:45 +03:00
Bogdan Poplauschi db252d3654 Updated podspec version to 3.7.0 2014-07-14 18:12:07 +03:00
Bogdan Poplauschi f080e38fb8 Replace #699 Fixed race condition in SDWebImageManager if one operation is cancelled, the completion block must not be called, otherwise it might race with a newer completion for the same object
Conflicts:
	SDWebImage/SDWebImageManager.m
2014-07-14 16:29:57 +03:00
Bogdan Poplauschi 6e4fbafa55 #625 In order to fix the deadlock, reviewed the `[SDImageCache diskImageExistsWithKey:]` method. Based on the Apple doc for NSFileManager, using the defaultManager without the dispatch on the ioQueue to avoid the deadlocks. This instance is thread safe. Also created an async variant of this method `[SDImageCache diskImageExistsWithKey:completion:]`
For consistency, added async methods in `SDWebImageManager` `cachedImageExistsForURL:completion:` and `diskImageExistsForURL:completion:`
2014-07-14 16:22:00 +03:00
Bogdan Poplauschi 0b47342b2f No need for explicit ivar and getters, as long as we have the @synthesize in place 2014-07-14 13:01:05 +03:00
Bogdan Poplauschi 39db378082 Merge pull request #783 from bpoplauschi/race_condition
Replace #621Fixed race condition between operation cancelation and loading finish
2014-07-11 09:57:28 +03:00
Bogdan Poplauschi 894a1b1810 Merge pull request #794 from vjyanand/master
Update MKAnnotationView+WebCache.m
2014-07-10 10:57:51 +03:00
Vjy Anand 99590ed6ec Update MKAnnotationView+WebCache.m
Replace deprecated method call
2014-07-06 06:40:06 -04:00
Bogdan Poplauschi 2e708d3518 Updated README.md with badges 2014-07-04 10:56:09 +03:00
Bogdan Poplauschi 30e034d60d Fixed misspell 2014-06-30 00:07:32 +03:00
Bogdan Poplauschi 72a4e7b830 Replace #621Fixed race condition between operation cancelation and loading finish 2014-06-26 00:30:45 +03:00
Bogdan Poplauschi 30f672661c Added option to use the cached image instead of the placeholder for UIImageView. Replaces #541. Fixes #599 2014-06-26 00:27:56 +03:00
Bogdan Poplauschi a6f11b3ad7 Fixed #775, made sure all the category methods that are public have the sd_ prefix (deprecated the old ones)
-there were a few exceptions where I just renamed the methods since they were added in this method
2014-06-25 21:32:53 +03:00
Bogdan Poplauschi 23874cdca4 Update for #771 - instead of removing the old methods, deprecated them so we are backwards compatible. 2014-06-25 11:24:59 +03:00
Bogdan Poplauschi 6d01e80409 Added comments and coding style to previous pull request #771 2014-06-25 11:04:28 +03:00
Bogdan Poplauschi 9b18145e56 Merge pull request #771 from Whirlwind/new_cancel_logic
Refactor the cancel logic
2014-06-25 10:49:44 +03:00
Bogdan Poplauschi 3a7adbbacf Merge pull request #780 from rokgregoric/master
Do not load placeholder image if SDWebImageDelayPlaceholder option specified.
2014-06-24 18:29:09 +03:00
Rok Gregorič 8d668b4121 Do not load placeholder image if SDWebImageDelayPlaceholder option specified. 2014-06-24 12:49:34 +02:00
Bogdan Poplauschi 50c4d1d2eb Implemented NTLM auth support. Replaced deprecated auth challenge methods from `NSURLConnectionDelegate`. Replaces #711.
- added `username` and `password` properties on `SDWebImageDownloader`
- added `shouldUseCredentialStorage` and `credential` properties on `SDWebImageDownloaderOperation`
- `SDWebImageDownloaderOperation` conforms to `NSURLConnectionDataDelegate` (it used to implement the methods, but didn't stated the protocol in the declaration)
- removed deprecated methods: `- connection:canAuthenticateAgainstProtectionSpace:` and `- connection:didReceiveAuthenticationChallenge:` with `- connectionShouldUseCredentialStorage:` and `- connection:willSendRequestForAuthenticationChallenge:`
- updated demo project to download one image the requires HTTP auth
2014-06-23 21:57:33 +03:00
Bogdan Poplauschi c7330db3a6 Merge branch 'unit_tests'
Unit testing setup + created workspace
- created a SDWebImage.xcworkspace
- includes the existing SDWebImage.xcodeproj (responsible of compiling the library)
- includes the existing SDWebImage Demo.xcodeproj
- includes the newly created SDWebImage Tests.xcodeproj (tests project). The test project uses the local CocoaPods repo to link to the library

Unit testing backbone:
- XCTest framework (the one from Apple)
- XCTestAsync - extension for XCTest that allows easily creating asynchronous tests. Relies on dispatch_after.
- Expecta - matcher Framework for Objective-C/Cocoa

Updated gitignore
2014-06-23 21:23:56 +03:00
Bogdan Poplauschi e5faad0026 Reverted demo project referencing source files directly. Re-added SDWebImage project as subproject 2014-06-20 18:04:06 +03:00
Bogdan Poplauschi e0b3de4357 Added error test 2014-06-20 17:51:40 +03:00
Bogdan Poplauschi c1fae30d63 Added SDWebImage Tests project. It uses CocoaPods (Expecta + XCTestAsync). Added some demo tests 2014-06-20 17:21:01 +03:00
Bogdan Poplauschi 60b043755f Created a SDWebImage workspace with the 2 existing projects, fixed the demo project so it directly references the source files. Shared a demo project scheme 2014-06-20 16:41:53 +03:00
Bogdan Poplauschi 7855f89185 Prepared gitignore for CocoaPods and workspaces 2014-06-20 16:40:43 +03:00
Bogdan Poplauschi fe4b3a088a Fixed warnings from demo project (started using the new methods, the ones with the sd_ prefix). 2014-06-20 10:07:12 +03:00
Whirlwind 5615cf12de Merge branch 'master' into new_cancel_logic
Conflicts:
	SDWebImage/MKAnnotationView+WebCache.m
	SDWebImage/UIButton+WebCache.m
	SDWebImage/UIImageView+HighlightedWebCache.h
	SDWebImage/UIImageView+HighlightedWebCache.m
	SDWebImage/UIImageView+WebCache.m
2014-06-20 10:51:17 +08:00
Bogdan Poplauschi af3e4f87e4 Returning error in setImage completedBlock if the url was nil. Added `dispatch_main_async_safe` macro. Fixes #505 2014-06-19 23:24:08 +03:00
Bogdan Poplauschi eb91fdd3b8 Fixed issue #529 - if the `cacheKeyFilter` was set, this was ignored when computing the `scaledImageForKey`. For most of the developers that did not set `cacheKeyFilter`, the code will work exactly the same 2014-06-19 23:05:14 +03:00
Olivier Poitrey a8a69ab9b6 Merge pull request #770 from bpoplauschi/completion_with_url
Pass imageURL in completedBlock
2014-06-19 12:38:12 -07:00
Bogdan Poplauschi 136daba9df Added proper handling for SDWebImageDownloaderLowPriority (aka NSOperationQueuePriorityLow). Fixes #713 #745 2014-06-19 22:19:22 +03:00
Bogdan Poplauschi e116aa5ce0 Updated some older code to match the coding style 2014-06-19 21:58:20 +03:00
Bogdan Poplauschi ea663b9602 As discussed with @rs, prefixed all the new methods to sd_set* 2014-06-19 21:54:25 +03:00
Whirlwind 4c18545dbc Refactor the cancel logic 2014-06-19 22:46:37 +08:00
Bogdan Poplauschi 03a751430d Pass image URL in completion blocks - step 6:
- deprecated block type `SDWebImageCompletedBlock `, replaced with `SDWebImageCompletedBlock ` that contains NSURL* param
2014-06-19 12:27:08 +03:00
Bogdan Poplauschi 81b5e72a9c Pass image URL in completion blocks - step 5:
- deprecated all UIImageView(WebCache) `setImage*` methods. Replaced with `loadImage*` methods that use the `SDWebImageCompletionBlock` as completion block type
- created WebCacheDeprecated category on UIImageView (to avoid collisions, we didn't name it Deprecated)
- replaced the usages of the deprecated items with the new ones
2014-06-19 12:26:12 +03:00
Bogdan Poplauschi 21b230f28f Fixed misspell (downloand -> download) 2014-06-19 12:13:39 +03:00
Bogdan Poplauschi 76b552e21e Pass image URL in completion blocks - step 4:
- deprecated all UIImageView(HighlightedWebCache) `setImage*` methods. Replaced with `loadImage*` methods that use the `SDWebImageCompletionBlock` as completion block type
- created HighlightedWebCacheDeprecated category on UIImageView (to avoid collisions, we didn't name it Deprecated)
- replaced the usages of the deprecated items with the new ones
2014-06-19 12:12:58 +03:00
Bogdan Poplauschi c38409b813 Updated UIButton category documentation (forth param for the completion block) + alignaments 2014-06-19 12:04:07 +03:00
Bogdan Poplauschi 673fca9113 Documentation alignaments 2014-06-19 12:00:23 +03:00
Bogdan Poplauschi 939f68d27e Updated MKAnnotation view category documentation (forth param for the completion block) + alignaments 2014-06-19 11:55:02 +03:00
Bogdan Poplauschi 7108b4f404 Pass image URL in completion blocks - step 3:
- deprecated all UIButton(WebCache) `setImage*` methods. Replaced with `loadImage*` methods that use the `SDWebImageCompletionBlock` as completion block type
- created WebCacheDeprecated category on UIButton (to avoid collisions, we didn't name it Deprecated)
- replaced the usages of the deprecated items with the new ones
2014-06-19 11:49:27 +03:00
Bogdan Poplauschi 654a9c98ea Pass image URL in completion blocks - step 2:
- created block type `SDWebImageCompletionBlock` that contains NSURL* param
- deprecated all MKAnnotationView(WebCache) `setImage*` methods. Replaced with `loadImage*` methods that use the `SDWebImageCompletionBlock` as completion block type
- created WebCacheDeprecated category on MKAnnotationView (to avoid collisions, we didn't name it Deprecated)
- replaced the usages of the deprecated items with the new ones
2014-06-19 11:32:28 +03:00
Bogdan Poplauschi 233ef65f98 Pass image URL in completion blocks - step 1:
- deprecated block type `SDWebImageCompletedWithFinishedBlock`, replaced with `SDWebImageCompletionWithFinishedBlock` that contains NSURL* param
- deprecated SDWebImageManager `-downloadWithURL:options:progress:completed:` method. Replaced with `downloadImageWithURL:options:progress:completed:` that uses the `SDWebImageCompletionWithFinishedBlock ` as completion block type
- created Deprecated category for SDWebImageManager containing the old method
- replaced the usages of the deprecated items with the new ones
2014-06-19 11:10:38 +03:00
Bogdan Poplauschi 99b7a090f8 Missing new line 2014-06-19 10:51:55 +03:00
Bogdan Poplauschi a8f5627052 Added doc description for the NSData category 2014-06-19 10:36:13 +03:00
Bogdan Poplauschi dfceb49d2b Reordered categories in project file 2014-06-19 10:35:55 +03:00
Bogdan Poplauschi e4b9ef512b Fixed a warning in the demo project 2014-06-19 10:21:09 +03:00
Bogdan Poplauschi 455188355f Merge pull request #764 from n13/master
support for image orientation
2014-06-19 00:02:20 +03:00
Bogdan Poplauschi 9dcd68d5ee Merge pull request #751 from robertmryan/master
Avoid premature completion of prefetcher if request fails
2014-06-18 15:39:57 +03:00
Bogdan Poplauschi e4104942ee Return nil from SDScaledImageForKey if the input image is nil. Replaces #750. Fixes #365 2014-06-18 15:28:13 +03:00
Bogdan Poplauschi f6fdaeb6ae Merge pull request #766 from Whirlwind/origin_master
should not add url to failedURLs when timeout, cancel and so on. #707
2014-06-17 21:57:54 +03:00
Whirlwind 364f5c4d7a should not add url to failedURLs when timeout, cancel and so on. #707 2014-06-18 00:14:23 +08:00
Bogdan Poplauschi b81b7f9b4a Merge pull request #765 from Whirlwind/fix_highlight_error
fix UIImageView+HighlightedWebCache call error method
2014-06-17 19:08:28 +03:00
Bogdan Poplauschi 6c409cd8a0 Exposing the SDWebImageManager from the SDWebImagePrefetcher class. Fixes #394 2014-06-17 18:54:04 +03:00
Nikolaus Heger c76aba6c00 support for image orientation 2014-06-17 22:38:37 +07:00
Bogdan Poplauschi 2973aedd09 Merge pull request #683 from brynbodayle/master
Fixed issue where cancelled operations aren't removed from runningOperations.
2014-06-17 17:04:34 +03:00
Bogdan Poplauschi 0772019e4d SDWebImageManager uses the shared instance of SDWebImageDownloader. This was requested by several developers for easier setup of their downloads. Replaces #486 2014-06-16 18:21:06 +03:00
Bogdan Poplauschi 22782052a1 Updated README.md 2014-06-16 18:10:23 +03:00
Bogdan Poplauschi 6759e5982e Merge pull request #376 from ivanoblomov/master
Added alternate compiler flag for frameworks that extend optional libraries, like Parse and RestKit
2014-06-16 18:07:39 +03:00
Bogdan Poplauschi d6a7e1a8c3 Merge pull request #763 from dchohfi/master
#761 fixing potential bug when sending a nil url for UIButton+WebCache
2014-06-16 17:59:22 +03:00
Diego Chohfi f5d0ddc270 #761 fixing potential bug when sending a nil url for UIButton+WebCache 2014-06-16 11:46:19 -03:00
Bogdan Poplauschi 689586f73a Merge pull request #687 from rokemoon/master
Create NSOperation when start operation.
2014-06-15 22:38:07 +03:00
Bogdan Poplauschi e6c0f56d1f Exposed cache paths - fixes #339 2014-06-15 22:23:48 +03:00
Bogdan Poplauschi a0bc09df7d Merge pull request #644 from kencoken/master
Added method to SDWebImageManager to check if an image exists in either ...
2014-06-15 18:29:23 +03:00
Bogdan Poplauschi 5fd21e5ce1 Exposed SDWebImageManager cacheKeyForURL 2014-06-15 18:08:32 +03:00
Bogdan Poplauschi 5b1451e11c Since we use tag 3.6, the podspec file must match that. Fixes #757 2014-06-13 18:23:17 +03:00
Bogdan Poplauschi b29850b61b Merge pull request #714 from derpoliuk/master
Saves image to cache without downloading it.
2014-06-13 10:11:28 +03:00
Bogdan Poplauschi 7abff886ae Merge pull request #560 from klaaspieter/imageURL-property
Keep a reference to the image URL
2014-06-13 10:07:30 +03:00
Klaas Pieter Annema 1ac6b92d9d Conform to coding style 2014-06-12 13:31:40 -04:00
Klaas Pieter Annema b9389350cb Store image URLs by state in the UIButton category 2014-06-12 13:31:40 -04:00
Klaas Pieter Annema 67ed774c0c Scratch that, this won't work on UIButton 2014-06-12 13:31:40 -04:00
Klaas Pieter Annema 825207d1d0 Add imageURL property to remaining categories 2014-06-12 13:31:40 -04:00
Klaas Pieter Annema 77be243598 Add documentation to imageURL property 2014-06-12 13:30:48 -04:00
Klaas Pieter Annema 074ce1f4cf Keep a reference to the image URL 2014-06-12 13:30:48 -04:00
Olivier Poitrey f5bd783b5e Merge pull request #701 from billburgess/delayplaceholder
Delay the loading of the placeholder image until after load
2014-06-12 06:38:34 -07:00
Bogdan Poplauschi 3284e157ff Documented SDWebImageDownloaderOperation initWithRequest:options:progress:completed:cancelled: method. Fixes #526 2014-06-12 14:58:32 +03:00
Bogdan Poplauschi fe48ee54f3 Added SDWebImageCompat.m to SDWebImage+MKAnnotation target 2014-06-11 12:46:20 +03:00
Bogdan Poplauschi 5b59677437 Fixed #384 (documentation wrognly stated a return type was NSOperation) 2014-06-11 11:52:06 +03:00
Bogdan Poplauschi 12ee2d114b Updated README.md to fix #476 2014-06-11 11:44:45 +03:00
robertmryan f63a45add6 Adjusted completion logic in prefetcher, as the old implementation would finish prematurely if any requests were skipped.
Also adjusted documentation in headers to make it clear that the `finishedCount` includes both successful and unsuccessful requests.
2014-06-11 02:36:47 -04:00
robertmryan a46f6149e5 Resolve race condition.
While exceedingly unlikely, the old construct introduced potential race condition where it checked wself first, and assigned sself second. This now assigns sself first, and then checks that, which is the correct pattern, already used elsewhere in SDWebImage.
2014-06-11 02:14:40 -04:00
Bogdan Poplauschi 257da39e4d Merge pull request #732 from dchohfi/master
#725 adding completition block when removing image from cache
2014-06-10 13:41:43 +03:00
Bogdan Poplauschi caf3299c27 Merge pull request #744 from Pei116/master
fixed SDWebImageRefreshCached bug for large images
2014-06-10 13:38:28 +03:00
Bogdan Poplauschi 3b32f1dd9d Merge pull request #741 from martinblech/master
Synthesize `executing` and `finished` properties.
2014-06-08 19:00:31 +03:00
Edison Chang f43dd896fa fixed SDWebImageRefreshCached bug for large images 2014-06-04 12:36:11 +08:00
Olivier Poitrey 542d930f10 Merge pull request #742 from openresearch/master
Fix getter names. Fixes commit: 097b502eae
2014-06-03 14:26:08 -07:00
Philipp Schmid 5f239c07b8 Fix getter names. Fixes commit: 097b502eae
The getters of the properties “executing” and
“finished” both use custom getter names.

097b502eae implemented the wrong getter names
without the “is” prefix.
2014-06-03 22:42:15 +02:00
Martin Blech 241dafdd57 Synthesize `executing` and `finished` properties.
It wouldn't build on Xcode 6 otherwise.
2014-06-03 11:37:22 -03:00
Olivier Poitrey a83f440269 Merge pull request #737 from openresearch/master
Fix build on Xcode6
2014-06-02 15:04:53 -07:00
Philipp Schmid 097b502eae Fix build on Xcode6 2014-06-02 23:59:57 +02:00
Olivier Poitrey 4566b67f98 Merge pull request #735 from nickhingston/pullRequestBranch
If NSURLConnection response statusCode not valid (e.g. 404) , downloader...
2014-06-02 10:10:16 -07:00
Nick Hingston db614bc53e If NSURLConnection response statusCode not valid (e.g. 404) , downloader never stops its runloop and hangs the operation queue 2014-06-02 12:42:24 +01:00
Olivier Poitrey 5b3c54ba16 Merge pull request #734 from soundcloud/master
add a suspension method to image downloaders
2014-06-02 02:23:59 -07:00
Richard Howell 2c5ee720ba add a suspension method to image downloaders 2014-06-02 11:12:26 +02:00
Diego Chohfi 2ca5eab0e5 #725 adding completition block when removing image from cache, added an extra method so we don't break compatibility with older versions 2014-05-29 11:05:43 -03:00
Bogdan Poplauschi 7edeef9f1a Updated README.md with CocoaPods install 2014-05-28 09:46:40 +03:00
Olivier Poitrey fca411224b Merge pull request #728 from kejinlu/master
The ioQueue is "SERIAL" ,so "dispatch_barrier_async" is not needed.
2014-05-24 10:38:16 -07:00
卢克 dab65ae8f5 The ioQueue is "SERIAL" ,so "dispatch_barrier_async" is not needed. 2014-05-24 21:08:39 +08:00
Olivier Poitrey 7764e47a36 Merge pull request #727 from kejinlu/master
It's generally a bad idea to remove items from a container while iterating through it.
2014-05-23 15:00:20 -07:00
卢克 b1203d4a9e It's generally a bad idea to remove items from a container while iterating through it. And fix the thread safe issue. 2014-05-23 17:44:59 +08:00
Whirlwind acac18d6a2 fix UIImageView+HighlightedWebCache call error method 2014-05-22 22:55:21 +08:00
Olivier Poitrey 1c5060369e Merge pull request #721 from rivera-ernesto/improve_logging
Improve logging and fix arm64 warnings when printing integers with %d
2014-05-21 22:44:47 -07:00
Olivier Poitrey 36d5069b66 Merge pull request #720 from rivera-ernesto/update_projects
Update projects to Xcode recommended settings
2014-05-21 07:47:16 -07:00
利辺羅エルネスト 29302f49b3 Improve logging and fix arm64 warnings when printing integers with %d 2014-05-21 17:15:01 +09:00
利辺羅エルネスト 6c79daad00 Update projects to recommended settings 2014-05-21 17:10:25 +09:00
Olivier Poitrey 6f02d77add Merge pull request #646 from Whirlwind/master
add category for imageView's highlighted state
2014-05-20 23:39:25 -07:00
Xiaoliang Chen c335e1f597 fix duplicate symbols when using with webp via pods 2014-05-18 12:18:18 +08:00
derpoliuk 78a50d3929 Adds -[SDWebImageManager saveImageToCache:forURL:] method 2014-05-13 11:11:36 +03:00
Bill Burgess 9a45faac3f Wrapped placeholder check in parens to work with bitwise 2014-04-29 10:27:54 -05:00
Bill Burgess 7ca81d0e36 Updated bitwise operator to correctly find option if more than 1 are included 2014-04-29 10:13:28 -05:00
Bill Burgess f7ee9d3375 Moved the delay placeholder flag to SDWebImageOptions 2014-04-28 12:30:27 -05:00
Bill Burgess 12715da31b Overload -setImageWithURL to delay setting of placeholder image until after loading 2014-04-28 10:07:43 -05:00
Olivier Poitrey 8fe72023dc Merge pull request #700 from herrernst/master
Save image in cache before calling completion block
2014-04-28 12:31:04 +02:00
herrernst 83843a493a Save image in cache before calling completion block 2014-04-26 12:43:25 +02:00
Olivier Poitrey c9a24e294a Merge pull request #698 from salling/master
Fixing race in SDWebImageDownloaderOperation leading to erroneous timeout.
2014-04-22 18:35:30 +02:00
Jonas Salling bdef7651f0 Update SDWebImageDownloaderOperation.m
Fixing race condition that causes cancellation of one download operation to stop a run loop that is now used for another download operation. Race is introduced through -performSelector:onThread:withObject:waitUntilDone:
2014-04-22 14:52:20 +02:00
Olivier Poitrey 88e6ca3e49 Merge pull request #694 from shifu/master
Port Max's crash fix to my 3.6 fork
2014-04-16 20:22:13 -07:00
Chang Luo 1f202ed7a3 Port Max's crash fix to my 3.6 fork 2014-04-16 16:06:22 -07:00
Ruslan Ahapkin c285074321 Create NSOperation when start operation.
Method getDiskCount returns NSUInteger.
2014-04-03 23:16:48 +04:00
Olivier Poitrey db86161132 Merge pull request #685 from jeffleeismyhero/patch-1
Updates progress callback to use NSInteger
2014-04-03 07:52:00 -07:00
Jeffrey Lee 065db6db0c Updates progress callback to use NSInteger
Pull Request #606 resolves this issue in the code but not in the Documentation.
2014-04-03 09:37:08 -05:00
Bryn Bodayle ec5369db13 Fixed issue where cancelled operations aren't removed from runningOperations 2014-04-01 10:21:11 -05:00
Olivier Poitrey b49243d147 Bump version to 3.6.0 2014-03-24 13:32:45 -07:00
Olivier Poitrey 710908ed91 Merge pull request #676 from matej/cache-gcd-fixes
Various GCD related fixes for SDImageCache
2014-03-24 13:27:54 -07:00
Matej Bukovinski 556665d8a7 Exposed cleanDiskWithCompletionBlock:, added some additional documentation and fixed a typo. 2014-03-24 21:14:32 +01:00
Matej Bukovinski 87aed00733 Fixed the background task handled in backgroundCleanDisk.
- the background task had no effect, since cleanDisk returns immediately and thereby cancels the background task
 - adding cleanDiskWithCompletionBlock: and modifying backgroundCleanDisk to use this method resolves the issue
2014-03-24 21:14:21 +01:00
Matej Bukovinski 63f5c9706e Performing getSize and getDiskCount on the ioQueue. 2014-03-24 20:48:06 +01:00
Matej Bukovinski 1c463ad46b Using the private fileManager instance when on the ioQueue. 2014-03-24 20:35:52 +01:00
Matej Bukovinski dd682c92b5 Performing cache callbacks from the ioQueue asynchronously.
- more appropriate than dispatch_main_sync_safe, since we’ll always be on the ioQueue when calling
- prevents deadlock situation described in #625
2014-03-24 20:14:18 +01:00
Olivier Poitrey 4b26a89ac4 Merge pull request #671 from T-Pham/patch-1
Typo in README.md
2014-03-18 20:19:44 -07:00
Phạm Minh Thành 65163ea1ac Typo in README.md 2014-03-19 10:14:57 +07:00
Olivier Poitrey 71de51d658 Merge pull request #665 from taichino/fix_backgrounding_task
Call endBackgroundTask at the end of start method
2014-03-16 00:26:53 -07:00
Matsumoto Taichi efb0b359bf SDWebImageDownloaderOperation: call endBackgroundTask after operation is finished so that beginBackgroundTaskWithExpirationHandler and endBackgroundTask are balanced 2014-03-15 07:56:09 -04:00
Olivier Poitrey 938c2e0f3f Fix some indentation issues 2014-03-14 23:56:40 -07:00
Olivier Poitrey a883c63e9c Merge pull request #664 from xuki/master
add support for high priority download
2014-03-14 23:49:01 -07:00
jason 8b315a3585 add support for high priority download 2014-03-15 03:24:02 +08:00
Olivier Poitrey 4e4ecd6d02 Merge pull request #649 from finik/patch-1
Add typedef for cache operation complete block
2014-03-10 00:02:17 -07:00
Dmitry Fink b9bb5558e4 Add typedef for cache operation complete block
Makes it cleaner when users want to define the block independantly
2014-03-09 23:51:56 -07:00
Olivier Poitrey 1293582047 Merge pull request #647 from musaicapp/bug
Prefetcher: check progressBlock is not nil before executing.
2014-03-03 20:58:05 -08:00
Michael Henderson f2546c7333 Check progressBlock is not nil before executing. 2014-03-04 14:10:50 +10:00
Whirlwind 986794012d add category for imageView's highlighted state 2014-03-03 12:32:27 +08:00
Ken Chatfield 25d20ead49 Added method to SDWebImageManager to check if an image exists in either the disk OR the memory cache 2014-02-27 21:07:00 +00:00
Olivier Poitrey 5f3e9272c8 Fix deployement target for arm64 2014-02-24 09:43:14 -08:00
Olivier Poitrey e34e8e6c65 Bump version to 3.5.4 2014-02-24 09:38:08 -08:00
Olivier Poitrey 657bd81658 Merge pull request #638 from limbo-lab/master
added clearDiskOnCompletion
2014-02-18 00:27:53 -08:00
limbo-lab 1d8bfa6064 added clearDiskOnCompletion 2014-02-18 15:30:14 +08:00
Olivier Poitrey 1b394c14b6 Merge pull request #637 from runmad/master
Missing method definition in header file
2014-02-15 13:20:56 -08:00
Rune Madsen f717d507a5 Missing method definition in header file 2014-02-15 15:46:10 -05:00
Olivier Poitrey 65acbec16d Merge pull request #635 from burakkilic/patch-1
Update SDWebImagePrefetecher.m
2014-02-14 02:05:36 -08:00
burakkilic c04e4efbf1 Update SDWebImagePrefetecher.m
I added "+ self.skippedCount" because it never completes if there are skipped operations.
2014-02-14 11:56:09 +02:00
Olivier Poitrey 2ad8d81768 Merge pull request #634 from burakkilic/patch-1
Update SDWebImagePrefetecher.m
2014-02-14 01:46:19 -08:00
burakkilic 159f08279a Update SDWebImagePrefetecher.m
I added progress block that I need.
2014-02-14 11:38:20 +02:00
Olivier Poitrey 895249b312 Merge pull request #633 from hlian/progressive-orientation
SDWebImageDownloaderOperation: pass orientation to initWithCGImage during progressive rendering
2014-02-12 16:02:01 -08:00
Hao Lian c13ec87b15 SDWebImageDownloaderOperation: pass orientation to initWithCGImage during progressive rendering 2014-02-11 18:03:20 -05:00
Olivier Poitrey 10ff1892b4 Merge pull request #624 from akhenakh/620_move_categories
refs #620 move NSData+ImageContenttype to the SDWebImage subdirectory
2014-01-21 10:57:19 -08:00
Fabrice Aneche edc1d882e8 refs #620 move NSData+ImageContenttype to the SDWebImage subdirectory 2014-01-21 09:57:50 -08:00
Olivier Poitrey 4589e4a744 Merge pull request #616 from akhenakh/fix_demo
fix demo
2014-01-15 12:42:36 -08:00
Fabrice Aneche 8b16de2575 fix demo 2014-01-15 10:25:14 -08:00
Olivier Poitrey 42f9736972 Merge pull request #607 from akhenakh/reformat_code
Code standardization
2014-01-06 18:39:38 -08:00
Fabrice Aneche 03eeb5842f reformat a long method call 2014-01-06 17:37:52 -08:00
Fabrice Aneche bdea43aec1 Dot-notation should always be used for accessing and mutating properties. Bracket notation is preferred in all other instances 2014-01-06 17:30:34 -08:00
Fabrice Aneche 6d8133557c NS_ENUM & NS_OPTIONS 2014-01-06 17:13:30 -08:00
Fabrice Aneche 6dc02bd8f7 reformat code (appcode) 2014-01-06 17:12:24 -08:00
Olivier Poitrey c00c2e0ed4 Merge pull request #606 from akhenakh/64bits_support
use a NSInteger as size (was NSUInteger, was long long) cause we are using -1 (NSURLResponseUnknownLength) in progress callback
2014-01-06 16:32:43 -08:00
Fabrice Aneche 765a897120 more details about delegate call with -1 NSURLResponseUnknownLength 2014-01-06 16:22:07 -08:00
Fabrice Aneche 056e1e6562 use a NSInteger as size (cause we are using -1 as start indicator) 2014-01-06 16:14:32 -08:00
Olivier Poitrey 1e0af36f3f Merge pull request #605 from akhenakh/upgrade_webp
upgrade libwebp to 0.4.0
2014-01-06 15:06:32 -08:00
Olivier Poitrey 6aca6a2100 Merge pull request #604 from akhenakh/webp_detect
Webp detect
2014-01-06 15:04:08 -08:00
Fabrice Aneche 5e3384e77b upgrade libwebp to 0.4.0 2014-01-06 14:46:20 -08:00
Fabrice Aneche adffebc8fb reformat code 2014-01-06 13:14:10 -08:00
Fabrice Aneche 20bada38a0 fixed code format 2014-01-06 13:04:49 -08:00
Fabrice Aneche 6d6796c31a explicit webp detection 2014-01-06 13:00:13 -08:00
Olivier Poitrey 853ad83647 Merge pull request #603 from akhenakh/64bits_support
64bits support (fix #572, fix #504, fix #494)
2014-01-06 11:59:40 -08:00
Fabrice Aneche 77fad5cdf1 changed sizes to NSUInteger 2014-01-03 17:38:29 -08:00
Fabrice Aneche 21842747aa update documentation 2014-01-03 17:19:17 -08:00
Fabrice Aneche d3a9a57a0d support arm64 2014-01-03 17:14:13 -08:00
Olivier Poitrey 8f8228e2a6 Bump version to 3.5.2 2014-01-02 11:12:43 -08:00
Olivier Poitrey 48846851ee Merge pull request #591 from hsoi/downloader-timeout
Expose timeout property for the downloader.
2013-12-20 06:59:19 -08:00
John C. Daub f66b8b807e Expose timeout property for the downloader. 2013-12-20 08:24:33 -06:00
Olivier Poitrey 639aa643eb Merge pull request #588 from wishabi/master
Assign thread for downloada cancellation + minor doc fix
2013-12-16 12:41:21 -08:00
Erik Charlebois 00918d0908 Fix documentation param name mismatch 2013-12-16 14:45:30 -05:00
Erik Charlebois f8d26f5172 Track current thread in downloader operation 2013-12-16 14:41:35 -05:00
Olivier Poitrey 7ace0684f2 Merge branch 'master' of git://github.com/vincentjames501/SDWebImage into vincentjames501-master 2013-12-16 10:28:33 +01:00
Olivier Poitrey 25007e0b06 Merge branch 'master' of git://github.com/wishabi/SDWebImage into wishabi-master 2013-12-16 10:12:54 +01:00
Olivier Poitrey 616828b19b Merge pull request #587 from JaviSoto/master
Removing warnings in Xcode 5.1DP2
2013-12-15 03:08:46 -08:00
Javier Soto 2cbc5d71e0 Removing warning in 5.1DP2 by marking variable as unused 2013-12-13 17:05:36 -08:00
Javier Soto be4a9e0ac8 Removing warning in 5.1DP2 by removing “extern inline” (this doesn’t really make sense) 2013-12-13 17:04:57 -08:00
Olivier Poitrey 4382672c4a Merge pull request #582 from jenshandersson/master
Added new option to allow invalid SSL Certificates. Useful for testing
2013-12-11 07:49:17 -08:00
Jens Andersson 706c57308e Cleaned up code to follow project code style 2013-12-11 16:26:08 +01:00
Jens Andersson fbe3b95e8c Added new option to allow invalid SSL Certificates. Useful for testing 2013-12-11 13:31:03 +01:00
Bogdan Poplauschi b201e137d8 Added PNG detection to be able to determine at runtime if a downloaded image should be saved as PNG or as JPEG 2013-12-11 12:15:05 +01:00
Erik Charlebois 3f20a101c5 Fix race condition in image download cancellation
There are many race conditions around cancelling
SDWebImageDownloaderOperation instances from other threads. For example,
imageData may be set to nil and deallocated just as it is being appended
to, or the threading can interleave in such a way that messages are sent
to a deallocated connection. These were discovered using SDWebImage for
a Google Maps-style tiled mapping application where there is a lot of
download and cancellation if users pan rapidly.

This fix tracks the worker thread that the NSURLConnection instance runs on and
performs cancellation on the worker thread. The cancel and start methods need
to be synchronized to handle the case where cancellation happens before
start is called; since no thread has been assigned yet, cancellation is
performed on the calling thread.

Because cancellation is now scheduled on the same run loop as
NSURLConnectionDelegate callbacks, there is an added window of time that
a download can finish prior to cancellation. This means it's possible to
cancel an operation yet still get a successful completion callback. This
was always possible because of race conditions, but it is more
pronounced and predictable now. An application that relies on
a cancelled operation never calling its completion block (e.g. recycling
image views in a scrolling table view) must adopt some other mechanism
(e.g. a version number) to avoid running completion code for a stale operation.
2013-12-09 17:08:56 -05:00
Vincent Pizzo 8a541f6f31 bleh 2013-12-09 15:58:32 -06:00
Vincent Pizzo 716fc38c93 Updating podspec 2013-12-09 15:54:44 -06:00
Vincent Pizzo 4335fb7e41 Using webkit's method for determing frame durations of various gif images 2013-12-06 16:51:31 -06:00
Olivier Poitrey 3380e56a7d Merge pull request #577 from pieterclaerhout/master
Added a delegate for the web image prefetched.
2013-12-06 07:57:44 -08:00
Pieter Claerhout 51be4e298c Code cleanup. 2013-12-06 16:53:22 +01:00
Pieter Claerhout 1a917d8239 Added a delegate for the web image prefetched. 2013-12-06 16:21:00 +01:00
Olivier Poitrey 6878fba926 Bump version to 3.5.1 (fix #568) 2013-12-03 00:07:28 -08:00
Olivier Poitrey 1872fed8f0 Merge pull request #562 from mknippen/master
added currentDownload Count, to allow someone to see how many operations are left.
2013-11-26 19:34:49 -08:00
Matthew Knippen d0f8571dd2 matched coding conventions 2013-11-26 21:29:10 -06:00
Matthew Knippen d020aea02f added currentDownload Count, to allow someone to see how many operations are left. 2013-11-26 16:54:59 -06:00
Olivier Poitrey 75a76d983a Merge pull request #514 from crazytonyli/header-picking
Add HTTP header passing test to pick header for downloading request
2013-11-24 22:28:19 -08:00
Tony Li 597a70a8b6 Add HTTP header filter to pick headers for downloading request 2013-11-25 14:21:42 +08:00
Olivier Poitrey 1e20c3bd07 Merge pull request #558 from shifu/master
up version 3.5 in podspec to be consistent with latest
2013-11-22 17:23:14 -08:00
Chang Luo d6d4a3c3db up version 3.5 in podspec to be consistent with latest 2013-11-22 17:18:29 -08:00
Olivier Poitrey 2043094ab5 Merge pull request #556 from JoshuaGross/master
Allow setting a custom memory cost limit for the in-memory NSCache.
2013-11-22 16:46:16 -08:00
Joshua Gross c3ee589681 NSInteger -> NSUInteger, add getter method 2013-11-22 16:38:18 -08:00
Joshua Gross c7f2665d05 Allow setting a custom memory cost limit for the in-memory NSCache. This can help to keep memory down before memory warnings are sent by the device. 2013-11-22 16:16:03 -08:00
Olivier Poitrey 417feed2ca Merge pull request #553 from danpe/master
Added SDWebImageOption to enable Cookies Handling.
2013-11-18 15:56:52 -08:00
Dan Peleg d08d63fadd Added SDWebImageOption to enable Cookies Handling. 2013-11-18 17:18:58 -05:00
Olivier Poitrey 8b63e9ac06 Merge pull request #552 from garnett/master
Use UIImagePNGRepresentation to preserve transparency (fix for #545)
2013-11-08 22:37:53 -08:00
Olivier Poitrey 2184e301c8 Merge pull request #551 from robertmryan/master
SDWebImagePrefetcher should only perform `NSLog` statements if `SD_VERBOSE` is defined
2013-11-08 20:51:25 -08:00
robertmryan 8b0bd16f18 Only perform `NSLog` statements if `SD_VERBOSE` is defined 2013-11-08 23:03:41 -05:00
Denis Lebedev ae4ecb16f6 Use UIImagePNGRepresentation to preserve transparency 2013-11-04 14:36:34 +03:00
Olivier Poitrey e5b05c3109 Merge pull request #539 from sibljon/patch-1
Update argument list for example in README
2013-10-27 10:37:50 -07:00
Jonathan Sibley 00c200b8c1 Update argument list for example in README 2013-10-27 09:53:00 -07:00
Olivier Poitrey 3645b6f41b Merge pull request #537 from raylillywhite/patch-1
Fix link to "Who Uses SDWebImage" wiki page
2013-10-25 13:41:14 -07:00
Ray Lillywhite 1d6ace1886 Fix link to "Who Uses SDWebImage" wiki page 2013-10-25 10:20:34 -07:00
Olivier Poitrey 8830781f8f Merge pull request #534 from pixable/ios-background
iOS Background: Provide background option through the manager
2013-10-23 11:29:55 -07:00
Luis Solano Bonet 81d6bf91a9 Provide background option through the manager 2013-10-23 14:20:12 -04:00
Luis Solano Bonet c79e6ffe04 Add option to continue download in background 2013-10-22 15:21:30 -07:00
Olivier Poitrey 5df0eafc92 Fix WebP target 2013-10-04 11:43:27 -07:00
Olivier Poitrey 94f51343b8 Merge pull request #522 from redhand/master
Removed strong reference to UIImageView in nested block
2013-09-30 22:17:29 -07:00
Pete Koat 83f476ba8f Merge branch '63d60d9' 2013-09-30 17:09:33 -07:00
Pete Koat 63d60d9826 Removed strong reference to UIImageView which was causing a crash in the nested block. 2013-09-30 17:02:32 -07:00
Olivier Poitrey 9820cafe9b Merge pull request #498 from donholly/master
Added and exposed some methods that allow to check if an image exists on...
2013-09-20 11:03:18 -07:00
Olivier Poitrey 340db263fa Remove WebP support from default target and add a dedicated target
Too many people have issue with WebP library dependancy.
2013-09-20 10:53:11 -07:00
Olivier Poitrey 03d28fee03 Only use the runloop with timeout on iOS 5 (fix #497) 2013-09-20 10:46:35 -07:00
Olivier Poitrey 0076bb9a55 Share schema so it can be used by Xcode bots 2013-09-20 10:45:35 -07:00
Don 8a2ae7e547 Fixed styling to match rs/SDWebImage repo 2013-09-12 13:45:11 -07:00
Don 547345c7f5 Added and exposed some methods that allow to check if an image exists on disk without taking it off disk and decompressing it first. Makes for a nice performance boost when checking if many files exist in the disk cache already 2013-09-12 11:58:43 -07:00
Olivier Poitrey 2bded38216 Merge pull request #487 from Gabro/patch-1
Enforced presence of a completedBlock in downloadWithURL:options:progress:completed
2013-08-29 07:41:34 -07:00
Gabriele Petronella 5bbddae80d Updated doc marking the completedBlock parameter of downloadWithURL:options:progress:completed as required 2013-08-29 13:03:33 +01:00
Gabriele Petronella f37474d5c8 Enforced presence of a completedBlock in downloadWithURL:options:progress:completed:
This method bails out in case of a missing `completedBlock`. While this makes sense (downloading the image without a completion block and not doing anything with it is pointless), a client passing a empty block is not informed about the mistake.

`NSParameterAssert` validates the input and it informs the client about bad usage of the API.
2013-08-29 12:46:15 +01:00
Olivier Poitrey 22cd4e49c4 Fix xcode project settings 2013-08-27 16:23:59 -07:00
Olivier Poitrey 7e2763a500 Merge pull request #479 from longlongjump/master
Fix long running requests
2013-08-23 08:19:52 -07:00
Eugene 16e1a1fff6 Fix long running requests 2013-08-23 00:49:45 +03:00
Olivier Poitrey 76d2fc8d0e Update project to comply with Xcode 5 2013-08-20 16:25:27 -07:00
Olivier Poitrey 8c295cfe80 Update webp to upstream head 2013-08-19 18:44:27 -07:00
Olivier Poitrey a0df1a0dc2 Merge pull request #472 from ikesyo/webp-subspec
Use 'default_subspec' and separate the WebP support to its sub-spec
2013-08-14 08:48:41 -07:00
Syo Ikeda 6f3debd7a2 Fix sub-spec dependency 2013-08-14 16:57:20 +09:00
Syo Ikeda bbf0b5c0e6 Use 'default_subspec' and separate the WebP support to its sub-spec
This removes unnecessary dependency to 'libwebp' for users who don't need WebP support.
2013-08-14 16:02:06 +09:00
Olivier Poitrey 67a28d90ef Change version to 3.4 2013-08-13 10:22:25 -07:00
Olivier Poitrey 9f1ac247e7 Merge pull request #471 from PinchProject/hotfix/fast_enumeration_fix
The callbacksForURL: method in SDWebImageDownloader should return a copy of the mutable array!
2013-08-13 05:51:31 -07:00
Kevin Cador f356b86c29 The callbacksForURL: method of SDWebImageDownloader now returns a copied array. This should fix the crash in multithread environment such as:
Collection <__NSArrayM: 0x226d9310> was mutated while being enumerated.
2013-08-13 10:40:46 +02:00
Matt Pennig fa987a1818 Canceling the SDWebImageOperation will also cancel the expensive disk cache query operation. 2013-08-11 23:12:55 -07:00
Olivier Poitrey ffd9e02e1e Update README.md 2013-08-11 13:16:47 -07:00
Olivier Poitrey 4540745382 Fix the dead thread bug on iOS 5 (fix #466) 2013-08-09 15:08:05 -07:00
Olivier Poitrey 5f12cabdac Fix unreleased operation (fix #466, fix #444) 2013-08-09 00:39:46 -07:00
Olivier Poitrey 5dd219ffa7 Try to fix the thread block (#399) 2013-08-08 12:44:54 -07:00
Olivier Poitrey 1e63f33a85 Always call the completedBlock from main thread (fix #397)
This is not a good practice but doing otherwise leads to a lot of mistakes
2013-08-07 21:15:32 -07:00
Olivier Poitrey 3a6d9481c9 Call handlers on the main thread synchronously to enhance responsivity (fix #462) 2013-08-07 21:07:59 -07:00
Olivier Poitrey f07a34da59 Fix downloadImageWithURL:options:progress:completed returning nil (fix #464) 2013-08-07 20:53:34 -07:00
Olivier Poitrey 8b37b16f45 Merge branch 'master' of git://github.com/gringoireDM/SDWebImage into gringoireDM-master 2013-07-31 13:54:40 -07:00
Chang Luo fb196ead9b Added background clean disk to UIApplicationDidEnterBackgroundNotification #306 2013-07-31 13:45:04 -07:00
Giuseppe Lanza 6faa7bfcb5 added multiple download of images for animationImages property of UIImageView 2013-07-30 17:14:52 +02:00
masarusanjp 282e817919 Use an empty string to if str was NULL. 2013-07-11 11:12:33 +02:00
Olivier Poitrey b3895a5124 Merge pull request #446 from tissak/master
Tiny Doc fix
2013-07-07 02:51:18 -07:00
Tony Issakov b54f530925 Update README.md
Minor fix to callback arguments. NSData included now.
2013-07-07 12:46:04 +08:00
Olivier Poitrey 42468464b5 Merge pull request #444 from hsoi/scrolling-lockup
Break a retain cycle
2013-07-05 08:31:48 -07:00
John C. Daub 95277bae45 Break a retain cycle 2013-07-05 09:58:20 -05:00
Olivier Poitrey 834ffada11 Merge pull request #436 from jparise/unused-callbacksForURL
Remove an unused call to -callbacksForURL:.
2013-06-27 13:19:12 -07:00
Jon Parise 4a4e496171 Remove an unused call to -callbacksForURL:.
We don't currently signal cancellation via a callback.
2013-06-27 10:16:25 -07:00
Olivier Poitrey 8a95ce759c Merge pull request #434 from jparise/calculate-size
Add -calculateSizeWithCompletionBlock:.
2013-06-25 23:50:31 -07:00
Jon Parise 18334bcc8f Add -calculateSizeWithCompletionBlock:.
This method provides a way to asynchronously calculate the size of the
disk cache, reporting both the number of files and the total file
size.

This is useful when querying large disk caches because the file system
enumeration operation can take some time.
2013-06-25 19:27:20 -07:00
Olivier Poitrey 48ce95f0ae Merge pull request #423 from BB9z/superfluous-semicolon
Minor typo fix.
2013-06-16 22:39:32 -07:00
BB9z d76779196f Minor typo fix. 2013-06-17 11:09:16 +08:00
Olivier Poitrey 0b330b562b Merge pull request #422 from BB9z/WebP_switch
Import WebP category only when the macro is activated.
2013-06-16 03:15:57 -07:00
BB9z 4eaf0d7cee Import WebP category only when the macro is activated. 2013-06-16 18:04:28 +08:00
Olivier Poitrey 2f98db9888 Change version to 3.3 2013-06-14 16:22:27 +02:00
Olivier Poitrey c6664248f1 Ensure we always set the UIKit image properties from the main thread (fix #403, fix #417, fix #398) 2013-06-12 17:02:40 +02:00
Olivier Poitrey 9a1f072e5e Merge pull request #418 from dalexsoto/master
Fix for #416
2013-06-12 07:32:02 -07:00
Alex Soto 10a0f21856 Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device
Added Functions to resolve some undefined symbols when using WebP and force_load flag

void WebPInitPremultiplyNEON(void) {}
void WebPInitUpsamplersNEON(void) {}
void VP8DspInitNEON(void) {}

Changes under MIT License
2013-06-11 18:58:44 -05:00
Alex Soto 63805ef590 // Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device
Added Functions to resolve some undefined symbols when using WebP and force_load flag

void WebPInitPremultiplyNEON(void);
void WebPInitUpsamplersNEON(void);
void VP8DspInitNEON(void);

Changes under MIT License
2013-06-11 18:57:07 -05:00
Olivier Poitrey 5ecb8d56af Do not enable webp when not explicitly activated by a macro (fix #415) 2013-06-10 21:42:58 +02:00
Olivier Poitrey 90d120258e Merge pull request #413 from stylight/master
Fixed dependency on libwebp in the podspec
2013-06-08 00:22:54 -07:00
Alexander Kolov c1e686bff0 Added libwebp dependency. Also fix a typo in description. 2013-06-08 07:31:36 +02:00
Olivier Poitrey 04fa4c97b5 Add WebP format support (fix #410)
How awesome is that?! =)
2013-06-07 20:43:51 +02:00
Olivier Poitrey 1dbb79f903 Refactor GIF support
Remove GIF specific code from main source, isolate it in a UIImage category to ease future addition of format support
2013-06-07 19:39:07 +02:00
Salvatore Randazzo 447f1ccc23 Custom image cache search paths
This is particularly useful if you are bundling images with your app that have been cached by SDWebImage. (ie. if you are 'seeding' your app with a core-data file that contains a lot of URL's to images and would like to also seed those images without having to copy every one of them over)

For example, you can tell SDImageCache to add '[[NSBundle mainBundle] resourcePath]' as a custom path, so that the main bundle will be queried for cached images.

This prevents the need for you to copy pre-cached images over to the caches/ImageCache folder that SDImageCache normally checks for.

The custom paths are read-only.
2013-06-07 17:57:28 +02:00
Olivier Poitrey d38e13c58d Merge pull request #408 from dlbuckley/issue-406-Failed-URL-Problem
#406 - Fixed failed URL problem
2013-06-04 05:12:07 -07:00
Dale Buckley 7d9c93fb51 #406 - Fixed a problem where hitting a failed URL more than once wouldn't call the completion block 2013-06-04 12:04:36 +01:00
Olivier Poitrey d04fd47f5b Fix typo in download page URL 2013-06-01 14:23:45 -07:00
Olivier Poitrey 4ab6d18900 Merge pull request #401 from docallag/master
Prevent warnings on iOS
2013-05-31 09:12:39 -07:00
David O'Callaghan 1b7305c8a7 Update SDWebImageCompat.h
Undefine macros before define to prevent warning on iOS
2013-05-31 12:07:16 +02:00
Olivier Poitrey e8c5ed17c0 Merge pull request #400 from BB9z/fix/document-parameter
Some document improves.
2013-05-27 09:53:45 -07:00
BB9z 51bdfdf0b2 Format code in document. 2013-05-27 18:19:02 +08:00
BB9z 5b6e84a953 Adjust indenting. 2013-05-27 18:10:42 +08:00
BB9z 1f31915e59 Fix a mismatch description. 2013-05-27 18:03:57 +08:00
BB9z 124a87b85f Fix some document error. 2013-05-27 18:00:26 +08:00
Olivier Poitrey ff2b30e263 Merge pull request #383 from garthex/white_png_issue
fix alpha pngs turning into white pngs
2013-05-14 02:57:12 -07:00
Olivier Poitrey b8ab9d77b5 Merge pull request #389 from lavoy/master
Calls progress block regardless of completion block and options
2013-05-08 20:25:57 -07:00
Andy LaVoy 827fcac89b call progress block regardless of completion block, options 2013-05-08 15:35:37 -07:00
Olivier Poitrey 899d67ba54 Merge pull request #388 from cfis/synchronize_failed_urls
Synchronize self.failedURLs
2013-05-08 05:37:18 -07:00
Charlie Savage 0426f07355 Images can be downloaded in multiple threads. Therefore the call to self.failedURLs containsObject:url must be synchronized to avoid a collection mutation error. 2013-05-07 13:21:04 -06:00
Olivier Poitrey 990df9f828 Update README.md 2013-05-06 15:11:26 +03:00
Kyle Fleming e3b15e3dbe fix alpha pngs turning into white pngs when caching when you have a method that transforms the image but doesn't touch the pngs 2013-05-01 14:36:13 -07:00
Olivier Poitrey 4137bce30d Add prefix to GIF support category's methods 2013-04-29 12:47:37 +02:00
Olivier Poitrey 65807f262e Merge pull request #379 from lavoy/master
Moved scaling to earlier in the process
2013-04-29 03:32:21 -07:00
Olivier Poitrey eaf6cd26e1 Merge pull request #380 from stylight/master
Fixed Podspec by including NS* files into source files
2013-04-29 02:29:39 -07:00
Alexander Kolov 952eeec05a Include NS* files in source files of Podspec 2013-04-29 12:23:29 +03:00
Andy LaVoy f58c2ebb43 moved scaling up the process 2013-04-28 20:10:36 -07:00
Andy LaVoy ad4babd25d Scale GIF images 2013-04-29 02:41:31 +02:00
Olivier Poitrey 5db0d00ef3 Merge pull request #375 from lavoy/master
Animated GIF Support
2013-04-28 15:51:36 -07:00
Andy LaVoy d789fd92e8 change var name 2013-04-28 15:38:50 -07:00
Roderick Monje 0e7d3cde68 documented workaround for frameworks that extend optional libraries 2013-04-28 17:18:03 -05:00
Andy LaVoy 2a370b062b updated formatting for project 2013-04-28 14:59:33 -07:00
Andy LaVoy 5bf37d5472 cache the GIF data instead of the jpeg representation 2013-04-28 14:37:47 -07:00
Andy LaVoy 3f98095704 support GIFs 2013-04-28 14:06:54 -07:00
Olivier Poitrey 17d04b70e5 Merge pull request #366 from bm-i/master
Fix and make SDScaledImageForPath extensible
2013-04-27 12:13:31 -07:00
Bastian Müller 9eff469cb6 Make SDWebImageManager cache creation extensible 2013-04-27 20:55:06 +02:00
Bastian Müller 55ebe66b4c Fix and make SDScaledImageForPath extensible 2013-04-27 20:55:06 +02:00
Olivier Poitrey ae1476b3f2 Merge pull request #340 from odanu/master
Add SDWebImageCompact.m to Compile sources of the SDWebImage+MKAnnotation target
2013-04-27 09:35:19 -07:00
Olivier Poitrey 4965c7d09f Merge pull request #373 from cfis/download_cleanup
More SDWebImageDownloader Cleanup
2013-04-27 08:19:04 -07:00
Charlie Savage d53a47e982 Remove async calls from SDWebImageDownloader. The operation is already run in a background thread also the async calls are unnecessary. 2013-04-26 21:43:11 -06:00
Charlie Savage b85556fa86 This is an attempt to avoid the crashes in #341.
It won't fix the underlying issue but I hope it will avoid it in most cases.
The various crash reports indicate the underlying download operation is being
freed before the async block in dataReceived is being executed.

This fix change tries to avoid every calling the async block.
2013-04-27 01:00:47 +02:00
Olivier Poitrey 116258502b Merge pull request #353 from jparise/max-cache-size
Support a maximum disk cache size in -cleanDisk.
2013-04-26 14:22:52 -07:00
Olivier Poitrey 308570af2b Merge pull request #362 from 0xced/patch-1
Fix completionBlock setter semantics
2013-04-17 07:36:20 -07:00
Cédric Luthi 0b5291517f Fix completionBlock setter semantics
Using `SDDispatchQueueSetterSementics`, which might be `assign` for a block is a terrible idea.
2013-04-17 16:31:04 +03:00
Randall Li 9f4e6915c7 Added auto release pool to keep memory foot print down when retrieving image from disk in queryDiskCacheForKey 2013-04-05 08:57:11 +02:00
Olivier Poitrey 7d6e17c43c Merge pull request #355 from u16suzu/fix_double_import
Remove double import for SDWebImageDecoder.h
2013-03-29 05:48:29 -07:00
u16suzu 7d12c3e9fc Remove double import for SDWebImageDecoder.h 2013-03-29 05:17:43 -07:00
Jon Parise 32f011185a Support a maximum disk cache size in -cleanDisk.
Previously, -cleanDisk would only remove cache files that were older
than the configured expiration date.  This allowed the disk cache to
grow significantly if a large number of resources were cached over a
short period of time.

This change adds a second (optional) size-based cleaning pass that
removes files from the disk cache until its overall size falls below
half of the configured maximum size.  Older files are deleted first.

The size-based pass is disabled by default (maxCacheSize == 0).
2013-03-27 19:06:22 -07:00
Olivier Poitrey 1655803bc7 Merge pull request #352 from jparise/getSize-return-type
-getSize now returns an `unsigned long long`.
2013-03-27 15:53:23 -07:00
Jon Parise 1e37b716c7 -getSize now returns an `unsigned long long`.
This type now matches the type and width of the value returned by the
`fileSize` accessor of the `NSDictionary (NSFileAttributes)` category
(which is what is used when accumulating the total cache size).
2013-03-27 14:55:30 -07:00
Olivier Poitrey eda987815b Merge pull request #351 from Vyazovoy/master
New name for SDWebImageDownloaderQueueMode type, typo fixing, strong cycle fixing.
2013-03-27 10:04:09 -07:00
Andrew Vyazovoy c3968b30ce Merge branch 'develop'
* develop:
  Potential strong cycle fixed.
  SDWebImageDownloaderQueueMode type renamed. Fixed typo. Added description for renamed type. Type renamed because "queue" notion is a FIFO only, but LIFO is a stack, and if we give the type a neutral name, we can avoid logical inconsistencies.
  Fixed typo.
2013-03-27 23:45:47 +07:00
Andrew Vyazovoy c77652755a Potential strong cycle fixed. 2013-03-27 23:44:47 +07:00
Andrew Vyazovoy ee9af6406c SDWebImageDownloaderQueueMode type renamed. Fixed typo. Added description for renamed type. Type renamed because "queue" notion is a FIFO only, but LIFO is a stack, and if we give the type a neutral name, we can avoid logical inconsistencies. 2013-03-27 23:43:42 +07:00
Andrew Vyazovoy 6284e4070d Fixed typo. 2013-03-27 22:33:20 +07:00
Olivier Poitrey c50be70558 Inline the SDScaledImageForPath function so it doesn't polute the stack traces 2013-03-25 15:02:28 +01:00
Olivier Poitrey 4c51485e22 Merge pull request #344 from Kapin/master
Fixing comments to better reflect how methods work and some typo fixes
2013-03-22 12:34:24 -07:00
Joshua Kalpin 7779896163 Updating comments to be more accurate and fix typos 2013-03-22 15:10:00 -04:00
odanu 474b0d9496 Added SDWebImageCompact.m to Compile sources of the SDWebImage+MKAnnotation target 2013-03-20 03:44:18 -07:00
Olivier Poitrey f04b4a0731 Fix OS_OBJECT_USE_OBJC handling (fix #329) 2013-03-13 14:43:34 +01:00
Olivier Poitrey f747804843 Add some words about SDWebImageRefreshCached in README 2013-03-13 00:11:17 +01:00
Olivier Poitrey b1f1c08be6 Bump version 3.2 2013-03-12 23:40:18 +01:00
Olivier Poitrey fb28dfeb75 Merge pull request #327 from bm-i/patch-1
Fix SDWebImageManager transformDownloadedImage
2013-03-12 15:38:20 -07:00
bm-i 55096d8b91 Fix SDWebImageManager transformDownloadedImage
storing data of transformed image instead of downloaded one
(passing nil to storeImage will generate data)
2013-03-12 23:32:35 +01:00
Olivier Poitrey 8cfd26f78b Disable duplicate disk cache prevention with SDWebImageRefreshCached to handle 302 caching correctly
See https://github.com/rs/SDWebImage/pull/326#issuecomment-14791505 for more info
2013-03-12 19:26:53 +01:00
Olivier Poitrey 9a29af466b Fix typo 2013-03-12 19:15:25 +01:00
Olivier Poitrey eed78e37e8 Ensure image isn't decoded twice if not necessary when SDWebImageRefreshCached flag is used #326 2013-03-12 16:35:35 +01:00
Olivier Poitrey a3e3c61d46 Prevent double disk caching when `SDWebImageRefreshCached` option is used #326 2013-03-12 14:55:29 +01:00
Olivier Poitrey 9b574e58bf Force progressive download off when force refresh is on #326 2013-03-12 14:55:05 +01:00
Olivier Poitrey f097ef7558 Fix NSURLResponse not cached when `SDWebImageDownloaderEnableNSURLCache` is passed #326 2013-03-12 14:31:48 +01:00
Olivier Poitrey 5cd7c0db46 Fix condition logic issue in #326 2013-03-12 14:31:24 +01:00
Steven Chan bbad1bcfcc New option SDWebImageRefreshCached
Even if the image is cached, fetch the URL again anyway. When set,
NSURLCache is enabled in the downloader via the new option
SDWebImageDownloaderEnableNSURLCache.

NSURLCache will handle the protocol caching while SDWebImage remains
useful for offline images.

This option helps deal with images changing behind the same request URL,
e.g. Facebook graph api profile pics where the request URL
https://graph.facebook.com/[userid]/picture returns a redirect to the
actual profile image.

If a cached image exists, the completion block is called once with the
cached image and again with the final image.
2013-03-12 01:08:57 +08:00
Olivier Poitrey 95337c47e9 Merge pull request #311 from sebreh/master
Detect cancelled parent operation in download operation callback
2013-02-26 06:02:41 -08:00
Sebastian Rehnby d57b92cd0e Detect parent operation cancellation in download operation completion block 2013-02-26 12:08:55 +01:00
Olivier Poitrey 05dd3f4815 Merge pull request #307 from nebillo/master
Optimizing enumeration of files while cleaning the disk cache
2013-02-20 17:26:00 -08:00
Nebil Kriedi fbf14d2e16 Prefetching file properties in the disk cleaning enumerator 2013-02-21 01:07:44 +00:00
Olivier Poitrey ae57215c29 Merge pull request #302 from n-miyo/fix_cache_policy
Wrong cache policy value.
2013-02-19 17:04:12 -08:00
MIYOKAWA, Nobuyoshi 15c5785320 correct cachePolicy constants.
NSMutableURLRequest accepts NSURLRequestCachePolicy as cachePolicy,
not NSURLCacheStoragePolicy.
2013-02-19 13:10:31 +09:00
Olivier Poitrey f024890ba7 Add (kinda) LIFO queue mode support for image downloading (fix #294) 2013-02-17 03:02:04 +01:00
Olivier Poitrey 350c0bea9a Add completion block support to `SDWebImagePrefetcher` (fix #127) 2013-02-17 02:43:46 +01:00
Olivier Poitrey ebd63a88c1 Add `SDWebImageManager` delegate allowing fine control of manager's cache-in
- `imageManager:shouldDownloadImageForURL:` let delegate to conditionaly block cache-in (fix #134)
- `imageManager:transformDownloadedImage:` let delegate to transform the image prior to cache-in (fix #63, fix #284)
2013-02-17 00:55:27 +01:00
Olivier Poitrey 6f198abd1b Add ability to set custom downloader HTTP headers (fix #171) 2013-02-16 23:33:41 +01:00
Olivier Poitrey 5f535602f1 Merge pull request #299 from Reflejo/master
Fix "Alpha on JPEG with no alpha" when decoding
2013-02-16 10:41:14 -08:00
Olivier Poitrey b27d5719c2 Synchronize access to SDWebImageManager's mutable structures (fix #301) 2013-02-16 17:49:27 +01:00
Martin Conte Mac Donell de19c24241 [BUG] Fix invalid alpha on JPEG files 2013-02-13 21:55:26 -03:00
Olivier Poitrey a8a398386b Merge pull request #297 from inamiy/disk-cache
Add synchronous disk-cache loading method.
2013-02-13 07:21:31 -08:00
Yasuhiro Inami 17cc72d5ab Add synchronous disk-cache loading method. 2013-02-13 19:07:56 +09:00
Olivier Poitrey de485a8618 Fix downloader queue using assign instead of strong under iOS 6 2013-02-12 01:17:55 +01:00
Olivier Poitrey 63178bde3c Revert "Fixed CGBitmapContextCreate warnings for invalid alpha properties"
This reverts commit 12196f4de6.
It adds alpha on JPEG with no alpha.
2013-02-07 18:15:16 +01:00
Olivier Poitrey 87568ce141 Merge pull request #287 from NachoSoto/disk-cache
Check SDWebImageCacheMemoryOnly for disk caching
2013-01-29 15:02:01 -08:00
NachoSoto 42c7455776 Check SDWebImageCacheMemoryOnly for disk caching 2013-01-29 20:10:09 +00:00
Olivier Poitrey e7c02bb910 Migrate the no longer github supported download page to a wiki page 2013-01-21 09:36:08 +01:00
Olivier Poitrey 3016754250 Share framework target 2013-01-21 09:27:53 +01:00
Olivier Poitrey 85dacacb23 Bump version to 3.1 2013-01-21 09:24:43 +01:00
Olivier Poitrey 0ee103263c Merge pull request #277 from Reflejo/upstream
Fixed CGBitmapContextCreate warnings for invalid alpha properties
2013-01-17 13:52:47 -08:00
Olivier Poitrey 788ff6759f Merge pull request #278 from Reflejo/invalidcost
Invalid cost calculation when saving image to memory cache
2013-01-17 13:48:48 -08:00
Martin Conte Mac Donell 73884be367 Invalid cost calculation when saving image to memory cache 2013-01-17 15:49:19 -03:00
Martin Conte Mac Donell 12196f4de6 Fixed CGBitmapContextCreate warnings for invalid alpha properties 2013-01-17 15:14:40 -03:00
Olivier Poitrey 815d1c5eae Merge pull request #274 from reidmain/master
NSInvalidArgumentException is thrown if a nil NSURL is downloaded.
2013-01-16 22:58:21 -08:00
Reid Main 599636fa58 Removed creation of NSError when a nil URL is downloaded. 2013-01-16 22:22:33 -05:00
Reid Main b59b42e6b5 Fixed bug where NSInvalidArgumentException was thrown if an image with a nil URL was downloaded. 2013-01-16 14:53:38 -05:00
Olivier Poitrey bc29d0a7ae Fix podspec (fix #253) 2013-01-16 12:10:53 +01:00
Olivier Poitrey 1e53e91513 Add imageFromMemoryCacheForKey: method to synchronously query the memory cache (fix #263) 2013-01-16 11:43:21 +01:00
Olivier Poitrey 555a320b9e Merge pull request #260 from kawanet/master
isRunning method added at SDWebImageManager
2013-01-16 02:26:04 -08:00
Olivier Poitrey a755f64752 Merge pull request #268 from matej/prefetcher-fix
Don't dispatch cancelAll calls.
2013-01-11 05:34:49 -08:00
Matej Bukovinski e31b157394 Don't dispatch cancelAll calls.
- should fix pre-fetcher problems #247
- cancelAll should be always called using the main thread
2013-01-11 13:54:54 +01:00
Olivier Poitrey b398208beb Do not mark URLs a fail when error is due to missing network connection 2013-01-11 01:14:56 +01:00
Olivier Poitrey 75cf6a09ae Merge pull request #264 from aburgel/use_shared_cache
Change SDWebImageManager to use shared image cache
2013-01-04 14:38:56 -08:00
Alex Burgel cfb65f2d75 Change SDWebImageManager to use shared image cache 2013-01-04 16:45:09 -05:00
kawanet e8b1532cba isRunning method added at SDWebImageManager 2012-12-25 22:02:48 +09:00
Olivier Poitrey c876cafa7a Fix Xcode 4.6 warnings 2012-12-19 16:41:06 +01:00
Olivier Poitrey 043eb14273 Fix an LLVM warning (fix #254) 2012-12-19 12:16:48 +01:00
Olivier Poitrey 5f7d288645 Merge pull request #252 from reidmain/master
decodedImageWithImage: ignores scale and orientation
2012-12-15 15:23:06 -08:00
Reid Main f800a52f1c Fixed bug where decodedImageWithImage: ignored image scale and orientation. 2012-12-15 17:59:00 -05:00
Olivier Poitrey 7cd4d8e155 Merge pull request #249 from matej/early-progress-callback
Early progress callback
2012-12-13 15:25:28 -08:00
Matej Bukovinski 7ba77023c7 Using spaces instead of tabs for indentation.
- also configured the Xcode project to use spaces instead of tabs by default
2012-12-14 00:18:17 +01:00
Matej Bukovinski 85759911b7 Changed the expected size to -1 in the initial progress callback.
- simplifies callback code by removing possible division by 0 issues during progress computation
2012-12-14 00:18:00 +01:00
Matej Bukovinski b4fb940cbc Send out progress callbacks sooner.
- as soon as the NSURLConnection gets initialized
- helps to allocate and show progress indication sooner and prevent large delays without progress indication (for example when the server takes long to respond)
- estimated size is always 0 at this point, clients can use this to decide if they want to handle this callback or skip it
2012-12-14 00:17:24 +01:00
Matej Bukovinski 37f71de26c Using the source image's the color space for image decoding (fix #237)
Should fix most system warnings regarding invalid context configurations
2012-12-13 23:11:40 +01:00
Olivier Poitrey a94b3eca7c Fix typo (fix #246) 2012-12-11 23:36:55 +01:00
Olivier Poitrey d3b5fd2bd2 Fix ARC compilation warning breaking some non-ARC projects (fix #229) 2012-12-11 16:11:06 +01:00
Olivier Poitrey e3d8bc8daf Fix podspec typo (fix #240) 2012-12-10 15:31:44 +01:00
Olivier Poitrey 84fe4a6669 Fix indentation tab/space 2012-12-10 15:30:54 +01:00
Olivier Poitrey 616d824dc7 Return an error if the downloaded image has no pixels (fix #241) 2012-12-10 15:30:54 +01:00
Olivier Poitrey 21ff7bd6ff Do not use GCD barrier for reading 2012-12-10 15:30:54 +01:00
Olivier Poitrey 43e94e7380 Fix typo 2012-12-06 09:26:19 +01:00
Olivier Poitrey 12ab710ebc Add 2.0-compat branch info to README 2012-12-06 09:24:09 +01:00
Olivier Poitrey 0691f7cd97 Remove podspect tag 2012-12-06 09:22:35 +01:00
Olivier Poitrey ddd03f7d2c Add some sanity check on the URL parameter 2012-11-29 18:52:28 +01:00
Olivier Poitrey 4284b5797e Remove no longer necessary cleanMemory on app going to background as NSCache does this by itself 2012-11-29 18:52:28 +01:00
Olivier Poitrey d487bccf5e Try to fix a random crash on dealloc 2012-11-29 18:52:28 +01:00
Olivier Poitrey 82faab82d3 Do not capture self in operations in categories 2012-11-29 18:52:28 +01:00
Olivier Poitrey 10c44577f6 Fix SDWebImagePrefetcher maxConcurrentDownloads property 2012-11-20 14:49:27 +01:00
Alex Barlow 44c6224763 Fix bug in SDWebImagePrefetcher where startPrefetchingAtIndex would never be called due to is always being 0 2012-11-20 14:45:34 +01:00
Olivier Poitrey 1ec36c7c99 Do not init an activity indictor if image isn't downloading in demo app (good practice) 2012-11-19 18:30:31 +01:00
Olivier Poitrey a7af2a19e4 Try to fix decode image error message 2012-11-19 17:59:26 +01:00
Olivier Poitrey 6e99059007 Fix demo app regarding last changes 2012-11-19 16:58:45 +01:00
Matej Bukovinski 9546c84f94 Making sure cache queries always callback in the main thread.
- queryDiskCacheForKey:done: now always invokes the callback in the main thread
- removed the now redundant main thread dispatch in the image manager class
2012-11-19 16:17:27 +01:00
Matej Bukovinski 713a83381f Resolved some downloader threading issues.
- callbacks could be released between the callback existence if check and invocation
- could be nilled out in a background thread call to done, while being prepared for invocation on the main thread
- now making sure done is always performed on the main thread
- also added some related threading fixes and optimizations
2012-11-19 16:17:20 +01:00
Matej Bukovinski 331053d26e Calling completion callbacks in the main thread.
- made sure this is true even if the downloader is used on its own
- SDWebImageManager doesn't need to perform a dispatch to the main thread any longer
2012-11-19 16:06:05 +01:00
Matej Bukovinski 9a3aff4851 Always making callbacks using the main thread.
Even if using the downloader directly without SDWebImageManager.
2012-11-19 16:03:39 +01:00
Matej Bukovinski ab185ea6e8 Implemented progress callbacks and related fixes. 2012-11-19 15:58:50 +01:00
Matej Bukovinski 2e8c02556a Passing the exact cache type in the completion block.
- none, disk and memory
- can still be used as a bool (if true there was a cache hit)
2012-11-19 15:55:09 +01:00
Matej Bukovinski 5c94f17a17 Disk cache now uses the raw image data returned from the server.
This preserves the image quality and retains some image attributes, such as the alpha channel (for non-jpeg images).
2012-11-19 15:50:30 +01:00
Matej Bukovinski d30c2ae209 Improved background image decoding performance.
Tests on large images indicate an up to 4x improvement with regard to the time spent in decodedImageWithImage:.
2012-11-19 15:50:22 +01:00
Olivier Poitrey 022aa2146e Fix a race condition (fix #220) 2012-11-14 00:59:40 +01:00
Olivier Poitrey 0920e7a001 Add activity indicator demo 2012-11-13 18:09:39 +01:00
Olivier Poitrey 0c1dd3c857 Fix CGBitmapContextCreate errors (fix #204) 2012-11-12 00:05:52 +01:00
Olivier Poitrey 152c75f437 Merge pull request #219 from SRandazzo/patch-1
Fix documentation directive
2012-11-09 06:25:59 -08:00
Salvatore Randazzo bd72fe1034 Fix documentation directive 2012-11-09 09:05:49 -05:00
Olivier Poitrey 7b947163da Copy all stored blocks 2012-11-09 11:05:18 +01:00
Olivier Poitrey 8f50bf6322 Set max concurrent to 2 by default 2012-11-08 17:58:22 +01:00
Olivier Poitrey 3109110dc0 Fix lazy copy/pasted typo 2012-11-07 17:15:11 +01:00
Olivier Poitrey 2eee009392 Add some doc 2012-11-07 02:04:55 +01:00
Olivier Poitrey e343bdfb42 Add details on `finished` parameter 2012-11-06 18:32:15 +01:00
Olivier Poitrey 95be2aad35 Inline conditions are baaad 2012-11-06 18:28:14 +01:00
Olivier Poitrey b29bb2e2e1 Do not call completed block on categories for intermediate progressive images 2012-11-06 18:24:57 +01:00
Olivier Poitrey e5b0d22e64 Do not break category API (cf previous commit) 2012-11-06 18:22:18 +01:00
Olivier Poitrey 2904559f54 Fix progressive mode 2012-11-06 18:14:22 +01:00
Olivier Poitrey 1f0a8f4b13 Use the correct setter sementics for dispatch (fix 213) 2012-11-06 17:18:51 +01:00
Olivier Poitrey 541f3a1284 Fix cancel not cancelling connection 2012-11-06 14:04:12 +01:00
Olivier Poitrey cceb56353c Fix crash under iOS 6 when dispatch_release is called (see #213) 2012-11-06 13:15:44 +01:00
Olivier Poitrey 651d8ff583 Serialize all background operations 2012-11-06 11:30:23 +01:00
Olivier Poitrey 326890b476 Fix disk image cache read not setting memory cache + ensure decodedImageWithImage never fail 2012-11-06 10:14:21 +01:00
Olivier Poitrey b5bb74bf96 Ensure every data manipulation performed in NSURLConnection delegates are handled in the global background queue 2012-11-06 10:03:59 +01:00
Olivier Poitrey bf1b946b9a Fix double call to NSURLConnection start + wrong condition for low priority (fix #212) 2012-11-06 09:19:50 +01:00
Olivier Poitrey ed690465d8 Ensure we're not decoding the image in the main thread 2012-11-06 03:31:32 +01:00
Olivier Poitrey 570965f6cf Use dispatch_barrier to handle NSMutableDictionary thread unsafety instead of main thread dispatching 2012-11-06 03:31:03 +01:00
Olivier Poitrey 13210a6925 Use global low prio queue instead of a dedicated queue for caching I/Os 2012-11-06 03:01:16 +01:00
Olivier Poitrey a8a9b12896 Do not use dispatch_io_write as it generate random crashes
Either it's buggy under iOS or I didn't use it the right way...
2012-11-06 02:50:36 +01:00
Olivier Poitrey 73df9d7281 Track leaks 2012-11-05 23:05:54 +01:00
Olivier Poitrey 78a4df12c6 Fix aggregation tracking urls not cleaned in case of cancellation 2012-11-05 21:10:18 +01:00
Olivier Poitrey 149afed476 Add progress block support to UIImageView category 2012-11-05 20:45:15 +01:00
Olivier Poitrey f7d0f1d12f Fix example app 2012-11-05 20:38:31 +01:00
Olivier Poitrey d85d5833af Fix fucked-up merge 2012-11-05 20:04:58 +01:00
Olivier Poitrey 8a55d97fc9 Prevent caching of responses by NSURLCache (fix #211) 2012-11-05 19:57:15 +01:00
Olivier Poitrey df89ee44cd Update podspec 2012-11-05 18:21:20 +01:00
Olivier Poitrey efe65bfd3b Fix source file headers 2012-11-05 18:21:19 +01:00
Olivier Poitrey 56a0eea941 Setup NSURLRequest
- Activate pipelineing
- Disable cookie support
- Add image/* Accept header to force image on servers handling content negociation
2012-11-05 18:21:19 +01:00
Olivier Poitrey e91cbcf0aa Fix wrong cache policy used (fix #211) 2012-11-05 17:54:31 +01:00
Olivier Poitrey 9a283273f1 Fix typo in license URL 2012-11-05 12:20:18 +01:00
Olivier Poitrey 4f2b5bf674 Add Licenses section 2012-11-04 17:48:20 +01:00
Olivier Poitrey 64a745f2fc Add "How is SDWebImage better than X?" wiki link 2012-11-04 16:17:32 +01:00
Olivier Poitrey f8798294ab Remove outdated motivation section 2012-11-04 15:39:50 +01:00
Olivier Poitrey 535203d90c Add who use it section 2012-11-04 15:17:32 +01:00
Olivier Poitrey 2227266c41 First beta of SDWebImage 3.0
This version is a rewrite of the lib using iOS 5.0 as minimum target.
The lib as thus been refactored to use blocks/GCD from the ground up.
As a consequence, all delegate code style has been removed. The result
is a lot less lines of code and more flexibility.
2012-11-04 10:09:10 +01:00
Olivier Poitrey 8963f996e9 Add cancelAll method (fix #168) 2012-11-04 01:52:09 +01:00
Olivier Poitrey 55fd4a1d77 Merge pull request #205 from triposo/send-downloader-with-notification
Send downloader as part of notification.
2012-11-03 16:53:08 -07:00
Olivier Poitrey 048bdbb751 Fix alpha handling in image decoder (fix #204) 2012-11-04 00:51:35 +01:00
Jure Žove c609027314 Fixed Alpha chanel detection when decoding images. 2012-11-04 00:49:34 +01:00
Olivier Poitrey 1a360b6faf Revert "Fixed Alpha chanel detection when decoding images."
This reverts commit e6ede1104c.
2012-11-03 21:21:45 +01:00
Olivier Poitrey ead67a6c9c Change deployement target to 4.x as NSCache wasn't available in 3.0 2012-11-02 01:27:05 +01:00
Olivier Poitrey 9df9bf8498 Fix example app 2012-11-02 01:24:09 +01:00
Olivier Poitrey 497207466f Add NSCache's cost argument 2012-11-02 01:23:22 +01:00
Olivier Poitrey 16595c950d Merge pull request #183 from gotosleep/502f74042f10aa3a34d95a5e3f3e9a6500471554
Use NSCache instead of a dictionary for the memory cache.
2012-11-01 17:11:48 -07:00
Jon Tirsen fbad013800 Send downloader as part of notification. 2012-10-30 14:47:20 +01:00
Olivier Poitrey 520124114f Merge pull request #203 from Stigec/master
Fixed Alpha detection when decoding images.
2012-10-28 12:57:45 -07:00
Jure Žove e6ede1104c Fixed Alpha chanel detection when decoding images. 2012-10-28 19:58:14 +01:00
Olivier Poitrey ab07f23fbc Fix #200 crash on archived builds 2012-10-23 15:50:53 +02:00
Olivier Poitrey ccd3b025f0 Add missing installation instruction about linker flag 2012-10-20 04:06:04 +02:00
Olivier Poitrey 62a61ab249 Switch to framework distribution 2012-10-19 13:34:40 +02:00
Olivier Poitrey 0102bdf7b7 Merge pull request #195 from JaviSoto/bitmap-info-error
Creating the CGBitmapContext with the right bytes per pixel and bitmap info depending on the original image.
2012-10-12 15:22:03 -07:00
Javier Soto 487db1b385 Creating the CGBitmapContext with the right bytes per pixel and bitmap info depending on the original image.
This removes an error that was making CGBitmapContext return NULL with some images:
<Error>: CGBitmapContextCreate: unsupported parameter combination: 8 integer bits/component; 32 bits/pixel; 3-component color space; kCGImageAlphaLast; 400 bytes/row.
2012-10-12 13:43:33 -07:00
Olivier Poitrey 6818520744 Merge pull request #194 from NachoSoto/patch-1
Keeping original image alpha info when decoding
2012-10-10 16:38:26 -07:00
Nacho Soto 1bf9668d97 Keeping original image alpha info when decoding
This fixes issue #26 and #55, after the change introduced in commit c32f9c03f816dac58a8cac25d6189310272ca9c1
2012-10-10 16:36:53 -07:00
Olivier Poitrey 3c4c61f54c Merge pull request #189 from kurige/master
Podspec: Add 'MK' as acceptable prefix for MKAnnotationView category
2012-10-01 13:20:22 -07:00
Christopher Gateley c5b712d09a Podspec: Add 'MK' as acceptable prefix for MKAnnotationView category 2012-10-01 15:50:12 -04:00
Olivier Poitrey cac29dc753 Add ImageIO dep 2012-09-12 13:02:33 +02:00
Olivier Poitrey c32f9c03f8 Remove alpha channel (may break some PNG/GIF with alpha, pull request welcome) 2012-09-12 02:45:54 +02:00
Olivier Poitrey 324aae620e Update podspec for 2.7 2012-09-10 19:06:10 +02:00
Olivier Poitrey b734f289d0 Add a cached parameter to the success block to tell the receiver if the image came from cache or network #181 2012-09-07 23:00:50 +02:00
Olivier Poitrey 3cdbb9b966 Merge pull request #149 from acoomans/master
Added build directory to gitignore
2012-09-06 16:22:58 -07:00
Kevin Monahan 4ea95b1342 Add and update podspec 2012-09-07 01:21:06 +02:00
Kevin Monahan 0e075907a4 Add the ability to set max cache age. 2012-09-07 01:20:13 +02:00
Sema Belokovsky 7b941a0cb2 Non ARC fix 2012-09-07 01:14:10 +02:00
Olivier Poitrey 40524876e9 Add some security around wrongly typed URL argument 2012-09-06 22:50:05 +02:00
Olivier Poitrey 5f27d2d20d Merge pull request #176 from jianlin/master
needed to quote <Multiple values>
2012-09-02 04:48:12 -07:00
jianlin c1b22e83e5 needed to quote the <Multiple values> 2012-09-02 04:09:47 -07:00
Olivier Poitrey eaca9576ba Merge pull request #175 from jianlin/master
add instructions
2012-09-02 03:46:54 -07:00
jianlin e728b29170 more readable 2012-09-02 03:40:21 -07:00
jianlin 38f5acdb69 HeaderFile.h confusing
users may copy and paste it to source code (HeaderFile.h)
2012-09-02 03:39:34 -07:00
jianlin 633a86805f quote the string to add
for the search paths
2012-09-02 03:33:44 -07:00
jianlin 097276c0bb add instructions on how to pop out the box for header search paths 2012-09-02 03:28:56 -07:00
Olivier Poitrey 05574623d6 Merge pull request #174 from jianlin/master
add explanation of where to find the link flag and the header search paths
2012-09-02 03:16:32 -07:00
jianlin e89f27bebf add further explanation for Build Settings info 2012-09-02 03:10:31 -07:00
Olivier Poitrey ef8bced49d Merge pull request #167 from ltbl/master
Fix SDWebImageDecoder to obey the orientation tag
2012-08-20 03:00:14 -07:00
Taeho Kim 0d14e54214 Fix SDWebImageDecoder to obey the orientation tag 2012-08-20 18:06:51 +09:00
Arnaud Coomans 377eca03ea Updated gitignore to include build 2012-07-01 20:01:06 -07:00
Olivier Poitrey c474512548 Fix the no image issue when no placeholder image is used with UITableViewCell default templates 2012-06-26 03:45:25 +02:00
Olivier Poitrey 46cc079069 Fix README type (fix #146) 2012-06-25 14:55:12 +02:00
Olivier Poitrey 34f18e012f Add a dedicated target with MKAnnotation category
This free other targets from unwanted MapKit framework requirement
2012-06-25 14:55:12 +02:00
Jesse Andersen 502f74042f Use NSCache instead of a dictionary for the memory cache. 2012-06-05 22:15:04 -07:00
Olivier Poitrey b357e8210c Add a dedicated target with MKAnnotation category
This free other targets from unwanted MapKit framework requirement
2012-06-05 23:31:27 +02:00
clowwindy 0bce0b99bc Memory cache reserves 12MB free RAM to prevent watchdog from killing the app before memory warning is sent 2012-06-05 01:34:16 +02:00
Olivier Poitrey 248fbc2148 Fix blocks not called when same URL requested for download several times simultanously (fix #137) 2012-06-05 01:16:52 +02:00
Olivier Poitrey b78238802d Fix an implicit conversion error (fix #129) 2012-05-22 16:39:21 +02:00
Olivier Poitrey aa64d20128 Fix README for static library instruction with archiving 2012-05-16 20:42:19 +02:00
Olivier Poitrey 960674fce1 Fix typo (fix #123) 2012-05-14 18:28:38 +02:00
Olivier Poitrey ea5b82d963 Fix a crash with progressive download activated in non-ARC env 2012-05-14 11:54:25 +02:00
Olivier Poitrey 76132c3e84 Fix ARC target not activating ARC correctly 2012-05-14 11:53:25 +02:00
Olivier Poitrey 874f944d8e Add support for setBackgroundImage:* in UIButton category (fix #121) 2012-05-14 11:17:30 +02:00
Olivier Poitrey eff6cac284 Set placeholder on all UIButton stats (fix #120) 2012-05-14 10:32:26 +02:00
Olivier Poitrey b6e0630b17 Fix some typos/misses (fix #119) 2012-05-14 08:45:09 +02:00
Olivier Poitrey 5aa5b46952 Merge pull request #118 from jcole/master
Allows you to set SDWebImageOptions for SDWebImageOptions.  Defaults to SDWebImageLowPriority.
2012-05-11 17:34:26 -07:00
Jeff Cole 35b6553eac Allows SDWebImagePrefetcher options to be set set. Defaults to SDWebImageLowPriority. 2012-05-11 18:44:37 -04:00
Olivier Poitrey aa25f3a67b Enable more useful warnings 2012-05-12 00:37:37 +02:00
Olivier Poitrey b52f85b31f Merge branch 'rebasedMaster' of https://github.com/cbowns/SDWebImage into cbowns-rebasedMaster 2012-05-12 00:26:55 +02:00
Olivier Poitrey fc24642149 Fix ARC warning (fix #116) 2012-05-12 00:25:17 +02:00
Olivier Poitrey af3924c447 Merge pull request #115 from jcole/master
Added a few methods to SDImageCache to get number of items in file cache and memory cache, and size of items in memory
2012-05-11 12:47:04 -07:00
Jeff Cole 102d7bd484 Fix the description for getMemorySize 2012-05-11 10:02:00 -04:00
Jeff Cole d6534c7fbc Add getDiskCount, getMemorySize, and getMemoryCount methods to SDImageCache for diagnostic purposes 2012-05-11 07:40:49 -04:00
Olivier Poitrey f94ecf0600 Add URL to the API documentation to the README 2012-05-10 14:16:10 +02:00
Olivier Poitrey 110799614f Add appledoc comments 2012-05-10 14:07:38 +02:00
Olivier Poitrey 6574083a95 Add image decoder and retina support to partial images when progressive download is used 2012-05-10 12:57:30 +02:00
Olivier Poitrey ea819b2a45 Rework static library settings and documentation and add an example project
Inspired by http://www.blog.montgomerie.net/easy-xcode-static-library-subprojects-and-submodules
2012-05-10 00:30:48 +02:00
Olivier Poitrey ba71333e17 Add support for optional progressive downloading using ImageIO (fix #114)
Thanks to @Xenofex for his idea and implementation example
2012-05-09 22:33:28 +02:00
Eli Wang 16d661488a Update README.md with syntax color. 2012-05-09 12:42:09 +02:00
Olivier Poitrey dd5f15055d Move all source to a subdirectory to comply with XCode 4 standards 2012-05-09 12:37:35 +02:00
Olivier Poitrey 10aff8e1f0 Add cache key filter support to SDWebManager in order to allow custom cache key generation 2012-05-09 11:04:09 +02:00
Olivier Poitrey 6aee6411f9 Do not check request response status code when the protocol isn't HTTP (fix #110) 2012-05-04 16:30:38 +02:00
Olivier Poitrey dd6d8dba6e Add SDImageCache removeImageForKey:fromDisk: to allow cache item removal from memory only (fix #111) 2012-05-01 20:01:51 +02:00
Christopher Bowns 0237551b8f Remove spaces to match code style 2012-04-27 12:14:38 -07:00
Christopher Bowns 89b8cf5cb0 Update README.md 2012-04-26 17:56:41 -07:00
Christopher Bowns 5b0a45e6ec Converts ints to NSUInts to avoid signed-comparison warnings 2012-04-26 17:56:40 -07:00
Christopher Bowns 2aeed9830e Brace-wraps inline struct initializer 2012-04-26 17:56:40 -07:00
Christopher Bowns cdb651b6a3 Adds newlines to ends of files 2012-04-26 17:56:40 -07:00
Olivier Poitrey ffc247f479 Merge pull request #106 from athasach/patch-1
Added missing newline at end of file to fix a compilation error
2012-04-26 02:41:29 -07:00
Kent Wong 16cae985fc Added missing newline at end of file to fix a compilation error where warnings are stricter [-Werror,-pedantic,-Wnewline-eof]. 2012-04-25 22:46:47 -03:00
Olivier Poitrey 973591d433 Merge pull request #97 from muhku/master
UIButton+WebCache: set the cached image in the UIControlStateSelected and UIControlStateHighlighted states
2012-04-25 16:22:30 -07:00
Olivier Poitrey a677421ad3 Merge pull request #105 from rickygu/patch-1
Update static library instruction to be more comprehensive.
2012-04-25 16:16:47 -07:00
Ricky Gu 7030a8f802 Update static library instruction to be more comprehensive. 2012-04-25 15:05:43 -07:00
Olivier Poitrey 8e27086802 Merge pull request #104 from piotrb/master
Updated README to match the header location changes from #101
2012-04-25 05:38:33 -07:00
Olivier Poitrey c145057d11 Merge pull request #103 from fannheyward/master
Fix warning: "performSelector may cause a leak because its selector is unknown."
2012-04-25 05:38:10 -07:00
Piotr Banasik 6c402c1cc6 Updated README to match the header location changes from #101 2012-04-25 10:02:42 +08:00
Heyward Fann d0ca6dec2c fix warning: performSelector may cause a leak because its selector is unknown. 2012-04-25 09:56:56 +08:00
Olivier Poitrey 3f28c9e6ea Merge pull request #102 from piotrb/master
Updated the project to use RestKit style ../../Headers/$(TARGET_NAME) Headers path
2012-04-24 06:05:40 -07:00
Piotr Banasik 2125d13252 Updated the project to use RestKit style ../../Headers/$(TARGET_NAME) Headers path to avoid issues in Archive builds 2012-04-24 17:46:53 +08:00
Matias Muhonen 7283ce7bb0 Set the cached image in UIControlStateSelected and UIControlStateHighlighted.
This is required that the UIViewContentModeScaleAspectFit contentMode works
correctly for UIButton.
2012-04-16 21:25:23 +03:00
Olivier Poitrey f89508d6f7 Merge pull request #92 from andybee/master
Fix for SDWebImageManger block issue (84)
2012-04-13 01:45:31 -07:00
andybee 5cacab1b30 Tweaked the safe release methodology for the copied blocks to remove un-necessary autorelease. 2012-04-05 10:24:46 +02:00
andybee f87c057cb8 Made fix ARC-safe 2012-04-04 22:15:06 +02:00
andybee ba818f0d65 Attempting to fix rs/SDWebImage#84 by passing success/failure blocks in user info dictionary. This avoids holding success and failure block in manager object which is used as a singleton by the UIImageView and UIButton additions classes, thus repeatedly calling the same block multiple times when making multiple requests. 2012-04-04 21:19:57 +02:00
Olivier Poitrey e63e925821 Merge pull request #91 from andybee/master
@2x retina support is broken when images pass through UIImage (ForceDecode) addition
2012-04-04 05:36:25 -07:00
andybee 0cd7f6953b Allowed original image scale to be preserved. 2012-04-04 13:34:55 +02:00
Olivier Poitrey 61df06926a Fix placeholder not passed to the designated follow up method (fix #87) 2012-03-29 11:27:14 +02:00
Olivier Poitrey 2283e2e458 Merge pull request #86 from tvon/patch-1
SDWebImageDownloader adds excessive observers when SDNetworkActivityIndicator is used
2012-03-28 13:34:27 -07:00
Tom von Schwerdtner 6ca759f182 Two observers get added every time downloaderWithURL is called, which is unnecessary and seems to result in an imbalance in SDNetworkActivityIndicator between startActivity and stopActivity calls (which leads to the indicator not showing when it should during any initial app activity).
This fix is possibly not ideal, but it does the trick.
2012-03-28 16:27:31 -03:00
Olivier Poitrey dfa03af19f Fix a mem leak in SDWebImageDownloader (fix #83) 2012-03-22 11:40:05 +01:00
Olivier Poitrey a8d5b3ec72 Fix a bug in SDImageCache making first request to disk cache to always return nil (fix #81) 2012-03-22 10:37:23 +01:00
Olivier Poitrey 14b79734d2 Add some common problem tips 2012-03-22 10:33:07 +01:00
Olivier Poitrey 24f0842ea0 Treat image URL with response status code >= 400 as errors (fix #79) 2012-03-19 19:13:18 +01:00
Olivier Poitrey 1cf1703ec1 Add MKAnnotationView+WebCache category (fix #78) 2012-03-14 22:05:03 +01:00
Olivier Poitrey 580a90d6a0 Better ARC support 2012-03-12 11:46:16 +01:00
Olivier Poitrey ab97899a23 Add macro for ARC conditional call to [super dealloc] 2012-03-11 16:59:37 +01:00
Olivier Poitrey dcc6673bf1 Fix an EXC_BAD_ACCESS introduced by aa6956e9fc (fix #77) 2012-03-11 16:49:33 +01:00
Olivier Poitrey 6781045698 Add some backward compatible block support (fix #64) 2012-03-10 20:15:06 +01:00
Olivier Poitrey 30b9534294 Add some callback methods to SDWebImageManager protocol with requested URL appended (fix #67) 2012-03-10 18:22:07 +01:00
Olivier Poitrey 3074f55de2 Fix a conditing preventing from disk caching when data is not provided (fix #69) 2012-03-10 17:53:24 +01:00
Olivier Poitrey 8357f64a68 Add ARC info in README 2012-03-10 17:40:02 +01:00
Olivier Poitrey c327ee3737 Remove conditional activation of the new decoder optimization (now it's always activated) 2012-03-10 17:34:34 +01:00
Olivier Poitrey 40bcaa1181 Make SDWebImage ARC friendly by detecting if project is using ARC or not and do the right thing with retain and release 2012-03-10 17:32:24 +01:00
Olivier Poitrey aa6956e9fc Refactor 2x scale support 2012-03-10 16:30:43 +01:00
Sebastian Vieira c972489931 absoluteString for iOS 3 2012-03-10 16:30:43 +01:00
Sebastian Vieira 3ef0f609fd checking if uiimage supports the scale parameter for retina display phones (only supported form ios 4 onwards) 2012-03-10 16:30:43 +01:00
Sebastian Vieira baea8eed4a Adding the ability to render retina display images based on the file to which the url is pointing at 2012-03-10 16:30:43 +01:00
Olivier Poitrey 6660c51d36 Merge pull request #65 from ecentinela/master
Added a method to see the cache size
2012-03-10 06:01:48 -08:00
Olivier Poitrey 05725b4ab5 Merge pull request #70 from besi/patch-1
Fixed typos
2012-02-22 08:03:04 -08:00
Beat Besmer 03142f607c Fixed typos 2012-02-22 16:37:23 +01:00
Javier Martinez Fernandez e5cd63617f Added a method to see cache size. 2012-02-07 11:43:29 +01:00
Olivier Poitrey b207dcc6a8 Setup xcode project to allow import in a project as a static library 2012-01-28 00:05:40 +01:00
Adam Ernst 8318b295bf Introduce a cacheURLs array to prevent race conditions related to checking the on-disk image cache. (Fix #47)
If a cache check is initiated, then canceled with cancelForDelegate: before a new cache check
is started with a different URL but the same delegate, the ongoing disk cache check would still
message the delegate despite being canceled by cancelForDelegate:. This is because it only
checked to see if the delegate was in the cacheDelegates array; it had been removed by
cancelForDelegate:, but added back by the new unrelated cache check. cacheURLs keeps track
of which specific URLs are actually requested by the delegate. If the URL from a completed
disk cache check does not match the delegate in cacheDelegates, the delegate is not messaged
(since we know that request was canceled).
2011-12-05 15:56:32 +01:00
Olivier Poitrey 86b60e9c98 Add Xcode project 2011-12-05 02:50:29 +01:00
Fernando Saragoca 0dfb649faf Documented categories (appledoc) 2011-11-23 00:33:57 +01:00
Olivier Poitrey b3d7a5c450 Merge pull request #39 from 433/version_check_fix
update version check to make #if work for iOS >= 4
2011-10-25 04:00:34 -07:00
Ilya Samartsev 6cda5dcf4d update version check to make #if work for iOS >= 4 2011-10-25 11:02:50 +04:00
Olivier Poitrey 17450bdf1f Merge pull request #37 from neogithub/patch-1
Update README.md
2011-10-20 11:15:07 -07:00
neogithub 0b9b945a37 Update README.md 2011-10-20 10:03:19 -03:00
Olivier Poitrey 23ae1cb00c Add SDWebImagePrefetcher, an utility class to preventively warm-up SDWebImage cache (fix #32)
Contributed by https://github.com/mystcolor
2011-10-04 16:07:36 +02:00
Olivier Poitrey 9e2d414c28 Fix wrong options values 2011-10-04 16:05:32 +02:00
Olivier Poitrey 92d7a01a52 Perform image decoding/optimization in the IO thread instead of main thread for better responsiveness (fix #18)
This new optimization is currently disabled by default so you can test it and give us feedback.
To enable it, add #define ENABLE_SDWEBIMAGE_DECODER and to not forget to add SDWebImageDecoder class
to your projet.

Thanks to Adam Jernst (https://github.com/adamjernst) and James Tang (https://github.com/mystcolor)
for this great optimization. See https://github.com/rs/SDWebImage/pull/18 for more info.
2011-10-04 13:07:26 +02:00
Olivier Poitrey 4792909c5b Merge pull request #29 from nonamelive/patch-1
Fixed a potential crash when the delegate retainCount = 1, which means th
2011-10-03 07:18:06 -07:00
Olivier Poitrey 7d0e544c50 Add an option to disable on disk caching (fix #16) + refactor other options (low prio and retry failed) to an options: parameter 2011-10-03 15:54:49 +02:00
Olivier Poitrey 7c06b3a314 Failsafe a very common usage error (passing URL as NSString instead of NSURL) 2011-10-01 00:38:44 +02:00
nonamelive 2b0bb248f4 Fixed a potential crash when the delegate retainCount = 1, which means the delegate is only retained by the SDWebImageManager and the delegate's dealloc method has a structure like the code below.
- (void)dealloc
{
    [manager cancelForDelegate:self];
    [super dealloc];
}
2011-09-28 14:29:51 +08:00
Olivier Poitrey e9d43e443a When storeImage:imageData:forKey:toDisk: is called with toDisk:YES but no data, do not prevent memory caching (fix: #24) 2011-09-21 15:03:14 +02:00
Olivier Poitrey 1a355d09c2 Merge pull request #20 from exalted/master
Added UIButton+WebCache category
2011-07-25 11:12:18 -07:00
Ali Servet Donmez 4b00568942 Added UIButton+WebCache category 2011-07-25 17:50:21 +02:00
Adam Ernst 45cc126d32 Fix race condition with SDWebImageManager's cancelForDelegate:
The -cancelForDelegate: method was working for downloads but not local cache checks. Add some new machinery to keep track of pending cache requests and only message the delegate if it hasn't since requested cancellation.
2011-07-13 23:03:36 +02:00
Olivier Poitrey 47aad5b55f Fix some implicit conversion warnings 2011-07-13 21:55:34 +02:00
Olivier Poitrey 4005884df5 Fix coding style 2011-07-13 21:23:13 +02:00
siuying 314837de7e Fix a leak on Mac OSX 2011-07-13 20:47:54 +02:00
Olivier Poitrey 0a2e9a3040 Merge pull request #12 from apptitude/master
Low priority download mode
2011-05-07 04:11:44 -07:00
Jeppe Vesterbæk 34e8082cde Add low priority download mode. Low priorities run NSUrlConnection in NSEventTrackingRunLoopMode 2011-05-06 10:30:50 +02:00
Olivier Poitrey 44fd72843b Clean delegates even on failed downloads 2011-03-21 16:40:09 +01:00
Jamie Pinkham 3116810b18 Added Mac OS X compatibility 2011-03-18 00:17:59 +01:00
Elio Gonzalez ee153fee04 Force retry of failed downloads 2011-01-25 03:37:04 +01:00
Olivier Poitrey 20b8cdf69d Remove wrong UIKit import and fix wrong indentation (space instead of tab) 2011-01-25 03:29:57 +01:00
Olivier Poitrey 1fe20c25d6 Remove the need for storeDataQueue dictionnary which required synchronization 2010-10-10 01:13:44 +02:00
niblh 9f492ccdf8 Add userInfo on SDWebImageDownloader.m 2010-10-07 12:15:16 +02:00
Olivier Poitrey 3f2f360ee2 Add support for system network activity indicator show/hide via notification
As showing/hiding the network activity indicator could conflict with your own code (i.e. the lib may hide the indicator when your code would still do some network stuff), the show/hide of the indicator isn't performed by the lib directly but SDWebImageDownloadStartNotification and SDWebImageDownloadStopNotification notifications are posted instead.

This lets you handle the indicator visiblity by yourself. If you're lazy, you can use the SDNetworkActivityIndicator library (http://github.com/rs/SDNetworkActivityIndicator) to handle it automatically. Once added to your project, all you have to do is to import this lib in addition to the SDWebImage lib.

Note that you should then use SDNetworkActivityIndicator for all your network status indicator visibility changes in your code if you don't want conflicts to happen.
2010-10-03 10:16:26 +02:00
Olivier Poitrey 2b352c3c3a Perform disk cache out operations asynchronousely in order to prevent from blocking the main runloop when a lot of cache queries are performed at the same time 2010-09-16 22:56:11 +02:00
Olivier Poitrey dffff12607 If nil is given as URL to setImageWithURL:, set the image to the placeholder image (or nil if no placeholder)
This is the recommanded way clear an image for reuse (as a UITableViewCell for instance). Calling setImageWithURL:
with nil URL will have the effect to cancel an eventual currently in progress download of a thumbnail for this UIImageView.
Affecting the image property directly won't have this effect and may lead to image being re-affected once download is completed.
2010-09-16 13:02:33 +02:00
Olivier Poitrey d2dc4cbbac Do not convert images to JPEG when stored to disk for caching
This saves CPU and memory in all cases and alpha channel / image clearness if orignal format was PNG or GIF.
2010-08-29 03:22:20 +02:00
Olivier Poitrey 7f7dfbecd6 Ensure the downloader is started from the main thread 2010-06-21 01:30:12 +02:00
Olivier Poitrey 65549dec10 Better nil url handling 2010-06-12 16:37:47 +02:00
Olivier Poitrey 7350e1fa03 Fix english in new method naming 2010-06-11 16:32:35 +02:00
Olivier Poitrey 1b0cf3a3fb Add a compile time condition in order to compile with Base SDK pre iOS4 2010-06-11 15:14:42 +02:00
Olivier Poitrey d128c27cad Add `cancelCurrentImageLoading` method to UIImageView+WebCache 2010-06-11 15:06:04 +02:00
Olivier Poitrey 8cc6acb502 Fix typos in the README file (thanks Laurent Etiemble) 2010-06-11 14:40:44 +02:00
Olivier Poitrey 1cae0c4021 Set image to nil when trying to load nil URL 2010-06-11 06:17:54 +02:00
92 changed files with 10376 additions and 735 deletions

42
.github/CONTRIBUTING.md vendored Normal file
View File

@ -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 projects 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)

23
.github/ISSUE_TEMPLATE.md vendored Normal file
View File

@ -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.

18
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@ -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
...

30
.gitignore vendored Normal file
View File

@ -0,0 +1,30 @@
# Xcode
#
build/
*.pbxuser
!default.pbxuser
*.mode1v3
!default.mode1v3
*.mode2v3
!default.mode2v3
*.perspectivev3
!default.perspectivev3
project.xcworkspace
!default.xcworkspace
xcuserdata
*.xccheckout
*.moved-aside
DerivedData
*.hmap
*.ipa
*.xcuserstate
*.xcscmblueprint
# CocoaPods
#
# We recommend against adding the Pods directory to your .gitignore. However
# you should judge for yourself, the pros and cons are mentioned at:
# http://guides.cocoapods.org/using/using-cocoapods.html#should-i-ignore-the-pods-directory-in-source-control
#
Pods/
Podfile.lock

3
.gitmodules vendored Normal file
View File

@ -0,0 +1,3 @@
[submodule "Vendors/libwebp"]
path = Vendors/libwebp
url = https://github.com/webmproject/libwebp

27
.travis.yml Normal file
View File

@ -0,0 +1,27 @@
language: objective-c
osx_image: xcode7.1
before_install:
- export LANG=en_US.UTF-8
- env
- locale
- gem install cocoapods --no-rdoc --no-ri --no-document --quiet
- pod --version
- pod setup --silent > /dev/null
- pod repo update --silent
script:
- pod lib lint --allow-warnings
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator build
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+WebP' -sdk iphonesimulator build
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+MKAnnotation' -sdk iphonesimulator build
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator build
- pod install --project-directory=Tests
- xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator clean
- xctool -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test

283
CHANGELOG.md Normal file
View File

@ -0,0 +1,283 @@
## [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
- bumped `libwep` version to `0.4.4`
#### Features:
- added tvOS support #1327 and #1358 - fix #1368 and #1302
#### Fixes:
- #1217 contains several of the above fixes
- fix #391 -> option to cache only on Disk. will replace #1130
- fix #343 -> iCloud backup Option
- fix #371 -> CGBitmapContextCreate: unsupported parameter combination + #1268 #1412 #1340
- fix #576 -> scale set to screen scale
- fix #1035 -> progress queue with dispatch_async
- new feature -> activity indicator using auto layout. The activity indicator feature will replace #131
- #1218 progress callbacks now report on main thread - fixes #1035
- #1321 Added a new constructor to SDWebImagePrefetcher - replaces #956
- #976 append the original path extension to the hash filename - fixes #967
- replaced #999 with #1221
- added cache tests #1125
- #1236 fixes #1203
- bf899e2 fixes #1261 #1263 compilation issue CocoaPods vs non-CocoaPods
- #1367 fixes a bug where image scale & orientation are ignored when decoding / decompressing an image
- cac21e1 fixes #1366, addresses #1350 and reverts a part of #1221 - from commit 6406d8e, the wrong usage of dispatch_apply
- #1363 fixes #1361 sd_cancelBackgroundImageLoadForState
- #1348 Create a strong ref of weakOperation in the entry of The image download subOperation, use the strong ref instead weakOperation. At the same time, repair some logic of the 'If cancelled'
- dcb7985 replaces #1345 - Load local credential file
- #1323 don't to perform download if url is "" but not nil
- #1310 Added support for SDWebImageAvoidAutoSetImage option to UIButton and highlighted UIImageView categories
- #1308 Added Swift installation tips
- 32923fa Xcode 7.1 updates
- #1297 cleaner implementation of failedUrl error handling - fixes #1275
- #1280 Fix sd_animatedImageByScalingAndCroppingToSize
- Remove logging from the image prefetcher - #1276
- Fix typos #1256 #1257 #1258 #1331 #1290
## [3.7.3 Patch release for 3.7.0 with iOS8+ framework and Carthage on Jun 13th, 2015](https://github.com/rs/SDWebImage/releases/tag/3.7.3)
- Adds support for **iOS 8+ Framework and Carthage** [#1071](https://github.com/rs/SDWebImage/pull/1071) [#1081](https://github.com/rs/SDWebImage/pull/1081) [#1101](https://github.com/rs/SDWebImage/pull/1101)
- [Refactor] Use `NSMutableSet` for failed URLs' storage instead of array [#1076](https://github.com/rs/SDWebImage/pull/1076)
- Make a constant for the error domain [#1011](https://github.com/rs/SDWebImage/pull/1011)
- Improve operation behavior [#988](https://github.com/rs/SDWebImage/pull/988)
- Bug fix: `Collection <__NSArrayM: > was mutated while being enumerated` [#985](https://github.com/rs/SDWebImage/pull/985)
- added `SDWebImageAvoidAutoSetImage` option to avoid automatic image addition in `UIImageView` and let developer to do it himself [#1188](https://github.com/rs/SDWebImage/pull/1188)
- Added support for custom disk cache folder with fall back for caches directory [#1153](https://github.com/rs/SDWebImage/pull/1153)
- Added some files to the workspace so they are easier to edit [8431481](https://github.com/rs/SDWebImage/commit/8431481)
- Doc update [72ed897](https://github.com/rs/SDWebImage/commit/72ed897) [7f99c01](https://github.com/rs/SDWebImage/commit/7f99c01) [#1016](https://github.com/rs/SDWebImage/pull/1016) [#1038](https://github.com/rs/SDWebImage/pull/1038) [#1045](https://github.com/rs/SDWebImage/pull/1045)
- [Memory Issue] Clear `SDWebImagePrefetcher` `progressBlock` when it has completed [#1017](https://github.com/rs/SDWebImage/pull/1017)
- avoid warning `<Error>: ImageIO: CGImageSourceCreateWithData data parameter is nil` if `imageData` is nil [88ee3c6](https://github.com/rs/SDWebImage/commit/88ee3c6) [#1018](https://github.com/rs/SDWebImage/pull/1018)
- allow override `diskCachePath` [#1041](https://github.com/rs/SDWebImage/pull/1041)
- Use `__typeof(self)` when assigning `weak` reference for block [#1054](https://github.com/rs/SDWebImage/pull/1054)
- [Refactor] Implement cache cost calculation as a inline function [#1075](https://github.com/rs/SDWebImage/pull/1075)
- @3x support [9620fff](https://github.com/rs/SDWebImage/commit/9620fff) [#1005](https://github.com/rs/SDWebImage/pull/1005)
- Fix parenthesis to avoid crashes [#1104](https://github.com/rs/SDWebImage/pull/1104)
- Add `NSCache` countLimit property [#1140](https://github.com/rs/SDWebImage/pull/1140)
- `failedURLs` can be removed at the appropriate time [#1111](https://github.com/rs/SDWebImage/pull/1111)
- Purge `NSCache` on system memory notifications [#1143](https://github.com/rs/SDWebImage/pull/1143)
- Determines at runtime is `UIApplication` is available as per [#1082](https://github.com/rs/SDWebImage/issues/1082) [#1085](https://github.com/rs/SDWebImage/pull/1085)
- Fixes http://git.chromium.org/webm/libwebp.git/info/refs not valid [#1175](https://github.com/rs/SDWebImage/pull/1175) + Reverted [#1193](https://github.com/rs/SDWebImage/pull/1193) + [#1177](https://github.com/rs/SDWebImage/pull/1177)
- 404 image url was causing the test to fail [0e761f4](https://github.com/rs/SDWebImage/commit/0e761f4)
- Fix for transparency being lost in transformed images. [#1121](https://github.com/rs/SDWebImage/pull/1121)
- Add handling for additional error codes that shouldn't be considered a permanent failure [#1159](https://github.com/rs/SDWebImage/pull/1159)
- add webp accepted content type only if `WebP` enabled [#1178](https://github.com/rs/SDWebImage/pull/1178)
- fix `ImageIO: CGImageSourceCreateWithData` data parameter is nil [#1167](https://github.com/rs/SDWebImage/pull/1167)
- Applied patch for issue [#1074](https://github.com/rs/SDWebImage/issues/1074) SDWebImage residing in swift module breaks the debugger [#1138](https://github.com/rs/SDWebImage/pull/1138)
- Fixed URLs with trailing parameters get assigned an incorrect image scale value [#1157](https://github.com/rs/SDWebImage/issues/1157) [#1158](https://github.com/rs/SDWebImage/pull/1158)
- Add newline to avoid compiler warning in `WebImage.h` [#1199](https://github.com/rs/SDWebImage/pull/1199)
## [3.7.2 Updated patch release for 3.7.0 on Mar 17th, 2015](https://github.com/rs/SDWebImage/releases/tag/3.7.2)
#### Updates
- bumped `libwep` version to `0.4.3`
#### Features:
- implement `SDWebImageDownloaderAllowInvalidSSLCertificates` option - [#937](https://github.com/rs/SDWebImage/pull/937)
- flag to transform animated images (`SDWebImageTransformAnimatedImage`) - [#703](https://github.com/rs/SDWebImage/pull/703)
- allows user to override default `SDWebImageDownloaderOperation` - [#876](https://github.com/rs/SDWebImage/pull/876)
- adds option to decompress images and select prefetcher queue - [#996](https://github.com/rs/SDWebImage/pull/996)
#### Fixes:
- fixed [#809](https://github.com/rs/SDWebImage/issues/809) `cancelAll` crash - [#838](https://github.com/rs/SDWebImage/pull/838)
- fixed [#900](https://github.com/rs/SDWebImage/issues/900) by adding a new flag `SD_LOG_NONE` that allows silencing the SD logs from the Prefetcher
- fixed [#895](https://github.com/rs/SDWebImage/issues/895) unsafe setImage in `setImageWithURL:` - [#896](https://github.com/rs/SDWebImage/pull/896)
- fix `NSNotificationCenter` dispatch on subthreads - [#987](https://github.com/rs/SDWebImage/pull/987)
- fix `SDWebImageDownloader` threading issue - [#104](https://github.com/rs/SDWebImage/pull/104)6
- fixed duplicate failed urls are added into `failedURLs` - [#994](https://github.com/rs/SDWebImage/pull/994)
- increased default `maxConcurrentOperationCount`, fixes [#527](https://github.com/rs/SDWebImage/issues/527) - [#897](https://github.com/rs/SDWebImage/pull/897)
- handle empty urls `NSArray` - [#929](https://github.com/rs/SDWebImage/pull/929)
- decoding webp, depends on source image data alpha status - [#936](https://github.com/rs/SDWebImage/pull/936)
- fix [#610](https://github.com/rs/SDWebImage/issues/610) display progressive jpeg issue - [#840](https://github.com/rs/SDWebImage/pull/840)
- the code from `SDWebImageDownloaderOperation connection:didFailWithError:` should match the code from `connectionDidFinishLoading:`. This fixes [#872](https://github.com/rs/SDWebImage/issues/872) - [7f39e5e](https://github.com/rs/SDWebImage/commit/7f39e5e)
- `304 - Not Modified` HTTP status code handling - [#942](https://github.com/rs/SDWebImage/pull/942)
- cost compute fix - [#941](https://github.com/rs/SDWebImage/pull/941)
- initialise `kPNGSignatureData` data - [#981](https://github.com/rs/SDWebImage/pull/981)
#### Documentation
- documentation updated
## [3.7.1 Patch release for 3.7.0 on Jul 23rd, 2014](https://github.com/rs/SDWebImage/releases/tag/3.7.1)
- fixed `sd_imageOrientationFromImageData:` crash if imageSource is nil - [#819](https://github.com/rs/SDWebImage/pull/819) [#813](https://github.com/rs/SDWebImage/pull/813) [#808](https://github.com/rs/SDWebImage/issues/808) [#828](https://github.com/rs/SDWebImage/issues/828) - temporary fix
- fixed `SDWebImageCombinedOperation cancel` crash (also visible as `SDWebImageManager cancelAll`) - [28109c4](https://github.com/rs/SDWebImage/commit/28109c4) [#798](https://github.com/rs/SDWebImage/issues/798) [#809](https://github.com/rs/SDWebImage/issues/809)
- fixed duplicate symbols when using with webp via pods - [#795](https://github.com/rs/SDWebImage/pull/795)
- fixed missing `mark` from `pragma mark` - [#827](https://github.com/rs/SDWebImage/pull/827)
## [3.7.0 Xcode6, arm64, highlight UIImageView, imageURL ref, NTLM, ... on Jul 14th, 2014](https://github.com/rs/SDWebImage/releases/tag/3.7.0)
## Features
- Add category for imageView's highlighted state `UIImageView+HighlightedWebCache` - [#646](https://github.com/rs/SDWebImage/pull/646) [#765](https://github.com/rs/SDWebImage/pull/765)
- Keep a reference to the image URL - [#560](https://github.com/rs/SDWebImage/pull/560)
- Pass imageURL in completedBlock - [#770](https://github.com/rs/SDWebImage/pull/770)
- Implemented NTLM auth support. Replaced deprecated auth challenge methods from `NSURLConnectionDelegate` - [#711](https://github.com/rs/SDWebImage/pull/711) [50c4d1d](https://github.com/rs/SDWebImage/commit/50c4d1d)
- Ability to suspend image downloaders `SDWebImageDownloader setSuspended:` - [#734](https://github.com/rs/SDWebImage/pull/734)
- Delay the loading of the placeholder image until after load - [#701](https://github.com/rs/SDWebImage/pull/701)
- Ability to save images to cache directly - [#714](https://github.com/rs/SDWebImage/pull/714)
- Support for image orientation - [#764](https://github.com/rs/SDWebImage/pull/764)
- Added async `SDImageCache removeImageForKey:withCompletion:` - [#732](https://github.com/rs/SDWebImage/pull/732) [cd4b925](https://github.com/rs/SDWebImage/commit/cd4b925)
- Exposed cache paths - [#339](https://github.com/rs/SDWebImage/issues/339)
- Exposed `SDWebImageManager cacheKeyForURL:` - [5fd21e5](https://github.com/rs/SDWebImage/commit/5fd21e5)
- Exposing `SDWebImageManager` instance from the `SDWebImagePrefetcher` class - [6c409cd](https://github.com/rs/SDWebImage/commit/6c409cd)
- `SDWebImageManager` uses the shared instance of `SDWebImageDownloader` - [0772019](https://github.com/rs/SDWebImage/commit/0772019)
- Refactor the cancel logic - [#771](https://github.com/rs/SDWebImage/pull/771) [6d01e80](https://github.com/rs/SDWebImage/commit/6d01e80) [23874cd](https://github.com/rs/SDWebImage/commit/23874cd) [a6f11b3](https://github.com/rs/SDWebImage/commit/a6f11b3)
- Added method `SDWebImageManager cachedImageExistsForURL:` to check if an image exists in either the disk OR the memory cache - [#644](https://github.com/rs/SDWebImage/pull/644)
- Added option to use the cached image instead of the placeholder for `UIImageView`. Replaces [#541](https://github.com/rs/SDWebImage/pull/541) - [#599](https://github.com/rs/SDWebImage/issues/599) [30f6726](https://github.com/rs/SDWebImage/commit/30f6726)
- Created workspace + added unit tests target
- Updated documentation - [#476](https://github.com/rs/SDWebImage/issues/476) [#384](https://github.com/rs/SDWebImage/issues/384) [#526](https://github.com/rs/SDWebImage/issues/526) [#376](https://github.com/rs/SDWebImage/pull/376) [a8f5627](https://github.com/rs/SDWebImage/commit/a8f5627)
## Bugfixes
- Fixed Xcode 6 builds - [#741](https://github.com/rs/SDWebImage/pull/741) [0b47342](https://github.com/rs/SDWebImage/commit/0b47342)
- Fixed `diskImageExistsWithKey:` deadlock - [#625](https://github.com/rs/SDWebImage/issues/625) [6e4fbaf](https://github.com/rs/SDWebImage/commit/6e4fbaf)
For consistency, added async methods in `SDWebImageManager` `cachedImageExistsForURL:completion:` and `diskImageExistsForURL:completion:`
- Fixed race condition that causes cancellation of one download operation to stop a run loop that is now used for another download operation. Race is introduced through `performSelector:onThread:withObject:waitUntilDone:` - [#698](https://github.com/rs/SDWebImage/pull/698)
- Fixed race condition between operation cancelation and loading finish - [39db378](https://github.com/rs/SDWebImage/commit/39db378) [#621](https://github.com/rs/SDWebImage/pull/621) [#783](https://github.com/rs/SDWebImage/pull/783)
- Fixed race condition in SDWebImageManager if one operation is cancelled - [f080e38](https://github.com/rs/SDWebImage/commit/f080e38) [#699](https://github.com/rs/SDWebImage/pull/699)
- Fixed issue where cancelled operations aren't removed from `runningOperations` - [#68](https://github.com/rs/SDWebImage/issues/68)
- Should not add url to failedURLs when timeout, cancel and so on - [#766](https://github.com/rs/SDWebImage/pull/766) [#707](https://github.com/rs/SDWebImage/issues/707)
- Fixed potential *object mutated while being enumerated* crash - [#727](https://github.com/rs/SDWebImage/pull/727) [#728](https://github.com/rs/SDWebImage/pull/728) (revert a threading fix from [#727](https://github.com/rs/SDWebImage/pull/727))
- Fixed `NSURLConnection` response statusCode not valid (e.g. 404), downloader never stops its runloop and hangs the operation queue - [#735](https://github.com/rs/SDWebImage/pull/735)
- Fixed `SDWebImageRefreshCached` bug for large images - [#744](https://github.com/rs/SDWebImage/pull/744)
- Added proper handling for `SDWebImageDownloaderLowPriority` - [#713](https://github.com/rs/SDWebImage/issues/713) [#745](https://github.com/rs/SDWebImage/issues/745)
- Fixed fixing potential bug when sending a nil url for UIButton+WebCache - [#761](https://github.com/rs/SDWebImage/issues/761) [#763](https://github.com/rs/SDWebImage/pull/763)
- Fixed issue [#529](https://github.com/rs/SDWebImage/pull/529) - if the `cacheKeyFilter` was set, this was ignored when computing the `scaledImageForKey`. For most of the developers that did not set `cacheKeyFilter`, the code will work exactly the same - [eb91fdd](https://github.com/rs/SDWebImage/commit/eb91fdd)
- Returning error in setImage completedBlock if the url was nil. Added `dispatch_main_async_safe` macro - [#505](https://github.com/rs/SDWebImage/issues/505) [af3e4f8](https://github.com/rs/SDWebImage/commit/af3e4f8)
- Avoid premature completion of prefetcher if request fails - [#751](https://github.com/rs/SDWebImage/pull/751)
- Return nil from `SDScaledImageForKey` if the input image is nil - [#365](https://github.com/rs/SDWebImage/issues/365) [#750](https://github.com/rs/SDWebImage/pull/750)
- Do not load placeholder image if `SDWebImageDelayPlaceholder` option specified - [#780](https://github.com/rs/SDWebImage/pull/780)
- Make sure we call the `startPrefetchingAtIndex:` method from main queue - [#694](https://github.com/rs/SDWebImage/pull/694)
- Save image in cache before calling completion block - [#700](https://github.com/rs/SDWebImage/pull/700)
- Fixed arm64 warnings - [#685](https://github.com/rs/SDWebImage/pull/685) [#720](https://github.com/rs/SDWebImage/pull/720) [#721](https://github.com/rs/SDWebImage/pull/721) [#687](https://github.com/rs/SDWebImage/pull/687)
- Improved logging - [#721](https://github.com/rs/SDWebImage/pull/721)
- Added `SDWebImageCompat.m` to `SDWebImage+MKAnnotation` target
## [3.6 Fix and cleanup on Mar 24th, 2014](https://github.com/rs/SDWebImage/releases/tag/3.6)
## [3.5.4 ARM64 Support on Feb 24th, 2014](https://github.com/rs/SDWebImage/releases/tag/3.5.4)
## [3.5.3 on Jan 7th, 2014](https://github.com/rs/SDWebImage/releases/tag/3.5.3)
## [3.5.2 on Jan 2nd, 2014](https://github.com/rs/SDWebImage/releases/tag/3.5.2)
## [3.5.1 on Dec 3rd, 2013](https://github.com/rs/SDWebImage/releases/tag/3.5.1)
## [3.5 WebP Target, iOS 7, Fixes on Oct 4th, 2013](https://github.com/rs/SDWebImage/releases/tag/3.5)
- Fix iOS 7 related issues
- Move `WebP` support to a dedicated target
- Removed strong reference to `UIImageView` which was causing a crash in the nested block
- Fix timeout issue
- Add some methods that allow to check if an image exists on disk without taking it off disk and decompressing it first
## [3.4 Animated image category, bug fixes on Aug 13th, 2013](https://github.com/rs/SDWebImage/releases/tag/3.4)
- Add `calculateSizeWithCompletionBlock`
- Add multiple download of images for animationImages property of `UIImageView`
- Add background task for disk cleanup [#306](https://github.com/rs/SDWebImage/issues/306)
- Fix dead thread issue on iOS 5 [#444](https://github.com/rs/SDWebImage/pull/444), [#399](https://github.com/rs/SDWebImage/issues/399), [#466](https://github.com/rs/SDWebImage/issues/466)
- Make IO operations cancelable to fix perf issue with heavy images [#462](https://github.com/rs/SDWebImage/issues/462)
- Fix crash `Collection <__NSArrayM: ...> was mutated while being enumerated.` [#471](https://github.com/rs/SDWebImage/pull/471)
## [3.3 WebP, Animated GIF and more on Jun 14th, 2013](https://github.com/rs/SDWebImage/releases/tag/3.3)
- WebP image format support [#410](https://github.com/rs/SDWebImage/issues/410)
- Animated GIF support [#375](https://github.com/rs/SDWebImage/pull/375)
- Custom image cache search paths [#156](https://github.com/rs/SDWebImage/pull/156)
- Bug fixes
## [3.2 Bug fixes on Mar 13th, 2013](https://github.com/rs/SDWebImage/releases/tag/3.2)
- `SDWebImageRefreshCached` download option [#326](https://github.com/rs/SDWebImage/pull/326)
- New `SDWebImageManager` delegate methods [ebd63a88c1](https://github.com/rs/SDWebImage/commit/ebd63a88c116ac7acfbeded5c84d0fffa2443438)
- Fix long standing issue with alpha en JPEGs [#299](https://github.com/rs/SDWebImage/pull/299)
- Add synchronous disk-cache loading method [#297](https://github.com/rs/SDWebImage/pull/297)
- Fix `SDWebImageCacheMemoryOnly` flag
- Bug fixes
## [3.1 Bug fixes on Jan 21st, 2013](https://github.com/rs/SDWebImage/releases/tag/3.1)
## [3.0 Complete rewrite on Nov 29th, 2012](https://github.com/rs/SDWebImage/releases/tag/3.0)
- Complete rewrite of the library using `GCD`, `ARC`, `NSCache` and blocks
- Drop compatibility with iOS 3 and 4
## [2.7.4 Bug fixes on Nov 14th, 2012](https://github.com/rs/SDWebImage/releases/tag/2.7.4)
## [2.7.3 on Nov 3rd, 2012](https://github.com/rs/SDWebImage/releases/tag/2.7.3)
## [2.7.2 on Oct 23rd, 2012](https://github.com/rs/SDWebImage/releases/tag/2.7.2)
## [2.7.1 on Oct 19th, 2012](https://github.com/rs/SDWebImage/releases/tag/2.7.1)
## [2.7 on Sep 8th, 2012](https://github.com/rs/SDWebImage/releases/tag/2.7)
## [2.6 on May 4th, 2012](https://github.com/rs/SDWebImage/releases/tag/2.6)
## [2.5 on Mar 22nd, 2012](https://github.com/rs/SDWebImage/releases/tag/2.5)
## [2.4 on Oct 1st, 2011](https://github.com/rs/SDWebImage/releases/tag/2.4)
## [2.3 on Sep 16th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.3)
## [2.2 on Aug 29th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.2)
## [2.1.0 on Jun 12th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.1.0)
## [2.1 on Jun 12th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.1)
## [2.0.0 on Jun 9th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.0.0)
## [2.0 on Jun 9th, 2010](https://github.com/rs/SDWebImage/releases/tag/2.0)
## [1.0.0 on Dec 31st, 2009](https://github.com/rs/SDWebImage/releases/tag/1.0.0)
## [1.0 on Dec 31st, 2009](https://github.com/rs/SDWebImage/releases/tag/1.0)

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -0,0 +1,434 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
3E75A9861742DBE700DA412D /* CustomPathImages in Resources */ = {isa = PBXBuildFile; fileRef = 3E75A9851742DBE700DA412D /* CustomPathImages */; };
531041C1157EAC8F00BBABC3 /* ImageIO.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537612E6155ABA44005750A4 /* ImageIO.framework */; };
5376129A155AB74D005750A4 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 53761299155AB74D005750A4 /* UIKit.framework */; };
5376129C155AB74D005750A4 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5376129B155AB74D005750A4 /* Foundation.framework */; };
5376129E155AB74D005750A4 /* CoreGraphics.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5376129D155AB74D005750A4 /* CoreGraphics.framework */; };
537612A6155AB74D005750A4 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 537612A5155AB74D005750A4 /* main.m */; };
537612AA155AB74D005750A4 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 537612A9155AB74D005750A4 /* AppDelegate.m */; };
537612AD155AB74D005750A4 /* MasterViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 537612AC155AB74D005750A4 /* MasterViewController.m */; };
537612B0155AB74D005750A4 /* DetailViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 537612AF155AB74D005750A4 /* DetailViewController.m */; };
537612B3155AB74D005750A4 /* MasterViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537612B1155AB74D005750A4 /* MasterViewController.xib */; };
537612B6155AB74D005750A4 /* DetailViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 537612B4155AB74D005750A4 /* DetailViewController.xib */; };
53A2B50D155B155A00B12423 /* placeholder.png in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B50B155B155A00B12423 /* placeholder.png */; };
53A2B50E155B155A00B12423 /* placeholder@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53A2B50C155B155A00B12423 /* placeholder@2x.png */; };
53EEC18916484553007601E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 53EEC18816484553007601E1 /* Default-568h@2x.png */; };
DA248D44195470FD00390AB0 /* MapKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 537612E3155ABA3C005750A4 /* MapKit.framework */; };
DA248D79195484A500390AB0 /* libSDWebImage+WebP.a in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D761954841D00390AB0 /* libSDWebImage+WebP.a */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
43A0FAAE1BDD16AC00B7582B /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
proxyType = 2;
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 */;
proxyType = 2;
remoteGlobalIDString = 53761325155AD0D5005750A4;
remoteInfo = SDWebImage;
};
DA248D751954841D00390AB0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 537D95C117ECC1FE0097C263;
remoteInfo = "SDWebImage+WebP";
};
DA248D771954841D00390AB0 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
proxyType = 2;
remoteGlobalIDString = 531041E0157EAFA400BBABC3;
remoteInfo = "SDWebImage+MKAnnotation";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
3E75A9851742DBE700DA412D /* CustomPathImages */ = {isa = PBXFileReference; lastKnownFileType = folder; path = CustomPathImages; sourceTree = SOURCE_ROOT; };
53761295155AB74D005750A4 /* SDWebImage Demo.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "SDWebImage Demo.app"; sourceTree = BUILT_PRODUCTS_DIR; };
53761299155AB74D005750A4 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; };
5376129B155AB74D005750A4 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = System/Library/Frameworks/Foundation.framework; sourceTree = SDKROOT; };
5376129D155AB74D005750A4 /* CoreGraphics.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreGraphics.framework; path = System/Library/Frameworks/CoreGraphics.framework; sourceTree = SDKROOT; };
537612A1155AB74D005750A4 /* SDWebImage Demo-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "SDWebImage Demo-Info.plist"; sourceTree = "<group>"; };
537612A5155AB74D005750A4 /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
537612A7155AB74D005750A4 /* SDWebImage Demo-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "SDWebImage Demo-Prefix.pch"; sourceTree = "<group>"; };
537612A8155AB74D005750A4 /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
537612A9155AB74D005750A4 /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
537612AB155AB74D005750A4 /* MasterViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MasterViewController.h; sourceTree = "<group>"; };
537612AC155AB74D005750A4 /* MasterViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = MasterViewController.m; sourceTree = "<group>"; };
537612AE155AB74D005750A4 /* DetailViewController.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = DetailViewController.h; sourceTree = "<group>"; };
537612AF155AB74D005750A4 /* DetailViewController.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = DetailViewController.m; sourceTree = "<group>"; };
537612B2155AB74D005750A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/MasterViewController.xib; sourceTree = "<group>"; };
537612B5155AB74D005750A4 /* en */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = en; path = en.lproj/DetailViewController.xib; sourceTree = "<group>"; };
537612E3155ABA3C005750A4 /* MapKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = MapKit.framework; path = System/Library/Frameworks/MapKit.framework; sourceTree = SDKROOT; };
537612E6155ABA44005750A4 /* ImageIO.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ImageIO.framework; path = System/Library/Frameworks/ImageIO.framework; sourceTree = SDKROOT; };
53A2B50B155B155A00B12423 /* placeholder.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = placeholder.png; sourceTree = "<group>"; };
53A2B50C155B155A00B12423 /* placeholder@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "placeholder@2x.png"; sourceTree = "<group>"; };
53EEC18816484553007601E1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "Default-568h@2x.png"; path = "../Default-568h@2x.png"; sourceTree = "<group>"; };
DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = SDWebImage.xcodeproj; path = ../SDWebImage.xcodeproj; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
53761292155AB74D005750A4 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DA248D79195484A500390AB0 /* libSDWebImage+WebP.a in Frameworks */,
DA248D44195470FD00390AB0 /* MapKit.framework in Frameworks */,
531041C1157EAC8F00BBABC3 /* ImageIO.framework in Frameworks */,
5376129A155AB74D005750A4 /* UIKit.framework in Frameworks */,
5376129C155AB74D005750A4 /* Foundation.framework in Frameworks */,
5376129E155AB74D005750A4 /* CoreGraphics.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
5376128A155AB74D005750A4 = {
isa = PBXGroup;
children = (
DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */,
5376129F155AB74D005750A4 /* SDWebImage Demo */,
53761298155AB74D005750A4 /* Frameworks */,
53761296155AB74D005750A4 /* Products */,
);
sourceTree = "<group>";
};
53761296155AB74D005750A4 /* Products */ = {
isa = PBXGroup;
children = (
53761295155AB74D005750A4 /* SDWebImage Demo.app */,
);
name = Products;
sourceTree = "<group>";
};
53761298155AB74D005750A4 /* Frameworks */ = {
isa = PBXGroup;
children = (
537612E6155ABA44005750A4 /* ImageIO.framework */,
537612E3155ABA3C005750A4 /* MapKit.framework */,
53761299155AB74D005750A4 /* UIKit.framework */,
5376129B155AB74D005750A4 /* Foundation.framework */,
5376129D155AB74D005750A4 /* CoreGraphics.framework */,
);
name = Frameworks;
sourceTree = "<group>";
};
5376129F155AB74D005750A4 /* SDWebImage Demo */ = {
isa = PBXGroup;
children = (
3E75A9851742DBE700DA412D /* CustomPathImages */,
537612A8155AB74D005750A4 /* AppDelegate.h */,
537612A9155AB74D005750A4 /* AppDelegate.m */,
537612AB155AB74D005750A4 /* MasterViewController.h */,
537612AC155AB74D005750A4 /* MasterViewController.m */,
537612AE155AB74D005750A4 /* DetailViewController.h */,
537612AF155AB74D005750A4 /* DetailViewController.m */,
537612B1155AB74D005750A4 /* MasterViewController.xib */,
537612B4155AB74D005750A4 /* DetailViewController.xib */,
537612A0155AB74D005750A4 /* Supporting Files */,
);
path = "SDWebImage Demo";
sourceTree = "<group>";
};
537612A0155AB74D005750A4 /* Supporting Files */ = {
isa = PBXGroup;
children = (
53EEC18816484553007601E1 /* Default-568h@2x.png */,
537612A1155AB74D005750A4 /* SDWebImage Demo-Info.plist */,
537612A5155AB74D005750A4 /* main.m */,
537612A7155AB74D005750A4 /* SDWebImage Demo-Prefix.pch */,
53A2B50B155B155A00B12423 /* placeholder.png */,
53A2B50C155B155A00B12423 /* placeholder@2x.png */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
DA248D6D1954841D00390AB0 /* Products */ = {
isa = PBXGroup;
children = (
DA248D741954841D00390AB0 /* libSDWebImage.a */,
DA248D761954841D00390AB0 /* libSDWebImage+WebP.a */,
DA248D781954841D00390AB0 /* libSDWebImage+MKAnnotation.a */,
43A0FAAF1BDD16AC00B7582B /* WebImage.framework */,
43AEAFAA1D008FEE005B41A8 /* WebImage.framework */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
53761294155AB74D005750A4 /* SDWebImage Demo */ = {
isa = PBXNativeTarget;
buildConfigurationList = 537612B9155AB74D005750A4 /* Build configuration list for PBXNativeTarget "SDWebImage Demo" */;
buildPhases = (
53761291155AB74D005750A4 /* Sources */,
53761292155AB74D005750A4 /* Frameworks */,
53761293155AB74D005750A4 /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "SDWebImage Demo";
productName = "SDWebImage Demo";
productReference = 53761295155AB74D005750A4 /* SDWebImage Demo.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
5376128C155AB74D005750A4 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0710;
ORGANIZATIONNAME = Dailymotion;
};
buildConfigurationList = 5376128F155AB74D005750A4 /* Build configuration list for PBXProject "SDWebImage Demo" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 5376128A155AB74D005750A4;
productRefGroup = 53761296155AB74D005750A4 /* Products */;
projectDirPath = "";
projectReferences = (
{
ProductGroup = DA248D6D1954841D00390AB0 /* Products */;
ProjectRef = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */;
},
);
projectRoot = "";
targets = (
53761294155AB74D005750A4 /* SDWebImage Demo */,
);
};
/* End PBXProject section */
/* Begin PBXReferenceProxy section */
43A0FAAF1BDD16AC00B7582B /* WebImage.framework */ = {
isa = PBXReferenceProxy;
fileType = wrapper.framework;
path = WebImage.framework;
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;
path = libSDWebImage.a;
remoteRef = DA248D731954841D00390AB0 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
DA248D761954841D00390AB0 /* libSDWebImage+WebP.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libSDWebImage+WebP.a";
remoteRef = DA248D751954841D00390AB0 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
DA248D781954841D00390AB0 /* libSDWebImage+MKAnnotation.a */ = {
isa = PBXReferenceProxy;
fileType = archive.ar;
path = "libSDWebImage+MKAnnotation.a";
remoteRef = DA248D771954841D00390AB0 /* PBXContainerItemProxy */;
sourceTree = BUILT_PRODUCTS_DIR;
};
/* End PBXReferenceProxy section */
/* Begin PBXResourcesBuildPhase section */
53761293155AB74D005750A4 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
537612B3155AB74D005750A4 /* MasterViewController.xib in Resources */,
537612B6155AB74D005750A4 /* DetailViewController.xib in Resources */,
53A2B50D155B155A00B12423 /* placeholder.png in Resources */,
53A2B50E155B155A00B12423 /* placeholder@2x.png in Resources */,
53EEC18916484553007601E1 /* Default-568h@2x.png in Resources */,
3E75A9861742DBE700DA412D /* CustomPathImages in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
53761291155AB74D005750A4 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
537612A6155AB74D005750A4 /* main.m in Sources */,
537612AA155AB74D005750A4 /* AppDelegate.m in Sources */,
537612AD155AB74D005750A4 /* MasterViewController.m in Sources */,
537612B0155AB74D005750A4 /* DetailViewController.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
537612B1155AB74D005750A4 /* MasterViewController.xib */ = {
isa = PBXVariantGroup;
children = (
537612B2155AB74D005750A4 /* en */,
);
name = MasterViewController.xib;
sourceTree = "<group>";
};
537612B4155AB74D005750A4 /* DetailViewController.xib */ = {
isa = PBXVariantGroup;
children = (
537612B5155AB74D005750A4 /* en */,
);
name = DetailViewController.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
537612B7155AB74D005750A4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = "compiler-default";
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
};
name = Debug;
};
537612B8155AB74D005750A4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ENABLE_OBJC_ARC = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = YES;
GCC_C_LANGUAGE_STANDARD = "compiler-default";
GCC_VERSION = "";
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 7.0;
OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
537612BA155AB74D005750A4 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SDWebImage Demo/SDWebImage Demo-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
HEADER_SEARCH_PATHS = (
"\"$(OBJROOT)/UninstalledProducts/include\"",
"\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
);
INFOPLIST_FILE = "SDWebImage Demo/SDWebImage Demo-Info.plist";
OTHER_CFLAGS = "";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.dailymotion.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Debug;
};
537612BB155AB74D005750A4 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"\"$(SRCROOT)\"",
);
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "SDWebImage Demo/SDWebImage Demo-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = "";
HEADER_SEARCH_PATHS = (
"\"$(OBJROOT)/UninstalledProducts/include\"",
"\"$(TARGET_BUILD_DIR)/usr/local/lib/include\"",
);
INFOPLIST_FILE = "SDWebImage Demo/SDWebImage Demo-Info.plist";
OTHER_LDFLAGS = "-ObjC";
PRODUCT_BUNDLE_IDENTIFIER = "com.dailymotion.${PRODUCT_NAME:rfc1034identifier}";
PRODUCT_NAME = "$(TARGET_NAME)";
WRAPPER_EXTENSION = app;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
5376128F155AB74D005750A4 /* Build configuration list for PBXProject "SDWebImage Demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
537612B7155AB74D005750A4 /* Debug */,
537612B8155AB74D005750A4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
537612B9155AB74D005750A4 /* Build configuration list for PBXNativeTarget "SDWebImage Demo" */ = {
isa = XCConfigurationList;
buildConfigurations = (
537612BA155AB74D005750A4 /* Debug */,
537612BB155AB74D005750A4 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 5376128C155AB74D005750A4 /* Project object */;
}

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:SDWebImage Demo.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,17 @@
//
// AppDelegate.h
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface AppDelegate : UIResponder <UIApplicationDelegate>
@property (strong, nonatomic) UIWindow *window;
@property (strong, nonatomic) UINavigationController *navigationController;
@end

View File

@ -0,0 +1,63 @@
//
// AppDelegate.m
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "AppDelegate.h"
#import "MasterViewController.h"
#import <SDWebImage/SDImageCache.h>
@implementation AppDelegate
@synthesize window = _window;
@synthesize navigationController = _navigationController;
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
//Add a custom read-only cache path
NSString *bundledPath = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:@"CustomPathImages"];
[[SDImageCache sharedImageCache] addReadOnlyCachePath:bundledPath];
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
// Override point for customization after application launch.
MasterViewController *masterViewController = [[MasterViewController alloc] initWithNibName:@"MasterViewController" bundle:nil];
self.navigationController = [[UINavigationController alloc] initWithRootViewController:masterViewController];
self.window.rootViewController = self.navigationController;
[self.window makeKeyAndVisible];
return YES;
}
- (void)applicationWillResignActive:(UIApplication *)application
{
// Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
// Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
}
- (void)applicationDidEnterBackground:(UIApplication *)application
{
// Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
// If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
}
- (void)applicationWillEnterForeground:(UIApplication *)application
{
// Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
// Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
}
- (void)applicationWillTerminate:(UIApplication *)application
{
// Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
}
@end

View File

@ -0,0 +1,17 @@
//
// DetailViewController.h
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface DetailViewController : UIViewController
@property (strong, nonatomic) NSURL *imageURL;
@property (strong, nonatomic) IBOutlet UIImageView *imageView;
@end

View File

@ -0,0 +1,71 @@
//
// DetailViewController.m
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "DetailViewController.h"
#import <SDWebImage/UIImageView+WebCache.h>
@interface DetailViewController ()
- (void)configureView;
@end
@implementation DetailViewController
@synthesize imageURL = _imageURL;
@synthesize imageView = _imageView;
#pragma mark - Managing the detail item
- (void)setImageURL:(NSURL *)imageURL
{
if (_imageURL != imageURL)
{
_imageURL = imageURL;
[self configureView];
}
}
- (void)configureView
{
if (self.imageURL) {
__block UIActivityIndicatorView *activityIndicator;
__weak UIImageView *weakImageView = self.imageView;
[self.imageView sd_setImageWithURL:self.imageURL
placeholderImage:nil
options:SDWebImageProgressiveDownload
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
if (!activityIndicator) {
[weakImageView addSubview:activityIndicator = [UIActivityIndicatorView.alloc initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray]];
activityIndicator.center = weakImageView.center;
[activityIndicator startAnimating];
}
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
[activityIndicator removeFromSuperview];
activityIndicator = nil;
}];
}
}
- (void)viewDidLoad
{
[super viewDidLoad];
[self configureView];
}
- (void)viewDidUnload
{
[super viewDidUnload];
self.imageView = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
@end

View File

@ -0,0 +1,17 @@
//
// MasterViewController.h
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
@class DetailViewController;
@interface MasterViewController : UITableViewController
@property (strong, nonatomic) DetailViewController *detailViewController;
@end

View File

@ -0,0 +1,109 @@
//
// MasterViewController.m
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "MasterViewController.h"
#import <SDWebImage/UIImageView+WebCache.h>
#import "DetailViewController.h"
@interface MasterViewController () {
NSMutableArray *_objects;
}
@end
@implementation MasterViewController
@synthesize detailViewController = _detailViewController;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self)
{
self.title = @"SDWebImage";
self.navigationItem.rightBarButtonItem = [UIBarButtonItem.alloc initWithTitle:@"Clear Cache"
style:UIBarButtonItemStylePlain
target:self
action:@selector(flushCache)];
// HTTP NTLM auth example
// Add your NTLM image url to the array below and replace the credentials
[SDWebImageManager sharedManager].imageDownloader.username = @"httpwatch";
[SDWebImageManager sharedManager].imageDownloader.password = @"httpwatch01";
_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",
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;
return self;
}
- (void)flushCache
{
[SDWebImageManager.sharedManager.imageCache clearMemory];
[SDWebImageManager.sharedManager.imageCache clearDisk];
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
return (interfaceOrientation != UIInterfaceOrientationPortraitUpsideDown);
}
#pragma mark - Table View
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return _objects.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
[cell.imageView setShowActivityIndicatorView:YES];
[cell.imageView setIndicatorStyle:UIActivityIndicatorViewStyleGray];
cell.textLabel.text = [NSString stringWithFormat:@"Image #%ld", (long)indexPath.row];
cell.imageView.contentMode = UIViewContentModeScaleAspectFill;
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:[_objects objectAtIndex:indexPath.row]]
placeholderImage:[UIImage imageNamed:@"placeholder"] options:indexPath.row == 0 ? SDWebImageRefreshCached : 0];
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (!self.detailViewController)
{
self.detailViewController = [[DetailViewController alloc] initWithNibName:@"DetailViewController" bundle:nil];
}
NSString *largeImageURL = [[_objects objectAtIndex:indexPath.row] stringByReplacingOccurrencesOfString:@"small" withString:@"source"];
self.detailViewController.imageURL = [NSURL URLWithString:largeImageURL];
[self.navigationController pushViewController:self.detailViewController animated:YES];
}
@end

View File

@ -0,0 +1,43 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleDisplayName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>${PRODUCT_NAME}</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>LSRequiresIPhoneOS</key>
<true/>
<key>NSAppTransportSecurity</key>
<dict>
<key>NSAllowsArbitraryLoads</key>
<true/>
</dict>
<key>UIRequiredDeviceCapabilities</key>
<array>
<string>armv7</string>
</array>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
</dict>
</plist>

View File

@ -0,0 +1,14 @@
//
// Prefix header for all source files of the 'SDWebImage Demo' target in the 'SDWebImage Demo' project
//
#import <Availability.h>
#ifndef __IPHONE_4_0
#warning "This project uses features only available in iOS SDK 4.0 and later."
#endif
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

View File

@ -0,0 +1,164 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1296</int>
<string key="IBDocument.SystemVersion">11D50b</string>
<string key="IBDocument.InterfaceBuilderVersion">2182</string>
<string key="IBDocument.AppKitVersion">1138.32</string>
<string key="IBDocument.HIToolboxVersion">568.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">1181</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUIView</string>
<string>IBUIImageView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="372490531">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="975951072">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUIView" id="191373211">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<array class="NSMutableArray" key="NSSubviews">
<object class="IBUIImageView" id="268130440">
<reference key="NSNextResponder" ref="191373211"/>
<int key="NSvFlags">274</int>
<string key="NSFrameSize">{320, 460}</string>
<reference key="NSSuperview" ref="191373211"/>
<reference key="NSWindow"/>
<string key="NSReuseIdentifierKey">_NS:9</string>
<int key="IBUIContentMode">1</int>
<bool key="IBUIUserInteractionEnabled">NO</bool>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
<object class="NSColorSpace" key="NSCustomColorSpace">
<int key="NSID">2</int>
</object>
</object>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="191373211"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">imageView</string>
<reference key="source" ref="372490531"/>
<reference key="destination" ref="268130440"/>
</object>
<int key="connectionID">8</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">1</int>
<reference key="object" ref="191373211"/>
<array class="NSMutableArray" key="children">
<reference ref="268130440"/>
</array>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="372490531"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="975951072"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">7</int>
<reference key="object" ref="268130440"/>
<reference key="parent" ref="191373211"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">DetailViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="7.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">8</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">DetailViewController</string>
<string key="superclassName">UIViewController</string>
<object class="NSMutableDictionary" key="outlets">
<string key="NS.key.0">imageView</string>
<string key="NS.object.0">UIImageView</string>
</object>
<object class="NSMutableDictionary" key="toOneOutletInfosByName">
<string key="NS.key.0">imageView</string>
<object class="IBToOneOutletInfo" key="NS.object.0">
<string key="name">imageView</string>
<string key="candidateClassName">UIImageView</string>
</object>
</object>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/DetailViewController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<object class="NSMutableDictionary" key="IBDocument.PluginDeclaredDependencyDefaults">
<string key="NS.key.0">com.apple.InterfaceBuilder.CocoaTouchPlugin.iPhoneOS</string>
<real value="1296" key="NS.object.0"/>
</object>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">1181</string>
</data>
</archive>

View File

@ -0,0 +1,139 @@
<?xml version="1.0" encoding="UTF-8"?>
<archive type="com.apple.InterfaceBuilder3.CocoaTouch.XIB" version="8.00">
<data>
<int key="IBDocument.SystemTarget">1280</int>
<string key="IBDocument.SystemVersion">11C25</string>
<string key="IBDocument.InterfaceBuilderVersion">1919</string>
<string key="IBDocument.AppKitVersion">1138.11</string>
<string key="IBDocument.HIToolboxVersion">566.00</string>
<object class="NSMutableDictionary" key="IBDocument.PluginVersions">
<string key="NS.key.0">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="NS.object.0">916</string>
</object>
<array key="IBDocument.IntegratedClassDependencies">
<string>IBProxyObject</string>
<string>IBUITableView</string>
</array>
<array key="IBDocument.PluginDependencies">
<string>com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</array>
<object class="NSMutableDictionary" key="IBDocument.Metadata">
<string key="NS.key.0">PluginDependencyRecalculationVersion</string>
<integer value="1" key="NS.object.0"/>
</object>
<array class="NSMutableArray" key="IBDocument.RootObjects" id="1000">
<object class="IBProxyObject" id="841351856">
<string key="IBProxiedObjectIdentifier">IBFilesOwner</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBProxyObject" id="371349661">
<string key="IBProxiedObjectIdentifier">IBFirstResponder</string>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
</object>
<object class="IBUITableView" id="709618507">
<reference key="NSNextResponder"/>
<int key="NSvFlags">274</int>
<string key="NSFrame">{{0, 20}, {320, 460}}</string>
<reference key="NSSuperview"/>
<reference key="NSWindow"/>
<object class="NSColor" key="IBUIBackgroundColor">
<int key="NSColorSpace">3</int>
<bytes key="NSWhite">MQA</bytes>
</object>
<bool key="IBUIClipsSubviews">YES</bool>
<object class="IBUISimulatedStatusBarMetrics" key="IBUISimulatedStatusBarMetrics"/>
<string key="targetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBUIAlwaysBounceVertical">YES</bool>
<int key="IBUISeparatorStyle">1</int>
<int key="IBUISectionIndexMinimumDisplayRowCount">0</int>
<bool key="IBUIShowsSelectionImmediatelyOnTouchBegin">YES</bool>
<float key="IBUIRowHeight">44</float>
<float key="IBUISectionHeaderHeight">22</float>
<float key="IBUISectionFooterHeight">22</float>
</object>
</array>
<object class="IBObjectContainer" key="IBDocument.Objects">
<array class="NSMutableArray" key="connectionRecords">
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">view</string>
<reference key="source" ref="841351856"/>
<reference key="destination" ref="709618507"/>
</object>
<int key="connectionID">3</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">dataSource</string>
<reference key="source" ref="709618507"/>
<reference key="destination" ref="841351856"/>
</object>
<int key="connectionID">4</int>
</object>
<object class="IBConnectionRecord">
<object class="IBCocoaTouchOutletConnection" key="connection">
<string key="label">delegate</string>
<reference key="source" ref="709618507"/>
<reference key="destination" ref="841351856"/>
</object>
<int key="connectionID">5</int>
</object>
</array>
<object class="IBMutableOrderedSet" key="objectRecords">
<array key="orderedObjects">
<object class="IBObjectRecord">
<int key="objectID">0</int>
<array key="object" id="0"/>
<reference key="children" ref="1000"/>
<nil key="parent"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">-1</int>
<reference key="object" ref="841351856"/>
<reference key="parent" ref="0"/>
<string key="objectName">File's Owner</string>
</object>
<object class="IBObjectRecord">
<int key="objectID">-2</int>
<reference key="object" ref="371349661"/>
<reference key="parent" ref="0"/>
</object>
<object class="IBObjectRecord">
<int key="objectID">2</int>
<reference key="object" ref="709618507"/>
<reference key="parent" ref="0"/>
</object>
</array>
</object>
<dictionary class="NSMutableDictionary" key="flattenedProperties">
<string key="-1.CustomClassName">MasterViewController</string>
<string key="-1.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="-2.CustomClassName">UIResponder</string>
<string key="-2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
<string key="2.IBPluginDependency">com.apple.InterfaceBuilder.IBCocoaTouchPlugin</string>
</dictionary>
<dictionary class="NSMutableDictionary" key="unlocalizedProperties"/>
<nil key="activeLocalization"/>
<dictionary class="NSMutableDictionary" key="localizations"/>
<nil key="sourceID"/>
<int key="maxID">5</int>
</object>
<object class="IBClassDescriber" key="IBDocument.Classes">
<array class="NSMutableArray" key="referencedPartialClassDescriptions">
<object class="IBPartialClassDescription">
<string key="className">MasterViewController</string>
<string key="superclassName">UITableViewController</string>
<object class="IBClassDescriptionSource" key="sourceIdentifier">
<string key="majorKey">IBProjectSource</string>
<string key="minorKey">./Classes/MasterViewController.h</string>
</object>
</object>
</array>
</object>
<int key="IBDocument.localizationMode">0</int>
<string key="IBDocument.TargetRuntimeIdentifier">IBCocoaTouchFramework</string>
<bool key="IBDocument.PluginDeclaredDependenciesTrackSystemTargetVersion">YES</bool>
<int key="IBDocument.defaultPropertyAccessControl">3</int>
<string key="IBCocoaTouchPluginVersion">916</string>
</data>
</archive>

View File

@ -0,0 +1,18 @@
//
// main.m
// SDWebImage Demo
//
// Created by Olivier Poitrey on 09/05/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char *argv[])
{
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -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

380
README.md
View File

@ -1,168 +1,334 @@
Web Image
=========
[![Build Status](http://img.shields.io/travis/rs/SDWebImage/master.svg?style=flat)](https://travis-ci.org/rs/SDWebImage)
[![Pod Version](http://img.shields.io/cocoapods/v/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
[![Pod Platform](http://img.shields.io/cocoapods/p/SDWebImage.svg?style=flat)](http://cocoadocs.org/docsets/SDWebImage/)
[![Pod License](http://img.shields.io/cocoapods/l/SDWebImage.svg?style=flat)](https://www.apache.org/licenses/LICENSE-2.0.html)
[![Dependency Status](https://www.versioneye.com/objective-c/sdwebimage/3.3/badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/3.3)
[![Reference Status](https://www.versioneye.com/objective-c/sdwebimage/reference_badge.svg?style=flat)](https://www.versioneye.com/objective-c/sdwebimage/references)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/rs/SDWebImage)
This library provides a category for UIImageVIew with support for remote images coming from the web.
This library provides a category for UIImageView with support for remote images coming from the web.
It provides:
- An UIImageView category adding web image and cache management to the Cocoa Touch framework
- An `UIImageView` category adding web image and cache management to the Cocoa Touch framework
- An asynchronous image downloader
- An asynchronous memory + disk image caching with automatic cache expiration handling
- A garantie that the same URL won't be downloaded several times
- A garantie that bogus URLs won't be retried again and again
- Animated GIF support
- WebP format support
- A background image decompression
- A guarantee that the same URL won't be downloaded several times
- A guarantee that bogus URLs won't be retried again and again
- A guarantee that main thread will never be blocked
- Performances!
- Use GCD and ARC
- Arm64 support
Motivation
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 Uses It
----------
As a dummy Objective-C developer working on my first iPhone application for my company
([Dailymotion][]), I've been very frustrated by the lack of support in the Cocoa Touch framework for
UITableView with remote images. After some googling, I found lot of forums and blogs coming with
their solution, most of the time based on asynchronous usage have NSURLConnection, but none provides
a simple library doing the work of async image grabbing + caching for you.
Find out [who uses SDWebImage](https://github.com/rs/SDWebImage/wiki/Who-Uses-SDWebImage) and add your app to the list.
Actually there is one in the famous [Three20][] framework by [Joe Hewitt][], but it's yet massive
and undocumented piece of code. You can't import just the the libraries you want without taking the
whole framework (damn #import "TTGlobal.h"). Anyway, the [Three20][] implementation is based on
NSURLConnection, and I soon discovered this solution wasn't ideal, keep reading to find out why.
How To Use
----------
As a hurried beginner in iPhone development, I couldn't admit to implement my own async image
grabber with caching support as my first steps in this new world. Thus, I asked for help to my good
friend Sebastien Flory ([Fraggle][]), who was working on his great iPhone game ([Urban Rivals][], a
future app-store hit) since almost a year. He spent quite an amount of time on implementing the very
same solution for his needs, and was kind enough to give me his implementation for my own use. This
worked quite well and allowed me to concentrate on other parts of my application. But when I started
to compare my application with its direct competitor - the built-in Youtube application - I was very
unhappy with the loading speed of the images. After some network sniffing, I found that every HTTP
requests for my images was 10 times slower than Youtube's ones... On my own network, Youtube was 10
time faster than my own servers... WTF??
In fact, my servers were well but a lot of latency was added to the requests, certainly because my
application wasn't responsive enough to handle the requests at full speed. At this moment, I
understood something important, asynchronous NSURLConnections are tied to the main runloop in the
NSEventTrackingRunLoopMode. As explained in the documentation, this runloop mode is affected by
UI events:
> Cocoa uses this mode to restrict incoming events during mouse-dragging loops and other sorts of
> user interface tracking loops.
A simple test to recognize an application using NSURLConnection in its default mode to load there
remote images is to scroll the UITableView with your finger to disclose an unloaded image, and to
keep your finger pressed on the screen. If the image doesn't load until you release you finger,
you've got one (try with the Facebook app for instance). It took me quite some time to understand
the reason for this lagging issue. Actually I first used NSOperation to workaround this issue.
This technic combined with an image cache instantly gave a lot of responsiveness to my app.
I thought this lib could benefits to a lot of other Cocoa Touch application so I open-sourced it.
How To Use It
-------------
API documentation is available at [CocoaDocs - SDWebImage](http://cocoadocs.org/docsets/SDWebImage/)
### Using UIImageView+WebCache category with UITableView
Just #import the UIImageView+WebCache.h header, and call the setImageWithURL:placeholderImage:
Just #import the UIImageView+WebCache.h header, and call the sd_setImageWithURL:placeholderImage:
method from the tableView:cellForRowAtIndexPath: UITableViewDataSource method. Everything will be
handled for you, from async downloads to caching management.
#import "UIImageView+WebCache.h"
```objective-c
#import <SDWebImage/UIImageView+WebCache.h>
...
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided setImageWithURL: method to load the web image
[cell.imageView setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease];
}
// Here we use the new provided sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]];
cell.textLabel.text = @"My Text";
return cell;
}
```
### Using blocks
With blocks, you can be notified about the image download progress and whenever the image retrieval
has completed with success or not:
```objective-c
// Here we use the new provided sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
... completion code here ...
}];
```
Note: neither your success nor failure block will be call if your image request is canceled before completion.
### Using SDWebImageManager
The SDWebImageManager is the class behind the UIImageView+WebCache category. It ties the
asynchronous downloader with the image cache store. You can use this classe directly to benefits
from web image downloading with caching in another context than a UIView (ie: with Cocos).
asynchronous downloader with the image cache store. You can use this class directly to benefit
from web image downloading with caching in another context than a UIView (ie: with Cocoa).
Here is a simple example of how to use SDWebImageManager:
SDWebImageManager *manager = [SDWebImageManager sharedManager];
UIImage *cachedImage = [manager imageWithURL:url];
if (cachedImage)
{
// Use the cached image immediatly
}
else
{
// Start an async download
[manager downloadWithURL:url delegate:self];
}
Your class will have to implement the SDWebImageManagerDelegate protocol, and to implement the
imageHelper:didFinishWithImage: method from this protocol:
- (void)imageHelper:(SDWebImageManager *)imageHelper didFinishWithImage:(UIImage *)image
{
// Do something with the downloaded image
}
```objective-c
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:imageURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// do something with image
}
}];
```
### Using Asynchronous Image Downloader Independently
It is possible to use the async image downloader independently. You just have to create an instance
of SDWebImageDownloader using its convenience constructor downloaderWithURL:delegate:.
It's also possible to use the async image downloader independently:
downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];
The download will start immediately and the imageDownloader:didFinishWithImage: method from the
SDWebImageDownloaderDelegate protocol will be called as soon as the download of image is completed.
```objective-c
SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
[downloader downloadImageWithURL:imageURL
options:0
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code
}
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
if (image && finished) {
// do something with image
}
}];
```
### Using Asynchronous Image Caching Independently
It is also possible to use the NSOperation based image cache store independently. SDImageCache
It is also possible to use the async based image cache store independently. SDImageCache
maintains a memory cache and an optional disk cache. Disk cache write operations are performed
asynchronous so it doesn't add unnecessary latency to the UI.
The SDImageCache class provides a singleton instance for convenience but you can create your own
instance if you want to create separated cache namespaces.
instance if you want to create separated cache namespace.
To lookup the cache, you use the imageForKey: method. If the method returns nil, it means the cache
doesn't currently own the image. You are thus responsible of generating and caching it. The cache
To lookup the cache, you use the `queryDiskCacheForKey:done:` method. If the method returns nil, it means the cache
doesn't currently own the image. You are thus responsible for generating and caching it. The cache
key is an application unique identifier for the image to cache. It is generally the absolute URL of
the image.
UIImage *myCachedImage = [[SDImageCache sharedImageCache] imageFromKey:myCacheKey];
```objective-c
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"];
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) {
// image is not nil if image was found
}];
```
By default SDImageCache will lookup the disk cache if an image can't be found in the memory cache.
You can prevent this from happening by calling the alternative method imageFromKey:fromDisk: with a
negative second argument.
You can prevent this from happening by calling the alternative method `imageFromMemoryCacheForKey:`.
To store an image into the cache, you use the storeImage:forKey: method:
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
```objective-c
[[SDImageCache sharedImageCache] storeImage:myImage forKey:myCacheKey];
```
By default, the image will be stored in memory cache as well as on disk cache (asynchronously). If
you want only the memory cache, use the alternative method storeImage:forKey:toDisk: with a negative
third argument.
### Using cache key filter
Sometime, you may not want to use the image URL as cache key because part of the URL is dynamic
(i.e.: for access control purpose). SDWebImageManager provides a way to set a cache key filter that
takes the NSURL as input, and output a cache key NSString.
The following example sets a filter in the application delegate that will remove any query-string from
the URL before to use it as a cache key:
```objective-c
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString];
};
// Your app init code...
return YES;
}
```
Common Problems
---------------
### Using dynamic image size with UITableViewCell
UITableView determines the size of the image by the first image set for a cell. If your remote images
don't have the same size as your placeholder image, you may experience strange anamorphic scaling issue.
The following article gives a way to workaround this issue:
[http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/](http://www.wrichards.com/blog/2011/11/sdwebimage-fixed-width-cell-images/)
### Handle image refresh
SDWebImage does very aggressive caching by default. It ignores all kind of caching control header returned by the HTTP server and cache the returned images with no time restriction. It implies your images URLs are static URLs pointing to images that never change. If the pointed image happen to change, some parts of the URL should change accordingly.
If you don't control the image server you're using, you may not be able to change the URL when its content is updated. This is the case for Facebook avatar URLs for instance. In such case, you may use the `SDWebImageRefreshCached` flag. This will slightly degrade the performance but will respect the HTTP caching control headers:
``` objective-c
[imageView sd_setImageWithURL:[NSURL URLWithString:@"https://graph.facebook.com/olivier.poitrey/picture"]
placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]
options:SDWebImageRefreshCached];
```
### Add a progress indicator
See this category: https://github.com/JJSaccolo/UIActivityIndicator-for-SDWebImage
Installation
------------
There are three ways to use SDWebImage in your project:
- using CocoaPods
- copying all the files into your project
- importing the project as a static library
### Installation with CocoaPods
[CocoaPods](http://cocoapods.org/) is a dependency manager for Objective-C, which automates and simplifies the process of using 3rd-party libraries in your projects. See the [Get Started](http://cocoapods.org/#get_started) section for more details.
#### Podfile
```
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+:
```
platform :ios, '8.0'
use_frameworks!
```
#### Subspecs
There are 3 subspecs available now: `Core`, `MapKit` and `WebP` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `WebP`, you need to specify it).
Podfile example:
```
pod 'SDWebImage/WebP'
```
### Installation with Carthage (iOS 8+)
[Carthage](https://github.com/Carthage/Carthage) is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods.
To install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage)
#### Cartfile
```
github "rs/SDWebImage"
```
#### Usage
Swift
If you installed using CocoaPods:
```
import SDWebImage
```
If you installed manually:
```
import WebImage
```
Objective-C
```
@import WebImage;
```
### Installation by cloning the repository
In order to gain access to all the files from the repository, you should clone it.
```
git clone --recursive https://github.com/rs/SDWebImage.git
```
### Add the SDWebImage project to your project
- Download and unzip the last version of the framework from the [download page](https://github.com/rs/SDWebImage/releases)
- Right-click on the project navigator and select "Add Files to "Your Project":
- In the dialog, select SDWebImage.framework:
- Check the "Copy items into destination group's folder (if needed)" checkbox
### Add dependencies
- In you application project apps target settings, find the "Build Phases" section and open the "Link Binary With Libraries" block:
- Click the "+" button again and select the "ImageIO.framework", this is needed by the progressive download feature:
### Add Linker Flag
Open the "Build Settings" tab, in the "Linking" section, locate the "Other Linker Flags" setting and add the "-ObjC" flag:
![Other Linker Flags](http://dl.dropbox.com/u/123346/SDWebImage/10_other_linker_flags.jpg)
Alternatively, if this causes compilation problems with frameworks that extend optional libraries, such as Parse, RestKit or opencv2, instead of the -ObjC flag use:
```
-force_load SDWebImage.framework/Versions/Current/SDWebImage
```
If you're using Cocoa Pods and have any frameworks that extend optional libraries, such as Parsen RestKit or opencv2, instead of the -ObjC flag use:
```
-force_load $(TARGET_BUILD_DIR)/libPods.a
```
and this:
```
$(inherited)
```
### Import headers in your source files
In the source files where you need to use the library, import the header file:
```objective-c
#import <SDWebImage/UIImageView+WebCache.h>
```
### Build Project
At this point your workspace should build without error. If you are having problem, post to the Issue and the
community can help you solve it.
Future Enhancements
-------------------
- LRU memory cache cleanup instead of reset on memory warning
[Dailymotion]: http://www.dailymotion.com
[Fraggle]: http://fraggle.squarespace.com
[Urban Rivals]: http://fraggle.squarespace.com/blog/2009/9/15/almost-done-here-is-urban-rivals-iphone-trailer.html
[Three20]: http://groups.google.com/group/three20
[Joe Hewitt]: http://www.joehewitt.com
## Licenses
All source code is licensed under the [MIT License](https://raw.github.com/rs/SDWebImage/master/LICENSE).

View File

@ -1,28 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
@interface SDImageCache : NSObject
{
NSMutableDictionary *memCache;
NSString *diskCachePath;
NSOperationQueue *cacheInQueue;
}
+ (SDImageCache *)sharedImageCache;
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
- (UIImage *)imageFromKey:(NSString *)key;
- (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk;
- (void)removeImageForKey:(NSString *)key;
- (void)clearMemory;
- (void)clearDisk;
- (void)cleanDisk;
@end

View File

@ -1,206 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDImageCache.h"
#import <CommonCrypto/CommonDigest.h>
static NSInteger cacheMaxCacheAge = 60*60*24*7; // 1 week
static SDImageCache *instance;
@implementation SDImageCache
#pragma mark NSObject
- (id)init
{
if ((self = [super init]))
{
// Init the memory cache
memCache = [[NSMutableDictionary alloc] init];
// Init the disk cache
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
diskCachePath = [[[paths objectAtIndex:0] stringByAppendingPathComponent:@"ImageCache"] retain];
if (![[NSFileManager defaultManager] fileExistsAtPath:diskCachePath])
{
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:NULL];
}
// Init the operation queue
cacheInQueue = [[NSOperationQueue alloc] init];
cacheInQueue.maxConcurrentOperationCount = 2;
// Subscribe to app events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clearMemory)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cleanDisk)
name:UIApplicationWillTerminateNotification
object:nil];
UIDevice *device = [UIDevice currentDevice];
if ([device respondsToSelector:@selector(isMultitaskingSupported)] && device.multitaskingSupported)
{
// When in background, clean memory in order to have less chance to be killed
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clearMemory)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
}
}
return self;
}
- (void)dealloc
{
[memCache release], memCache = nil;
[diskCachePath release], diskCachePath = nil;
[cacheInQueue release], cacheInQueue = nil;
[[NSNotificationCenter defaultCenter] removeObserver:self];
[super dealloc];
}
#pragma mark SDImageCache (class methods)
+ (SDImageCache *)sharedImageCache
{
if (instance == nil)
{
instance = [[SDImageCache alloc] init];
}
return instance;
}
#pragma mark SDImageCache (private)
- (NSString *)cachePathForKey:(NSString *)key
{
const char *str = [key UTF8String];
unsigned char r[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, strlen(str), r);
NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]];
return [diskCachePath stringByAppendingPathComponent:filename];
}
- (void)storeKeyToDisk:(NSString *)key
{
UIImage *image = [[self imageFromKey:key fromDisk:YES] retain]; // be thread safe with no lock
if (image != nil)
{
[[NSFileManager defaultManager] createFileAtPath:[self cachePathForKey:key] contents:UIImageJPEGRepresentation(image, (CGFloat)1.0) attributes:nil];
[image release];
}
}
#pragma mark ImageCache
- (void)storeImage:(UIImage *)image forKey:(NSString *)key
{
[self storeImage:image forKey:key toDisk:YES];
}
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk
{
if (image == nil || key == nil)
{
return;
}
[memCache setObject:image forKey:key];
if (toDisk)
{
[cacheInQueue addOperation:[[[NSInvocationOperation alloc] initWithTarget:self selector:@selector(storeKeyToDisk:) object:key] autorelease]];
}
}
- (UIImage *)imageFromKey:(NSString *)key
{
return [self imageFromKey:key fromDisk:YES];
}
- (UIImage *)imageFromKey:(NSString *)key fromDisk:(BOOL)fromDisk
{
if (key == nil)
{
return nil;
}
UIImage *image = [memCache objectForKey:key];
if (!image && fromDisk)
{
image = [[UIImage alloc] initWithData:[NSData dataWithContentsOfFile:[self cachePathForKey:key]]];
if (image != nil)
{
[memCache setObject:image forKey:key];
[image autorelease];
}
}
return image;
}
- (void)removeImageForKey:(NSString *)key
{
if (key == nil)
{
return;
}
[memCache removeObjectForKey:key];
[[NSFileManager defaultManager] removeItemAtPath:[self cachePathForKey:key] error:nil];
}
- (void)clearMemory
{
[cacheInQueue cancelAllOperations]; // won't be able to complete
[memCache removeAllObjects];
}
- (void)clearDisk
{
[cacheInQueue cancelAllOperations];
[[NSFileManager defaultManager] removeItemAtPath:diskCachePath error:nil];
[[NSFileManager defaultManager] createDirectoryAtPath:diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:NULL];
}
- (void)cleanDisk
{
NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-cacheMaxCacheAge];
NSDirectoryEnumerator *fileEnumerator = [[NSFileManager defaultManager] enumeratorAtPath:diskCachePath];
for (NSString *fileName in fileEnumerator)
{
NSString *filePath = [diskCachePath stringByAppendingPathComponent:fileName];
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
if ([[[attrs fileModificationDate] laterDate:expirationDate] isEqualToDate:expirationDate])
{
[[NSFileManager defaultManager] removeItemAtPath:filePath error:nil];
}
}
}
@end

47
SDWebImage.podspec Normal file
View File

@ -0,0 +1,47 @@
Pod::Spec.new do |s|
s.name = 'SDWebImage'
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.'
s.homepage = 'https://github.com/rs/SDWebImage'
s.author = { 'Olivier Poitrey' => 'rs@dailymotion.com' }
s.source = { :git => 'https://github.com/rs/SDWebImage.git', :tag => s.version.to_s }
s.description = 'This library provides a category for UIImageView with support for remote ' \
'images coming from the web. It provides an UIImageView category adding web ' \
'image and cache management to the Cocoa Touch framework, an asynchronous ' \
'image downloader, an asynchronous memory + disk image caching with automatic ' \
'cache expiration handling, a guarantee that the same URL won\'t be downloaded ' \
'several times, a guarantee that bogus URLs won\'t be retried again and again, ' \
'and performances!'
s.requires_arc = true
s.framework = 'ImageIO'
s.default_subspec = 'Core'
s.subspec 'Core' do |core|
core.source_files = 'SDWebImage/{NS,SD,UI}*.{h,m}'
core.exclude_files = 'SDWebImage/UIImage+WebP.{h,m}'
core.tvos.exclude_files = 'SDWebImage/MKAnnotationView+WebCache.*'
end
s.subspec 'MapKit' do |mk|
mk.ios.deployment_target = '7.0'
mk.source_files = 'SDWebImage/MKAnnotationView+WebCache.*'
mk.framework = 'MapKit'
mk.dependency 'SDWebImage/Core'
end
s.subspec 'WebP' do |webp|
webp.source_files = 'SDWebImage/UIImage+WebP.{h,m}'
webp.xcconfig = {
'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1',
'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src'
}
webp.dependency 'SDWebImage/Core'
webp.dependency 'libwebp'
end
end

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage tvOS"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage tvOS"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "00733A4B1BC487C000A5A117"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage tvOS"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Examples/SDWebImage Demo.xcodeproj">
</FileRef>
<FileRef
location = "group:Tests/SDWebImage Tests.xcodeproj">
</FileRef>
<FileRef
location = "group:LICENSE">
</FileRef>
<FileRef
location = "group:README.md">
</FileRef>
<FileRef
location = "group:SDWebImage.podspec">
</FileRef>
<FileRef
location = "group:CHANGELOG.md">
</FileRef>
<FileRef
location = "group:Tests/Pods/Pods.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,91 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761294155AB74D005750A4"
BuildableName = "SDWebImage Demo.app"
BlueprintName = "SDWebImage Demo"
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761294155AB74D005750A4"
BuildableName = "SDWebImage Demo.app"
BlueprintName = "SDWebImage Demo"
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761294155AB74D005750A4"
BuildableName = "SDWebImage Demo.app"
BlueprintName = "SDWebImage Demo"
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761294155AB74D005750A4"
BuildableName = "SDWebImage Demo.app"
BlueprintName = "SDWebImage Demo"
ReferencedContainer = "container:Examples/SDWebImage Demo.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "531041C2157EAFA400BBABC3"
BuildableName = "libSDWebImage+MKAnnotation.a"
BlueprintName = "SDWebImage+MKAnnotation"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "531041C2157EAFA400BBABC3"
BuildableName = "libSDWebImage+MKAnnotation.a"
BlueprintName = "SDWebImage+MKAnnotation"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "537D957317ECC1FE0097C263"
BuildableName = "libSDWebImage+WebP.a"
BlueprintName = "SDWebImage+WebP"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "537D957317ECC1FE0097C263"
BuildableName = "libSDWebImage+WebP.a"
BlueprintName = "SDWebImage+WebP"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761307155AD0D5005750A4"
BuildableName = "libSDWebImage.a"
BlueprintName = "SDWebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "53761307155AD0D5005750A4"
BuildableName = "libSDWebImage.a"
BlueprintName = "SDWebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,71 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "539F912B16316D2D00160719"
BuildableName = "SDWebImageFramework"
BlueprintName = "SDWebImageFramework"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "539F912B16316D2D00160719"
BuildableName = "SDWebImageFramework"
BlueprintName = "SDWebImageFramework"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "NO"
buildForArchiving = "NO"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA248D52195472AA00390AB0"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests/SDWebImage Tests.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA248D52195472AA00390AB0"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests/SDWebImage Tests.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA248D52195472AA00390AB0"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests/SDWebImage Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA248D52195472AA00390AB0"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests/SDWebImage Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "DA248D52195472AA00390AB0"
BuildableName = "Tests.xctest"
BlueprintName = "Tests"
ReferencedContainer = "container:Tests/SDWebImage Tests.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0710"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "4A2CADFE1AB4BB5300B6BC39"
BuildableName = "WebImage.framework"
BlueprintName = "WebImage"
ReferencedContainer = "container:SDWebImage.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -0,0 +1,124 @@
//
// MKAnnotationView+WebCache.h
// SDWebImage
//
// Created by Olivier Poitrey on 14/03/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "MapKit/MapKit.h"
#import "SDWebImageManager.h"
/**
* Integrates SDWebImage async downloading and caching of remote images with MKAnnotationView.
*/
@interface MKAnnotationView (WebCache)
/**
* Get the current image URL.
*
* Note that because of the limitations of categories this property can get out of sync
* if you use sd_setImage: directly.
*/
- (NSURL *)sd_imageURL;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
*/
- (void)sd_setImageWithURL:(NSURL *)url;
/**
* Set the imageView `image` with an `url` and a placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @see sd_setImageWithURL:placeholderImage:options:
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Cancel the current download
*/
- (void)sd_cancelCurrentImageLoad;
@end
@interface MKAnnotationView (WebCacheDeprecated)
- (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`");
- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:`");
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`");
@end

View File

@ -0,0 +1,135 @@
//
// MKAnnotationView+WebCache.m
// SDWebImage
//
// Created by Olivier Poitrey on 14/03/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "MKAnnotationView+WebCache.h"
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
static char imageURLKey;
@implementation MKAnnotationView (WebCache)
- (NSURL *)sd_imageURL {
return objc_getAssociatedObject(self, &imageURLKey);
}
- (void)sd_setImageWithURL:(NSURL *)url {
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
self.image = placeholder;
if (url) {
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe(^{
__strong MKAnnotationView *sself = wself;
if (!sself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock) {
completedBlock(image, error, cacheType, url);
return;
} else if (image) {
wself.image = image;
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forKey:@"MKAnnotationViewImage"];
} else {
dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
if (completedBlock) {
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
- (void)sd_cancelCurrentImageLoad {
[self sd_cancelImageLoadOperationWithKey:@"MKAnnotationViewImage"];
}
@end
@implementation MKAnnotationView (WebCacheDeprecated)
- (NSURL *)imageURL {
return [self sd_imageURL];
}
- (void)setImageWithURL:(NSURL *)url {
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:nil];
}
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)cancelCurrentImageLoad {
[self sd_cancelCurrentImageLoad];
}
@end

View File

@ -0,0 +1,26 @@
//
// Created by Fabrice Aneche on 06/01/14.
// Copyright (c) 2014 Dailymotion. All rights reserved.
//
#import <Foundation/Foundation.h>
@interface NSData (ImageContentType)
/**
* Compute the content type for an image data
*
* @param data the input data
*
* @return the content type as string (i.e. image/jpeg, image/gif)
*/
+ (NSString *)sd_contentTypeForImageData:(NSData *)data;
@end
@interface NSData (ImageContentTypeDeprecated)
+ (NSString *)contentTypeForImageData:(NSData *)data __deprecated_msg("Use `sd_contentTypeForImageData:`");
@end

View File

@ -0,0 +1,49 @@
//
// Created by Fabrice Aneche on 06/01/14.
// Copyright (c) 2014 Dailymotion. All rights reserved.
//
#import "NSData+ImageContentType.h"
@implementation NSData (ImageContentType)
+ (NSString *)sd_contentTypeForImageData:(NSData *)data {
uint8_t c;
[data getBytes:&c length:1];
switch (c) {
case 0xFF:
return @"image/jpeg";
case 0x89:
return @"image/png";
case 0x47:
return @"image/gif";
case 0x49:
case 0x4D:
return @"image/tiff";
case 0x52:
// R as RIFF for WEBP
if ([data length] < 12) {
return nil;
}
NSString *testString = [[NSString alloc] initWithData:[data subdataWithRange:NSMakeRange(0, 12)] encoding:NSASCIIStringEncoding];
if ([testString hasPrefix:@"RIFF"] && [testString hasSuffix:@"WEBP"]) {
return @"image/webp";
}
return nil;
}
return nil;
}
@end
@implementation NSData (ImageContentTypeDeprecated)
+ (NSString *)contentTypeForImageData:(NSData *)data {
return [self sd_contentTypeForImageData:data];
}
@end

280
SDWebImage/SDImageCache.h Normal file
View File

@ -0,0 +1,280 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageCompat.h"
typedef NS_ENUM(NSInteger, SDImageCacheType) {
/**
* The image wasn't available the SDWebImage caches, but was downloaded from the web.
*/
SDImageCacheTypeNone,
/**
* The image was obtained from the disk cache.
*/
SDImageCacheTypeDisk,
/**
* The image was obtained from the memory cache.
*/
SDImageCacheTypeMemory
};
typedef void(^SDWebImageQueryCompletedBlock)(UIImage *image, SDImageCacheType cacheType);
typedef void(^SDWebImageCheckCacheCompletionBlock)(BOOL isInCache);
typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger totalSize);
/**
* SDImageCache maintains a memory cache and an optional disk cache. Disk cache write operations are performed
* asynchronous so it doesnt add unnecessary latency to the UI.
*/
@interface SDImageCache : NSObject
/**
* Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
*/
@property (assign, nonatomic) BOOL shouldDecompressImages;
/**
* disable iCloud backup [defaults to YES]
*/
@property (assign, nonatomic) BOOL shouldDisableiCloud;
/**
* use memory cache [defaults to YES]
*/
@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;
/**
* The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
*/
@property (assign, nonatomic) NSUInteger maxMemoryCost;
/**
* The maximum number of objects the cache should hold.
*/
@property (assign, nonatomic) NSUInteger maxMemoryCountLimit;
/**
* The maximum length of time to keep an image in the cache, in seconds
*/
@property (assign, nonatomic) NSInteger maxCacheAge;
/**
* The maximum size of the cache, in bytes.
*/
@property (assign, nonatomic) NSUInteger maxCacheSize;
/**
* Returns global shared cache instance
*
* @return SDImageCache global instance
*/
+ (SDImageCache *)sharedImageCache;
/**
* Init a new cache store with a specific namespace
*
* @param ns The namespace to use for this cache store
*/
- (id)initWithNamespace:(NSString *)ns;
/**
* Init a new cache store with a specific namespace and directory
*
* @param ns The namespace to use for this cache store
* @param directory Directory to cache disk images in
*/
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory;
-(NSString *)makeDiskCachePath:(NSString*)fullNamespace;
/**
* Add a read-only cache path to search for images pre-cached by SDImageCache
* Useful if you want to bundle pre-loaded images with your app
*
* @param path The path to use for this read-only cache path
*/
- (void)addReadOnlyCachePath:(NSString *)path;
/**
* Store an image into memory and disk cache at the given key.
*
* @param image The image to store
* @param key The unique image cache key, usually it's image absolute URL
*/
- (void)storeImage:(UIImage *)image forKey:(NSString *)key;
/**
* Store an image into memory and optionally disk cache at the given key.
*
* @param image The image to store
* @param key The unique image cache key, usually it's image absolute URL
* @param toDisk Store the image to disk cache if YES
*/
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk;
/**
* Store an image into memory and optionally disk cache at the given key.
*
* @param image The image to store
* @param recalculate BOOL indicates if imageData can be used or a new data should be constructed from the UIImage
* @param imageData The image data as returned by the server, this representation will be used for disk storage
* instead of converting the given image object into a storable/compressed image format in order
* to save quality and CPU
* @param key The unique image cache key, usually it's image absolute URL
* @param toDisk Store the image to disk cache if YES
*/
- (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.
*
* @param key The unique key used to store the wanted image
*/
- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
/**
* Query the memory cache synchronously.
*
* @param key The unique key used to store the wanted image
*/
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key;
/**
* Query the disk cache synchronously after checking the memory cache.
*
* @param key The unique key used to store the wanted image
*/
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key;
/**
* Remove the image from memory and disk cache asynchronously
*
* @param key The unique image cache key
*/
- (void)removeImageForKey:(NSString *)key;
/**
* Remove the image from memory and disk cache asynchronously
*
* @param key The unique image cache key
* @param completion An block that should be executed after the image has been removed (optional)
*/
- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion;
/**
* Remove the image from memory and optionally disk cache asynchronously
*
* @param key The unique image cache key
* @param fromDisk Also remove cache entry from disk if YES
*/
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk;
/**
* Remove the image from memory and optionally disk cache asynchronously
*
* @param key The unique image cache key
* @param fromDisk Also remove cache entry from disk if YES
* @param completion An block that should be executed after the image has been removed (optional)
*/
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion;
/**
* Clear all memory cached images
*/
- (void)clearMemory;
/**
* Clear all disk cached images. Non-blocking method - returns immediately.
* @param completion An block that should be executed after cache expiration completes (optional)
*/
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion;
/**
* Clear all disk cached images
* @see clearDiskOnCompletion:
*/
- (void)clearDisk;
/**
* Remove all expired cached image from disk. Non-blocking method - returns immediately.
* @param completionBlock An block that should be executed after cache expiration completes (optional)
*/
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock;
/**
* Remove all expired cached image from disk
* @see cleanDiskWithCompletionBlock:
*/
- (void)cleanDisk;
/**
* Get the size used by the disk cache
*/
- (NSUInteger)getSize;
/**
* Get the number of images in the disk cache
*/
- (NSUInteger)getDiskCount;
/**
* Asynchronously calculate the disk cache's size.
*/
- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock;
/**
* Async check if image exists in disk cache already (does not load the image)
*
* @param key the key describing the url
* @param completionBlock the block to be executed when the check is done.
* @note the completion block will be always executed on the main queue
*/
- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
/**
* Check if image exists in disk cache already (does not load the image)
*
* @param key the key describing the url
*
* @return YES if an image exists for the given key
*/
- (BOOL)diskImageExistsWithKey:(NSString *)key;
/**
* Get the cache path for a certain key (needs the cache path root folder)
*
* @param key the key (can be obtained from url using cacheKeyForURL)
* @param path the cache path root folder
*
* @return the cache path
*/
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path;
/**
* Get the default cache path for a certain key
*
* @param key the key (can be obtained from url using cacheKeyForURL)
*
* @return the default cache path
*/
- (NSString *)defaultCachePathForKey:(NSString *)key;
@end

657
SDWebImage/SDImageCache.m Normal file
View File

@ -0,0 +1,657 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDImageCache.h"
#import "SDWebImageDecoder.h"
#import "UIImage+MultiFormat.h"
#import <CommonCrypto/CommonDigest.h>
// See https://github.com/rs/SDWebImage/pull/1141 for discussion
@interface AutoPurgeCache : NSCache
@end
@implementation AutoPurgeCache
- (id)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(removeAllObjects) name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
return self;
}
- (void)dealloc
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:UIApplicationDidReceiveMemoryWarningNotification object:nil];
}
@end
static const NSInteger kDefaultCacheMaxCacheAge = 60 * 60 * 24 * 7; // 1 week
// PNG signature bytes and data (below)
static unsigned char kPNGSignatureBytes[8] = {0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A};
static NSData *kPNGSignatureData = nil;
BOOL ImageDataHasPNGPreffix(NSData *data);
BOOL ImageDataHasPNGPreffix(NSData *data) {
NSUInteger pngSignatureLength = [kPNGSignatureData length];
if ([data length] >= pngSignatureLength) {
if ([[data subdataWithRange:NSMakeRange(0, pngSignatureLength)] isEqualToData:kPNGSignatureData]) {
return YES;
}
}
return NO;
}
FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
return image.size.height * image.size.width * image.scale * image.scale;
}
@interface SDImageCache ()
@property (strong, nonatomic) NSCache *memCache;
@property (strong, nonatomic) NSString *diskCachePath;
@property (strong, nonatomic) NSMutableArray *customPaths;
@property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t ioQueue;
@end
@implementation SDImageCache {
NSFileManager *_fileManager;
}
+ (SDImageCache *)sharedImageCache {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [self new];
});
return instance;
}
- (id)init {
return [self initWithNamespace:@"default"];
}
- (id)initWithNamespace:(NSString *)ns {
NSString *path = [self makeDiskCachePath:ns];
return [self initWithNamespace:ns diskCacheDirectory:path];
}
- (id)initWithNamespace:(NSString *)ns diskCacheDirectory:(NSString *)directory {
if ((self = [super init])) {
NSString *fullNamespace = [@"com.hackemist.SDWebImageCache." stringByAppendingString:ns];
// initialise PNG signature data
kPNGSignatureData = [NSData dataWithBytes:kPNGSignatureBytes length:8];
// Create IO serial queue
_ioQueue = dispatch_queue_create("com.hackemist.SDWebImageCache", DISPATCH_QUEUE_SERIAL);
// Init default values
_maxCacheAge = kDefaultCacheMaxCacheAge;
// Init the memory cache
_memCache = [[AutoPurgeCache alloc] init];
_memCache.name = fullNamespace;
// Init the disk cache
if (directory != nil) {
_diskCachePath = [directory stringByAppendingPathComponent:fullNamespace];
} else {
NSString *path = [self makeDiskCachePath:ns];
_diskCachePath = path;
}
// Set decompression to YES
_shouldDecompressImages = YES;
// memory cache enabled
_shouldCacheImagesInMemory = YES;
// Disable iCloud
_shouldDisableiCloud = YES;
dispatch_sync(_ioQueue, ^{
_fileManager = [NSFileManager new];
});
#if TARGET_OS_IOS
// Subscribe to app events
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(clearMemory)
name:UIApplicationDidReceiveMemoryWarningNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(cleanDisk)
name:UIApplicationWillTerminateNotification
object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(backgroundCleanDisk)
name:UIApplicationDidEnterBackgroundNotification
object:nil];
#endif
}
return self;
}
- (void)dealloc {
[[NSNotificationCenter defaultCenter] removeObserver:self];
SDDispatchQueueRelease(_ioQueue);
}
- (void)addReadOnlyCachePath:(NSString *)path {
if (!self.customPaths) {
self.customPaths = [NSMutableArray new];
}
if (![self.customPaths containsObject:path]) {
[self.customPaths addObject:path];
}
}
- (NSString *)cachePathForKey:(NSString *)key inPath:(NSString *)path {
NSString *filename = [self cachedFileNameForKey:key];
return [path stringByAppendingPathComponent:filename];
}
- (NSString *)defaultCachePathForKey:(NSString *)key {
return [self cachePathForKey:key inPath:self.diskCachePath];
}
#pragma mark SDImageCache (private)
- (NSString *)cachedFileNameForKey:(NSString *)key {
const char *str = [key UTF8String];
if (str == NULL) {
str = "";
}
unsigned char r[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, (CC_LONG)strlen(str), r);
NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@",
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],
r[11], r[12], r[13], r[14], r[15], [[key pathExtension] isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", [key pathExtension]]];
return filename;
}
#pragma mark ImageCache
// Init the disk cache
-(NSString *)makeDiskCachePath:(NSString*)fullNamespace{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
return [paths[0] stringByAppendingPathComponent:fullNamespace];
}
- (void)storeImage:(UIImage *)image recalculateFromImage:(BOOL)recalculate imageData:(NSData *)imageData forKey:(NSString *)key toDisk:(BOOL)toDisk {
if (!image || !key) {
return;
}
// if memory cache is enabled
if (self.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(image);
[self.memCache setObject:image forKey:key cost:cost];
}
if (toDisk) {
dispatch_async(self.ioQueue, ^{
NSData *data = imageData;
if (image && (recalculate || !data)) {
#if TARGET_OS_IPHONE
// We need to determine if the image is a PNG or a JPEG
// PNGs are easier to detect because they have a unique signature (http://www.w3.org/TR/PNG-Structure.html)
// The first eight bytes of a PNG file always contain the following (decimal) values:
// 137 80 78 71 13 10 26 10
// If the imageData is nil (i.e. if trying to save a UIImage directly or the image was transformed on download)
// and the image has an alpha channel, we will consider it PNG to avoid losing the transparency
int alphaInfo = CGImageGetAlphaInfo(image.CGImage);
BOOL hasAlpha = !(alphaInfo == kCGImageAlphaNone ||
alphaInfo == kCGImageAlphaNoneSkipFirst ||
alphaInfo == kCGImageAlphaNoneSkipLast);
BOOL imageIsPng = hasAlpha;
// But if we have an image data, we will look at the preffix
if ([imageData length] >= [kPNGSignatureData length]) {
imageIsPng = ImageDataHasPNGPreffix(imageData);
}
if (imageIsPng) {
data = UIImagePNGRepresentation(image);
}
else {
data = UIImageJPEGRepresentation(image, (CGFloat)1.0);
}
#else
data = [NSBitmapImageRep representationOfImageRepsInArray:image.representations usingType: NSJPEGFileType properties:nil];
#endif
}
[self storeImageDataToDisk:data forKey:key];
});
}
}
- (void)storeImage:(UIImage *)image forKey:(NSString *)key {
[self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:YES];
}
- (void)storeImage:(UIImage *)image forKey:(NSString *)key toDisk:(BOOL)toDisk {
[self storeImage:image recalculateFromImage:YES imageData:nil forKey:key toDisk:toDisk];
}
- (void)storeImageDataToDisk:(NSData *)imageData forKey:(NSString *)key {
if (!imageData) {
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;
}
- (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);
});
}
});
}
- (UIImage *)imageFromMemoryCacheForKey:(NSString *)key {
return [self.memCache objectForKey:key];
}
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key {
// First check the in-memory cache...
UIImage *image = [self imageFromMemoryCacheForKey:key];
if (image) {
return image;
}
// Second check the disk cache...
UIImage *diskImage = [self diskImageForKey:key];
if (diskImage && self.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(diskImage);
[self.memCache setObject:diskImage forKey:key cost:cost];
}
return diskImage;
}
- (NSData *)diskImageDataBySearchingAllPathsForKey:(NSString *)key {
NSString *defaultPath = [self defaultCachePathForKey:key];
NSData *data = [NSData dataWithContentsOfFile:defaultPath];
if (data) {
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];
NSData *imageData = [NSData dataWithContentsOfFile:filePath];
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;
}
- (UIImage *)diskImageForKey:(NSString *)key {
NSData *data = [self diskImageDataBySearchingAllPathsForKey:key];
if (data) {
UIImage *image = [UIImage sd_imageWithData:data];
image = [self scaledImageForKey:key image:image];
if (self.shouldDecompressImages) {
image = [UIImage decodedImageWithImage:image];
}
return image;
}
else {
return nil;
}
}
- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image {
return SDScaledImageForKey(key, image);
}
- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock {
if (!doneBlock) {
return nil;
}
if (!key) {
doneBlock(nil, SDImageCacheTypeNone);
return nil;
}
// First check the in-memory cache...
UIImage *image = [self imageFromMemoryCacheForKey:key];
if (image) {
doneBlock(image, SDImageCacheTypeMemory);
return nil;
}
NSOperation *operation = [NSOperation new];
dispatch_async(self.ioQueue, ^{
if (operation.isCancelled) {
return;
}
@autoreleasepool {
UIImage *diskImage = [self diskImageForKey:key];
if (diskImage && self.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(diskImage);
[self.memCache setObject:diskImage forKey:key cost:cost];
}
dispatch_async(dispatch_get_main_queue(), ^{
doneBlock(diskImage, SDImageCacheTypeDisk);
});
}
});
return operation;
}
- (void)removeImageForKey:(NSString *)key {
[self removeImageForKey:key withCompletion:nil];
}
- (void)removeImageForKey:(NSString *)key withCompletion:(SDWebImageNoParamsBlock)completion {
[self removeImageForKey:key fromDisk:YES withCompletion:completion];
}
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk {
[self removeImageForKey:key fromDisk:fromDisk withCompletion:nil];
}
- (void)removeImageForKey:(NSString *)key fromDisk:(BOOL)fromDisk withCompletion:(SDWebImageNoParamsBlock)completion {
if (key == nil) {
return;
}
if (self.shouldCacheImagesInMemory) {
[self.memCache removeObjectForKey:key];
}
if (fromDisk) {
dispatch_async(self.ioQueue, ^{
[_fileManager removeItemAtPath:[self defaultCachePathForKey:key] error:nil];
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}
});
} else if (completion){
completion();
}
}
- (void)setMaxMemoryCost:(NSUInteger)maxMemoryCost {
self.memCache.totalCostLimit = maxMemoryCost;
}
- (NSUInteger)maxMemoryCost {
return self.memCache.totalCostLimit;
}
- (NSUInteger)maxMemoryCountLimit {
return self.memCache.countLimit;
}
- (void)setMaxMemoryCountLimit:(NSUInteger)maxCountLimit {
self.memCache.countLimit = maxCountLimit;
}
- (void)clearMemory {
[self.memCache removeAllObjects];
}
- (void)clearDisk {
[self clearDiskOnCompletion:nil];
}
- (void)clearDiskOnCompletion:(SDWebImageNoParamsBlock)completion
{
dispatch_async(self.ioQueue, ^{
[_fileManager removeItemAtPath:self.diskCachePath error:nil];
[_fileManager createDirectoryAtPath:self.diskCachePath
withIntermediateDirectories:YES
attributes:nil
error:NULL];
if (completion) {
dispatch_async(dispatch_get_main_queue(), ^{
completion();
});
}
});
}
- (void)cleanDisk {
[self cleanDiskWithCompletionBlock:nil];
}
- (void)cleanDiskWithCompletionBlock:(SDWebImageNoParamsBlock)completionBlock {
dispatch_async(self.ioQueue, ^{
NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
NSArray *resourceKeys = @[NSURLIsDirectoryKey, NSURLContentModificationDateKey, NSURLTotalFileAllocatedSizeKey];
// This enumerator prefetches useful properties for our cache files.
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
includingPropertiesForKeys:resourceKeys
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:NULL];
NSDate *expirationDate = [NSDate dateWithTimeIntervalSinceNow:-self.maxCacheAge];
NSMutableDictionary *cacheFiles = [NSMutableDictionary dictionary];
NSUInteger currentCacheSize = 0;
// Enumerate all of the files in the cache directory. This loop has two purposes:
//
// 1. Removing files that are older than the expiration date.
// 2. Storing file attributes for the size-based cleanup pass.
NSMutableArray *urlsToDelete = [[NSMutableArray alloc] init];
for (NSURL *fileURL in fileEnumerator) {
NSDictionary *resourceValues = [fileURL resourceValuesForKeys:resourceKeys error:NULL];
// Skip nil or directories.
if (!resourceValues || [resourceValues[NSURLIsDirectoryKey] boolValue]) {
continue;
}
// Remove files that are older than the expiration date;
NSDate *modificationDate = resourceValues[NSURLContentModificationDateKey];
if ([[modificationDate laterDate:expirationDate] isEqualToDate:expirationDate]) {
[urlsToDelete addObject:fileURL];
continue;
}
// Store a reference to this file and account for its total size.
NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
currentCacheSize += [totalAllocatedSize unsignedIntegerValue];
[cacheFiles setObject:resourceValues forKey:fileURL];
}
for (NSURL *fileURL in urlsToDelete) {
[_fileManager removeItemAtURL:fileURL error:nil];
}
// If our remaining disk cache exceeds a configured maximum size, perform a second
// size-based cleanup pass. We delete the oldest files first.
if (self.maxCacheSize > 0 && currentCacheSize > self.maxCacheSize) {
// Target half of our maximum cache size for this cleanup pass.
const NSUInteger desiredCacheSize = self.maxCacheSize / 2;
// Sort the remaining cache files by their last modification time (oldest first).
NSArray *sortedFiles = [cacheFiles keysSortedByValueWithOptions:NSSortConcurrent
usingComparator:^NSComparisonResult(id obj1, id obj2) {
return [obj1[NSURLContentModificationDateKey] compare:obj2[NSURLContentModificationDateKey]];
}];
// Delete files until we fall below our desired cache size.
for (NSURL *fileURL in sortedFiles) {
if ([_fileManager removeItemAtURL:fileURL error:nil]) {
NSDictionary *resourceValues = cacheFiles[fileURL];
NSNumber *totalAllocatedSize = resourceValues[NSURLTotalFileAllocatedSizeKey];
currentCacheSize -= [totalAllocatedSize unsignedIntegerValue];
if (currentCacheSize < desiredCacheSize) {
break;
}
}
}
}
if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock();
});
}
});
}
- (void)backgroundCleanDisk {
Class UIApplicationClass = NSClassFromString(@"UIApplication");
if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) {
return;
}
UIApplication *application = [UIApplication performSelector:@selector(sharedApplication)];
__block UIBackgroundTaskIdentifier bgTask = [application beginBackgroundTaskWithExpirationHandler:^{
// Clean up any unfinished task business by marking where you
// stopped or ending the task outright.
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
// Start the long-running task and return immediately.
[self cleanDiskWithCompletionBlock:^{
[application endBackgroundTask:bgTask];
bgTask = UIBackgroundTaskInvalid;
}];
}
- (NSUInteger)getSize {
__block NSUInteger size = 0;
dispatch_sync(self.ioQueue, ^{
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
for (NSString *fileName in fileEnumerator) {
NSString *filePath = [self.diskCachePath stringByAppendingPathComponent:fileName];
NSDictionary *attrs = [[NSFileManager defaultManager] attributesOfItemAtPath:filePath error:nil];
size += [attrs fileSize];
}
});
return size;
}
- (NSUInteger)getDiskCount {
__block NSUInteger count = 0;
dispatch_sync(self.ioQueue, ^{
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtPath:self.diskCachePath];
count = [[fileEnumerator allObjects] count];
});
return count;
}
- (void)calculateSizeWithCompletionBlock:(SDWebImageCalculateSizeBlock)completionBlock {
NSURL *diskCacheURL = [NSURL fileURLWithPath:self.diskCachePath isDirectory:YES];
dispatch_async(self.ioQueue, ^{
NSUInteger fileCount = 0;
NSUInteger totalSize = 0;
NSDirectoryEnumerator *fileEnumerator = [_fileManager enumeratorAtURL:diskCacheURL
includingPropertiesForKeys:@[NSFileSize]
options:NSDirectoryEnumerationSkipsHiddenFiles
errorHandler:NULL];
for (NSURL *fileURL in fileEnumerator) {
NSNumber *fileSize;
[fileURL getResourceValue:&fileSize forKey:NSURLFileSizeKey error:NULL];
totalSize += [fileSize unsignedIntegerValue];
fileCount += 1;
}
if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(fileCount, totalSize);
});
}
});
}
@end

View File

@ -0,0 +1,72 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
* (c) Jamie Pinkham
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <TargetConditionals.h>
#ifdef __OBJC_GC__
#error SDWebImage does not support Objective-C Garbage Collection
#endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
#error SDWebImage doesn't support Deployment Target version < 5.0
#endif
#if !TARGET_OS_IPHONE
#import <AppKit/AppKit.h>
#ifndef UIImage
#define UIImage NSImage
#endif
#ifndef UIImageView
#define UIImageView NSImageView
#endif
#else
#import <UIKit/UIKit.h>
#endif
#ifndef NS_ENUM
#define NS_ENUM(_type, _name) enum _name : _type _name; enum _name : _type
#endif
#ifndef NS_OPTIONS
#define NS_OPTIONS(_type, _name) enum _name : _type _name; enum _name : _type
#endif
#if OS_OBJECT_USE_OBJC
#undef SDDispatchQueueRelease
#undef SDDispatchQueueSetterSementics
#define SDDispatchQueueRelease(q)
#define SDDispatchQueueSetterSementics strong
#else
#undef SDDispatchQueueRelease
#undef SDDispatchQueueSetterSementics
#define SDDispatchQueueRelease(q) (dispatch_release(q))
#define SDDispatchQueueSetterSementics assign
#endif
extern UIImage *SDScaledImageForKey(NSString *key, UIImage *image);
typedef void(^SDWebImageNoParamsBlock)();
extern NSString *const SDWebImageErrorDomain;
#define dispatch_main_sync_safe(block)\
if ([NSThread isMainThread]) {\
block();\
} else {\
dispatch_sync(dispatch_get_main_queue(), block);\
}
#define dispatch_main_async_safe(block)\
if ([NSThread isMainThread]) {\
block();\
} else {\
dispatch_async(dispatch_get_main_queue(), block);\
}

View File

@ -0,0 +1,51 @@
//
// SDWebImageCompat.m
// SDWebImage
//
// Created by Olivier Poitrey on 11/12/12.
// Copyright (c) 2012 Dailymotion. All rights reserved.
//
#import "SDWebImageCompat.h"
#if !__has_feature(objc_arc)
#error SDWebImage is ARC only. Either turn on ARC for the project or use -fobjc-arc flag
#endif
inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
if (!image) {
return nil;
}
if ([image.images count] > 0) {
NSMutableArray *scaledImages = [NSMutableArray array];
for (UIImage *tempImage in image.images) {
[scaledImages addObject:SDScaledImageForKey(key, tempImage)];
}
return [UIImage animatedImageWithImages:scaledImages duration:image.duration];
}
else {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
CGFloat scale = 1;
if (key.length >= 8) {
NSRange range = [key rangeOfString:@"@2x."];
if (range.location != NSNotFound) {
scale = 2.0;
}
range = [key rangeOfString:@"@3x."];
if (range.location != NSNotFound) {
scale = 3.0;
}
}
UIImage *scaledImage = [[UIImage alloc] initWithCGImage:image.CGImage scale:scale orientation:image.imageOrientation];
image = scaledImage;
}
return image;
}
}
NSString *const SDWebImageErrorDomain = @"SDWebImageErrorDomain";

View File

@ -0,0 +1,18 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* Created by james <https://github.com/mystcolor> on 9/28/11.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageCompat.h"
@interface UIImage (ForceDecode)
+ (UIImage *)decodedImageWithImage:(UIImage *)image;
@end

View File

@ -0,0 +1,92 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* Created by james <https://github.com/mystcolor> on 9/28/11.
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageDecoder.h"
@implementation UIImage (ForceDecode)
+ (UIImage *)decodedImageWithImage:(UIImage *)image {
// while downloading huge amount of images
// autorelease the bitmap context
// and all vars to help system to free memory
// when there are memory warning.
// on iOS7, do not forget to call
// [[SDImageCache sharedImageCache] clearMemory];
if (image == nil) { // Prevent "CGBitmapContextCreateImage: invalid context 0x0" error
return nil;
}
@autoreleasepool{
// do not decode animated images
if (image.images != nil) {
return image;
}
CGImageRef imageRef = image.CGImage;
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
alpha == kCGImageAlphaLast ||
alpha == kCGImageAlphaPremultipliedFirst ||
alpha == kCGImageAlphaPremultipliedLast);
if (anyAlpha) {
return image;
}
// current
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
BOOL unsupportedColorSpace = (imageColorSpaceModel == kCGColorSpaceModelUnknown ||
imageColorSpaceModel == kCGColorSpaceModelMonochrome ||
imageColorSpaceModel == kCGColorSpaceModelCMYK ||
imageColorSpaceModel == kCGColorSpaceModelIndexed);
if (unsupportedColorSpace) {
colorspaceRef = CGColorSpaceCreateDeviceRGB();
}
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,
bitsPerComponent,
bytesPerRow,
colorspaceRef,
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 imageRefWithoutAlpha = CGBitmapContextCreateImage(context);
UIImage *imageWithoutAlpha = [UIImage imageWithCGImage:imageRefWithoutAlpha
scale:image.scale
orientation:image.imageOrientation];
if (unsupportedColorSpace) {
CGColorSpaceRelease(colorspaceRef);
}
CGContextRelease(context);
CGImageRelease(imageRefWithoutAlpha);
return imageWithoutAlpha;
}
}
@end

View File

@ -0,0 +1,196 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageCompat.h"
#import "SDWebImageOperation.h"
typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
SDWebImageDownloaderLowPriority = 1 << 0,
SDWebImageDownloaderProgressiveDownload = 1 << 1,
/**
* By default, request prevent the use of NSURLCache. With this flag, NSURLCache
* is used with default policies.
*/
SDWebImageDownloaderUseNSURLCache = 1 << 2,
/**
* Call completion block with nil image/imageData if the image was read from NSURLCache
* (to be combined with `SDWebImageDownloaderUseNSURLCache`).
*/
SDWebImageDownloaderIgnoreCachedResponse = 1 << 3,
/**
* In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for
* extra time in background to let the request finish. If the background task expires the operation will be cancelled.
*/
SDWebImageDownloaderContinueInBackground = 1 << 4,
/**
* Handles cookies stored in NSHTTPCookieStore by setting
* NSMutableURLRequest.HTTPShouldHandleCookies = YES;
*/
SDWebImageDownloaderHandleCookies = 1 << 5,
/**
* Enable to allow untrusted SSL certificates.
* Useful for testing purposes. Use with caution in production.
*/
SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
/**
* Put the image in the high priority queue.
*/
SDWebImageDownloaderHighPriority = 1 << 7,
};
typedef NS_ENUM(NSInteger, SDWebImageDownloaderExecutionOrder) {
/**
* Default value. All download operations will execute in queue style (first-in-first-out).
*/
SDWebImageDownloaderFIFOExecutionOrder,
/**
* All download operations will execute in stack style (last-in-first-out).
*/
SDWebImageDownloaderLIFOExecutionOrder
};
extern NSString *const SDWebImageDownloadStartNotification;
extern NSString *const SDWebImageDownloadStopNotification;
typedef void(^SDWebImageDownloaderProgressBlock)(NSInteger receivedSize, NSInteger expectedSize);
typedef void(^SDWebImageDownloaderCompletedBlock)(UIImage *image, NSData *data, NSError *error, BOOL finished);
typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDictionary *headers);
/**
* Asynchronous downloader dedicated and optimized for image loading.
*/
@interface SDWebImageDownloader : NSObject
/**
* Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
*/
@property (assign, nonatomic) BOOL shouldDecompressImages;
@property (assign, nonatomic) NSInteger maxConcurrentDownloads;
/**
* Shows the current amount of downloads that still need to be downloaded
*/
@property (readonly, nonatomic) NSUInteger currentDownloadCount;
/**
* The timeout value (in seconds) for the download operation. Default: 15.0.
*/
@property (assign, nonatomic) NSTimeInterval downloadTimeout;
/**
* Changes download operations execution order. Default value is `SDWebImageDownloaderFIFOExecutionOrder`.
*/
@property (assign, nonatomic) SDWebImageDownloaderExecutionOrder executionOrder;
/**
* Singleton method, returns the shared instance
*
* @return global shared instance of downloader class
*/
+ (SDWebImageDownloader *)sharedDownloader;
/**
* Set the default URL credential to be set for request operations.
*/
@property (strong, nonatomic) NSURLCredential *urlCredential;
/**
* Set username
*/
@property (strong, nonatomic) NSString *username;
/**
* Set password
*/
@property (strong, nonatomic) NSString *password;
/**
* Set filter to pick headers for downloading image HTTP request.
*
* This block will be invoked for each downloading image request, returned
* NSDictionary will be used as headers in corresponding HTTP request.
*/
@property (nonatomic, copy) SDWebImageDownloaderHeadersFilterBlock headersFilter;
/**
* Set a value for a HTTP header to be appended to each download HTTP request.
*
* @param value The value for the header field. Use `nil` value to remove the header.
* @param field The name of the header field to set.
*/
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field;
/**
* Returns the value of the specified HTTP header field.
*
* @return The value associated with the header field field, or `nil` if there is no corresponding header field.
*/
- (NSString *)valueForHTTPHeaderField:(NSString *)field;
/**
* Sets a subclass of `SDWebImageDownloaderOperation` as the default
* `NSOperation` to be used each time SDWebImage constructs a request
* operation to download an image.
*
* @param operationClass The subclass of `SDWebImageDownloaderOperation` to set
* as default. Passing `nil` will revert to `SDWebImageDownloaderOperation`.
*/
- (void)setOperationClass:(Class)operationClass;
/**
* Creates a SDWebImageDownloader async downloader instance with a given URL
*
* The delegate will be informed when the image is finish downloaded or an error has happen.
*
* @see SDWebImageDownloaderDelegate
*
* @param url The URL to the image to download
* @param options The options to be used for this download
* @param progressBlock A block called repeatedly while the image is downloading
* @param completedBlock A block called once the download is completed.
* If the download succeeded, the image parameter is set, in case of error,
* error parameter is set with the error. The last parameter is always YES
* if SDWebImageDownloaderProgressiveDownload isn't use. With the
* SDWebImageDownloaderProgressiveDownload option, this block is called
* repeatedly with the partial image object and the finished argument set to NO
* before to be called a last time with the full image and finished argument
* set to YES. In case of error, the finished argument is always YES.
*
* @return A cancellable SDWebImageOperation
*/
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageDownloaderOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageDownloaderCompletedBlock)completedBlock;
/**
* Sets the download queue suspension state
*/
- (void)setSuspended:(BOOL)suspended;
/**
* Cancels all download operations in the queue
*/
- (void)cancelAllDownloads;
@end

View File

@ -0,0 +1,317 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageDownloader.h"
#import "SDWebImageDownloaderOperation.h"
#import <ImageIO/ImageIO.h>
static NSString *const kProgressCallbackKey = @"progress";
static NSString *const kCompletedCallbackKey = @"completed";
@interface SDWebImageDownloader () <NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
@property (strong, nonatomic) NSOperationQueue *downloadQueue;
@property (weak, nonatomic) NSOperation *lastAddedOperation;
@property (assign, nonatomic) Class operationClass;
@property (strong, nonatomic) NSMutableDictionary *URLCallbacks;
@property (strong, nonatomic) NSMutableDictionary *HTTPHeaders;
// 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
+ (void)initialize {
// Bind SDNetworkActivityIndicator if available (download it here: http://github.com/rs/SDNetworkActivityIndicator )
// To use it, just add #import "SDNetworkActivityIndicator.h" in addition to the SDWebImage import
if (NSClassFromString(@"SDNetworkActivityIndicator")) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
id activityIndicator = [NSClassFromString(@"SDNetworkActivityIndicator") performSelector:NSSelectorFromString(@"sharedActivityIndicator")];
#pragma clang diagnostic pop
// Remove observer in case it was previously added.
[[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStartNotification object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:activityIndicator name:SDWebImageDownloadStopNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:activityIndicator
selector:NSSelectorFromString(@"startActivity")
name:SDWebImageDownloadStartNotification object:nil];
[[NSNotificationCenter defaultCenter] addObserver:activityIndicator
selector:NSSelectorFromString(@"stopActivity")
name:SDWebImageDownloadStopNotification object:nil];
}
}
+ (SDWebImageDownloader *)sharedDownloader {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [self new];
});
return instance;
}
- (id)init {
if ((self = [super init])) {
_operationClass = [SDWebImageDownloaderOperation class];
_shouldDecompressImages = YES;
_executionOrder = SDWebImageDownloaderFIFOExecutionOrder;
_downloadQueue = [NSOperationQueue new];
_downloadQueue.maxConcurrentOperationCount = 6;
_URLCallbacks = [NSMutableDictionary new];
#ifdef SD_WEBP
_HTTPHeaders = [@{@"Accept": @"image/webp,image/*;q=0.8"} mutableCopy];
#else
_HTTPHeaders = [@{@"Accept": @"image/*;q=0.8"} mutableCopy];
#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);
}
- (void)setValue:(NSString *)value forHTTPHeaderField:(NSString *)field {
if (value) {
self.HTTPHeaders[field] = value;
}
else {
[self.HTTPHeaders removeObjectForKey:field];
}
}
- (NSString *)valueForHTTPHeaderField:(NSString *)field {
return self.HTTPHeaders[field];
}
- (void)setMaxConcurrentDownloads:(NSInteger)maxConcurrentDownloads {
_downloadQueue.maxConcurrentOperationCount = maxConcurrentDownloads;
}
- (NSUInteger)currentDownloadCount {
return _downloadQueue.operationCount;
}
- (NSInteger)maxConcurrentDownloads {
return _downloadQueue.maxConcurrentOperationCount;
}
- (void)setOperationClass:(Class)operationClass {
_operationClass = operationClass ?: [SDWebImageDownloaderOperation class];
}
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock {
__block SDWebImageDownloaderOperation *operation;
__weak __typeof(self)wself = self;
[self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^{
NSTimeInterval timeoutInterval = wself.downloadTimeout;
if (timeoutInterval == 0.0) {
timeoutInterval = 15.0;
}
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests if told otherwise
NSMutableURLRequest *request = [[NSMutableURLRequest alloc] initWithURL:url cachePolicy:(options & SDWebImageDownloaderUseNSURLCache ? NSURLRequestUseProtocolCachePolicy : NSURLRequestReloadIgnoringLocalCacheData) timeoutInterval:timeoutInterval];
request.HTTPShouldHandleCookies = (options & SDWebImageDownloaderHandleCookies);
request.HTTPShouldUsePipelining = YES;
if (wself.headersFilter) {
request.allHTTPHeaderFields = wself.headersFilter(url, [wself.HTTPHeaders copy]);
}
else {
request.allHTTPHeaderFields = wself.HTTPHeaders;
}
operation = [[wself.operationClass alloc] initWithRequest:request
inSession:self.session
options:options
progress:^(NSInteger receivedSize, NSInteger expectedSize) {
SDWebImageDownloader *sself = wself;
if (!sself) return;
__block NSArray *callbacksForURL;
dispatch_sync(sself.barrierQueue, ^{
callbacksForURL = [sself.URLCallbacks[url] copy];
});
for (NSDictionary *callbacks in callbacksForURL) {
dispatch_async(dispatch_get_main_queue(), ^{
SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey];
if (callback) callback(receivedSize, expectedSize);
});
}
}
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
SDWebImageDownloader *sself = wself;
if (!sself) return;
__block NSArray *callbacksForURL;
dispatch_barrier_sync(sself.barrierQueue, ^{
callbacksForURL = [sself.URLCallbacks[url] copy];
if (finished) {
[sself.URLCallbacks removeObjectForKey:url];
}
});
for (NSDictionary *callbacks in callbacksForURL) {
SDWebImageDownloaderCompletedBlock callback = callbacks[kCompletedCallbackKey];
if (callback) callback(image, data, error, finished);
}
}
cancelled:^{
SDWebImageDownloader *sself = wself;
if (!sself) return;
dispatch_barrier_async(sself.barrierQueue, ^{
[sself.URLCallbacks removeObjectForKey:url];
});
}];
operation.shouldDecompressImages = wself.shouldDecompressImages;
if (wself.urlCredential) {
operation.credential = wself.urlCredential;
} else if (wself.username && wself.password) {
operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession];
}
if (options & SDWebImageDownloaderHighPriority) {
operation.queuePriority = NSOperationQueuePriorityHigh;
} else if (options & SDWebImageDownloaderLowPriority) {
operation.queuePriority = NSOperationQueuePriorityLow;
}
[wself.downloadQueue addOperation:operation];
if (wself.executionOrder == SDWebImageDownloaderLIFOExecutionOrder) {
// Emulate LIFO execution order by systematically adding new operations as last operation's dependency
[wself.lastAddedOperation addDependency:operation];
wself.lastAddedOperation = operation;
}
}];
return operation;
}
- (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageNoParamsBlock)createCallback {
// The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data.
if (url == nil) {
if (completedBlock != nil) {
completedBlock(nil, nil, nil, NO);
}
return;
}
dispatch_barrier_sync(self.barrierQueue, ^{
BOOL first = NO;
if (!self.URLCallbacks[url]) {
self.URLCallbacks[url] = [NSMutableArray new];
first = YES;
}
// Handle single download of simultaneous download request for the same URL
NSMutableArray *callbacksForURL = self.URLCallbacks[url];
NSMutableDictionary *callbacks = [NSMutableDictionary new];
if (progressBlock) callbacks[kProgressCallbackKey] = [progressBlock copy];
if (completedBlock) callbacks[kCompletedCallbackKey] = [completedBlock copy];
[callbacksForURL addObject:callbacks];
self.URLCallbacks[url] = callbacksForURL;
if (first) {
createCallback();
}
});
}
- (void)setSuspended:(BOOL)suspended {
[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

View File

@ -0,0 +1,106 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageDownloader.h"
#import "SDWebImageOperation.h"
extern NSString *const SDWebImageDownloadStartNotification;
extern NSString *const SDWebImageDownloadReceiveResponseNotification;
extern NSString *const SDWebImageDownloadStopNotification;
extern NSString *const SDWebImageDownloadFinishNotification;
@interface SDWebImageDownloaderOperation : NSOperation <SDWebImageOperation, NSURLSessionTaskDelegate, NSURLSessionDataDelegate>
/**
* 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;
/**
* 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 __deprecated_msg("Property deprecated. Does nothing. Kept only for backwards compatibility");
/**
* The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`.
*
* This will be overridden by any shared credentials that exist for the username or password of the request URL, if present.
*/
@property (nonatomic, strong) NSURLCredential *credential;
/**
* The SDWebImageDownloaderOptions for the receiver.
*/
@property (assign, nonatomic, readonly) SDWebImageDownloaderOptions options;
/**
* The expected size of data.
*/
@property (assign, nonatomic) NSInteger expectedSize;
/**
* The response returned by the operation's connection.
*/
@property (strong, nonatomic) NSURLResponse *response;
/**
* Initializes a `SDWebImageDownloaderOperation` object
*
* @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
* @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
*/
- (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

View File

@ -0,0 +1,504 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageDownloaderOperation.h"
#import "SDWebImageDecoder.h"
#import "UIImage+MultiFormat.h"
#import <ImageIO/ImageIO.h>
#import "SDWebImageManager.h"
NSString *const SDWebImageDownloadStartNotification = @"SDWebImageDownloadStartNotification";
NSString *const SDWebImageDownloadReceiveResponseNotification = @"SDWebImageDownloadReceiveResponseNotification";
NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification";
NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinishNotification";
@interface SDWebImageDownloaderOperation ()
@property (copy, nonatomic) SDWebImageDownloaderProgressBlock progressBlock;
@property (copy, nonatomic) SDWebImageDownloaderCompletedBlock completedBlock;
@property (copy, nonatomic) SDWebImageNoParamsBlock cancelBlock;
@property (assign, nonatomic, getter = isExecuting) BOOL executing;
@property (assign, nonatomic, getter = isFinished) BOOL finished;
@property (strong, nonatomic) NSMutableData *imageData;
// 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
@property (assign, nonatomic) UIBackgroundTaskIdentifier backgroundTaskId;
#endif
@end
@implementation SDWebImageDownloaderOperation {
size_t width, height;
UIImageOrientation orientation;
BOOL responseFromCached;
}
@synthesize executing = _executing;
@synthesize finished = _finished;
- (id)initWithRequest:(NSURLRequest *)request
options:(SDWebImageDownloaderOptions)options
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;
_options = options;
_progressBlock = [progressBlock copy];
_completedBlock = [completedBlock copy];
_cancelBlock = [cancelBlock copy];
_executing = NO;
_finished = NO;
_expectedSize = 0;
_unownedSession = session;
responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called
}
return self;
}
- (void)start {
@synchronized (self) {
if (self.isCancelled) {
self.finished = YES;
[self reset];
return;
}
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
Class UIApplicationClass = NSClassFromString(@"UIApplication");
BOOL hasApplication = UIApplicationClass && [UIApplicationClass respondsToSelector:@selector(sharedApplication)];
if (hasApplication && [self shouldContinueWhenAppEntersBackground]) {
__weak __typeof__ (self) wself = self;
UIApplication * app = [UIApplicationClass performSelector:@selector(sharedApplication)];
self.backgroundTaskId = [app beginBackgroundTaskWithExpirationHandler:^{
__strong __typeof (wself) sself = wself;
if (sself) {
[sself cancel];
[app endBackgroundTask:sself.backgroundTaskId];
sself.backgroundTaskId = UIBackgroundTaskInvalid;
}
}];
}
#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.thread = [NSThread currentThread];
}
[self.dataTask resume];
if (self.dataTask) {
if (self.progressBlock) {
self.progressBlock(0, NSURLResponseUnknownLength);
}
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self];
});
}
else {
if (self.completedBlock) {
self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Connection can't be initialized"}], YES);
}
}
#if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0
Class UIApplicationClass = NSClassFromString(@"UIApplication");
if(!UIApplicationClass || ![UIApplicationClass respondsToSelector:@selector(sharedApplication)]) {
return;
}
if (self.backgroundTaskId != UIBackgroundTaskInvalid) {
UIApplication * app = [UIApplication performSelector:@selector(sharedApplication)];
[app endBackgroundTask:self.backgroundTaskId];
self.backgroundTaskId = UIBackgroundTaskInvalid;
}
#endif
}
- (void)cancel {
@synchronized (self) {
if (self.thread) {
[self performSelector:@selector(cancelInternalAndStop) onThread:self.thread withObject:nil waitUntilDone:NO];
}
else {
[self cancelInternal];
}
}
}
- (void)cancelInternalAndStop {
if (self.isFinished) return;
[self cancelInternal];
}
- (void)cancelInternal {
if (self.isFinished) return;
[super cancel];
if (self.cancelBlock) self.cancelBlock();
if (self.dataTask) {
[self.dataTask cancel];
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self];
});
// As we cancelled the connection, its callback won't be called and thus won't
// maintain the isFinished and isExecuting flags.
if (self.isExecuting) self.executing = NO;
if (!self.isFinished) self.finished = YES;
}
[self reset];
}
- (void)done {
self.finished = YES;
self.executing = NO;
[self reset];
}
- (void)reset {
self.cancelBlock = nil;
self.completedBlock = nil;
self.progressBlock = nil;
self.dataTask = nil;
self.imageData = nil;
self.thread = nil;
if (self.ownedSession) {
[self.ownedSession invalidateAndCancel];
self.ownedSession = nil;
}
}
- (void)setFinished:(BOOL)finished {
[self willChangeValueForKey:@"isFinished"];
_finished = finished;
[self didChangeValueForKey:@"isFinished"];
}
- (void)setExecuting:(BOOL)executing {
[self willChangeValueForKey:@"isExecuting"];
_executing = executing;
[self didChangeValueForKey:@"isExecuting"];
}
- (BOOL)isConcurrent {
return YES;
}
#pragma mark NSURLSessionDataDelegate
- (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)) {
NSInteger expected = response.expectedContentLength > 0 ? (NSInteger)response.expectedContentLength : 0;
self.expectedSize = expected;
if (self.progressBlock) {
self.progressBlock(0, expected);
}
self.imageData = [[NSMutableData alloc] initWithCapacity:expected];
self.response = response;
dispatch_async(dispatch_get_main_queue(), ^{
[[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadReceiveResponseNotification object:self];
});
}
else {
NSUInteger code = [((NSHTTPURLResponse *)response) statusCode];
//This is the case when server returns '304 Not Modified'. It means that remote image is not changed.
//In case of 304 we need just cancel the operation and return cached image from the cache.
if (code == 304) {
[self cancelInternal];
} else {
[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);
}
[self done];
}
if (completionHandler) {
completionHandler(NSURLSessionResponseAllow);
}
}
- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data {
[self.imageData appendData:data];
if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock) {
// The following code is from http://www.cocoaintheshell.com/2011/05/progressive-images-download-imageio/
// Thanks to the author @Nyx0uf
// Get the total bytes downloaded
const NSInteger totalSize = self.imageData.length;
// Update the data source, we must pass ALL the data, not just the new bytes
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)self.imageData, NULL);
if (width + height == 0) {
CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
if (properties) {
NSInteger orientationValue = -1;
CFTypeRef val = CFDictionaryGetValue(properties, kCGImagePropertyPixelHeight);
if (val) CFNumberGetValue(val, kCFNumberLongType, &height);
val = CFDictionaryGetValue(properties, kCGImagePropertyPixelWidth);
if (val) CFNumberGetValue(val, kCFNumberLongType, &width);
val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
if (val) CFNumberGetValue(val, kCFNumberNSIntegerType, &orientationValue);
CFRelease(properties);
// 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 didCompleteWithError.) So save it here and pass it on later.
orientation = [[self class] orientationFromPropertyValue:(orientationValue == -1 ? 1 : orientationValue)];
}
}
if (width + height > 0 && totalSize < self.expectedSize) {
// Create the image
CGImageRef partialImageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
#ifdef TARGET_OS_IPHONE
// Workaround for iOS anamorphic image
if (partialImageRef) {
const size_t partialHeight = CGImageGetHeight(partialImageRef);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL, width, height, 8, width * 4, colorSpace, kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
CGColorSpaceRelease(colorSpace);
if (bmContext) {
CGContextDrawImage(bmContext, (CGRect){.origin.x = 0.0f, .origin.y = 0.0f, .size.width = width, .size.height = partialHeight}, partialImageRef);
CGImageRelease(partialImageRef);
partialImageRef = CGBitmapContextCreateImage(bmContext);
CGContextRelease(bmContext);
}
else {
CGImageRelease(partialImageRef);
partialImageRef = nil;
}
}
#endif
if (partialImageRef) {
UIImage *image = [UIImage imageWithCGImage:partialImageRef scale:1 orientation:orientation];
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL];
UIImage *scaledImage = [self scaledImageForKey:key image:image];
if (self.shouldDecompressImages) {
image = [UIImage decodedImageWithImage:scaledImage];
}
else {
image = scaledImage;
}
CGImageRelease(partialImageRef);
dispatch_main_sync_safe(^{
if (self.completedBlock) {
self.completedBlock(image, nil, nil, NO);
}
});
}
}
CFRelease(imageSource);
}
if (self.progressBlock) {
self.progressBlock(self.imageData.length, self.expectedSize);
}
}
- (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:
return UIImageOrientationUp;
case 3:
return UIImageOrientationDown;
case 8:
return UIImageOrientationLeft;
case 6:
return UIImageOrientationRight;
case 2:
return UIImageOrientationUpMirrored;
case 4:
return UIImageOrientationDownMirrored;
case 5:
return UIImageOrientationLeftMirrored;
case 7:
return UIImageOrientationRightMirrored;
default:
return UIImageOrientationUp;
}
}
- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image {
return SDScaledImageForKey(key, image);
}
- (BOOL)shouldContinueWhenAppEntersBackground {
return self.options & SDWebImageDownloaderContinueInBackground;
}
@end

View File

@ -0,0 +1,304 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageCompat.h"
#import "SDWebImageOperation.h"
#import "SDWebImageDownloader.h"
#import "SDImageCache.h"
typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
/**
* By default, when a URL fail to be downloaded, the URL is blacklisted so the library won't keep trying.
* This flag disable this blacklisting.
*/
SDWebImageRetryFailed = 1 << 0,
/**
* By default, image downloads are started during UI interactions, this flags disable this feature,
* leading to delayed download on UIScrollView deceleration for instance.
*/
SDWebImageLowPriority = 1 << 1,
/**
* This flag disables on-disk caching
*/
SDWebImageCacheMemoryOnly = 1 << 2,
/**
* This flag enables progressive download, the image is displayed progressively during download as a browser would do.
* By default, the image is only displayed once completely downloaded.
*/
SDWebImageProgressiveDownload = 1 << 3,
/**
* Even if the image is cached, respect the HTTP response cache control, and refresh the image from remote location if needed.
* The disk caching will be handled by NSURLCache instead of SDWebImage leading to slight performance degradation.
* This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics.
* If a cached image is refreshed, the completion block is called once with the cached image and again with the final image.
*
* Use this flag only if you can't make your URLs static with embedded cache busting parameter.
*/
SDWebImageRefreshCached = 1 << 4,
/**
* In iOS 4+, continue the download of the image if the app goes to background. This is achieved by asking the system for
* extra time in background to let the request finish. If the background task expires the operation will be cancelled.
*/
SDWebImageContinueInBackground = 1 << 5,
/**
* Handles cookies stored in NSHTTPCookieStore by setting
* NSMutableURLRequest.HTTPShouldHandleCookies = YES;
*/
SDWebImageHandleCookies = 1 << 6,
/**
* Enable to allow untrusted SSL certificates.
* Useful for testing purposes. Use with caution in production.
*/
SDWebImageAllowInvalidSSLCertificates = 1 << 7,
/**
* 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,
/**
* By default, placeholder images are loaded while the image is loading. This flag will delay the loading
* of the placeholder image until after the image has finished loading.
*/
SDWebImageDelayPlaceholder = 1 << 9,
/**
* We usually don't call transformDownloadedImage delegate method on animated images,
* as most transformation code would mangle it.
* Use this flag to transform them anyway.
*/
SDWebImageTransformAnimatedImage = 1 << 10,
/**
* By default, image is added to the imageView after download. But in some cases, we want to
* have the hand before setting the image (apply a filter or add it with cross-fade animation for instance)
* Use this flag if you want to manually set the image in the completion when success
*/
SDWebImageAvoidAutoSetImage = 1 << 11
};
typedef void(^SDWebImageCompletionBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL);
typedef void(^SDWebImageCompletionWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL);
typedef NSString *(^SDWebImageCacheKeyFilterBlock)(NSURL *url);
@class SDWebImageManager;
@protocol SDWebImageManagerDelegate <NSObject>
@optional
/**
* Controls which image should be downloaded when the image is not found in the cache.
*
* @param imageManager The current `SDWebImageManager`
* @param imageURL The url of the image to be downloaded
*
* @return Return NO to prevent the downloading of the image on cache misses. If not implemented, YES is implied.
*/
- (BOOL)imageManager:(SDWebImageManager *)imageManager shouldDownloadImageForURL:(NSURL *)imageURL;
/**
* Allows to transform the image immediately after it has been downloaded and just before to cache it on disk and memory.
* NOTE: This method is called from a global queue in order to not to block the main thread.
*
* @param imageManager The current `SDWebImageManager`
* @param image The image to transform
* @param imageURL The url of the image to transform
*
* @return The transformed image object.
*/
- (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL;
@end
/**
* The SDWebImageManager is the class behind the UIImageView+WebCache category and likes.
* It ties the asynchronous downloader (SDWebImageDownloader) with the image cache store (SDImageCache).
* You can use this class directly to benefit from web image downloading with caching in another context than
* a UIView.
*
* Here is a simple example of how to use SDWebImageManager:
*
* @code
SDWebImageManager *manager = [SDWebImageManager sharedManager];
[manager downloadImageWithURL:imageURL
options:0
progress:nil
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (image) {
// do something with image
}
}];
* @endcode
*/
@interface SDWebImageManager : NSObject
@property (weak, nonatomic) id <SDWebImageManagerDelegate> delegate;
@property (strong, nonatomic, readonly) SDImageCache *imageCache;
@property (strong, nonatomic, readonly) SDWebImageDownloader *imageDownloader;
/**
* The cache filter is a block used each time SDWebImageManager need to convert an URL into a cache key. This can
* be used to remove dynamic part of an image URL.
*
* The following example sets a filter in the application delegate that will remove any query-string from the
* URL before to use it as a cache key:
*
* @code
[[SDWebImageManager sharedManager] setCacheKeyFilter:^(NSURL *url) {
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString];
}];
* @endcode
*/
@property (nonatomic, copy) SDWebImageCacheKeyFilterBlock cacheKeyFilter;
/**
* Returns global SDWebImageManager instance.
*
* @return SDWebImageManager shared instance
*/
+ (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.
*
* @param url The URL to the image
* @param options A mask to specify options to use for this request
* @param progressBlock A block called while image is downloading
* @param completedBlock A block called when operation has been completed.
*
* This parameter is required.
*
* This block has no return value and takes the requested UIImage as first parameter.
* In case of error the image parameter is nil and the second parameter may contain an NSError.
*
* The third parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache
* or from the memory cache or from the network.
*
* The last parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is
* downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the
* block is called a last time with the full image and the last parameter set to YES.
*
* @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation
*/
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletionWithFinishedBlock)completedBlock;
/**
* Saves image to cache for given URL
*
* @param image The image to cache
* @param url The URL to the image
*
*/
- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url;
/**
* Cancel all current operations
*/
- (void)cancelAll;
/**
* Check one or more operations running
*/
- (BOOL)isRunning;
/**
* Check if image has already been cached
*
* @param url image url
*
* @return if the image was already cached
*/
- (BOOL)cachedImageExistsForURL:(NSURL *)url;
/**
* Check if image has already been cached on disk only
*
* @param url image url
*
* @return if the image was already cached (disk only)
*/
- (BOOL)diskImageExistsForURL:(NSURL *)url;
/**
* Async check if image has already been cached
*
* @param url image url
* @param completionBlock the block to be executed when the check is finished
*
* @note the completion block is always executed on the main queue
*/
- (void)cachedImageExistsForURL:(NSURL *)url
completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
/**
* Async check if image has already been cached on disk only
*
* @param url image url
* @param completionBlock the block to be executed when the check is finished
*
* @note the completion block is always executed on the main queue
*/
- (void)diskImageExistsForURL:(NSURL *)url
completion:(SDWebImageCheckCacheCompletionBlock)completionBlock;
/**
*Return the cache key for a given URL
*/
- (NSString *)cacheKeyForURL:(NSURL *)url;
@end
#pragma mark - Deprecated
typedef void(^SDWebImageCompletedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionBlock`");
typedef void(^SDWebImageCompletedWithFinishedBlock)(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished) __deprecated_msg("Block type deprecated. Use `SDWebImageCompletionWithFinishedBlock`");
@interface SDWebImageManager (Deprecated)
/**
* Downloads the image at the given URL if not present in cache or return the cached version otherwise.
*
* @deprecated This method has been deprecated. Use `downloadImageWithURL:options:progress:completed:`
*/
- (id <SDWebImageOperation>)downloadWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletedWithFinishedBlock)completedBlock __deprecated_msg("Method deprecated. Use `downloadImageWithURL:options:progress:completed:`");
@end

View File

@ -0,0 +1,375 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageManager.h"
#import <objc/message.h>
@interface SDWebImageCombinedOperation : NSObject <SDWebImageOperation>
@property (assign, nonatomic, getter = isCancelled) BOOL cancelled;
@property (copy, nonatomic) SDWebImageNoParamsBlock cancelBlock;
@property (strong, nonatomic) NSOperation *cacheOperation;
@end
@interface SDWebImageManager ()
@property (strong, nonatomic, readwrite) SDImageCache *imageCache;
@property (strong, nonatomic, readwrite) SDWebImageDownloader *imageDownloader;
@property (strong, nonatomic) NSMutableSet *failedURLs;
@property (strong, nonatomic) NSMutableArray *runningOperations;
@end
@implementation SDWebImageManager
+ (id)sharedManager {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [self new];
});
return instance;
}
- (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 = cache;
_imageDownloader = downloader;
_failedURLs = [NSMutableSet new];
_runningOperations = [NSMutableArray new];
}
return self;
}
- (NSString *)cacheKeyForURL:(NSURL *)url {
if (!url) {
return @"";
}
if (self.cacheKeyFilter) {
return self.cacheKeyFilter(url);
} else {
return [url absoluteString];
}
}
- (BOOL)cachedImageExistsForURL:(NSURL *)url {
NSString *key = [self cacheKeyForURL:url];
if ([self.imageCache imageFromMemoryCacheForKey:key] != nil) return YES;
return [self.imageCache diskImageExistsWithKey:key];
}
- (BOOL)diskImageExistsForURL:(NSURL *)url {
NSString *key = [self cacheKeyForURL:url];
return [self.imageCache diskImageExistsWithKey:key];
}
- (void)cachedImageExistsForURL:(NSURL *)url
completion:(SDWebImageCheckCacheCompletionBlock)completionBlock {
NSString *key = [self cacheKeyForURL:url];
BOOL isInMemoryCache = ([self.imageCache imageFromMemoryCacheForKey:key] != nil);
if (isInMemoryCache) {
// making sure we call the completion block on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
if (completionBlock) {
completionBlock(YES);
}
});
return;
}
[self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) {
// the completion block of checkDiskCacheForImageWithKey:completion: is always called on the main queue, no need to further dispatch
if (completionBlock) {
completionBlock(isInDiskCache);
}
}];
}
- (void)diskImageExistsForURL:(NSURL *)url
completion:(SDWebImageCheckCacheCompletionBlock)completionBlock {
NSString *key = [self cacheKeyForURL:url];
[self.imageCache diskImageExistsWithKey:key completion:^(BOOL isInDiskCache) {
// the completion block of checkDiskCacheForImageWithKey:completion: is always called on the main queue, no need to further dispatch
if (completionBlock) {
completionBlock(isInDiskCache);
}
}];
}
- (id <SDWebImageOperation>)downloadImageWithURL:(NSURL *)url
options:(SDWebImageOptions)options
progress:(SDWebImageDownloaderProgressBlock)progressBlock
completed:(SDWebImageCompletionWithFinishedBlock)completedBlock {
// Invoking this method without a completedBlock is pointless
NSAssert(completedBlock != nil, @"If you mean to prefetch the image, use -[SDWebImagePrefetcher prefetchURLs] instead");
// Very common mistake is to send the URL using NSString object instead of NSURL. For some strange reason, XCode won't
// throw any warning for this type mismatch. Here we failsafe this error by allowing URLs to be passed as NSString.
if ([url isKindOfClass:NSString.class]) {
url = [NSURL URLWithString:(NSString *)url];
}
// Prevents app crashing on argument type error like sending NSNull instead of NSURL
if (![url isKindOfClass:NSURL.class]) {
url = nil;
}
__block SDWebImageCombinedOperation *operation = [SDWebImageCombinedOperation new];
__weak SDWebImageCombinedOperation *weakOperation = operation;
BOOL isFailedUrl = NO;
@synchronized (self.failedURLs) {
isFailedUrl = [self.failedURLs containsObject:url];
}
if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
dispatch_main_sync_safe(^{
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil];
completedBlock(nil, error, SDImageCacheTypeNone, YES, url);
});
return operation;
}
@synchronized (self.runningOperations) {
[self.runningOperations addObject:operation];
}
NSString *key = [self cacheKeyForURL:url];
operation.cacheOperation = [self.imageCache queryDiskCacheForKey:key done:^(UIImage *image, SDImageCacheType cacheType) {
if (operation.isCancelled) {
@synchronized (self.runningOperations) {
[self.runningOperations removeObject:operation];
}
return;
}
if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) {
if (image && options & SDWebImageRefreshCached) {
dispatch_main_sync_safe(^{
// If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image
// AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.
completedBlock(image, nil, cacheType, YES, url);
});
}
// download if no image or requested to refresh anyway, and download allowed by delegate
SDWebImageDownloaderOptions downloaderOptions = 0;
if (options & SDWebImageLowPriority) downloaderOptions |= SDWebImageDownloaderLowPriority;
if (options & SDWebImageProgressiveDownload) downloaderOptions |= SDWebImageDownloaderProgressiveDownload;
if (options & SDWebImageRefreshCached) downloaderOptions |= SDWebImageDownloaderUseNSURLCache;
if (options & SDWebImageContinueInBackground) downloaderOptions |= SDWebImageDownloaderContinueInBackground;
if (options & SDWebImageHandleCookies) downloaderOptions |= SDWebImageDownloaderHandleCookies;
if (options & SDWebImageAllowInvalidSSLCertificates) downloaderOptions |= SDWebImageDownloaderAllowInvalidSSLCertificates;
if (options & SDWebImageHighPriority) downloaderOptions |= SDWebImageDownloaderHighPriority;
if (image && options & SDWebImageRefreshCached) {
// force progressive off if image already cached but forced refreshing
downloaderOptions &= ~SDWebImageDownloaderProgressiveDownload;
// ignore image read from NSURLCache if image if cached but force refreshing
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
}
id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) {
__strong __typeof(weakOperation) strongOperation = weakOperation;
if (!strongOperation || strongOperation.isCancelled) {
// Do nothing if the operation was cancelled
// See #699 for more details
// if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data
}
else if (error) {
dispatch_main_sync_safe(^{
if (strongOperation && !strongOperation.isCancelled) {
completedBlock(nil, error, SDImageCacheTypeNone, finished, url);
}
});
if ( error.code != NSURLErrorNotConnectedToInternet
&& error.code != NSURLErrorCancelled
&& error.code != NSURLErrorTimedOut
&& error.code != NSURLErrorInternationalRoamingOff
&& error.code != NSURLErrorDataNotAllowed
&& error.code != NSURLErrorCannotFindHost
&& error.code != NSURLErrorCannotConnectToHost) {
@synchronized (self.failedURLs) {
[self.failedURLs addObject:url];
}
}
}
else {
if ((options & SDWebImageRetryFailed)) {
@synchronized (self.failedURLs) {
[self.failedURLs removeObject:url];
}
}
BOOL cacheOnDisk = !(options & SDWebImageCacheMemoryOnly);
if (options & SDWebImageRefreshCached && image && !downloadedImage) {
// Image refresh hit the NSURLCache cache, do not call the completion block
}
else if (downloadedImage && (!downloadedImage.images || (options & SDWebImageTransformAnimatedImage)) && [self.delegate respondsToSelector:@selector(imageManager:transformDownloadedImage:withURL:)]) {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{
UIImage *transformedImage = [self.delegate imageManager:self transformDownloadedImage:downloadedImage withURL:url];
if (transformedImage && finished) {
BOOL imageWasTransformed = ![transformedImage isEqual:downloadedImage];
[self.imageCache storeImage:transformedImage recalculateFromImage:imageWasTransformed imageData:(imageWasTransformed ? nil : data) forKey:key toDisk:cacheOnDisk];
}
dispatch_main_sync_safe(^{
if (strongOperation && !strongOperation.isCancelled) {
completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url);
}
});
});
}
else {
if (downloadedImage && finished) {
[self.imageCache storeImage:downloadedImage recalculateFromImage:NO imageData:data forKey:key toDisk:cacheOnDisk];
}
dispatch_main_sync_safe(^{
if (strongOperation && !strongOperation.isCancelled) {
completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url);
}
});
}
}
if (finished) {
@synchronized (self.runningOperations) {
if (strongOperation) {
[self.runningOperations removeObject:strongOperation];
}
}
}
}];
operation.cancelBlock = ^{
[subOperation cancel];
@synchronized (self.runningOperations) {
__strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation) {
[self.runningOperations removeObject:strongOperation];
}
}
};
}
else if (image) {
dispatch_main_sync_safe(^{
__strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation && !strongOperation.isCancelled) {
completedBlock(image, nil, cacheType, YES, url);
}
});
@synchronized (self.runningOperations) {
[self.runningOperations removeObject:operation];
}
}
else {
// Image not in cache and download disallowed by delegate
dispatch_main_sync_safe(^{
__strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation && !weakOperation.isCancelled) {
completedBlock(nil, nil, SDImageCacheTypeNone, YES, url);
}
});
@synchronized (self.runningOperations) {
[self.runningOperations removeObject:operation];
}
}
}];
return operation;
}
- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url {
if (image && url) {
NSString *key = [self cacheKeyForURL:url];
[self.imageCache storeImage:image forKey:key toDisk:YES];
}
}
- (void)cancelAll {
@synchronized (self.runningOperations) {
NSArray *copiedOperations = [self.runningOperations copy];
[copiedOperations makeObjectsPerformSelector:@selector(cancel)];
[self.runningOperations removeObjectsInArray:copiedOperations];
}
}
- (BOOL)isRunning {
BOOL isRunning = NO;
@synchronized(self.runningOperations) {
isRunning = (self.runningOperations.count > 0);
}
return isRunning;
}
@end
@implementation SDWebImageCombinedOperation
- (void)setCancelBlock:(SDWebImageNoParamsBlock)cancelBlock {
// check if the operation is already cancelled, then we just call the cancelBlock
if (self.isCancelled) {
if (cancelBlock) {
cancelBlock();
}
_cancelBlock = nil; // don't forget to nil the cancelBlock, otherwise we will get crashes
} else {
_cancelBlock = [cancelBlock copy];
}
}
- (void)cancel {
self.cancelled = YES;
if (self.cacheOperation) {
[self.cacheOperation cancel];
self.cacheOperation = nil;
}
if (self.cancelBlock) {
self.cancelBlock();
// TODO: this is a temporary fix to #809.
// Until we can figure the exact cause of the crash, going with the ivar instead of the setter
// self.cancelBlock = nil;
_cancelBlock = nil;
}
}
@end
@implementation SDWebImageManager (Deprecated)
// deprecated method, uses the non deprecated method
// adapter for the completion block
- (id <SDWebImageOperation>)downloadWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedWithFinishedBlock)completedBlock {
return [self downloadImageWithURL:url
options:options
progress:progressBlock
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType, finished);
}
}];
}
@end

View File

@ -6,12 +6,10 @@
* file that was distributed with this source code.
*/
@class SDWebImageManager;
#import <Foundation/Foundation.h>
@protocol SDWebImageManagerDelegate <NSObject>
@protocol SDWebImageOperation <NSObject>
@optional
- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image;
- (void)cancel;
@end

View File

@ -0,0 +1,108 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageManager.h"
@class SDWebImagePrefetcher;
@protocol SDWebImagePrefetcherDelegate <NSObject>
@optional
/**
* Called when an image was prefetched.
*
* @param imagePrefetcher The current image prefetcher
* @param imageURL The image url that was prefetched
* @param finishedCount The total number of images that were prefetched (successful or not)
* @param totalCount The total number of images that were to be prefetched
*/
- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didPrefetchURL:(NSURL *)imageURL finishedCount:(NSUInteger)finishedCount totalCount:(NSUInteger)totalCount;
/**
* Called when all images are prefetched.
* @param imagePrefetcher The current image prefetcher
* @param totalCount The total number of images that were prefetched (whether successful or not)
* @param skippedCount The total number of images that were skipped
*/
- (void)imagePrefetcher:(SDWebImagePrefetcher *)imagePrefetcher didFinishWithTotalCount:(NSUInteger)totalCount skippedCount:(NSUInteger)skippedCount;
@end
typedef void(^SDWebImagePrefetcherProgressBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfTotalUrls);
typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, NSUInteger noOfSkippedUrls);
/**
* Prefetch some URLs in the cache for future use. Images are downloaded in low priority.
*/
@interface SDWebImagePrefetcher : NSObject
/**
* The web image manager
*/
@property (strong, nonatomic, readonly) SDWebImageManager *manager;
/**
* Maximum number of URLs to prefetch at the same time. Defaults to 3.
*/
@property (nonatomic, assign) NSUInteger maxConcurrentDownloads;
/**
* SDWebImageOptions for prefetcher. Defaults to SDWebImageLowPriority.
*/
@property (nonatomic, assign) SDWebImageOptions options;
/**
* Queue options for Prefetcher. Defaults to Main Queue.
*/
@property (nonatomic, assign) dispatch_queue_t prefetcherQueue;
@property (weak, nonatomic) id <SDWebImagePrefetcherDelegate> delegate;
/**
* Return the global image prefetcher instance.
*/
+ (SDWebImagePrefetcher *)sharedImagePrefetcher;
/**
* Allows you to instantiate a prefetcher with any arbitrary image manager.
*/
- (id)initWithImageManager:(SDWebImageManager *)manager;
/**
* Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
* currently one image is downloaded at a time,
* and skips images for failed downloads and proceed to the next image in the list
*
* @param urls list of URLs to prefetch
*/
- (void)prefetchURLs:(NSArray *)urls;
/**
* Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
* currently one image is downloaded at a time,
* and skips images for failed downloads and proceed to the next image in the list
*
* @param urls list of URLs to prefetch
* @param progressBlock block to be called when progress updates;
* first parameter is the number of completed (successful or not) requests,
* second parameter is the total number of images originally requested to be prefetched
* @param completionBlock block to be called when prefetching is completed
* first param is the number of completed (successful or not) requests,
* second parameter is the number of skipped requests
*/
- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock;
/**
* Remove and cancel queued list
*/
- (void)cancelPrefetching;
@end

View File

@ -0,0 +1,140 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImagePrefetcher.h"
@interface SDWebImagePrefetcher ()
@property (strong, nonatomic) SDWebImageManager *manager;
@property (strong, nonatomic) NSArray *prefetchURLs;
@property (assign, nonatomic) NSUInteger requestedCount;
@property (assign, nonatomic) NSUInteger skippedCount;
@property (assign, nonatomic) NSUInteger finishedCount;
@property (assign, nonatomic) NSTimeInterval startedTime;
@property (copy, nonatomic) SDWebImagePrefetcherCompletionBlock completionBlock;
@property (copy, nonatomic) SDWebImagePrefetcherProgressBlock progressBlock;
@end
@implementation SDWebImagePrefetcher
+ (SDWebImagePrefetcher *)sharedImagePrefetcher {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [self new];
});
return instance;
}
- (id)init {
return [self initWithImageManager:[SDWebImageManager new]];
}
- (id)initWithImageManager:(SDWebImageManager *)manager {
if ((self = [super init])) {
_manager = manager;
_options = SDWebImageLowPriority;
_prefetcherQueue = dispatch_get_main_queue();
self.maxConcurrentDownloads = 3;
}
return self;
}
- (void)setMaxConcurrentDownloads:(NSUInteger)maxConcurrentDownloads {
self.manager.imageDownloader.maxConcurrentDownloads = maxConcurrentDownloads;
}
- (NSUInteger)maxConcurrentDownloads {
return self.manager.imageDownloader.maxConcurrentDownloads;
}
- (void)startPrefetchingAtIndex:(NSUInteger)index {
if (index >= self.prefetchURLs.count) return;
self.requestedCount++;
[self.manager downloadImageWithURL:self.prefetchURLs[index] options:self.options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!finished) return;
self.finishedCount++;
if (image) {
if (self.progressBlock) {
self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
}
}
else {
if (self.progressBlock) {
self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
}
// Add last failed
self.skippedCount++;
}
if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didPrefetchURL:finishedCount:totalCount:)]) {
[self.delegate imagePrefetcher:self
didPrefetchURL:self.prefetchURLs[index]
finishedCount:self.finishedCount
totalCount:self.prefetchURLs.count
];
}
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);
self.completionBlock = nil;
}
self.progressBlock = nil;
}
}];
}
- (void)reportStatus {
NSUInteger total = [self.prefetchURLs count];
if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) {
[self.delegate imagePrefetcher:self
didFinishWithTotalCount:(total - self.skippedCount)
skippedCount:self.skippedCount
];
}
}
- (void)prefetchURLs:(NSArray *)urls {
[self prefetchURLs:urls progress:nil completed:nil];
}
- (void)prefetchURLs:(NSArray *)urls progress:(SDWebImagePrefetcherProgressBlock)progressBlock completed:(SDWebImagePrefetcherCompletionBlock)completionBlock {
[self cancelPrefetching]; // Prevent duplicate prefetch request
self.startedTime = CFAbsoluteTimeGetCurrent();
self.prefetchURLs = urls;
self.completionBlock = completionBlock;
self.progressBlock = progressBlock;
if (urls.count == 0) {
if (completionBlock) {
completionBlock(0,0);
}
} else {
// Starts prefetching from the very first image on the list with the max allowed concurrency
NSUInteger listCount = self.prefetchURLs.count;
for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) {
[self startPrefetchingAtIndex:i];
}
}
}
- (void)cancelPrefetching {
self.prefetchURLs = nil;
self.skippedCount = 0;
self.requestedCount = 0;
self.finishedCount = 0;
[self.manager cancelAll];
}
@end

View File

@ -0,0 +1,229 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageCompat.h"
#import "SDWebImageManager.h"
/**
* Integrates SDWebImage async downloading and caching of remote images with UIButtonView.
*/
@interface UIButton (WebCache)
/**
* Get the current image URL.
*/
- (NSURL *)sd_currentImageURL;
/**
* Get the image URL for a control state.
*
* @param state Which state you want to know the URL for. The values are described in UIControlState.
*/
- (NSURL *)sd_imageURLForState:(UIControlState)state;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state;
/**
* Set the imageView `image` with an `url` and a placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @see sd_setImageWithURL:placeholderImage:options:
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the backgroundImageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state;
/**
* Set the backgroundImageView `image` with an `url` and a placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @see sd_setImageWithURL:placeholderImage:options:
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder;
/**
* Set the backgroundImageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
/**
* Set the backgroundImageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the backgroundImageView `image` with an `url`, placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param state The state that uses the specified title. The values are described in UIControlState.
* @param placeholder The image to be set initially, until the image request finishes.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the backgroundImageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Cancel the current image download
*/
- (void)sd_cancelImageLoadForState:(UIControlState)state;
/**
* Cancel the current backgroundImage download
*/
- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state;
@end
@interface UIButton (WebCacheDeprecated)
- (NSURL *)currentImageURL __deprecated_msg("Use `sd_currentImageURL`");
- (NSURL *)imageURLForState:(UIControlState)state __deprecated_msg("Use `sd_imageURLForState:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:completed:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:completed:`");
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:forState:placeholderImage:options:completed:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:completed:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:completed:`");
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setBackgroundImageWithURL:forState:placeholderImage:options:completed:`");
- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelImageLoadForState:`");
- (void)cancelBackgroundImageLoadForState:(UIControlState)state __deprecated_msg("Use `sd_cancelBackgroundImageLoadForState:`");
@end

View File

@ -0,0 +1,270 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "UIButton+WebCache.h"
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
static char imageURLStorageKey;
@implementation UIButton (WebCache)
- (NSURL *)sd_currentImageURL {
NSURL *url = self.imageURLStorage[@(self.state)];
if (!url) {
url = self.imageURLStorage[@(UIControlStateNormal)];
}
return url;
}
- (NSURL *)sd_imageURLForState:(UIControlState)state {
return self.imageURLStorage[@(state)];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state {
[self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self setImage:placeholder forState:state];
[self sd_cancelImageLoadForState:state];
if (!url) {
[self.imageURLStorage removeObjectForKey:@(state)];
dispatch_main_async_safe(^{
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
return;
}
self.imageURLStorage[@(state)] = url;
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe(^{
__strong UIButton *sself = wself;
if (!sself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
[sself setImage:image forState:state];
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forState:state];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:completedBlock];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:completedBlock];
}
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelBackgroundImageLoadForState:state];
[self setBackgroundImage:placeholder forState:state];
if (url) {
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe(^{
__strong UIButton *sself = wself;
if (!sself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
[sself setBackgroundImage:image forState:state];
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setBackgroundImageLoadOperation:operation forState:state];
} else {
dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
if (completedBlock) {
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
- (void)sd_setImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
[self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
}
- (void)sd_cancelImageLoadForState:(UIControlState)state {
[self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonImageOperation%@", @(state)]];
}
- (void)sd_setBackgroundImageLoadOperation:(id<SDWebImageOperation>)operation forState:(UIControlState)state {
[self sd_setImageLoadOperation:operation forKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
}
- (void)sd_cancelBackgroundImageLoadForState:(UIControlState)state {
[self sd_cancelImageLoadOperationWithKey:[NSString stringWithFormat:@"UIButtonBackgroundImageOperation%@", @(state)]];
}
- (NSMutableDictionary *)imageURLStorage {
NSMutableDictionary *storage = objc_getAssociatedObject(self, &imageURLStorageKey);
if (!storage)
{
storage = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, &imageURLStorageKey, storage, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
return storage;
}
@end
@implementation UIButton (WebCacheDeprecated)
- (NSURL *)currentImageURL {
return [self sd_currentImageURL];
}
- (NSURL *)imageURLForState:(UIControlState)state {
return [self sd_imageURLForState:state];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state {
[self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:nil];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:nil];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:nil];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:nil options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:0 completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setBackgroundImageWithURL:url forState:state placeholderImage:placeholder options:options completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)cancelCurrentImageLoad {
// in a backwards compatible manner, cancel for current state
[self sd_cancelImageLoadForState:self.state];
}
- (void)cancelBackgroundImageLoadForState:(UIControlState)state {
[self sd_cancelBackgroundImageLoadForState:state];
}
@end

19
SDWebImage/UIImage+GIF.h Executable file
View File

@ -0,0 +1,19 @@
//
// UIImage+GIF.h
// LBGIFImage
//
// Created by Laurin Brandner on 06.01.12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (GIF)
+ (UIImage *)sd_animatedGIFNamed:(NSString *)name;
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data;
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size;
@end

161
SDWebImage/UIImage+GIF.m Executable file
View File

@ -0,0 +1,161 @@
//
// UIImage+GIF.m
// LBGIFImage
//
// Created by Laurin Brandner on 06.01.12.
// Copyright (c) 2012 __MyCompanyName__. All rights reserved.
//
#import "UIImage+GIF.h"
#import <ImageIO/ImageIO.h>
@implementation UIImage (GIF)
+ (UIImage *)sd_animatedGIFWithData:(NSData *)data {
if (!data) {
return nil;
}
CGImageSourceRef source = CGImageSourceCreateWithData((__bridge CFDataRef)data, NULL);
size_t count = CGImageSourceGetCount(source);
UIImage *animatedImage;
if (count <= 1) {
animatedImage = [[UIImage alloc] initWithData:data];
}
else {
NSMutableArray *images = [NSMutableArray array];
NSTimeInterval duration = 0.0f;
for (size_t i = 0; i < count; i++) {
CGImageRef image = CGImageSourceCreateImageAtIndex(source, i, NULL);
if (!image) {
continue;
}
duration += [self sd_frameDurationAtIndex:i source:source];
[images addObject:[UIImage imageWithCGImage:image scale:[UIScreen mainScreen].scale orientation:UIImageOrientationUp]];
CGImageRelease(image);
}
if (!duration) {
duration = (1.0f / 10.0f) * count;
}
animatedImage = [UIImage animatedImageWithImages:images duration:duration];
}
CFRelease(source);
return animatedImage;
}
+ (float)sd_frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)source {
float frameDuration = 0.1f;
CFDictionaryRef cfFrameProperties = CGImageSourceCopyPropertiesAtIndex(source, index, nil);
NSDictionary *frameProperties = (__bridge NSDictionary *)cfFrameProperties;
NSDictionary *gifProperties = frameProperties[(NSString *)kCGImagePropertyGIFDictionary];
NSNumber *delayTimeUnclampedProp = gifProperties[(NSString *)kCGImagePropertyGIFUnclampedDelayTime];
if (delayTimeUnclampedProp) {
frameDuration = [delayTimeUnclampedProp floatValue];
}
else {
NSNumber *delayTimeProp = gifProperties[(NSString *)kCGImagePropertyGIFDelayTime];
if (delayTimeProp) {
frameDuration = [delayTimeProp floatValue];
}
}
// Many annoying ads specify a 0 duration to make an image flash as quickly as possible.
// We follow Firefox's behavior and use a duration of 100 ms for any frames that specify
// a duration of <= 10 ms. See <rdar://problem/7689300> and <http://webkit.org/b/36082>
// for more information.
if (frameDuration < 0.011f) {
frameDuration = 0.100f;
}
CFRelease(cfFrameProperties);
return frameDuration;
}
+ (UIImage *)sd_animatedGIFNamed:(NSString *)name {
CGFloat scale = [UIScreen mainScreen].scale;
if (scale > 1.0f) {
NSString *retinaPath = [[NSBundle mainBundle] pathForResource:[name stringByAppendingString:@"@2x"] ofType:@"gif"];
NSData *data = [NSData dataWithContentsOfFile:retinaPath];
if (data) {
return [UIImage sd_animatedGIFWithData:data];
}
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
data = [NSData dataWithContentsOfFile:path];
if (data) {
return [UIImage sd_animatedGIFWithData:data];
}
return [UIImage imageNamed:name];
}
else {
NSString *path = [[NSBundle mainBundle] pathForResource:name ofType:@"gif"];
NSData *data = [NSData dataWithContentsOfFile:path];
if (data) {
return [UIImage sd_animatedGIFWithData:data];
}
return [UIImage imageNamed:name];
}
}
- (UIImage *)sd_animatedImageByScalingAndCroppingToSize:(CGSize)size {
if (CGSizeEqualToSize(self.size, size) || CGSizeEqualToSize(size, CGSizeZero)) {
return self;
}
CGSize scaledSize = size;
CGPoint thumbnailPoint = CGPointZero;
CGFloat widthFactor = size.width / self.size.width;
CGFloat heightFactor = size.height / self.size.height;
CGFloat scaleFactor = (widthFactor > heightFactor) ? widthFactor : heightFactor;
scaledSize.width = self.size.width * scaleFactor;
scaledSize.height = self.size.height * scaleFactor;
if (widthFactor > heightFactor) {
thumbnailPoint.y = (size.height - scaledSize.height) * 0.5;
}
else if (widthFactor < heightFactor) {
thumbnailPoint.x = (size.width - scaledSize.width) * 0.5;
}
NSMutableArray *scaledImages = [NSMutableArray array];
for (UIImage *image in self.images) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
[image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
[scaledImages addObject:newImage];
UIGraphicsEndImageContext();
}
return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
}
@end

View File

@ -0,0 +1,15 @@
//
// UIImage+MultiFormat.h
// SDWebImage
//
// Created by Olivier Poitrey on 07/06/13.
// Copyright (c) 2013 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface UIImage (MultiFormat)
+ (UIImage *)sd_imageWithData:(NSData *)data;
@end

View File

@ -0,0 +1,118 @@
//
// UIImage+MultiFormat.m
// SDWebImage
//
// Created by Olivier Poitrey on 07/06/13.
// Copyright (c) 2013 Dailymotion. All rights reserved.
//
#import "UIImage+MultiFormat.h"
#import "UIImage+GIF.h"
#import "NSData+ImageContentType.h"
#import <ImageIO/ImageIO.h>
#ifdef SD_WEBP
#import "UIImage+WebP.h"
#endif
@implementation UIImage (MultiFormat)
+ (UIImage *)sd_imageWithData:(NSData *)data {
if (!data) {
return nil;
}
UIImage *image;
NSString *imageContentType = [NSData sd_contentTypeForImageData:data];
if ([imageContentType isEqualToString:@"image/gif"]) {
image = [UIImage sd_animatedGIFWithData:data];
}
#ifdef SD_WEBP
else if ([imageContentType isEqualToString:@"image/webp"])
{
image = [UIImage sd_imageWithWebPData:data];
}
#endif
else {
image = [[UIImage alloc] initWithData:data];
UIImageOrientation orientation = [self sd_imageOrientationFromImageData:data];
if (orientation != UIImageOrientationUp) {
image = [UIImage imageWithCGImage:image.CGImage
scale:image.scale
orientation:orientation];
}
}
return image;
}
+(UIImageOrientation)sd_imageOrientationFromImageData:(NSData *)imageData {
UIImageOrientation result = UIImageOrientationUp;
CGImageSourceRef imageSource = CGImageSourceCreateWithData((__bridge CFDataRef)imageData, NULL);
if (imageSource) {
CFDictionaryRef properties = CGImageSourceCopyPropertiesAtIndex(imageSource, 0, NULL);
if (properties) {
CFTypeRef val;
int exifOrientation;
val = CFDictionaryGetValue(properties, kCGImagePropertyOrientation);
if (val) {
CFNumberGetValue(val, kCFNumberIntType, &exifOrientation);
result = [self sd_exifOrientationToiOSOrientation:exifOrientation];
} // else - if it's not set it remains at up
CFRelease((CFTypeRef) properties);
} else {
//NSLog(@"NO PROPERTIES, FAIL");
}
CFRelease(imageSource);
}
return result;
}
#pragma mark EXIF orientation tag converter
// Convert an EXIF image orientation to an iOS one.
// reference see here: http://sylvana.net/jpegcrop/exif_orientation.html
+ (UIImageOrientation) sd_exifOrientationToiOSOrientation:(int)exifOrientation {
UIImageOrientation orientation = UIImageOrientationUp;
switch (exifOrientation) {
case 1:
orientation = UIImageOrientationUp;
break;
case 3:
orientation = UIImageOrientationDown;
break;
case 8:
orientation = UIImageOrientationLeft;
break;
case 6:
orientation = UIImageOrientationRight;
break;
case 2:
orientation = UIImageOrientationUpMirrored;
break;
case 4:
orientation = UIImageOrientationDownMirrored;
break;
case 5:
orientation = UIImageOrientationLeftMirrored;
break;
case 7:
orientation = UIImageOrientationRightMirrored;
break;
default:
break;
}
return orientation;
}
@end

26
SDWebImage/UIImage+WebP.h Normal file
View File

@ -0,0 +1,26 @@
//
// UIImage+WebP.h
// SDWebImage
//
// Created by Olivier Poitrey on 07/06/13.
// Copyright (c) 2013 Dailymotion. All rights reserved.
//
#ifdef SD_WEBP
#import <UIKit/UIKit.h>
// Fix for issue #416 Undefined symbols for architecture armv7 since WebP introduction when deploying to device
void WebPInitPremultiplyNEON(void);
void WebPInitUpsamplersNEON(void);
void VP8DspInitNEON(void);
@interface UIImage (WebP)
+ (UIImage *)sd_imageWithWebPData:(NSData *)data;
@end
#endif

78
SDWebImage/UIImage+WebP.m Normal file
View File

@ -0,0 +1,78 @@
//
// UIImage+WebP.m
// SDWebImage
//
// Created by Olivier Poitrey on 07/06/13.
// Copyright (c) 2013 Dailymotion. All rights reserved.
//
#ifdef SD_WEBP
#import "UIImage+WebP.h"
#if !COCOAPODS
#import "webp/decode.h"
#else
#import "webp/decode.h"
#endif
// Callback for CGDataProviderRelease
static void FreeImageData(void *info, const void *data, size_t size)
{
free((void *)data);
}
@implementation UIImage (WebP)
+ (UIImage *)sd_imageWithWebPData:(NSData *)data {
WebPDecoderConfig config;
if (!WebPInitDecoderConfig(&config)) {
return nil;
}
if (WebPGetFeatures(data.bytes, data.length, &config.input) != VP8_STATUS_OK) {
return nil;
}
config.output.colorspace = config.input.has_alpha ? MODE_rgbA : MODE_RGB;
config.options.use_threads = 1;
// Decode the WebP image data into a RGBA value array.
if (WebPDecode(data.bytes, data.length, &config) != VP8_STATUS_OK) {
return nil;
}
int width = config.input.width;
int height = config.input.height;
if (config.options.use_scaling) {
width = config.options.scaled_width;
height = config.options.scaled_height;
}
// Construct a UIImage from the decoded RGBA value array.
CGDataProviderRef provider =
CGDataProviderCreateWithData(NULL, config.output.u.RGBA.rgba, config.output.u.RGBA.size, FreeImageData);
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = config.input.has_alpha ? kCGBitmapByteOrder32Big | kCGImageAlphaPremultipliedLast : 0;
size_t components = config.input.has_alpha ? 4 : 3;
CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;
CGImageRef imageRef = CGImageCreate(width, height, 8, components * 8, components * width, colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
UIImage *image = [[UIImage alloc] initWithCGImage:imageRef];
CGImageRelease(imageRef);
return image;
}
@end
#if !COCOAPODS
// Functions to resolve some undefined symbols when using WebP and force_load flag
void WebPInitPremultiplyNEON(void) {}
void WebPInitUpsamplersNEON(void) {}
void VP8DspInitNEON(void) {}
#endif
#endif

View File

@ -0,0 +1,100 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <UIKit/UIKit.h>
#import "SDWebImageCompat.h"
#import "SDWebImageManager.h"
/**
* Integrates SDWebImage async downloading and caching of remote images with UIImageView for highlighted state.
*/
@interface UIImageView (HighlightedWebCache)
/**
* Set the imageView `highlightedImage` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
*/
- (void)sd_setHighlightedImageWithURL:(NSURL *)url;
/**
* Set the imageView `highlightedImage` with an `url` and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
*/
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options;
/**
* Set the imageView `highlightedImage` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `highlightedImage` with an `url` and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `highlightedImage` with an `url` and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param progressBlock A block called while image is downloading
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Cancel the current download
*/
- (void)sd_cancelCurrentHighlightedImageLoad;
@end
@interface UIImageView (HighlightedWebCacheDeprecated)
- (void)setHighlightedImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:`");
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:`");
- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:completed:`");
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:completed:`");
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setHighlightedImageWithURL:options:progress:completed:`");
- (void)cancelCurrentHighlightedImageLoad __deprecated_msg("Use `sd_cancelCurrentHighlightedImageLoad`");
@end

View File

@ -0,0 +1,112 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "UIImageView+HighlightedWebCache.h"
#import "UIView+WebCacheOperation.h"
#define UIImageViewHighlightedWebCacheOperationKey @"highlightedImage"
@implementation UIImageView (HighlightedWebCache)
- (void)sd_setHighlightedImageWithURL:(NSURL *)url {
[self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];
}
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options {
[self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];
}
- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:completedBlock];
}
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setHighlightedImageWithURL:url options:options progress:nil completed:completedBlock];
}
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelCurrentHighlightedImageLoad];
if (url) {
__weak __typeof(self)wself = self;
id<SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe (^
{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.highlightedImage = image;
[wself setNeedsLayout];
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forKey:UIImageViewHighlightedWebCacheOperationKey];
} else {
dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
if (completedBlock) {
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
- (void)sd_cancelCurrentHighlightedImageLoad {
[self sd_cancelImageLoadOperationWithKey:UIImageViewHighlightedWebCacheOperationKey];
}
@end
@implementation UIImageView (HighlightedWebCacheDeprecated)
- (void)setHighlightedImageWithURL:(NSURL *)url {
[self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:nil];
}
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options {
[self sd_setHighlightedImageWithURL:url options:options progress:nil completed:nil];
}
- (void)setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setHighlightedImageWithURL:url options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setHighlightedImageWithURL:url options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setHighlightedImageWithURL:url options:0 progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)cancelCurrentHighlightedImageLoad {
[self sd_cancelCurrentHighlightedImageLoad];
}
@end

View File

@ -0,0 +1,215 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageCompat.h"
#import "SDWebImageManager.h"
/**
* Integrates SDWebImage async downloading and caching of remote images with UIImageView.
*
* Usage with a UITableViewCell sub-class:
*
* @code
#import <SDWebImage/UIImageView+WebCache.h>
...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier]
autorelease];
}
// Here we use the provided sd_setImageWithURL: method to load the web image
// Ensure you use a placeholder image otherwise cells will be initialized with no image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://example.com/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder"]];
cell.textLabel.text = @"My Text";
return cell;
}
* @endcode
*/
@interface UIImageView (WebCache)
/**
* Get the current image URL.
*
* Note that because of the limitations of categories this property can get out of sync
* if you use sd_setImage: directly.
*/
- (NSURL *)sd_imageURL;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
*/
- (void)sd_setImageWithURL:(NSURL *)url;
/**
* Set the imageView `image` with an `url` and a placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @see sd_setImageWithURL:placeholderImage:options:
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options;
/**
* Set the imageView `image` with an `url`.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url`, placeholder and custom options.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param progressBlock A block called while image is downloading
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Set the imageView `image` with an `url` and optionally a placeholder image.
*
* The download is asynchronous and cached.
*
* @param url The url for the image.
* @param placeholder The image to be set initially, until the image request finishes.
* @param options The options to use when downloading the image. @see SDWebImageOptions for the possible values.
* @param progressBlock A block called while image is downloading
* @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url.
*/
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
/**
* Download an array of images and starts them in an animation loop
*
* @param arrayOfURLs An array of NSURL
*/
- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs;
/**
* Cancel the current download
*/
- (void)sd_cancelCurrentImageLoad;
- (void)sd_cancelCurrentAnimationImagesLoad;
/**
* Show activity UIActivityIndicatorView
*/
- (void)setShowActivityIndicatorView:(BOOL)show;
/**
* set desired UIActivityIndicatorViewStyle
*
* @param style The style of the UIActivityIndicatorView
*/
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;
@end
@interface UIImageView (WebCacheDeprecated)
- (NSURL *)imageURL __deprecated_msg("Use `sd_imageURL`");
- (void)setImageWithURL:(NSURL *)url __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options`");
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:completed:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:completed:`");
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock __deprecated_msg("Method deprecated. Use `sd_setImageWithURL:placeholderImage:options:completed:`");
- (void)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`");
- (void)cancelCurrentImageLoad __deprecated_msg("Use `sd_cancelCurrentImageLoad`");
@end

View File

@ -0,0 +1,281 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "UIImageView+WebCache.h"
#import "objc/runtime.h"
#import "UIView+WebCacheOperation.h"
static char imageURLKey;
static char TAG_ACTIVITY_INDICATOR;
static char TAG_ACTIVITY_STYLE;
static char TAG_ACTIVITY_SHOW;
@implementation UIImageView (WebCache)
- (void)sd_setImageWithURL:(NSURL *)url {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
}
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:completedBlock];
}
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelCurrentImageLoad];
objc_setAssociatedObject(self, &imageURLKey, url, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
if (!(options & SDWebImageDelayPlaceholder)) {
dispatch_main_async_safe(^{
self.image = placeholder;
});
}
if (url) {
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return;
dispatch_main_sync_safe(^{
if (!wself) return;
if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.image = image;
[wself setNeedsLayout];
} else {
if ((options & SDWebImageDelayPlaceholder)) {
wself.image = placeholder;
[wself setNeedsLayout];
}
}
if (completedBlock && finished) {
completedBlock(image, error, cacheType, url);
}
});
}];
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else {
dispatch_main_async_safe(^{
[self removeActivityIndicator];
if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url);
}
});
}
}
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
[self sd_setImageWithURL:url placeholderImage:lastPreviousCachedImage ?: placeholder options:options progress:progressBlock completed:completedBlock];
}
- (NSURL *)sd_imageURL {
return objc_getAssociatedObject(self, &imageURLKey);
}
- (void)sd_setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
[self sd_cancelCurrentAnimationImagesLoad];
__weak __typeof(self)wself = self;
NSMutableArray *operationsArray = [[NSMutableArray alloc] init];
for (NSURL *logoImageURL in arrayOfURLs) {
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:logoImageURL options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
if (!wself) return;
dispatch_main_sync_safe(^{
__strong UIImageView *sself = wself;
[sself stopAnimating];
if (sself && image) {
NSMutableArray *currentImages = [[sself animationImages] mutableCopy];
if (!currentImages) {
currentImages = [[NSMutableArray alloc] init];
}
[currentImages addObject:image];
sself.animationImages = currentImages;
[sself setNeedsLayout];
}
[sself startAnimating];
});
}];
[operationsArray addObject:operation];
}
[self sd_setImageLoadOperation:[NSArray arrayWithArray:operationsArray] forKey:@"UIImageViewAnimationImages"];
}
- (void)sd_cancelCurrentImageLoad {
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewImageLoad"];
}
- (void)sd_cancelCurrentAnimationImagesLoad {
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
}
#pragma mark -
- (UIActivityIndicatorView *)activityIndicator {
return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);
}
- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {
objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);
}
- (void)setShowActivityIndicatorView:(BOOL)show{
objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, [NSNumber numberWithBool:show], OBJC_ASSOCIATION_RETAIN);
}
- (BOOL)showActivityIndicatorView{
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];
}
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style{
objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);
}
- (int)getIndicatorStyle{
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];
}
- (void)addActivityIndicator {
if (!self.activityIndicator) {
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self getIndicatorStyle]];
self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
dispatch_main_async_safe(^{
[self addSubview:self.activityIndicator];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
});
}
dispatch_main_async_safe(^{
[self.activityIndicator startAnimating];
});
}
- (void)removeActivityIndicator {
if (self.activityIndicator) {
[self.activityIndicator removeFromSuperview];
self.activityIndicator = nil;
}
}
@end
@implementation UIImageView (WebCacheDeprecated)
- (NSURL *)imageURL {
return [self sd_imageURL];
}
- (void)setImageWithURL:(NSURL *)url {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:nil];
}
- (void)setImageWithURL:(NSURL *)url completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:nil options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:0 progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock {
[self sd_setImageWithURL:url placeholderImage:placeholder options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
if (completedBlock) {
completedBlock(image, error, cacheType);
}
}];
}
- (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];
}
- (void)cancelCurrentImageLoad {
[self sd_cancelCurrentImageLoad];
}
- (void)setAnimationImagesWithURLs:(NSArray *)arrayOfURLs {
[self sd_setAnimationImagesWithURLs:arrayOfURLs];
}
@end

View File

@ -0,0 +1,36 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <UIKit/UIKit.h>
#import "SDWebImageManager.h"
@interface UIView (WebCacheOperation)
/**
* Set the image load operation (storage in a UIView based dictionary)
*
* @param operation the operation
* @param key key for storing the operation
*/
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key;
/**
* Cancel all operations for the current UIView and key
*
* @param key key for identifying the operations
*/
- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key;
/**
* Just remove the operations corresponding to the current UIView and key without cancelling them
*
* @param key key for identifying the operations
*/
- (void)sd_removeImageLoadOperationWithKey:(NSString *)key;
@end

View File

@ -0,0 +1,55 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "UIView+WebCacheOperation.h"
#import "objc/runtime.h"
static char loadOperationKey;
@implementation UIView (WebCacheOperation)
- (NSMutableDictionary *)operationDictionary {
NSMutableDictionary *operations = objc_getAssociatedObject(self, &loadOperationKey);
if (operations) {
return operations;
}
operations = [NSMutableDictionary dictionary];
objc_setAssociatedObject(self, &loadOperationKey, operations, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
return operations;
}
- (void)sd_setImageLoadOperation:(id)operation forKey:(NSString *)key {
[self sd_cancelImageLoadOperationWithKey:key];
NSMutableDictionary *operationDictionary = [self operationDictionary];
[operationDictionary setObject:operation forKey:key];
}
- (void)sd_cancelImageLoadOperationWithKey:(NSString *)key {
// Cancel in progress downloader from queue
NSMutableDictionary *operationDictionary = [self operationDictionary];
id operations = [operationDictionary objectForKey:key];
if (operations) {
if ([operations isKindOfClass:[NSArray class]]) {
for (id <SDWebImageOperation> operation in operations) {
if (operation) {
[operation cancel];
}
}
} else if ([operations conformsToProtocol:@protocol(SDWebImageOperation)]){
[(id<SDWebImageOperation>) operations cancel];
}
[operationDictionary removeObjectForKey:key];
}
}
- (void)sd_removeImageLoadOperationWithKey:(NSString *)key {
NSMutableDictionary *operationDictionary = [self operationDictionary];
[operationDictionary removeObjectForKey:key];
}
@end

View File

@ -1,31 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <Foundation/Foundation.h>
#import "SDWebImageDownloaderDelegate.h"
@interface SDWebImageDownloader : NSObject
{
@private
NSURL *url;
id<SDWebImageDownloaderDelegate> delegate;
NSURLConnection *connection;
NSMutableData *imageData;
}
@property (nonatomic, retain) NSURL *url;
@property (nonatomic, assign) id<SDWebImageDownloaderDelegate> delegate;
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate;
- (void)start;
- (void)cancel;
// This method is now no-op and is deprecated
+ (void)setMaxConcurrentDownloads:(NSUInteger)max __attribute__((deprecated));
@end

View File

@ -1,110 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageDownloader.h"
@interface SDWebImageDownloader ()
@property (nonatomic, retain) NSURLConnection *connection;
@property (nonatomic, retain) NSMutableData *imageData;
@end
@implementation SDWebImageDownloader
@synthesize url, delegate, connection, imageData;
#pragma mark Public Methods
+ (id)downloaderWithURL:(NSURL *)url delegate:(id<SDWebImageDownloaderDelegate>)delegate
{
SDWebImageDownloader *downloader = [[[SDWebImageDownloader alloc] init] autorelease];
downloader.url = url;
downloader.delegate = delegate;
[downloader start];
return downloader;
}
+ (void)setMaxConcurrentDownloads:(NSUInteger)max
{
// NOOP
}
- (void)start
{
// In order to prevent from potential duplicate caching (NSURLCache + SDImageCache) we disable the cache for image requests
NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
self.connection = [[[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:NO] autorelease];
// Ensure we aren't blocked by UI manipulations (default runloop mode for NSURLConnection is NSEventTrackingRunLoopMode)
[connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes];
[connection start];
[request release];
if (connection)
{
self.imageData = [NSMutableData data];
}
else
{
if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)])
{
[delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:nil];
}
}
}
- (void)cancel
{
if (connection)
{
[connection cancel];
self.connection = nil;
}
}
#pragma mark NSURLConnection (delegate)
- (void)connection:(NSURLConnection *)aConnection didReceiveData:(NSData *)data
{
[imageData appendData:data];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection
{
UIImage *image = [[UIImage alloc] initWithData:imageData];
self.imageData = nil;
self.connection = nil;
if ([delegate respondsToSelector:@selector(imageDownloader:didFinishWithImage:)])
{
[delegate performSelector:@selector(imageDownloader:didFinishWithImage:) withObject:self withObject:image];
}
[image release];
}
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{
if ([delegate respondsToSelector:@selector(imageDownloader:didFailWithError:)])
{
[delegate performSelector:@selector(imageDownloader:didFailWithError:) withObject:self withObject:error];
}
self.connection = nil;
self.imageData = nil;
}
#pragma mark NSObject
- (void)dealloc
{
[url release], url = nil;
[connection release], connection = nil;
[imageData release], imageData = nil;
[super dealloc];
}
@end

View File

@ -1,18 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
@class SDWebImageDownloader;
@protocol SDWebImageDownloaderDelegate <NSObject>
@optional
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image;
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFailWithError:(NSError *)error;
@end

View File

@ -1,26 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <UIKit/UIKit.h>
#import "SDWebImageDownloaderDelegate.h"
#import "SDWebImageManagerDelegate.h"
@interface SDWebImageManager : NSObject <SDWebImageDownloaderDelegate>
{
NSMutableArray *delegates;
NSMutableArray *downloaders;
NSMutableDictionary *downloaderForURL;
NSMutableArray *failedURLs;
}
+ (id)sharedManager;
- (UIImage *)imageWithURL:(NSURL *)url;
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate;
- (void)cancelForDelegate:(id<SDWebImageManagerDelegate>)delegate;
@end

View File

@ -1,138 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "SDWebImageManager.h"
#import "SDImageCache.h"
#import "SDWebImageDownloader.h"
static SDWebImageManager *instance;
@implementation SDWebImageManager
- (id)init
{
if ((self = [super init]))
{
delegates = [[NSMutableArray alloc] init];
downloaders = [[NSMutableArray alloc] init];
downloaderForURL = [[NSMutableDictionary alloc] init];
failedURLs = [[NSMutableArray alloc] init];
}
return self;
}
- (void)dealloc
{
[delegates release], delegates = nil;
[downloaders release], downloaders = nil;
[downloaderForURL release], downloaderForURL = nil;
[failedURLs release], failedURLs = nil;
[super dealloc];
}
+ (id)sharedManager
{
if (instance == nil)
{
instance = [[SDWebImageManager alloc] init];
}
return instance;
}
- (UIImage *)imageWithURL:(NSURL *)url
{
return [[SDImageCache sharedImageCache] imageFromKey:[url absoluteString]];
}
- (void)downloadWithURL:(NSURL *)url delegate:(id<SDWebImageManagerDelegate>)delegate
{
if (url == nil || [failedURLs containsObject:url])
{
return;
}
// Share the same downloader for identical URLs so we don't download the same URL several times
SDWebImageDownloader *downloader = [downloaderForURL objectForKey:url];
if (!downloader)
{
downloader = [SDWebImageDownloader downloaderWithURL:url delegate:self];
[downloaderForURL setObject:downloader forKey:url];
}
[delegates addObject:delegate];
[downloaders addObject:downloader];
}
- (void)cancelForDelegate:(id<SDWebImageManagerDelegate>)delegate
{
NSUInteger idx = [delegates indexOfObjectIdenticalTo:delegate];
if (idx == NSNotFound)
{
return;
}
SDWebImageDownloader *downloader = [[downloaders objectAtIndex:idx] retain];
[delegates removeObjectAtIndex:idx];
[downloaders removeObjectAtIndex:idx];
if (![downloaders containsObject:downloader])
{
// No more delegate are waiting for this download, cancel it
[downloader cancel];
[downloaderForURL removeObjectForKey:downloader.url];
}
[downloader release];
}
- (void)imageDownloader:(SDWebImageDownloader *)downloader didFinishWithImage:(UIImage *)image
{
[downloader retain];
// Notify all the delegates with this downloader
for (NSInteger idx = [downloaders count] - 1; idx >= 0; idx--)
{
SDWebImageDownloader *aDownloader = [downloaders objectAtIndex:idx];
if (aDownloader == downloader)
{
id<SDWebImageManagerDelegate> delegate = [delegates objectAtIndex:idx];
if (image && [delegate respondsToSelector:@selector(webImageManager:didFinishWithImage:)])
{
[delegate performSelector:@selector(webImageManager:didFinishWithImage:) withObject:self withObject:image];
}
[downloaders removeObjectAtIndex:idx];
[delegates removeObjectAtIndex:idx];
}
}
if (image)
{
// Store the image in the cache
[[SDImageCache sharedImageCache] storeImage:image forKey:[downloader.url absoluteString]];
}
else
{
// The image can't be downloaded from this URL, mark the URL as failed so we won't try and fail again and again
[failedURLs addObject:downloader.url];
}
// Release the downloader
[downloaderForURL removeObjectForKey:downloader.url];
[downloader release];
}
@end

11
Tests/Podfile Normal file
View File

@ -0,0 +1,11 @@
source 'https://github.com/CocoaPods/Specs.git'
xcodeproj 'SDWebImage Tests'
workspace '../SDWebImage'
target 'Tests' do
platform :ios, '7.0'
pod 'Expecta', '<=0.3.1'
pod 'SDWebImage', :path => '../'
end

View File

@ -0,0 +1,370 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
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 */; };
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 */; };
DA248D61195472AA00390AB0 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = DA248D5F195472AA00390AB0 /* InfoPlist.strings */; };
DA248D69195475D800390AB0 /* SDImageCacheTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D68195475D800390AB0 /* SDImageCacheTests.m */; };
DA248D6B195476AC00390AB0 /* SDWebImageManagerTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */; };
DA91BEBC19795BC9006F2536 /* UIImageMultiFormatTests.m in Sources */ = {isa = PBXBuildFile; fileRef = DA91BEBB19795BC9006F2536 /* UIImageMultiFormatTests.m */; };
/* End PBXBuildFile section */
/* Begin PBXFileReference section */
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>"; };
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; };
DA248D5A195472AA00390AB0 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = Library/Frameworks/UIKit.framework; sourceTree = DEVELOPER_DIR; };
DA248D5E195472AA00390AB0 /* Tests-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "Tests-Info.plist"; sourceTree = "<group>"; };
DA248D60195472AA00390AB0 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
DA248D64195472AA00390AB0 /* Tests-Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Tests-Prefix.pch"; sourceTree = "<group>"; };
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>"; };
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 */
DA248D50195472AA00390AB0 /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */,
DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */,
DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */,
2278D185E97AF851CF3F9A07 /* libPods-Tests.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
8D1A343B1A6D91E95D7795EF /* Pods */ = {
isa = PBXGroup;
children = (
0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */,
2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */,
);
name = Pods;
sourceTree = "<group>";
};
DA248D451954721A00390AB0 = {
isa = PBXGroup;
children = (
DA248D5C195472AA00390AB0 /* Tests */,
DA248D55195472AA00390AB0 /* Frameworks */,
DA248D54195472AA00390AB0 /* Products */,
8D1A343B1A6D91E95D7795EF /* Pods */,
);
sourceTree = "<group>";
};
DA248D54195472AA00390AB0 /* Products */ = {
isa = PBXGroup;
children = (
DA248D53195472AA00390AB0 /* Tests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
DA248D55195472AA00390AB0 /* Frameworks */ = {
isa = PBXGroup;
children = (
DA248D56195472AA00390AB0 /* XCTest.framework */,
DA248D58195472AA00390AB0 /* Foundation.framework */,
DA248D5A195472AA00390AB0 /* UIKit.framework */,
F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */,
);
name = Frameworks;
sourceTree = "<group>";
};
DA248D5C195472AA00390AB0 /* Tests */ = {
isa = PBXGroup;
children = (
5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */,
DA248D5D195472AA00390AB0 /* Supporting Files */,
DA248D68195475D800390AB0 /* SDImageCacheTests.m */,
DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */,
DA91BEBB19795BC9006F2536 /* UIImageMultiFormatTests.m */,
);
path = Tests;
sourceTree = "<group>";
};
DA248D5D195472AA00390AB0 /* Supporting Files */ = {
isa = PBXGroup;
children = (
DA248D5E195472AA00390AB0 /* Tests-Info.plist */,
DA248D5F195472AA00390AB0 /* InfoPlist.strings */,
DA248D64195472AA00390AB0 /* Tests-Prefix.pch */,
);
name = "Supporting Files";
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
DA248D52195472AA00390AB0 /* Tests */ = {
isa = PBXNativeTarget;
buildConfigurationList = DA248D67195472AA00390AB0 /* Build configuration list for PBXNativeTarget "Tests" */;
buildPhases = (
FBC8982311CD4ED9A3006D45 /* 📦 Check Pods Manifest.lock */,
DA248D4F195472AA00390AB0 /* Sources */,
DA248D50195472AA00390AB0 /* Frameworks */,
DA248D51195472AA00390AB0 /* Resources */,
D6347736BDF64FC5A4D078A4 /* 📦 Copy Pods Resources */,
4B51E412BA3594400947AC71 /* 📦 Embed Pods Frameworks */,
);
buildRules = (
);
dependencies = (
);
name = Tests;
productName = Tests;
productReference = DA248D53195472AA00390AB0 /* Tests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
DA248D461954721A00390AB0 /* Project object */ = {
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0510;
};
buildConfigurationList = DA248D491954721A00390AB0 /* Build configuration list for PBXProject "SDWebImage Tests" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = DA248D451954721A00390AB0;
productRefGroup = DA248D54195472AA00390AB0 /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
DA248D52195472AA00390AB0 /* Tests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
DA248D51195472AA00390AB0 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
5F7F38AD1AE2A77A00B0E330 /* TestImage.jpg in Resources */,
DA248D61195472AA00390AB0 /* InfoPlist.strings in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
4B51E412BA3594400947AC71 /* 📦 Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "📦 Embed Pods Frameworks";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n";
showEnvVarsInLog = 0;
};
D6347736BDF64FC5A4D078A4 /* 📦 Copy Pods Resources */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
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;
shellPath = /bin/sh;
shellScript = "diff \"${PODS_ROOT}/../Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [[ $? != 0 ]] ; then\n cat << EOM\nerror: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\nEOM\n exit 1\nfi\n";
showEnvVarsInLog = 0;
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
DA248D4F195472AA00390AB0 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DA248D69195475D800390AB0 /* SDImageCacheTests.m in Sources */,
DA248D6B195476AC00390AB0 /* SDWebImageManagerTests.m in Sources */,
DA91BEBC19795BC9006F2536 /* UIImageMultiFormatTests.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
DA248D5F195472AA00390AB0 /* InfoPlist.strings */ = {
isa = PBXVariantGroup;
children = (
DA248D60195472AA00390AB0 /* en */,
);
name = InfoPlist.strings;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
DA248D4A1954721A00390AB0 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
DA248D4B1954721A00390AB0 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
DA248D65195472AA00390AB0 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Tests/Tests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
WRAPPER_EXTENSION = xctest;
};
name = Debug;
};
DA248D66195472AA00390AB0 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = YES;
ENABLE_NS_ASSERTIONS = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(DEVELOPER_FRAMEWORKS_DIR)",
);
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "Tests/Tests-Prefix.pch";
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "Tests/Tests-Info.plist";
IPHONEOS_DEPLOYMENT_TARGET = 5.0;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
WRAPPER_EXTENSION = xctest;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
DA248D491954721A00390AB0 /* Build configuration list for PBXProject "SDWebImage Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DA248D4A1954721A00390AB0 /* Debug */,
DA248D4B1954721A00390AB0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
DA248D67195472AA00390AB0 /* Build configuration list for PBXNativeTarget "Tests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DA248D65195472AA00390AB0 /* Debug */,
DA248D66195472AA00390AB0 /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = DA248D461954721A00390AB0 /* Project object */;
}

View File

@ -0,0 +1,225 @@
//
// SDImageCacheTests.m
// SDWebImage Tests
//
// Created by Bogdan Poplauschi on 20/06/14.
//
//
#define EXP_SHORTHAND // required by Expecta
#import <XCTest/XCTest.h>
#import <Expecta.h>
#import "SDImageCache.h"
NSString *kImageTestKey = @"TestImageKey.jpg";
@interface SDImageCacheTests : XCTestCase
@property (strong, nonatomic) SDImageCache *sharedImageCache;
@end
@implementation SDImageCacheTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
self.sharedImageCache = [SDImageCache sharedImageCache];
[self clearAllCaches];
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testSharedImageCache {
expect(self.sharedImageCache).toNot.beNil();
}
- (void)testSingleton{
expect(self.sharedImageCache).to.equal([SDImageCache sharedImageCache]);
}
- (void)testClearDiskCache{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache clearDiskOnCompletion:^{
expect([self.sharedImageCache diskImageExistsWithKey:kImageTestKey]).to.equal(NO);
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal([self imageForTesting]);
}];
}
- (void)testClearMemoryCache{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache clearMemory];
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
// Seems not able to access the files correctly (maybe only from test?)
//expect([self.sharedImageCache diskImageExistsWithKey:kImageTestKey]).to.equal(YES);
[self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) {
expect(isInCache).to.equal(YES);
}];
}
// Testing storeImage:forKey:
- (void)testInsertionOfImage {
UIImage *image = [self imageForTesting];
[self.sharedImageCache storeImage:image forKey:kImageTestKey];
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image);
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.equal(image);
}
// Testing storeImage:forKey:toDisk:YES
- (void)testInsertionOfImageForcingDiskStorage{
UIImage *image = [self imageForTesting];
[self.sharedImageCache storeImage:image forKey:kImageTestKey toDisk:YES];
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.equal(image);
// Seems not able to access the files correctly (maybe only from test?)
//expect([self.sharedImageCache diskImageExistsWithKey:kImageTestKey]).to.equal(YES);
[self.sharedImageCache diskImageExistsWithKey:kImageTestKey completion:^(BOOL isInCache) {
expect(isInCache).to.equal(YES);
}];
}
// Testing storeImage:forKey:toDisk:NO
- (void)testInsertionOfImageOnlyInMemory {
UIImage *image = [self imageForTesting];
[self.sharedImageCache storeImage:image forKey:@"TestImage" toDisk:NO];
[self.sharedImageCache diskImageExistsWithKey:@"TestImage" completion:^(BOOL isInCache) {
expect(isInCache).to.equal(YES);
}];
[self.sharedImageCache clearMemory];
[self.sharedImageCache diskImageExistsWithKey:@"TestImage" completion:^(BOOL isInCache) {
expect(isInCache).to.equal(NO);
}];
}
- (void)testRetrievalImageThroughNSOperation{
//- (NSOperation *)queryDiskCacheForKey:(NSString *)key done:(SDWebImageQueryCompletedBlock)doneBlock;
UIImage *imageForTesting = [self imageForTesting];
[self.sharedImageCache storeImage:imageForTesting forKey:kImageTestKey];
NSOperation *operation = [self.sharedImageCache queryDiskCacheForKey:kImageTestKey done:^(UIImage *image, SDImageCacheType cacheType) {
expect(image).to.equal(imageForTesting);
}];
expect(operation).toNot.beNil;
}
- (void)testRemoveImageForKey{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey];
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil;
}
- (void)testRemoveImageForKeyWithCompletion{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey withCompletion:^{
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil;
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
}];
}
- (void)testRemoveImageForKeyNotFromDisk{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:NO];
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).toNot.beNil;
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
}
- (void)testRemoveImageForKeyFromDisk{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:NO];
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil;
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
}
- (void)testRemoveImageforKeyNotFromDiskWithCompletion{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:NO withCompletion:^{
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).toNot.beNil;
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
}];
}
- (void)testRemoveImageforKeyFromDiskWithCompletion{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
[self.sharedImageCache removeImageForKey:kImageTestKey fromDisk:YES withCompletion:^{
expect([self.sharedImageCache imageFromDiskCacheForKey:kImageTestKey]).to.beNil;
expect([self.sharedImageCache imageFromMemoryCacheForKey:kImageTestKey]).to.beNil;
}];
}
// TODO -- Testing insertion with recalculate
- (void)testInsertionOfImageOnlyInDisk {
}
- (void)testInitialCacheSize{
expect([self.sharedImageCache getSize]).to.equal(0);
}
- (void)testInitialDiskCount{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
expect([self.sharedImageCache getDiskCount]).to.equal(1);
}
- (void)testDiskCountAfterInsertion{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
expect([self.sharedImageCache getDiskCount]).to.equal(1);
}
- (void)testDefaultCachePathForAnyKey{
NSString *path = [self.sharedImageCache defaultCachePathForKey:kImageTestKey];
expect(path).toNot.beNil;
}
- (void)testCachePathForNonExistingKey{
NSString *path = [self.sharedImageCache cachePathForKey:kImageTestKey inPath:[self.sharedImageCache defaultCachePathForKey:kImageTestKey]];
expect(path).to.beNil;
}
- (void)testCachePathForExistingKey{
[self.sharedImageCache storeImage:[self imageForTesting] forKey:kImageTestKey];
NSString *path = [self.sharedImageCache cachePathForKey:kImageTestKey inPath:[self.sharedImageCache defaultCachePathForKey:kImageTestKey]];
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{
[self.sharedImageCache clearDisk];
[self.sharedImageCache clearMemory];
}
- (UIImage *)imageForTesting{
return [UIImage imageWithContentsOfFile:[self testImagePath]];
}
- (NSString *)testImagePath {
NSBundle *testBundle = [NSBundle bundleForClass:[self class]];
return [testBundle pathForResource:@"TestImage" ofType:@"jpg"];
}
@end

View File

@ -0,0 +1,72 @@
//
// SDWebImageManagerTests.m
// SDWebImage Tests
//
// Created by Bogdan Poplauschi on 20/06/14.
//
//
#define EXP_SHORTHAND // required by Expecta
#import <XCTest/XCTest.h>
#import <Expecta.h>
#import "SDWebImageManager.h"
static int64_t kAsyncTestTimeout = 5;
@interface SDWebImageManagerTests : XCTestCase
@end
@implementation SDWebImageManagerTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testThatDownloadInvokesCompletionBlockWithCorrectParamsAsync {
__block XCTestExpectation *expectation = [self expectationWithDescription:@"Image download completes"];
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();
expect(error).to.beNil();
expect(originalImageURL).to.equal(imageURL);
[expectation fulfill];
expectation = nil;
}];
[self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
}
- (void)testThatDownloadWithIncorrectURLInvokesCompletionBlockWithAnErrorAsync {
__block XCTestExpectation *expectation = [self expectationWithDescription:@"Image download completes"];
NSURL *originalImageURL = [NSURL URLWithString:@"http://static2.dmcdn.net/static/video/656/177/44771656:jpeg_preview_small.png"];
[[SDWebImageManager sharedManager] downloadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
expect(image).to.beNil();
expect(error).toNot.beNil();
expect(originalImageURL).to.equal(imageURL);
[expectation fulfill];
expectation = nil;
}];
[self waitForExpectationsWithTimeout:kAsyncTestTimeout handler:nil];
}
@end

BIN
Tests/Tests/TestImage.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

View File

@ -0,0 +1,22 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
<string>com.SDWebImage.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

View File

@ -0,0 +1,10 @@
//
// Prefix header
//
// The contents of this file are implicitly included at the beginning of every source file.
//
#ifdef __OBJC__
#import <UIKit/UIKit.h>
#import <Foundation/Foundation.h>
#endif

View File

@ -0,0 +1,45 @@
//
// UIImageMultiFormatTests.m
// SDWebImage Tests
//
// Created by Bogdan Poplauschi on 18/07/14.
//
//
#define EXP_SHORTHAND // required by Expecta
#import <XCTest/XCTest.h>
#import <Expecta.h>
#import "UIImage+MultiFormat.h"
@interface UIImageMultiFormatTests : XCTestCase
@end
@implementation UIImageMultiFormatTests
- (void)setUp
{
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown
{
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testImageOrientationFromImageDataWithInvalidData {
// sync download image
SEL selector = @selector(sd_imageOrientationFromImageData:);
UIImageOrientation orientation = [[UIImage class] performSelector:selector withObject:nil];
expect(orientation).to.equal(UIImageOrientationUp);
}
@end

View File

@ -0,0 +1,2 @@
/* Localized versions of Info.plist keys */

View File

@ -1,17 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import <UIKit/UIKit.h>
#import "SDWebImageManagerDelegate.h"
@interface UIImageView (WebCache) <SDWebImageManagerDelegate>
- (void)setImageWithURL:(NSURL *)url;
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder;
@end

View File

@ -1,48 +0,0 @@
/*
* This file is part of the SDWebImage package.
* (c) Olivier Poitrey <rs@dailymotion.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
#import "UIImageView+WebCache.h"
#import "SDWebImageManager.h"
@implementation UIImageView (WebCache)
- (void)setImageWithURL:(NSURL *)url
{
[self setImageWithURL:url placeholderImage:nil];
}
- (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder
{
SDWebImageManager *manager = [SDWebImageManager sharedManager];
// Remove in progress downloader from queue
[manager cancelForDelegate:self];
UIImage *cachedImage = [manager imageWithURL:url];
if (cachedImage)
{
self.image = cachedImage;
}
else
{
if (placeholder)
{
self.image = placeholder;
}
[manager downloadWithURL:url delegate:self];
}
}
- (void)webImageManager:(SDWebImageManager *)imageManager didFinishWithImage:(UIImage *)image
{
self.image = image;
}
@end

1
Vendors/libwebp Submodule

@ -0,0 +1 @@
Subproject commit 1525784d5bc1d9e7e74ff18f9d21a910b60552af

26
WebImage/Info.plist Normal file
View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>3.8.1</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

37
WebImage/WebImage.h Normal file
View File

@ -0,0 +1,37 @@
//
// WebImage.h
// WebImage
//
// Created by Florent Vilmart on 2015-03-14.
// Copyright (c) 2015 Dailymotion. All rights reserved.
//
#import <UIKit/UIKit.h>
//! Project version number for WebImage.
FOUNDATION_EXPORT double WebImageVersionNumber;
//! Project version string for WebImage.
FOUNDATION_EXPORT const unsigned char WebImageVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <WebImage/PublicHeader.h>
#import <WebImage/SDWebImageManager.h>
#import <WebImage/SDImageCache.h>
#import <WebImage/UIImageView+WebCache.h>
#import <WebImage/SDWebImageCompat.h>
#import <WebImage/UIImageView+HighlightedWebCache.h>
#import <WebImage/SDWebImageDownloaderOperation.h>
#import <WebImage/UIButton+WebCache.h>
#import <WebImage/SDWebImagePrefetcher.h>
#import <WebImage/UIView+WebCacheOperation.h>
#import <WebImage/UIImage+MultiFormat.h>
#import <WebImage/SDWebImageOperation.h>
#import <WebImage/SDWebImageDownloader.h>
#if !TARGET_OS_TV
#import <WebImage/MKAnnotationView+WebCache.h>
#endif
#import <WebImage/SDWebImageDecoder.h>
#import <WebImage/UIImage+WebP.h>
#import <WebImage/UIImage+GIF.h>
#import <WebImage/NSData+ImageContentType.h>