From 1f165b48ee6a4411841383391a89cfcb90da4669 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sat, 28 May 2016 21:46:40 +0300 Subject: [PATCH 01/24] Added CONTRIBUTING, ISSUE and PULL_REQUEST TEMPLATE --- .github/CONTRIBUTING.md | 42 ++++++++++++++++++++++++++++++++ .github/ISSUE_TEMPLATE.md | 23 +++++++++++++++++ .github/PULL_REQUEST_TEMPLATE.md | 18 ++++++++++++++ 3 files changed, 83 insertions(+) create mode 100644 .github/CONTRIBUTING.md create mode 100644 .github/ISSUE_TEMPLATE.md create mode 100644 .github/PULL_REQUEST_TEMPLATE.md diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md new file mode 100644 index 00000000..b7b0e6d5 --- /dev/null +++ b/.github/CONTRIBUTING.md @@ -0,0 +1,42 @@ +# Contributing to SDWebImage + +We want to make contributing to this project as easy and transparent as possible. Here are a few guidelines for making all our lives easier. + +## Asking questions + +We don't use GitHub as a support forum. For any usage questions that are not specific to the project itself, please ask on [Stack Overflow](https://stackoverflow.com/) instead. By doing so, you'll be more likely to quickly solve your problem, and you'll allow anyone else with the same question to find the answer. This also allows maintainers to focus on improving the project for others. + +## Reporting Issues + +A great way to contribute to the project is to send a detailed issue when you encounter an problem. +It is very important to check for the same problem or suggestion in the project's issue list first. If you find a match, just add a small comment there. +Doing this helps prioritize the most common problems and requests. + +When reporting issues, please include the following: + +- The platform name and version (e.g. iOS 8.1) +- The library version +- The integration method (e.g. CocoaPods/Carthage/manually) +- The version of Xcode you're using +- The full output of any stack trace or compiler error +- A small demo project that replicates the issue (especially if the way to reproduce the issue is not straight-forward) +- Any other details that would be useful in understanding the problem + +This information will help us review and fix your issue faster. + + +Please do not be offended if we close your issue and reference this document. +If you believe the issue is truely a fault in the project’s codebase, re-open it. + +## Pull Requests + +We gladly accept any PR's assuming they are well written, documented ( if necessary ) and preferably have test code. +If you're unsure if we'll accept a new feature please open an issue requesting it and we can have a discussion before you code and submit a PR. + +Checklist: +- Fork the repo and create your branch from the latest master (to minimize the conflicts) +- If you've added code that should be tested, add tests. +- If you've changed APIs, update the documentation. +- Ensure the test suite passes. +- Make sure your code lints (pod lib lint) + diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md new file mode 100644 index 00000000..91f119a2 --- /dev/null +++ b/.github/ISSUE_TEMPLATE.md @@ -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. + diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 00000000..857367b6 --- /dev/null +++ b/.github/PULL_REQUEST_TEMPLATE.md @@ -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 + +... + From 11840d131390f3895b9b7875b84d95b04189543e Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sat, 28 May 2016 22:07:18 +0300 Subject: [PATCH 02/24] 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.) --- Tests/Podfile | 1 - 1 file changed, 1 deletion(-) diff --git a/Tests/Podfile b/Tests/Podfile index 7f86b807..2006d8a2 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -10,6 +10,5 @@ end target :ios do platform :ios, '5.0' - link_with 'Tests' import_pods end From f1a471e93fe2f2658b4cf5e75964cfd404e4ddb3 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sat, 28 May 2016 22:50:53 +0300 Subject: [PATCH 03/24] Fixed #1444 and the master build thanks to https://github.com/kenmaz/SDWebImage/commit/5034c334be50765dfe4e97c48bcb74ef64175188 --- SDWebImage.podspec | 5 ++++- SDWebImage/UIImage+WebP.m | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/SDWebImage.podspec b/SDWebImage.podspec index 6b3c3272..646126f6 100644 --- a/SDWebImage.podspec +++ b/SDWebImage.podspec @@ -37,7 +37,10 @@ Pod::Spec.new do |s| s.subspec 'WebP' do |webp| webp.source_files = 'SDWebImage/UIImage+WebP.{h,m}' - webp.xcconfig = { 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1' } + webp.xcconfig = { + 'GCC_PREPROCESSOR_DEFINITIONS' => '$(inherited) SD_WEBP=1', + 'USER_HEADER_SEARCH_PATHS' => '$(inherited) $(SRCROOT)/libwebp/src' + } webp.dependency 'SDWebImage/Core' webp.dependency 'libwebp' end diff --git a/SDWebImage/UIImage+WebP.m b/SDWebImage/UIImage+WebP.m index f27a1b6f..6444ddd2 100644 --- a/SDWebImage/UIImage+WebP.m +++ b/SDWebImage/UIImage+WebP.m @@ -12,7 +12,7 @@ #if !COCOAPODS #import "webp/decode.h" #else -#import "libwebp/webp/decode.h" +#import "webp/decode.h" #endif // Callback for CGDataProviderRelease From 5ac4e308c7bacd2f424c911db380d6b6f95d7663 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sat, 28 May 2016 23:00:16 +0300 Subject: [PATCH 04/24] Fixed the Tests/Podfile, the Target ios was not to be found, so took advantage of this change to simplify it --- Tests/Podfile | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/Tests/Podfile b/Tests/Podfile index 2006d8a2..f2a66884 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -3,12 +3,9 @@ source 'https://github.com/CocoaPods/Specs.git' xcodeproj 'SDWebImage Tests' workspace '../SDWebImage' -def import_pods - pod 'Expecta', '<=0.3.1' # A Matcher Framework for Objective-C/Cocoa - pod 'SDWebImage', :path => '../' -end - -target :ios do +target 'Tests' do platform :ios, '5.0' - import_pods + pod 'Expecta', '<=0.3.1' + pod 'SDWebImage', :path => '../' + end From afaf306222f46f557283f2de5fa57e69bbe713f1 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 00:00:33 +0300 Subject: [PATCH 05/24] This should fix the build (the tests project) --- .travis.yml | 2 +- .../project.pbxproj | 44 +++++++++---------- 2 files changed, 22 insertions(+), 24 deletions(-) diff --git a/.travis.yml b/.travis.yml index 2d65143a..699f7fe1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,4 +23,4 @@ script: - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator -arch i386 build - pod install --project-directory=Tests - - xcodebuild -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test \ No newline at end of file + - xctool -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test \ No newline at end of file diff --git a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj index e1328a2b..85897e6c 100644 --- a/Tests/SDWebImage Tests.xcodeproj/project.pbxproj +++ b/Tests/SDWebImage Tests.xcodeproj/project.pbxproj @@ -7,8 +7,8 @@ objects = { /* Begin PBXBuildFile section */ + 2278D185E97AF851CF3F9A07 /* libPods-Tests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */; }; 5F7F38AD1AE2A77A00B0E330 /* TestImage.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */; }; - ABC8501F672447AA91C788DA /* libPods-ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */; }; DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D56195472AA00390AB0 /* XCTest.framework */; }; DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D58195472AA00390AB0 /* Foundation.framework */; }; DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = DA248D5A195472AA00390AB0 /* UIKit.framework */; }; @@ -19,9 +19,9 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ - 1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.debug.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.debug.xcconfig"; sourceTree = ""; }; + 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 = ""; }; + 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 = ""; }; 5F7F38AC1AE2A77A00B0E330 /* TestImage.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = TestImage.jpg; sourceTree = ""; }; - CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-ios.release.xcconfig"; path = "Pods/Target Support Files/Pods-ios/Pods-ios.release.xcconfig"; sourceTree = ""; }; DA248D53195472AA00390AB0 /* Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = Tests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DA248D56195472AA00390AB0 /* XCTest.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = XCTest.framework; path = Library/Frameworks/XCTest.framework; sourceTree = DEVELOPER_DIR; }; DA248D58195472AA00390AB0 /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = Library/Frameworks/Foundation.framework; sourceTree = DEVELOPER_DIR; }; @@ -32,7 +32,7 @@ DA248D68195475D800390AB0 /* SDImageCacheTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDImageCacheTests.m; sourceTree = ""; }; DA248D6A195476AC00390AB0 /* SDWebImageManagerTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = SDWebImageManagerTests.m; sourceTree = ""; }; DA91BEBB19795BC9006F2536 /* UIImageMultiFormatTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = UIImageMultiFormatTests.m; sourceTree = ""; }; - EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-ios.a"; sourceTree = BUILT_PRODUCTS_DIR; }; + F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Tests.a"; sourceTree = BUILT_PRODUCTS_DIR; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -43,7 +43,7 @@ DA248D57195472AA00390AB0 /* XCTest.framework in Frameworks */, DA248D5B195472AA00390AB0 /* UIKit.framework in Frameworks */, DA248D59195472AA00390AB0 /* Foundation.framework in Frameworks */, - ABC8501F672447AA91C788DA /* libPods-ios.a in Frameworks */, + 2278D185E97AF851CF3F9A07 /* libPods-Tests.a in Frameworks */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -53,8 +53,8 @@ 8D1A343B1A6D91E95D7795EF /* Pods */ = { isa = PBXGroup; children = ( - 1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */, - CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */, + 0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */, + 2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */, ); name = Pods; sourceTree = ""; @@ -83,7 +83,7 @@ DA248D56195472AA00390AB0 /* XCTest.framework */, DA248D58195472AA00390AB0 /* Foundation.framework */, DA248D5A195472AA00390AB0 /* UIKit.framework */, - EB0D107E6B4C4094BA2FEE29 /* libPods-ios.a */, + F0EF05B6C461610578D6C2A6 /* libPods-Tests.a */, ); name = Frameworks; sourceTree = ""; @@ -117,12 +117,12 @@ isa = PBXNativeTarget; buildConfigurationList = DA248D67195472AA00390AB0 /* Build configuration list for PBXNativeTarget "Tests" */; buildPhases = ( - FBC8982311CD4ED9A3006D45 /* Check Pods Manifest.lock */, + FBC8982311CD4ED9A3006D45 /* πŸ“¦ Check Pods Manifest.lock */, DA248D4F195472AA00390AB0 /* Sources */, DA248D50195472AA00390AB0 /* Frameworks */, DA248D51195472AA00390AB0 /* Resources */, - D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */, - 4B51E412BA3594400947AC71 /* Embed Pods Frameworks */, + D6347736BDF64FC5A4D078A4 /* πŸ“¦ Copy Pods Resources */, + 4B51E412BA3594400947AC71 /* πŸ“¦ Embed Pods Frameworks */, ); buildRules = ( ); @@ -171,44 +171,44 @@ /* End PBXResourcesBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */ - 4B51E412BA3594400947AC71 /* Embed Pods Frameworks */ = { + 4B51E412BA3594400947AC71 /* πŸ“¦ Embed Pods Frameworks */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Embed Pods Frameworks"; + name = "πŸ“¦ Embed Pods Frameworks"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-frameworks.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-frameworks.sh\"\n"; showEnvVarsInLog = 0; }; - D6347736BDF64FC5A4D078A4 /* Copy Pods Resources */ = { + D6347736BDF64FC5A4D078A4 /* πŸ“¦ Copy Pods Resources */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Copy Pods Resources"; + name = "πŸ“¦ Copy Pods Resources"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-ios/Pods-ios-resources.sh\"\n"; + shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Tests/Pods-Tests-resources.sh\"\n"; showEnvVarsInLog = 0; }; - FBC8982311CD4ED9A3006D45 /* Check Pods Manifest.lock */ = { + FBC8982311CD4ED9A3006D45 /* πŸ“¦ Check Pods Manifest.lock */ = { isa = PBXShellScriptBuildPhase; buildActionMask = 2147483647; files = ( ); inputPaths = ( ); - name = "Check Pods Manifest.lock"; + name = "πŸ“¦ Check Pods Manifest.lock"; outputPaths = ( ); runOnlyForDeploymentPostprocessing = 0; @@ -257,7 +257,7 @@ }; DA248D65195472AA00390AB0 /* Debug */ = { isa = XCBuildConfiguration; - baseConfigurationReference = 1A6DF883515E8008203AB352 /* Pods-ios.debug.xcconfig */; + baseConfigurationReference = 0EAE9F732E05E3878DC9D2D1 /* Pods-Tests.debug.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -274,7 +274,6 @@ CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; COPY_PHASE_STRIP = NO; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); @@ -305,7 +304,7 @@ }; DA248D66195472AA00390AB0 /* Release */ = { isa = XCBuildConfiguration; - baseConfigurationReference = CA88E6BDE3581B2BFE933C10 /* Pods-ios.release.xcconfig */; + baseConfigurationReference = 2FAA0419497C5AA7F0EA0E20 /* Pods-Tests.release.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; @@ -323,7 +322,6 @@ COPY_PHASE_STRIP = YES; ENABLE_NS_ASSERTIONS = NO; FRAMEWORK_SEARCH_PATHS = ( - "$(SDKROOT)/Developer/Library/Frameworks", "$(inherited)", "$(DEVELOPER_FRAMEWORKS_DIR)", ); From 44eac986bb0c097fd2f362fe66d7855f3bda35c4 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 00:44:02 +0300 Subject: [PATCH 06/24] Another attempt at the build --- .travis.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 699f7fe1..581b3ee3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,11 +16,11 @@ before_install: script: - pod lib lint --allow-warnings - - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator -arch i386 build - - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+WebP' -sdk iphonesimulator -arch i386 build - - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+MKAnnotation' -sdk iphonesimulator -arch i386 build + - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage' -sdk iphonesimulator build + - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+WebP' -sdk iphonesimulator build + - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage+MKAnnotation' -sdk iphonesimulator build - - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator -arch i386 build + - xctool -workspace SDWebImage.xcworkspace -scheme 'SDWebImage Demo' -sdk iphonesimulator build - pod install --project-directory=Tests - xctool -workspace SDWebImage.xcworkspace -scheme 'Tests' -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 6,OS=latest' test \ No newline at end of file From 8e300c92a40b83e84971b82d6b1182a8d684d7dd Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 00:50:24 +0300 Subject: [PATCH 07/24] Need to clean the SDWebImage scheme to allow the tests to rebuild it using their required platform. --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 581b3ee3..af6197f7 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,4 +23,5 @@ script: - 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 \ No newline at end of file From f8a7b6bac78e44d62399281cd49bf688398d4caf Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 12:48:26 +0300 Subject: [PATCH 08/24] 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." --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index af6197f7..313c5929 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,9 +8,9 @@ before_install: - export LANG=en_US.UTF-8 - env - locale - - gem install cocoapods --quiet + - gem install cocoapods --no-rdoc --no-ri --no-document --quiet - pod --version - - pod setup --silent + - pod setup --silent > /dev/null - pod repo update --silent script: From 0dc2c41112017693c9b4eccfc64bf5c05f0deb60 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 12:49:06 +0300 Subject: [PATCH 09/24] =?UTF-8?q?Trying=20to=20get=20around=20this=20last?= =?UTF-8?q?=20build=20error=20"The=20certificate=20for=20this=20server=20i?= =?UTF-8?q?s=20invalid.=20You=20might=20be=20connecting=20to=20a=20server?= =?UTF-8?q?=20that=20is=20pretending=20to=20be=20=C3=A2=E2=82=AC=C5=93www.?= =?UTF-8?q?google.gr=C3=A2=E2=82=AC=C2=9D=20which=20could=20put=20your=20c?= =?UTF-8?q?onfidential=20information=20at=20risk."=20by=20using=20a=20diff?= =?UTF-8?q?erent=20image?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Tests/Tests/SDWebImageManagerTests.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Tests/Tests/SDWebImageManagerTests.m b/Tests/Tests/SDWebImageManagerTests.m index 33bab743..e19d4e4e 100644 --- a/Tests/Tests/SDWebImageManagerTests.m +++ b/Tests/Tests/SDWebImageManagerTests.m @@ -38,7 +38,7 @@ static int64_t kAsyncTestTimeout = 5; - (void)testThatDownloadInvokesCompletionBlockWithCorrectParamsAsync { __block XCTestExpectation *expectation = [self expectationWithDescription:@"Image download completes"]; - NSURL *originalImageURL = [NSURL URLWithString:@"https://www.google.gr/images/srpr/logo11w.png"]; + NSURL *originalImageURL = [NSURL URLWithString:@"http://s3.amazonaws.com/fast-image-cache/demo-images/FICDDemoImage000.jpg"]; [[SDWebImageManager sharedManager] downloadImageWithURL:originalImageURL options:SDWebImageRefreshCached progress:nil completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { expect(image).toNot.beNil(); From cc510a6a4ea43786032e38b5c125aa4b70b3fca9 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 16:25:31 +0300 Subject: [PATCH 10/24] 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). --- SDWebImage/SDWebImageManager.m | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index c804ee9a..91475c13 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -56,7 +56,13 @@ return self.cacheKeyFilter(url); } else { - return [url absoluteString]; + if (NSClassFromString(@"NSURLComponents")) { + NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO]; + urlComponents.query = nil; // Strip out query parameters. + return urlComponents.string; + } else { + return [url absoluteString]; + } } } From e6e5c5156b7b95249f44ea74dd318022aeebc520 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Sun, 29 May 2016 22:32:15 +0300 Subject: [PATCH 11/24] Fixed #1415 documentation was not updated when `removeImageForKey:` became async --- SDWebImage/SDImageCache.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDWebImage/SDImageCache.h b/SDWebImage/SDImageCache.h index 6704541e..739bca86 100644 --- a/SDWebImage/SDImageCache.h +++ b/SDWebImage/SDImageCache.h @@ -164,7 +164,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot - (UIImage *)imageFromDiskCacheForKey:(NSString *)key; /** - * Remove the image from memory and disk cache synchronously + * Remove the image from memory and disk cache asynchronously * * @param key The unique image cache key */ From 86fc47bf7b80bdfea49d39d9ad4d719bba90015c Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Mon, 30 May 2016 07:31:01 +0300 Subject: [PATCH 12/24] Replaces #1398 Allow to customise cache and image downloader instances used with SDWebImageManager - added a new initializer (`initWithCache:downloader:`) --- SDWebImage/SDWebImageManager.h | 6 ++++++ SDWebImage/SDWebImageManager.m | 16 +++++++++------- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/SDWebImage/SDWebImageManager.h b/SDWebImage/SDWebImageManager.h index 8750730a..9848999c 100644 --- a/SDWebImage/SDWebImageManager.h +++ b/SDWebImage/SDWebImageManager.h @@ -181,6 +181,12 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; */ + (SDWebImageManager *)sharedManager; +/** + * Allows to specify instance of cache and image downloader used with image manager. + * @return new instance of `SDWebImageManager` with specified cache and downloader. + */ +- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader; + /** * Downloads the image at the given URL if not present in cache or return the cached version otherwise. * diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 91475c13..a905e93f 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -37,20 +37,22 @@ return instance; } -- (id)init { +- (instancetype)init { + SDImageCache *cache = [SDImageCache sharedImageCache]; + SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader]; + return [self initWithCache:cache downloader:downloader]; +} + +- (instancetype)initWithCache:(SDImageCache *)cache downloader:(SDWebImageDownloader *)downloader { if ((self = [super init])) { - _imageCache = [self createCache]; - _imageDownloader = [SDWebImageDownloader sharedDownloader]; + _imageCache = cache; + _imageDownloader = downloader; _failedURLs = [NSMutableSet new]; _runningOperations = [NSMutableArray new]; } return self; } -- (SDImageCache *)createCache { - return [SDImageCache sharedImageCache]; -} - - (NSString *)cacheKeyForURL:(NSURL *)url { if (self.cacheKeyFilter) { return self.cacheKeyFilter(url); From af7b587936b5f839ce961ef539c7bea0e1bee791 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Tue, 31 May 2016 14:51:33 +0300 Subject: [PATCH 13/24] 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). --- SDWebImage/SDWebImageManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index a905e93f..7329f513 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -58,7 +58,7 @@ return self.cacheKeyFilter(url); } else { - if (NSClassFromString(@"NSURLComponents")) { + if (NSClassFromString(@"NSURLComponents") && [NSURLComponents instancesRespondToSelector:@selector(string)]) { NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO]; urlComponents.query = nil; // Strip out query parameters. return urlComponents.string; From 94c1ec3ed078824071b222a87e7e42dc23b71960 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Wed, 1 Jun 2016 15:53:08 +0300 Subject: [PATCH 14/24] Revisited all copyright comments and decided for just one format --- Examples/SDWebImage Demo/AppDelegate.h | 14 +++++++------- Examples/SDWebImage Demo/AppDelegate.m | 14 +++++++------- Examples/SDWebImage Demo/DetailViewController.h | 14 +++++++------- Examples/SDWebImage Demo/DetailViewController.m | 14 +++++++------- Examples/SDWebImage Demo/MasterViewController.h | 14 +++++++------- Examples/SDWebImage Demo/MasterViewController.m | 14 +++++++------- Examples/SDWebImage Demo/main.m | 14 +++++++------- SDWebImage/MKAnnotationView+WebCache.h | 14 +++++++------- SDWebImage/MKAnnotationView+WebCache.m | 14 +++++++------- SDWebImage/NSData+ImageContentType.h | 12 ++++++++---- SDWebImage/NSData+ImageContentType.m | 12 ++++++++---- SDWebImage/SDWebImageCompat.m | 14 +++++++------- SDWebImage/SDWebImageDecoder.h | 3 +-- SDWebImage/SDWebImageDecoder.m | 3 +-- SDWebImage/UIImage+GIF.h | 15 ++++++++------- SDWebImage/UIImage+GIF.m | 15 ++++++++------- SDWebImage/UIImage+MultiFormat.h | 14 +++++++------- SDWebImage/UIImage+MultiFormat.m | 14 +++++++------- SDWebImage/UIImage+WebP.h | 14 +++++++------- SDWebImage/UIImage+WebP.m | 14 +++++++------- Tests/Tests/SDImageCacheTests.m | 14 +++++++------- Tests/Tests/SDWebImageDownloaderTests.m | 15 ++++++++------- Tests/Tests/SDWebImageManagerTests.m | 14 +++++++------- Tests/Tests/UIImageMultiFormatTests.m | 14 +++++++------- WebImage/SDWebImage.h | 15 ++++++++------- 25 files changed, 169 insertions(+), 159 deletions(-) diff --git a/Examples/SDWebImage Demo/AppDelegate.h b/Examples/SDWebImage Demo/AppDelegate.h index 7e60e229..15f2cc6e 100644 --- a/Examples/SDWebImage Demo/AppDelegate.h +++ b/Examples/SDWebImage Demo/AppDelegate.h @@ -1,10 +1,10 @@ -// -// AppDelegate.h -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/Examples/SDWebImage Demo/AppDelegate.m b/Examples/SDWebImage Demo/AppDelegate.m index 4ddd8e64..a7c47598 100644 --- a/Examples/SDWebImage Demo/AppDelegate.m +++ b/Examples/SDWebImage Demo/AppDelegate.m @@ -1,10 +1,10 @@ -// -// AppDelegate.m -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "AppDelegate.h" diff --git a/Examples/SDWebImage Demo/DetailViewController.h b/Examples/SDWebImage Demo/DetailViewController.h index f4c6b76f..77d3897e 100644 --- a/Examples/SDWebImage Demo/DetailViewController.h +++ b/Examples/SDWebImage Demo/DetailViewController.h @@ -1,10 +1,10 @@ -// -// DetailViewController.h -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/Examples/SDWebImage Demo/DetailViewController.m b/Examples/SDWebImage Demo/DetailViewController.m index d7acf6a8..899f12de 100644 --- a/Examples/SDWebImage Demo/DetailViewController.m +++ b/Examples/SDWebImage Demo/DetailViewController.m @@ -1,10 +1,10 @@ -// -// DetailViewController.m -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "DetailViewController.h" #import diff --git a/Examples/SDWebImage Demo/MasterViewController.h b/Examples/SDWebImage Demo/MasterViewController.h index 3f3a1392..96983d10 100644 --- a/Examples/SDWebImage Demo/MasterViewController.h +++ b/Examples/SDWebImage Demo/MasterViewController.h @@ -1,10 +1,10 @@ -// -// MasterViewController.h -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/Examples/SDWebImage Demo/MasterViewController.m b/Examples/SDWebImage Demo/MasterViewController.m index 57711c44..42942932 100644 --- a/Examples/SDWebImage Demo/MasterViewController.m +++ b/Examples/SDWebImage Demo/MasterViewController.m @@ -1,10 +1,10 @@ -// -// MasterViewController.m -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "MasterViewController.h" #import diff --git a/Examples/SDWebImage Demo/main.m b/Examples/SDWebImage Demo/main.m index 463372ca..1d5fab2c 100644 --- a/Examples/SDWebImage Demo/main.m +++ b/Examples/SDWebImage Demo/main.m @@ -1,10 +1,10 @@ -// -// main.m -// SDWebImage Demo -// -// Created by Olivier Poitrey on 09/05/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/SDWebImage/MKAnnotationView+WebCache.h b/SDWebImage/MKAnnotationView+WebCache.h index 175b13fb..fc2d48a1 100644 --- a/SDWebImage/MKAnnotationView+WebCache.h +++ b/SDWebImage/MKAnnotationView+WebCache.h @@ -1,10 +1,10 @@ -// -// MKAnnotationView+WebCache.h -// SDWebImage -// -// Created by Olivier Poitrey on 14/03/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "MapKit/MapKit.h" #import "SDWebImageManager.h" diff --git a/SDWebImage/MKAnnotationView+WebCache.m b/SDWebImage/MKAnnotationView+WebCache.m index 7e982ede..f2eff861 100644 --- a/SDWebImage/MKAnnotationView+WebCache.m +++ b/SDWebImage/MKAnnotationView+WebCache.m @@ -1,10 +1,10 @@ -// -// MKAnnotationView+WebCache.m -// SDWebImage -// -// Created by Olivier Poitrey on 14/03/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "MKAnnotationView+WebCache.h" #import "objc/runtime.h" diff --git a/SDWebImage/NSData+ImageContentType.h b/SDWebImage/NSData+ImageContentType.h index f6d452f0..3a1a9f39 100644 --- a/SDWebImage/NSData+ImageContentType.h +++ b/SDWebImage/NSData+ImageContentType.h @@ -1,7 +1,11 @@ -// -// Created by Fabrice Aneche on 06/01/14. -// Copyright (c) 2014 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Fabrice Aneche + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/SDWebImage/NSData+ImageContentType.m b/SDWebImage/NSData+ImageContentType.m index beb73b59..0d3c1e8f 100644 --- a/SDWebImage/NSData+ImageContentType.m +++ b/SDWebImage/NSData+ImageContentType.m @@ -1,7 +1,11 @@ -// -// Created by Fabrice Aneche on 06/01/14. -// Copyright (c) 2014 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Fabrice Aneche + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "NSData+ImageContentType.h" diff --git a/SDWebImage/SDWebImageCompat.m b/SDWebImage/SDWebImageCompat.m index 3de79f4e..958bed65 100644 --- a/SDWebImage/SDWebImageCompat.m +++ b/SDWebImage/SDWebImageCompat.m @@ -1,10 +1,10 @@ -// -// SDWebImageCompat.m -// SDWebImage -// -// Created by Olivier Poitrey on 11/12/12. -// Copyright (c) 2012 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "SDWebImageCompat.h" diff --git a/SDWebImage/SDWebImageDecoder.h b/SDWebImage/SDWebImageDecoder.h index 0176a7ba..2bfe7b4d 100644 --- a/SDWebImage/SDWebImageDecoder.h +++ b/SDWebImage/SDWebImageDecoder.h @@ -1,8 +1,7 @@ /* * This file is part of the SDWebImage package. * (c) Olivier Poitrey - * - * Created by james on 9/28/11. + * (c) james * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/SDWebImage/SDWebImageDecoder.m b/SDWebImage/SDWebImageDecoder.m index 2bb5472f..e5d7b910 100644 --- a/SDWebImage/SDWebImageDecoder.m +++ b/SDWebImage/SDWebImageDecoder.m @@ -1,8 +1,7 @@ /* * This file is part of the SDWebImage package. * (c) Olivier Poitrey - * - * Created by james on 9/28/11. + * (c) james * * For the full copyright and license information, please view the LICENSE * file that was distributed with this source code. diff --git a/SDWebImage/UIImage+GIF.h b/SDWebImage/UIImage+GIF.h index 084f4241..216d90e1 100755 --- a/SDWebImage/UIImage+GIF.h +++ b/SDWebImage/UIImage+GIF.h @@ -1,10 +1,11 @@ -// -// UIImage+GIF.h -// LBGIFImage -// -// Created by Laurin Brandner on 06.01.12. -// Copyright (c) 2012 __MyCompanyName__. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Laurin Brandner + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/SDWebImage/UIImage+GIF.m b/SDWebImage/UIImage+GIF.m index de45dd35..3f236d77 100755 --- a/SDWebImage/UIImage+GIF.m +++ b/SDWebImage/UIImage+GIF.m @@ -1,10 +1,11 @@ -// -// UIImage+GIF.m -// LBGIFImage -// -// Created by Laurin Brandner on 06.01.12. -// Copyright (c) 2012 __MyCompanyName__. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Laurin Brandner + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "UIImage+GIF.h" #import diff --git a/SDWebImage/UIImage+MultiFormat.h b/SDWebImage/UIImage+MultiFormat.h index 186ebc0a..e05c111b 100644 --- a/SDWebImage/UIImage+MultiFormat.h +++ b/SDWebImage/UIImage+MultiFormat.h @@ -1,10 +1,10 @@ -// -// UIImage+MultiFormat.h -// SDWebImage -// -// Created by Olivier Poitrey on 07/06/13. -// Copyright (c) 2013 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import diff --git a/SDWebImage/UIImage+MultiFormat.m b/SDWebImage/UIImage+MultiFormat.m index a8307544..178e9048 100644 --- a/SDWebImage/UIImage+MultiFormat.m +++ b/SDWebImage/UIImage+MultiFormat.m @@ -1,10 +1,10 @@ -// -// UIImage+MultiFormat.m -// SDWebImage -// -// Created by Olivier Poitrey on 07/06/13. -// Copyright (c) 2013 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import "UIImage+MultiFormat.h" #import "UIImage+GIF.h" diff --git a/SDWebImage/UIImage+WebP.h b/SDWebImage/UIImage+WebP.h index 48cdf030..dbfb0a90 100644 --- a/SDWebImage/UIImage+WebP.h +++ b/SDWebImage/UIImage+WebP.h @@ -1,10 +1,10 @@ -// -// UIImage+WebP.h -// SDWebImage -// -// Created by Olivier Poitrey on 07/06/13. -// Copyright (c) 2013 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #ifdef SD_WEBP diff --git a/SDWebImage/UIImage+WebP.m b/SDWebImage/UIImage+WebP.m index a7e341f6..9acc03cc 100644 --- a/SDWebImage/UIImage+WebP.m +++ b/SDWebImage/UIImage+WebP.m @@ -1,10 +1,10 @@ -// -// UIImage+WebP.m -// SDWebImage -// -// Created by Olivier Poitrey on 07/06/13. -// Copyright (c) 2013 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #ifdef SD_WEBP #import "UIImage+WebP.h" diff --git a/Tests/Tests/SDImageCacheTests.m b/Tests/Tests/SDImageCacheTests.m index 231ea839..5a546498 100644 --- a/Tests/Tests/SDImageCacheTests.m +++ b/Tests/Tests/SDImageCacheTests.m @@ -1,10 +1,10 @@ -// -// SDImageCacheTests.m -// SDWebImage Tests -// -// Created by Bogdan Poplauschi on 20/06/14. -// -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #define EXP_SHORTHAND // required by Expecta diff --git a/Tests/Tests/SDWebImageDownloaderTests.m b/Tests/Tests/SDWebImageDownloaderTests.m index 233711fa..04273565 100644 --- a/Tests/Tests/SDWebImageDownloaderTests.m +++ b/Tests/Tests/SDWebImageDownloaderTests.m @@ -1,10 +1,11 @@ -// -// SDWebImageDownloaderTests.m -// SDWebImage Tests -// -// Created by Matt Galloway on 01/09/2014. -// -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Matt Galloway + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #define EXP_SHORTHAND // required by Expecta diff --git a/Tests/Tests/SDWebImageManagerTests.m b/Tests/Tests/SDWebImageManagerTests.m index cf26720b..65176c11 100644 --- a/Tests/Tests/SDWebImageManagerTests.m +++ b/Tests/Tests/SDWebImageManagerTests.m @@ -1,10 +1,10 @@ -// -// SDWebImageManagerTests.m -// SDWebImage Tests -// -// Created by Bogdan Poplauschi on 20/06/14. -// -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #define EXP_SHORTHAND // required by Expecta diff --git a/Tests/Tests/UIImageMultiFormatTests.m b/Tests/Tests/UIImageMultiFormatTests.m index 00b39549..310cfc7d 100644 --- a/Tests/Tests/UIImageMultiFormatTests.m +++ b/Tests/Tests/UIImageMultiFormatTests.m @@ -1,10 +1,10 @@ -// -// UIImageMultiFormatTests.m -// SDWebImage Tests -// -// Created by Bogdan Poplauschi on 18/07/14. -// -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #define EXP_SHORTHAND // required by Expecta diff --git a/WebImage/SDWebImage.h b/WebImage/SDWebImage.h index b95b911d..4ecf5bd2 100644 --- a/WebImage/SDWebImage.h +++ b/WebImage/SDWebImage.h @@ -1,10 +1,11 @@ -// -// WebImage.h -// WebImage -// -// Created by Florent Vilmart on 2015-03-14. -// Copyright (c) 2015 Dailymotion. All rights reserved. -// +/* + * This file is part of the SDWebImage package. + * (c) Olivier Poitrey + * (c) Florent Vilmart + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ #import From 5580c78282910716f63210b700c83d3415bdfc08 Mon Sep 17 00:00:00 2001 From: Oana Popescu Date: Thu, 2 Jun 2016 09:02:03 +0300 Subject: [PATCH 15/24] 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 --- SDWebImage/SDWebImageDownloaderOperation.h | 7 - SDWebImage/SDWebImageDownloaderOperation.m | 207 +++++++++++---------- 2 files changed, 108 insertions(+), 106 deletions(-) diff --git a/SDWebImage/SDWebImageDownloaderOperation.h b/SDWebImage/SDWebImageDownloaderOperation.h index dd48b228..4d31130e 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.h +++ b/SDWebImage/SDWebImageDownloaderOperation.h @@ -25,13 +25,6 @@ extern NSString *const SDWebImageDownloadFinishNotification; @property (assign, nonatomic) BOOL shouldDecompressImages; -/** - * Whether the URL connection should consult the credential storage for authenticating the connection. `YES` by default. - * - * This is the value that is returned in the `NSURLConnectionDelegate` method `-connectionShouldUseCredentialStorage:`. - */ -@property (nonatomic, assign) BOOL shouldUseCredentialStorage; - /** * The credential used for authentication challenges in `-connection:didReceiveAuthenticationChallenge:`. * diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 5a8bd11f..7753187a 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -17,7 +17,7 @@ NSString *const SDWebImageDownloadReceiveResponseNotification = @"SDWebImageDown NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification"; NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinishNotification"; -@interface SDWebImageDownloaderOperation () +@interface SDWebImageDownloaderOperation () @property (copy, nonatomic) SDWebImageDownloaderProgressBlock progressBlock; @property (copy, nonatomic) SDWebImageDownloaderCompletedBlock completedBlock; @@ -26,7 +26,10 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis @property (assign, nonatomic, getter = isExecuting) BOOL executing; @property (assign, nonatomic, getter = isFinished) BOOL finished; @property (strong, nonatomic) NSMutableData *imageData; -@property (strong, nonatomic) NSURLConnection *connection; + +@property (strong, nonatomic) NSURLSession *session; +@property (strong, nonatomic) NSURLSessionDataTask *dataTask; + @property (strong, atomic) NSThread *thread; #if TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MAX_ALLOWED >= __IPHONE_4_0 @@ -52,7 +55,6 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis if ((self = [super init])) { _request = request; _shouldDecompressImages = YES; - _shouldUseCredentialStorage = YES; _options = options; _progressBlock = [progressBlock copy]; _completedBlock = [completedBlock copy]; @@ -60,11 +62,15 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis _executing = NO; _finished = NO; _expectedSize = 0; - responseFromCached = YES; // Initially wrong until `connection:willCacheResponse:` is called or not called + responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called } return self; } +- (void)dealloc { + +} + - (void)start { @synchronized (self) { if (self.isCancelled) { @@ -91,36 +97,26 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis }]; } #endif - + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + sessionConfig.timeoutIntervalForRequest = 15; + self.session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:nil]; + self.executing = YES; - self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO]; + self.dataTask = [self.session dataTaskWithRequest:self.request]; self.thread = [NSThread currentThread]; } + + [self.dataTask resume]; - [self.connection start]; - - if (self.connection) { + if (self.dataTask) { if (self.progressBlock) { self.progressBlock(0, NSURLResponseUnknownLength); } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStartNotification object:self]; }); - - if (floor(NSFoundationVersionNumber) <= NSFoundationVersionNumber_iOS_5_1) { - // Make sure to run the runloop in our background thread so it can process downloaded data - // Note: we use a timeout to work around an issue with NSURLConnection cancel under iOS 5 - // not waking up the runloop, leading to dead threads (see https://github.com/rs/SDWebImage/issues/466) - CFRunLoopRunInMode(kCFRunLoopDefaultMode, 10, false); - } - else { - CFRunLoopRun(); - } - - if (!self.isFinished) { - [self.connection cancel]; - [self connection:self.connection didFailWithError:[NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorTimedOut userInfo:@{NSURLErrorFailingURLErrorKey : self.request.URL}]]; - } } else { if (self.completedBlock) { @@ -155,7 +151,6 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis - (void)cancelInternalAndStop { if (self.isFinished) return; [self cancelInternal]; - CFRunLoopStop(CFRunLoopGetCurrent()); } - (void)cancelInternal { @@ -163,8 +158,8 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis [super cancel]; if (self.cancelBlock) self.cancelBlock(); - if (self.connection) { - [self.connection cancel]; + if (self.dataTask) { + [self.dataTask cancel]; dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; }); @@ -188,9 +183,11 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis self.cancelBlock = nil; self.completedBlock = nil; self.progressBlock = nil; - self.connection = nil; + self.dataTask = nil; self.imageData = nil; self.thread = nil; + [self.session invalidateAndCancel]; + self.session = nil; } - (void)setFinished:(BOOL)finished { @@ -209,9 +206,12 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis return YES; } -#pragma mark NSURLConnection (delegate) +#pragma mark NSURLSessionTaskDelegate -- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response { +- (void)URLSession:(NSURLSession *)session + dataTask:(NSURLSessionDataTask *)dataTask +didReceiveResponse:(NSURLResponse *)response + completionHandler:(void (^)(NSURLSessionResponseDisposition disposition))completionHandler { //'304 Not Modified' is an exceptional one if (![response respondsToSelector:@selector(statusCode)] || ([((NSHTTPURLResponse *)response) statusCode] < 400 && [((NSHTTPURLResponse *)response) statusCode] != 304)) { @@ -220,7 +220,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis if (self.progressBlock) { self.progressBlock(0, expected); } - + self.imageData = [[NSMutableData alloc] initWithCapacity:expected]; self.response = response; dispatch_async(dispatch_get_main_queue(), ^{ @@ -235,21 +235,24 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis if (code == 304) { [self cancelInternal]; } else { - [self.connection cancel]; + [self.dataTask cancel]; } dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; }); - + if (self.completedBlock) { self.completedBlock(nil, nil, [NSError errorWithDomain:NSURLErrorDomain code:[((NSHTTPURLResponse *)response) statusCode] userInfo:nil], YES); } - CFRunLoopStop(CFRunLoopGetCurrent()); [self done]; } + + if (completionHandler) { + completionHandler(NSURLSessionResponseAllow); + } } -- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data { +- (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask didReceiveData:(NSData *)data { [self.imageData appendData:data]; if ((self.options & SDWebImageDownloaderProgressiveDownload) && self.expectedSize > 0 && self.completedBlock) { @@ -277,7 +280,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis // When we draw to Core Graphics, we lose orientation information, // which means the image below born of initWithCGIImage will be // oriented incorrectly sometimes. (Unlike the image born of initWithData - // in connectionDidFinishLoading.) So save it here and pass it on later. + // in didCompleteWithError.) So save it here and pass it on later. orientation = [[self class] orientationFromPropertyValue:(orientationValue == -1 ? 1 : orientationValue)]; } @@ -361,75 +364,73 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis return SDScaledImageForKey(key, image); } -- (void)connectionDidFinishLoading:(NSURLConnection *)aConnection { - SDWebImageDownloaderCompletedBlock completionBlock = self.completedBlock; +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { @synchronized(self) { - CFRunLoopStop(CFRunLoopGetCurrent()); self.thread = nil; - self.connection = nil; + self.dataTask = nil; dispatch_async(dispatch_get_main_queue(), ^{ [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:self]; + if (!error) { + [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadFinishNotification object:self]; + } }); } - if (![[NSURLCache sharedURLCache] cachedResponseForRequest:_request]) { - responseFromCached = NO; - } - - if (completionBlock) { - if (self.options & SDWebImageDownloaderIgnoreCachedResponse && responseFromCached) { - completionBlock(nil, nil, nil, YES); - } else if (self.imageData) { - UIImage *image = [UIImage sd_imageWithData:self.imageData]; - NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:self.request.URL]; - image = [self scaledImageForKey:key image:image]; - - // Do not force decoding animated GIFs - if (!image.images) { - if (self.shouldDecompressImages) { - image = [UIImage decodedImageWithImage:image]; + if (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); } - if (CGSizeEqualToSize(image.size, CGSizeZero)) { - completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Downloaded image has 0 pixels"}], YES); - } - else { - completionBlock(image, self.imageData, nil, YES); - } - } else { - completionBlock(nil, nil, [NSError errorWithDomain:SDWebImageErrorDomain code:0 userInfo:@{NSLocalizedDescriptionKey : @"Image data is nil"}], YES); } } + self.completionBlock = nil; [self done]; } -- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error { - @synchronized(self) { - CFRunLoopStop(CFRunLoopGetCurrent()); - self.thread = nil; - self.connection = nil; - dispatch_async(dispatch_get_main_queue(), ^{ - [[NSNotificationCenter defaultCenter] postNotificationName:SDWebImageDownloadStopNotification object:self]; - }); - } - - if (self.completedBlock) { - self.completedBlock(nil, nil, error, YES); - } - self.completionBlock = nil; - [self done]; -} - -- (NSCachedURLResponse *)connection:(NSURLConnection *)connection willCacheResponse:(NSCachedURLResponse *)cachedResponse { +- (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 - return nil; + cachedResponse = nil; } - else { - return cachedResponse; + if (completionHandler) { + completionHandler(cachedResponse); } } @@ -437,30 +438,38 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis return self.options & SDWebImageDownloaderContinueInBackground; } -- (BOOL)connectionShouldUseCredentialStorage:(NSURLConnection __unused *)connection { - return self.shouldUseCredentialStorage; -} - -- (void)connection:(NSURLConnection *)connection willSendRequestForAuthenticationChallenge:(NSURLAuthenticationChallenge *)challenge{ +- (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) && - [challenge.sender respondsToSelector:@selector(performDefaultHandlingForAuthenticationChallenge:)]) { - [challenge.sender performDefaultHandlingForAuthenticationChallenge:challenge]; + if (!(self.options & SDWebImageDownloaderAllowInvalidSSLCertificates)) { + disposition = NSURLSessionAuthChallengePerformDefaultHandling; } else { - NSURLCredential *credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; - [[challenge sender] useCredential:credential forAuthenticationChallenge:challenge]; + credential = [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]; + disposition = NSURLSessionAuthChallengeUseCredential; } } else { if ([challenge previousFailureCount] == 0) { if (self.credential) { - [[challenge sender] useCredential:self.credential forAuthenticationChallenge:challenge]; + credential = self.credential; + disposition = NSURLSessionAuthChallengeUseCredential; } else { - [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } else { - [[challenge sender] continueWithoutCredentialForAuthenticationChallenge:challenge]; + disposition = NSURLSessionAuthChallengeCancelAuthenticationChallenge; } } + + if (completionHandler) { + completionHandler(disposition, credential); + } } @end From 09a9e74eae4ae0bd9e910849827fd282a8ef6a81 Mon Sep 17 00:00:00 2001 From: Oana Popescu Date: Thu, 2 Jun 2016 18:23:49 +0300 Subject: [PATCH 16/24] Removed dealloc method and added comment regarding sending nil for delegateQueue --- SDWebImage/SDWebImageDownloaderOperation.m | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 7753187a..2c36f927 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -67,10 +67,6 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis return self; } -- (void)dealloc { - -} - - (void)start { @synchronized (self) { if (self.isCancelled) { @@ -99,6 +95,12 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis #endif 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.session = [NSURLSession sessionWithConfiguration:sessionConfig delegate:self delegateQueue:nil]; From 6545a3aba1a8488153dd77079402ee3c3b89f539 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Thu, 2 Jun 2016 19:10:31 +0300 Subject: [PATCH 17/24] Bumped the deployment target to iOS 7 (due to NSURLSession) and also incremented the library version to 3.8.0 --- .../SDWebImage Demo.xcodeproj/project.pbxproj | 19 +++++++++++++++++-- README.md | 8 ++++---- SDWebImage.podspec | 6 +++--- SDWebImage.xcodeproj/project.pbxproj | 12 ++---------- Tests/Podfile | 2 +- WebImage/Info.plist | 2 +- 6 files changed, 28 insertions(+), 21 deletions(-) diff --git a/Examples/SDWebImage Demo.xcodeproj/project.pbxproj b/Examples/SDWebImage Demo.xcodeproj/project.pbxproj index 26927625..061ecec6 100644 --- a/Examples/SDWebImage Demo.xcodeproj/project.pbxproj +++ b/Examples/SDWebImage Demo.xcodeproj/project.pbxproj @@ -33,6 +33,13 @@ remoteGlobalIDString = 4A2CADFF1AB4BB5300B6BC39; remoteInfo = WebImage; }; + 43AEAFA91D008FEE005B41A8 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 00733A4C1BC487C000A5A117; + remoteInfo = "WebImage tvOS"; + }; DA248D731954841D00390AB0 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = DA248D6C1954841D00390AB0 /* SDWebImage.xcodeproj */; @@ -165,6 +172,7 @@ DA248D761954841D00390AB0 /* libSDWebImage+WebP.a */, DA248D781954841D00390AB0 /* libSDWebImage+MKAnnotation.a */, 43A0FAAF1BDD16AC00B7582B /* WebImage.framework */, + 43AEAFAA1D008FEE005B41A8 /* WebImage.framework */, ); name = Products; sourceTree = ""; @@ -229,6 +237,13 @@ remoteRef = 43A0FAAE1BDD16AC00B7582B /* PBXContainerItemProxy */; sourceTree = BUILT_PRODUCTS_DIR; }; + 43AEAFAA1D008FEE005B41A8 /* WebImage.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = WebImage.framework; + remoteRef = 43AEAFA91D008FEE005B41A8 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; DA248D741954841D00390AB0 /* libSDWebImage.a */ = { isa = PBXReferenceProxy; fileType = archive.ar; @@ -322,7 +337,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; }; @@ -340,7 +355,7 @@ GCC_WARN_ABOUT_RETURN_TYPE = YES; GCC_WARN_UNINITIALIZED_AUTOS = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; OTHER_CFLAGS = "-DNS_BLOCK_ASSERTIONS=1"; SDKROOT = iphoneos; VALIDATE_PRODUCT = YES; diff --git a/README.md b/README.md index 37771588..81afa6ac 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,8 @@ It provides: - Use GCD and ARC - Arm64 support -NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 2.0 and requires iOS 5.1.1 -minimum deployment version. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat). +NOTE: Version 3.8 of SDWebImage requires iOS 7 or later (because of NSURLSession). +Versions 3.7 to 3.0 requires iOS 5.1.1. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat). [How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F) @@ -223,8 +223,8 @@ There are three ways to use SDWebImage in your project: #### Podfile ``` -platform :ios, '6.1' -pod 'SDWebImage', '~>3.7' +platform :ios, '7.0' +pod 'SDWebImage', '~>3.8' ``` If you are using Swift, be sure to add `use_frameworks!` and set your target to iOS 8+: diff --git a/SDWebImage.podspec b/SDWebImage.podspec index 646126f6..086f620b 100644 --- a/SDWebImage.podspec +++ b/SDWebImage.podspec @@ -1,7 +1,7 @@ Pod::Spec.new do |s| s.name = 'SDWebImage' - s.version = '3.7.6' - s.ios.deployment_target = '5.0' + s.version = '3.8.0' + s.ios.deployment_target = '7.0' s.tvos.deployment_target = '9.0' s.license = 'MIT' s.summary = 'Asynchronous image downloader with cache support with an UIImageView category.' @@ -29,7 +29,7 @@ Pod::Spec.new do |s| end s.subspec 'MapKit' do |mk| - mk.ios.deployment_target = '5.0' + mk.ios.deployment_target = '7.0' mk.source_files = 'SDWebImage/MKAnnotationView+WebCache.*' mk.framework = 'MapKit' mk.dependency 'SDWebImage/Core' diff --git a/SDWebImage.xcodeproj/project.pbxproj b/SDWebImage.xcodeproj/project.pbxproj index c570bc2c..ffdd535f 100644 --- a/SDWebImage.xcodeproj/project.pbxproj +++ b/SDWebImage.xcodeproj/project.pbxproj @@ -1409,7 +1409,6 @@ GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; ONLY_ACTIVE_ARCH = NO; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "SDWebImage+MKAnnotation"; @@ -1433,7 +1432,6 @@ GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "SDWebImage+MKAnnotation"; SKIP_INSTALL = YES; @@ -1457,7 +1455,6 @@ GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = "$(inherited)"; INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = SDWebImage; SKIP_INSTALL = YES; @@ -1481,7 +1478,6 @@ GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = ""; INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = SDWebImage; SKIP_INSTALL = YES; @@ -1508,7 +1504,6 @@ "$(inherited)", ); INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "SDWebImage+WebP"; SKIP_INSTALL = YES; @@ -1531,7 +1526,6 @@ GCC_PREFIX_HEADER = ""; GCC_PREPROCESSOR_DEFINITIONS = "SD_WEBP=1"; INSTALL_PATH = "$(BUILT_PRODUCTS_DIR)"; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; OTHER_LDFLAGS = "-ObjC"; PRODUCT_NAME = "SDWebImage+WebP"; SKIP_INSTALL = YES; @@ -1567,7 +1561,7 @@ GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = Vendors/libwebp/src; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; ONLY_ACTIVE_ARCH = YES; PUBLIC_HEADERS_FOLDER_PATH = include/SDWebImage; RUN_CLANG_STATIC_ANALYZER = YES; @@ -1596,7 +1590,7 @@ GCC_WARN_UNUSED_PARAMETER = NO; GCC_WARN_UNUSED_VARIABLE = YES; HEADER_SEARCH_PATHS = Vendors/libwebp/src; - IPHONEOS_DEPLOYMENT_TARGET = 6.0; + IPHONEOS_DEPLOYMENT_TARGET = 7.0; PUBLIC_HEADERS_FOLDER_PATH = include/SDWebImage; RUN_CLANG_STATIC_ANALYZER = YES; SDKROOT = iphoneos; @@ -1607,7 +1601,6 @@ 539F912D16316D2D00160719 /* Debug */ = { isa = XCBuildConfiguration; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 6.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Debug; @@ -1615,7 +1608,6 @@ 539F912E16316D2D00160719 /* Release */ = { isa = XCBuildConfiguration; buildSettings = { - IPHONEOS_DEPLOYMENT_TARGET = 6.0; PRODUCT_NAME = "$(TARGET_NAME)"; }; name = Release; diff --git a/Tests/Podfile b/Tests/Podfile index f2a66884..ba09b915 100644 --- a/Tests/Podfile +++ b/Tests/Podfile @@ -4,7 +4,7 @@ xcodeproj 'SDWebImage Tests' workspace '../SDWebImage' target 'Tests' do - platform :ios, '5.0' + platform :ios, '7.0' pod 'Expecta', '<=0.3.1' pod 'SDWebImage', :path => '../' diff --git a/WebImage/Info.plist b/WebImage/Info.plist index 9369da1a..ddbaa33b 100644 --- a/WebImage/Info.plist +++ b/WebImage/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.7.6 + 3.8.0 CFBundleSignature ???? CFBundleVersion From cb7a3db23c5eb785dd31e83f28a5d30ee2f3440c Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Thu, 2 Jun 2016 19:19:42 +0300 Subject: [PATCH 18/24] Updated the changelog --- CHANGELOG.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 553f102f..b683b89d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,20 @@ +## [3.8.0 Minor release - Replaces NSURLConnection (deprecated) with NSURLSession - on May 8th, 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 - 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 - fixes #1433 #1533 +- 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: From 335a437b2e70cf3f3cd41452d217098bad5acc10 Mon Sep 17 00:00:00 2001 From: Ahn Jung Min Date: Mon, 6 Jun 2016 04:42:02 +0900 Subject: [PATCH 19/24] fixed crash on ios7 user device fixed that string property of NSURLComponents can`t use on iOS7 --- SDWebImage/SDWebImageManager.m | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index 7329f513..e7bd5f7d 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -61,7 +61,7 @@ if (NSClassFromString(@"NSURLComponents") && [NSURLComponents instancesRespondToSelector:@selector(string)]) { NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO]; urlComponents.query = nil; // Strip out query parameters. - return urlComponents.string; + return [urlComponents.URL absoluteString]; } else { return [url absoluteString]; } From 1bf62d475a94015b383eddf5e7567c0747eb601d Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Mon, 6 Jun 2016 07:32:34 +0300 Subject: [PATCH 20/24] Fixed #1583 crash in `SDWebImageManager cacheKeyForURL:` when url is nil - replaced #1585 --- SDWebImage/SDWebImageManager.m | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/SDWebImage/SDWebImageManager.m b/SDWebImage/SDWebImageManager.m index e7bd5f7d..cdfa1fc9 100644 --- a/SDWebImage/SDWebImageManager.m +++ b/SDWebImage/SDWebImageManager.m @@ -54,10 +54,13 @@ } - (NSString *)cacheKeyForURL:(NSURL *)url { + if (!url) { + return @""; + } + if (self.cacheKeyFilter) { return self.cacheKeyFilter(url); - } - else { + } else { if (NSClassFromString(@"NSURLComponents") && [NSURLComponents instancesRespondToSelector:@selector(string)]) { NSURLComponents *urlComponents = [[NSURLComponents alloc] initWithURL:url resolvingAgainstBaseURL:NO]; urlComponents.query = nil; // Strip out query parameters. From eab427914046f56775bcab9e731d647536611fb8 Mon Sep 17 00:00:00 2001 From: Oana Popescu Date: Mon, 6 Jun 2016 19:12:56 +0300 Subject: [PATCH 21/24] 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. --- SDWebImage/SDWebImageDownloader.m | 83 ++++++++++- SDWebImage/SDWebImageDownloaderOperation.h | 33 ++++- SDWebImage/SDWebImageDownloaderOperation.m | 159 ++++++++++++--------- 3 files changed, 206 insertions(+), 69 deletions(-) diff --git a/SDWebImage/SDWebImageDownloader.m b/SDWebImage/SDWebImageDownloader.m index 96aefa77..ca703033 100644 --- a/SDWebImage/SDWebImageDownloader.m +++ b/SDWebImage/SDWebImageDownloader.m @@ -13,7 +13,7 @@ static NSString *const kProgressCallbackKey = @"progress"; static NSString *const kCompletedCallbackKey = @"completed"; -@interface SDWebImageDownloader () +@interface SDWebImageDownloader () @property (strong, nonatomic) NSOperationQueue *downloadQueue; @property (weak, nonatomic) NSOperation *lastAddedOperation; @@ -23,6 +23,9 @@ static NSString *const kCompletedCallbackKey = @"completed"; // This queue is used to serialize the handling of the network responses of all the download operation in a single queue @property (SDDispatchQueueSetterSementics, nonatomic) dispatch_queue_t barrierQueue; +// The session in which data tasks will run +@property (strong, nonatomic) NSURLSession *session; + @end @implementation SDWebImageDownloader @@ -74,11 +77,26 @@ static NSString *const kCompletedCallbackKey = @"completed"; #endif _barrierQueue = dispatch_queue_create("com.hackemist.SDWebImageDownloaderBarrierQueue", DISPATCH_QUEUE_CONCURRENT); _downloadTimeout = 15.0; + + NSURLSessionConfiguration *sessionConfig = [NSURLSessionConfiguration defaultSessionConfiguration]; + sessionConfig.timeoutIntervalForRequest = _downloadTimeout; + + /** + * Create the session for this task + * We send nil as delegate queue so that the session creates a serial operation queue for performing all delegate + * method calls and completion handler calls. + */ + self.session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:nil]; } return self; } - (void)dealloc { + [self.session invalidateAndCancel]; + self.session = nil; + [self.downloadQueue cancelAllOperations]; SDDispatchQueueRelease(_barrierQueue); } @@ -133,6 +151,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; request.allHTTPHeaderFields = wself.HTTPHeaders; } operation = [[wself.operationClass alloc] initWithRequest:request + inSession:self.session options:options progress:^(NSInteger receivedSize, NSInteger expectedSize) { SDWebImageDownloader *sself = wself; @@ -233,4 +252,66 @@ static NSString *const kCompletedCallbackKey = @"completed"; [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 diff --git a/SDWebImage/SDWebImageDownloaderOperation.h b/SDWebImage/SDWebImageDownloaderOperation.h index 4d31130e..7a995d2a 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.h +++ b/SDWebImage/SDWebImageDownloaderOperation.h @@ -15,13 +15,18 @@ extern NSString *const SDWebImageDownloadReceiveResponseNotification; extern NSString *const SDWebImageDownloadStopNotification; extern NSString *const SDWebImageDownloadFinishNotification; -@interface SDWebImageDownloaderOperation : NSOperation +@interface SDWebImageDownloaderOperation : NSOperation /** - * The request used by the operation's connection. + * The request used by the operation's task. */ @property (strong, nonatomic, readonly) NSURLRequest *request; +/** + * The operation's task + */ +@property (strong, nonatomic, readonly) NSURLSessionTask *dataTask; + @property (assign, nonatomic) BOOL shouldDecompressImages; @@ -53,6 +58,7 @@ extern NSString *const SDWebImageDownloadFinishNotification; * @see SDWebImageDownloaderOperation * * @param request the URL request + * @param session the URL session in which this operation will run * @param options downloader options * @param progressBlock the block executed when a new chunk of data arrives. * @note the progress block is executed on a background queue @@ -63,9 +69,32 @@ extern NSString *const SDWebImageDownloadFinishNotification; * @return the initialized instance */ - (id)initWithRequest:(NSURLRequest *)request + inSession:(NSURLSession *)session options:(SDWebImageDownloaderOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock cancelled:(SDWebImageNoParamsBlock)cancelBlock; +/** + * Initializes a `SDWebImageDownloaderOperation` object + * + * @see SDWebImageDownloaderOperation + * + * @param request the URL request + * @param options downloader options + * @param progressBlock the block executed when a new chunk of data arrives. + * @note the progress block is executed on a background queue + * @param completedBlock the block executed when the download is done. + * @note the completed block is executed on the main queue for success. If errors are found, there is a chance the block will be executed on a background queue + * @param cancelBlock the block executed if the download (operation) is cancelled + * + * @return the initialized instance. The operation will run in a separate session created for this operation + */ +- (id)initWithRequest:(NSURLRequest *)request + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock + cancelled:(SDWebImageNoParamsBlock)cancelBlock +__deprecated_msg("Method deprecated. Use `initWithRequest:inSession:options:progress:completed:cancelled`"); + @end diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 2c36f927..901e638c 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -17,7 +17,7 @@ NSString *const SDWebImageDownloadReceiveResponseNotification = @"SDWebImageDown NSString *const SDWebImageDownloadStopNotification = @"SDWebImageDownloadStopNotification"; NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinishNotification"; -@interface SDWebImageDownloaderOperation () +@interface SDWebImageDownloaderOperation () @property (copy, nonatomic) SDWebImageDownloaderProgressBlock progressBlock; @property (copy, nonatomic) SDWebImageDownloaderCompletedBlock completedBlock; @@ -27,8 +27,13 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis @property (assign, nonatomic, getter = isFinished) BOOL finished; @property (strong, nonatomic) NSMutableData *imageData; -@property (strong, nonatomic) NSURLSession *session; -@property (strong, nonatomic) NSURLSessionDataTask *dataTask; +// 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 *session; +// This is set to NO if we're using an injected NSURLSession, and to YES otherwise +@property (assign, nonatomic) BOOL ownSession; + +@property (strong, nonatomic, readwrite) NSURLSessionTask *dataTask; @property (strong, atomic) NSThread *thread; @@ -52,6 +57,21 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageDownloaderCompletedBlock)completedBlock cancelled:(SDWebImageNoParamsBlock)cancelBlock { + + return [self initWithRequest:request + inSession:nil + options:options + progress:progressBlock + completed:completedBlock + cancelled:cancelBlock]; +} + +- (id)initWithRequest:(NSURLRequest *)request + inSession:(NSURLSession *)session + options:(SDWebImageDownloaderOptions)options + progress:(SDWebImageDownloaderProgressBlock)progressBlock + completed:(SDWebImageDownloaderCompletedBlock)completedBlock + cancelled:(SDWebImageNoParamsBlock)cancelBlock { if ((self = [super init])) { _request = request; _shouldDecompressImages = YES; @@ -62,6 +82,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis _executing = NO; _finished = NO; _expectedSize = 0; + _session = session; responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called } return self; @@ -93,17 +114,21 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis }]; } #endif - 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.session = [NSURLSession sessionWithConfiguration:sessionConfig - delegate:self - delegateQueue:nil]; + if (!self.session) { + self.ownSession = YES; + + 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.session = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:nil]; + } self.executing = YES; self.dataTask = [self.session dataTaskWithRequest:self.request]; @@ -188,8 +213,10 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis self.dataTask = nil; self.imageData = nil; self.thread = nil; - [self.session invalidateAndCancel]; - self.session = nil; + if (self.ownSession) { + [self.session invalidateAndCancel]; + self.session = nil; + } } - (void)setFinished:(BOOL)finished { @@ -208,7 +235,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis return YES; } -#pragma mark NSURLSessionTaskDelegate +#pragma mark NSURLSessionDataDelegate - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)dataTask @@ -339,32 +366,24 @@ didReceiveResponse:(NSURLResponse *)response } } -+ (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; +- (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); } } -- (UIImage *)scaledImageForKey:(NSString *)key image:(UIImage *)image { - return SDScaledImageForKey(key, image); -} +#pragma mark NSURLSessionTaskDelegate - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didCompleteWithError:(NSError *)error { @synchronized(self) { @@ -419,32 +438,7 @@ didReceiveResponse:(NSURLResponse *)response [self done]; } -- (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); - } -} - -- (BOOL)shouldContinueWhenAppEntersBackground { - return self.options & SDWebImageDownloaderContinueInBackground; -} - -- (void)URLSession:(NSURLSession *)session - task:(NSURLSessionTask *)task -didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge - completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, - NSURLCredential *credential))completionHandler { +- (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential *credential))completionHandler { NSURLSessionAuthChallengeDisposition disposition = NSURLSessionAuthChallengePerformDefaultHandling; __block NSURLCredential *credential = nil; @@ -474,4 +468,37 @@ didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge } } +#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 From 1e412927cc94f5b63c00680a1af73efaeb09f137 Mon Sep 17 00:00:00 2001 From: Oana Popescu Date: Mon, 6 Jun 2016 20:09:43 +0300 Subject: [PATCH 22/24] 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. --- SDWebImage/SDWebImageDownloaderOperation.m | 30 +++++++++++----------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/SDWebImage/SDWebImageDownloaderOperation.m b/SDWebImage/SDWebImageDownloaderOperation.m index 901e638c..d4e2a99e 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.m +++ b/SDWebImage/SDWebImageDownloaderOperation.m @@ -29,9 +29,9 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis // 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 *session; -// This is set to NO if we're using an injected NSURLSession, and to YES otherwise -@property (assign, nonatomic) BOOL ownSession; +@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; @@ -82,7 +82,7 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis _executing = NO; _finished = NO; _expectedSize = 0; - _session = session; + _unownedSession = session; responseFromCached = YES; // Initially wrong until `- URLSession:dataTask:willCacheResponse:completionHandler: is called or not called } return self; @@ -114,24 +114,24 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis }]; } #endif - if (!self.session) { - self.ownSession = YES; - + 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.session = [NSURLSession sessionWithConfiguration:sessionConfig - delegate:self - delegateQueue:nil]; + self.ownedSession = [NSURLSession sessionWithConfiguration:sessionConfig + delegate:self + delegateQueue:nil]; + session = self.ownedSession; } + self.dataTask = [session dataTaskWithRequest:self.request]; self.executing = YES; - self.dataTask = [self.session dataTaskWithRequest:self.request]; self.thread = [NSThread currentThread]; } @@ -213,9 +213,9 @@ NSString *const SDWebImageDownloadFinishNotification = @"SDWebImageDownloadFinis self.dataTask = nil; self.imageData = nil; self.thread = nil; - if (self.ownSession) { - [self.session invalidateAndCancel]; - self.session = nil; + if (self.ownedSession) { + [self.ownedSession invalidateAndCancel]; + self.ownedSession = nil; } } From 473054879c02235aa0074a4fac010467de61ae61 Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Mon, 6 Jun 2016 21:08:17 +0300 Subject: [PATCH 23/24] Updated the changelog --- CHANGELOG.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b683b89d..adefeb16 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## [3.8.0 Minor release - Replaces NSURLConnection (deprecated) with NSURLSession - on May 8th, 2016](https://github.com/rs/SDWebImage/releases/tag/3.8.0) +## [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: @@ -6,12 +6,12 @@ #### Features: -- Replace deprecated `NSURLConnection` with `NSURLSession` #1578 - fixes #1291 #1318 #823 #1566 #1515 +- 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 - fixes #1433 #1533 +- Removed the URL query params from the filename (key) fb0cdb6d 1bf62d4 #1584 - fixes #1433 #1533 #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 From fc0de57066092f38b88b8e08f2f781a53e995f6c Mon Sep 17 00:00:00 2001 From: Bogdan Poplauschi Date: Mon, 6 Jun 2016 21:24:11 +0300 Subject: [PATCH 24/24] Readded `shouldUseCredentialStorage` to preserve backwards compatibility --- SDWebImage/SDWebImageDownloaderOperation.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/SDWebImage/SDWebImageDownloaderOperation.h b/SDWebImage/SDWebImageDownloaderOperation.h index 7a995d2a..c6debc38 100644 --- a/SDWebImage/SDWebImageDownloaderOperation.h +++ b/SDWebImage/SDWebImageDownloaderOperation.h @@ -30,6 +30,12 @@ extern NSString *const SDWebImageDownloadFinishNotification; @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:`. *