Commit a009db88 authored by Sandy's avatar Sandy

修改了一点界面文字

parent f29eb3a6
...@@ -22,11 +22,11 @@ PODS: ...@@ -22,11 +22,11 @@ PODS:
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- JPushSDK (1.8.2) - JPushSDK (1.8.2)
- MBProgressHUD (0.9.2) - MBProgressHUD (0.9.2)
- MJRefresh (3.0.8) - MJRefresh (3.1.0)
- RATreeView (2.1.0) - RATreeView (2.1.0)
- SDWebImage (3.7.3): - SDWebImage (3.7.5):
- SDWebImage/Core (= 3.7.3) - SDWebImage/Core (= 3.7.5)
- SDWebImage/Core (3.7.3) - SDWebImage/Core (3.7.5)
- UMengAnalytics (3.6.6) - UMengAnalytics (3.6.6)
DEPENDENCIES: DEPENDENCIES:
...@@ -42,9 +42,9 @@ SPEC CHECKSUMS: ...@@ -42,9 +42,9 @@ SPEC CHECKSUMS:
AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60
JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e
MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1 MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1
MJRefresh: fafde8f18f4afd66b434331a9beb67a6c0264056 MJRefresh: 743e6404967d1c2c688472ea3ecfde247d872db4
RATreeView: fc82ec26b8be18cfa0f5f99a5abbe6be68edb21f RATreeView: fc82ec26b8be18cfa0f5f99a5abbe6be68edb21f
SDWebImage: 1d2b1a1efda1ade1b00b6f8498865f8ddedc8a84 SDWebImage: 69c6303e3348fba97e03f65d65d4fbc26740f461
UMengAnalytics: 4bf831415146b9c57cb10be65fbd43462ef8cf65 UMengAnalytics: 4bf831415146b9c57cb10be65fbd43462ef8cf65
COCOAPODS: 0.39.0 COCOAPODS: 0.39.0
...@@ -22,11 +22,11 @@ PODS: ...@@ -22,11 +22,11 @@ PODS:
- AFNetworking/NSURLSession - AFNetworking/NSURLSession
- JPushSDK (1.8.2) - JPushSDK (1.8.2)
- MBProgressHUD (0.9.2) - MBProgressHUD (0.9.2)
- MJRefresh (3.0.8) - MJRefresh (3.1.0)
- RATreeView (2.1.0) - RATreeView (2.1.0)
- SDWebImage (3.7.3): - SDWebImage (3.7.5):
- SDWebImage/Core (= 3.7.3) - SDWebImage/Core (= 3.7.5)
- SDWebImage/Core (3.7.3) - SDWebImage/Core (3.7.5)
- UMengAnalytics (3.6.6) - UMengAnalytics (3.6.6)
DEPENDENCIES: DEPENDENCIES:
...@@ -42,9 +42,9 @@ SPEC CHECKSUMS: ...@@ -42,9 +42,9 @@ SPEC CHECKSUMS:
AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60 AFNetworking: cb8d14a848e831097108418f5d49217339d4eb60
JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e JPushSDK: c68dd04c595a5c93aa003f212974010790410d8e
MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1 MBProgressHUD: 1569cf7ace17a8bac47aabfbb8580a49690386d1
MJRefresh: fafde8f18f4afd66b434331a9beb67a6c0264056 MJRefresh: 743e6404967d1c2c688472ea3ecfde247d872db4
RATreeView: fc82ec26b8be18cfa0f5f99a5abbe6be68edb21f RATreeView: fc82ec26b8be18cfa0f5f99a5abbe6be68edb21f
SDWebImage: 1d2b1a1efda1ade1b00b6f8498865f8ddedc8a84 SDWebImage: 69c6303e3348fba97e03f65d65d4fbc26740f461
UMengAnalytics: 4bf831415146b9c57cb10be65fbd43462ef8cf65 UMengAnalytics: 4bf831415146b9c57cb10be65fbd43462ef8cf65
COCOAPODS: 0.39.0 COCOAPODS: 0.39.0
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -12,7 +12,7 @@ This library provides a category for UIImageView with support for remote images ...@@ -12,7 +12,7 @@ This library provides a category for UIImageView with support for remote images
It provides: It provides:
- An UIImageView category adding web image and cache management to the Cocoa Touch framework - An `UIImageView` category adding web image and cache management to the Cocoa Touch framework
- An asynchronous image downloader - An asynchronous image downloader
- An asynchronous memory + disk image caching with automatic cache expiration handling - An asynchronous memory + disk image caching with automatic cache expiration handling
- Animated GIF support - Animated GIF support
...@@ -26,7 +26,7 @@ It provides: ...@@ -26,7 +26,7 @@ It provides:
- Arm64 support - Arm64 support
NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 2.0 and requires iOS 5.1.1 NOTE: The version 3.0 of SDWebImage isn't fully backward compatible with 2.0 and requires iOS 5.1.1
minimum deployement version. If you need iOS < 5.0 support, please use the last [2.0 version](https://github.com/rs/SDWebImage/tree/2.0-compat). 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).
[How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F) [How is SDWebImage better than X?](https://github.com/rs/SDWebImage/wiki/How-is-SDWebImage-better-than-X%3F)
...@@ -51,14 +51,11 @@ handled for you, from async downloads to caching management. ...@@ -51,14 +51,11 @@ handled for you, from async downloads to caching management.
... ...
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
{
static NSString *MyIdentifier = @"MyIdentifier"; static NSString *MyIdentifier = @"MyIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier];
if (cell == nil) {
if (cell == nil)
{
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault
reuseIdentifier:MyIdentifier] autorelease]; reuseIdentifier:MyIdentifier] autorelease];
} }
...@@ -74,14 +71,16 @@ handled for you, from async downloads to caching management. ...@@ -74,14 +71,16 @@ handled for you, from async downloads to caching management.
### Using blocks ### Using blocks
With blocks, you can be notified about the image download progress and whenever the image retrival With blocks, you can be notified about the image download progress and whenever the image retrieval
has completed with success or not: has completed with success or not:
```objective-c ```objective-c
// Here we use the new provided sd_setImageWithURL: method to load the web image // Here we use the new provided sd_setImageWithURL: method to load the web image
[cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"] [cell.imageView sd_setImageWithURL:[NSURL URLWithString:@"http://www.domain.com/path/to/image.jpg"]
placeholderImage:[UIImage imageNamed:@"placeholder.png"] placeholderImage:[UIImage imageNamed:@"placeholder.png"]
completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {... completion code here ...}]; completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
... completion code here ...
}];
``` ```
Note: neither your success nor failure block will be call if your image request is canceled before completion. Note: neither your success nor failure block will be call if your image request is canceled before completion.
...@@ -113,19 +112,17 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; ...@@ -113,19 +112,17 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
It's also possible to use the async image downloader independently: It's also possible to use the async image downloader independently:
```objective-c ```objective-c
[SDWebImageDownloader.sharedDownloader downloadImageWithURL:imageURL SDWebImageDownloader *downloader = [SDWebImageDownloader sharedDownloader];
options:0 [downloader downloadImageWithURL:imageURL
progress:^(NSInteger receivedSize, NSInteger expectedSize) options:0
{ progress:^(NSInteger receivedSize, NSInteger expectedSize) {
// progression tracking code // progression tracking code
} }
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
{ if (image && finished) {
if (image && finished) // do something with image
{ }
// do something with image }];
}
}];
``` ```
### Using Asynchronous Image Caching Independently ### Using Asynchronous Image Caching Independently
...@@ -144,8 +141,7 @@ the image. ...@@ -144,8 +141,7 @@ the image.
```objective-c ```objective-c
SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"]; SDImageCache *imageCache = [[SDImageCache alloc] initWithNamespace:@"myNamespace"];
[imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) [imageCache queryDiskCacheForKey:myCacheKey done:^(UIImage *image) {
{
// image is not nil if image was found // image is not nil if image was found
}]; }];
``` ```
...@@ -173,8 +169,7 @@ The following example sets a filter in the application delegate that will remove ...@@ -173,8 +169,7 @@ The following example sets a filter in the application delegate that will remove
the URL before to use it as a cache key: the URL before to use it as a cache key:
```objective-c ```objective-c
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
{
SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) { SDWebImageManager.sharedManager.cacheKeyFilter = ^(NSURL *url) {
url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path]; url = [[NSURL alloc] initWithScheme:url.scheme host:url.host path:url.path];
return [url absoluteString]; return [url absoluteString];
...@@ -232,9 +227,24 @@ platform :ios, '6.1' ...@@ -232,9 +227,24 @@ platform :ios, '6.1'
pod 'SDWebImage', '~>3.7' pod 'SDWebImage', '~>3.7'
``` ```
If you are using Swift, be sure to add `use_frameworks!` and set your target to iOS 8+:
```
platform :ios, '8.0'
use_frameworks!
```
#### Subspecs
There are 3 subspecs available now: `Core`, `MapKit` and `WebP` (this means you can install only some of the SDWebImage modules. By default, you get just `Core`, so if you need `WebP`, you need to specify it).
Podfile example:
```
pod 'SDWebImage/WebP'
```
### Installation with Carthage (iOS 8+) ### Installation with Carthage (iOS 8+)
[Carthage](https://github.com/Carthage/Carthage) is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and ins less invasive than CocoaPods. [Carthage](https://github.com/Carthage/Carthage) is a lightweight dependency manager for Swift and Objective-C. It leverages CocoaTouch modules and is less invasive than CocoaPods.
To install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage) To install with carthage, follow the instruction on [Carthage](https://github.com/Carthage/Carthage)
...@@ -246,9 +256,14 @@ github "rs/SDWebImage" ...@@ -246,9 +256,14 @@ github "rs/SDWebImage"
#### Usage #### Usage
Swift Swift
If you installed using CocoaPods:
```
import SDWebImage
``` ```
import WebImage
If you installed manually:
```
import WebImage
``` ```
Objective-C Objective-C
...@@ -291,6 +306,10 @@ If you're using Cocoa Pods and have any frameworks that extend optional librarie ...@@ -291,6 +306,10 @@ If you're using Cocoa Pods and have any frameworks that extend optional librarie
``` ```
-force_load $(TARGET_BUILD_DIR)/libPods.a -force_load $(TARGET_BUILD_DIR)/libPods.a
``` ```
and this:
```
$(inherited)
```
### Import headers in your source files ### Import headers in your source files
......
...@@ -37,11 +37,21 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot ...@@ -37,11 +37,21 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
@interface SDImageCache : NSObject @interface SDImageCache : NSObject
/** /**
* Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. * Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
*/ */
@property (assign, nonatomic) BOOL shouldDecompressImages; @property (assign, nonatomic) BOOL shouldDecompressImages;
/**
* disable iCloud backup [defaults to YES]
*/
@property (assign, nonatomic) BOOL shouldDisableiCloud;
/**
* use memory cache [defaults to YES]
*/
@property (assign, nonatomic) BOOL shouldCacheImagesInMemory;
/** /**
* The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory. * The maximum "total cost" of the in-memory image cache. The cost function is the number of pixels held in memory.
*/ */
...@@ -244,7 +254,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot ...@@ -244,7 +254,7 @@ typedef void(^SDWebImageCalculateSizeBlock)(NSUInteger fileCount, NSUInteger tot
* Get the cache path for a certain key (needs the cache path root folder) * Get the cache path for a certain key (needs the cache path root folder)
* *
* @param key the key (can be obtained from url using cacheKeyForURL) * @param key the key (can be obtained from url using cacheKeyForURL)
* @param path the cach path root folder * @param path the cache path root folder
* *
* @return the cache path * @return the cache path
*/ */
......
...@@ -116,6 +116,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -116,6 +116,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
// Set decompression to YES // Set decompression to YES
_shouldDecompressImages = YES; _shouldDecompressImages = YES;
// memory cache enabled
_shouldCacheImagesInMemory = YES;
// Disable iCloud
_shouldDisableiCloud = YES;
dispatch_sync(_ioQueue, ^{ dispatch_sync(_ioQueue, ^{
_fileManager = [NSFileManager new]; _fileManager = [NSFileManager new];
}); });
...@@ -175,8 +181,9 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -175,8 +181,9 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
} }
unsigned char r[CC_MD5_DIGEST_LENGTH]; unsigned char r[CC_MD5_DIGEST_LENGTH];
CC_MD5(str, (CC_LONG)strlen(str), r); CC_MD5(str, (CC_LONG)strlen(str), r);
NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", NSString *filename = [NSString stringWithFormat:@"%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%@",
r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10], r[11], r[12], r[13], r[14], r[15]]; r[0], r[1], r[2], r[3], r[4], r[5], r[6], r[7], r[8], r[9], r[10],
r[11], r[12], r[13], r[14], r[15], [[key pathExtension] isEqualToString:@""] ? @"" : [NSString stringWithFormat:@".%@", [key pathExtension]]];
return filename; return filename;
} }
...@@ -193,9 +200,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -193,9 +200,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
if (!image || !key) { if (!image || !key) {
return; return;
} }
// if memory cache is enabled
NSUInteger cost = SDCacheCostForImage(image); if (self.shouldCacheImagesInMemory) {
[self.memCache setObject:image forKey:key cost:cost]; NSUInteger cost = SDCacheCostForImage(image);
[self.memCache setObject:image forKey:key cost:cost];
}
if (toDisk) { if (toDisk) {
dispatch_async(self.ioQueue, ^{ dispatch_async(self.ioQueue, ^{
...@@ -237,7 +246,17 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -237,7 +246,17 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
[_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL]; [_fileManager createDirectoryAtPath:_diskCachePath withIntermediateDirectories:YES attributes:nil error:NULL];
} }
[_fileManager createFileAtPath:[self defaultCachePathForKey:key] contents:data attributes:nil]; // get cache Path for image key
NSString *cachePathForKey = [self defaultCachePathForKey:key];
// transform to NSUrl
NSURL *fileURL = [NSURL fileURLWithPath:cachePathForKey];
[_fileManager createFileAtPath:cachePathForKey contents:data attributes:nil];
// disable iCloud backup
if (self.shouldDisableiCloud) {
[fileURL setResourceValue:[NSNumber numberWithBool:YES] forKey:NSURLIsExcludedFromBackupKey error:nil];
}
} }
}); });
} }
...@@ -257,6 +276,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -257,6 +276,12 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
// this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance // this is an exception to access the filemanager on another queue than ioQueue, but we are using the shared instance
// from apple docs on NSFileManager: The methods of the shared NSFileManager object can be called from multiple threads safely. // from apple docs on NSFileManager: The methods of the shared NSFileManager object can be called from multiple threads safely.
exists = [[NSFileManager defaultManager] fileExistsAtPath:[self defaultCachePathForKey:key]]; exists = [[NSFileManager defaultManager] fileExistsAtPath:[self defaultCachePathForKey:key]];
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
if (!exists) {
exists = [[NSFileManager defaultManager] fileExistsAtPath:[[self defaultCachePathForKey:key] stringByDeletingPathExtension]];
}
return exists; return exists;
} }
...@@ -264,6 +289,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -264,6 +289,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
- (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock { - (void)diskImageExistsWithKey:(NSString *)key completion:(SDWebImageCheckCacheCompletionBlock)completionBlock {
dispatch_async(_ioQueue, ^{ dispatch_async(_ioQueue, ^{
BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]]; BOOL exists = [_fileManager fileExistsAtPath:[self defaultCachePathForKey:key]];
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
if (!exists) {
exists = [_fileManager fileExistsAtPath:[[self defaultCachePathForKey:key] stringByDeletingPathExtension]];
}
if (completionBlock) { if (completionBlock) {
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
completionBlock(exists); completionBlock(exists);
...@@ -277,6 +309,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -277,6 +309,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
} }
- (UIImage *)imageFromDiskCacheForKey:(NSString *)key { - (UIImage *)imageFromDiskCacheForKey:(NSString *)key {
// First check the in-memory cache... // First check the in-memory cache...
UIImage *image = [self imageFromMemoryCacheForKey:key]; UIImage *image = [self imageFromMemoryCacheForKey:key];
if (image) { if (image) {
...@@ -285,7 +318,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -285,7 +318,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
// Second check the disk cache... // Second check the disk cache...
UIImage *diskImage = [self diskImageForKey:key]; UIImage *diskImage = [self diskImageForKey:key];
if (diskImage) { if (diskImage && self.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(diskImage); NSUInteger cost = SDCacheCostForImage(diskImage);
[self.memCache setObject:diskImage forKey:key cost:cost]; [self.memCache setObject:diskImage forKey:key cost:cost];
} }
...@@ -300,6 +333,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -300,6 +333,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
return data; return data;
} }
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
data = [NSData dataWithContentsOfFile:[defaultPath stringByDeletingPathExtension]];
if (data) {
return data;
}
NSArray *customPaths = [self.customPaths copy]; NSArray *customPaths = [self.customPaths copy];
for (NSString *path in customPaths) { for (NSString *path in customPaths) {
NSString *filePath = [self cachePathForKey:key inPath:path]; NSString *filePath = [self cachePathForKey:key inPath:path];
...@@ -307,6 +347,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -307,6 +347,13 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
if (imageData) { if (imageData) {
return imageData; return imageData;
} }
// fallback because of https://github.com/rs/SDWebImage/pull/976 that added the extension to the disk file name
// checking the key with and without the extension
imageData = [NSData dataWithContentsOfFile:[filePath stringByDeletingPathExtension]];
if (imageData) {
return imageData;
}
} }
return nil; return nil;
...@@ -356,7 +403,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -356,7 +403,7 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
@autoreleasepool { @autoreleasepool {
UIImage *diskImage = [self diskImageForKey:key]; UIImage *diskImage = [self diskImageForKey:key];
if (diskImage) { if (diskImage && self.shouldCacheImagesInMemory) {
NSUInteger cost = SDCacheCostForImage(diskImage); NSUInteger cost = SDCacheCostForImage(diskImage);
[self.memCache setObject:diskImage forKey:key cost:cost]; [self.memCache setObject:diskImage forKey:key cost:cost];
} }
...@@ -387,9 +434,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) { ...@@ -387,9 +434,11 @@ FOUNDATION_STATIC_INLINE NSUInteger SDCacheCostForImage(UIImage *image) {
if (key == nil) { if (key == nil) {
return; return;
} }
[self.memCache removeObjectForKey:key]; if (self.shouldCacheImagesInMemory) {
[self.memCache removeObjectForKey:key];
}
if (fromDisk) { if (fromDisk) {
dispatch_async(self.ioQueue, ^{ dispatch_async(self.ioQueue, ^{
[_fileManager removeItemAtPath:[self defaultCachePathForKey:key] error:nil]; [_fileManager removeItemAtPath:[self defaultCachePathForKey:key] error:nil];
......
...@@ -14,7 +14,7 @@ ...@@ -14,7 +14,7 @@
#endif #endif
#if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0 #if __IPHONE_OS_VERSION_MIN_REQUIRED != 20000 && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_5_0
#error SDWebImage doesn't support Deployement Target version < 5.0 #error SDWebImage doesn't support Deployment Target version < 5.0
#endif #endif
#if !TARGET_OS_IPHONE #if !TARGET_OS_IPHONE
......
...@@ -28,7 +28,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) { ...@@ -28,7 +28,7 @@ inline UIImage *SDScaledImageForKey(NSString *key, UIImage *image) {
} }
else { else {
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) { if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
CGFloat scale = 1.0; CGFloat scale = [UIScreen mainScreen].scale;
if (key.length >= 8) { if (key.length >= 8) {
NSRange range = [key rangeOfString:@"@2x."]; NSRange range = [key rangeOfString:@"@2x."];
if (range.location != NSNotFound) { if (range.location != NSNotFound) {
......
...@@ -13,60 +13,57 @@ ...@@ -13,60 +13,57 @@
@implementation UIImage (ForceDecode) @implementation UIImage (ForceDecode)
+ (UIImage *)decodedImageWithImage:(UIImage *)image { + (UIImage *)decodedImageWithImage:(UIImage *)image {
if (image.images) { // while downloading huge amount of images
// Do not decode animated images // autorelease the bitmap context
return image; // and all vars to help system to free memory
// when there are memory warning.
// on iOS7, do not forget to call
// [[SDImageCache sharedImageCache] clearMemory];
@autoreleasepool{
// do not decode animated images
if (image.images) { return image; }
CGImageRef imageRef = image.CGImage;
CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef);
BOOL anyAlpha = (alpha == kCGImageAlphaFirst ||
alpha == kCGImageAlphaLast ||
alpha == kCGImageAlphaPremultipliedFirst ||
alpha == kCGImageAlphaPremultipliedLast);
if (anyAlpha) { return image; }
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
// current
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(CGImageGetColorSpace(imageRef));
CGColorSpaceRef colorspaceRef = CGImageGetColorSpace(imageRef);
bool unsupportedColorSpace = (imageColorSpaceModel == 0 || imageColorSpaceModel == -1 || imageColorSpaceModel == kCGColorSpaceModelCMYK || imageColorSpaceModel == kCGColorSpaceModelIndexed);
if (unsupportedColorSpace)
colorspaceRef = CGColorSpaceCreateDeviceRGB();
CGContextRef context = CGBitmapContextCreate(NULL, width,
height,
CGImageGetBitsPerComponent(imageRef),
0,
colorspaceRef,
kCGBitmapByteOrderDefault | kCGImageAlphaPremultipliedFirst);
// Draw the image into the context and retrieve the new image, which will now have an alpha layer
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGImageRef imageRefWithAlpha = CGBitmapContextCreateImage(context);
UIImage *imageWithAlpha = [UIImage imageWithCGImage:imageRefWithAlpha scale:image.scale orientation:image.imageOrientation];
if (unsupportedColorSpace)
CGColorSpaceRelease(colorspaceRef);
CGContextRelease(context);
CGImageRelease(imageRefWithAlpha);
return imageWithAlpha;
} }
CGImageRef imageRef = image.CGImage;
CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef));
CGRect imageRect = (CGRect){.origin = CGPointZero, .size = imageSize};
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
int infoMask = (bitmapInfo & kCGBitmapAlphaInfoMask);
BOOL anyNonAlpha = (infoMask == kCGImageAlphaNone ||
infoMask == kCGImageAlphaNoneSkipFirst ||
infoMask == kCGImageAlphaNoneSkipLast);
// CGBitmapContextCreate doesn't support kCGImageAlphaNone with RGB.
// https://developer.apple.com/library/mac/#qa/qa1037/_index.html
if (infoMask == kCGImageAlphaNone && CGColorSpaceGetNumberOfComponents(colorSpace) > 1) {
// Unset the old alpha info.
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
// Set noneSkipFirst.
bitmapInfo |= kCGImageAlphaNoneSkipFirst;
}
// Some PNGs tell us they have alpha but only 3 components. Odd.
else if (!anyNonAlpha && CGColorSpaceGetNumberOfComponents(colorSpace) == 3) {
// Unset the old alpha info.
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
bitmapInfo |= kCGImageAlphaPremultipliedFirst;
}
// It calculates the bytes-per-row based on the bitsPerComponent and width arguments.
CGContextRef context = CGBitmapContextCreate(NULL,
imageSize.width,
imageSize.height,
CGImageGetBitsPerComponent(imageRef),
0,
colorSpace,
bitmapInfo);
CGColorSpaceRelease(colorSpace);
// If failed, return undecompressed image
if (!context) return image;
CGContextDrawImage(context, imageRect, imageRef);
CGImageRef decompressedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *decompressedImage = [UIImage imageWithCGImage:decompressedImageRef scale:image.scale orientation:image.imageOrientation];
CGImageRelease(decompressedImageRef);
return decompressedImage;
} }
@end @end
...@@ -40,7 +40,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) { ...@@ -40,7 +40,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageDownloaderOptions) {
SDWebImageDownloaderHandleCookies = 1 << 5, SDWebImageDownloaderHandleCookies = 1 << 5,
/** /**
* Enable to allow untrusted SSL ceriticates. * Enable to allow untrusted SSL certificates.
* Useful for testing purposes. Use with caution in production. * Useful for testing purposes. Use with caution in production.
*/ */
SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6, SDWebImageDownloaderAllowInvalidSSLCertificates = 1 << 6,
...@@ -78,7 +78,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi ...@@ -78,7 +78,7 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
@interface SDWebImageDownloader : NSObject @interface SDWebImageDownloader : NSObject
/** /**
* Decompressing images that are downloaded and cached can improve peformance but can consume lot of memory. * Decompressing images that are downloaded and cached can improve performance but can consume lot of memory.
* Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption. * Defaults to YES. Set this to NO if you are experiencing a crash due to excessive memory consumption.
*/ */
@property (assign, nonatomic) BOOL shouldDecompressImages; @property (assign, nonatomic) BOOL shouldDecompressImages;
...@@ -109,6 +109,11 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi ...@@ -109,6 +109,11 @@ typedef NSDictionary *(^SDWebImageDownloaderHeadersFilterBlock)(NSURL *url, NSDi
*/ */
+ (SDWebImageDownloader *)sharedDownloader; + (SDWebImageDownloader *)sharedDownloader;
/**
* Set the default URL credential to be set for request operations.
*/
@property (strong, nonatomic) NSURLCredential *urlCredential;
/** /**
* Set username * Set username
*/ */
......
...@@ -116,7 +116,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; ...@@ -116,7 +116,7 @@ static NSString *const kCompletedCallbackKey = @"completed";
__block SDWebImageDownloaderOperation *operation; __block SDWebImageDownloaderOperation *operation;
__weak __typeof(self)wself = self; __weak __typeof(self)wself = self;
[self addProgressCallback:progressBlock andCompletedBlock:completedBlock forURL:url createCallback:^{ [self addProgressCallback:progressBlock completedBlock:completedBlock forURL:url createCallback:^{
NSTimeInterval timeoutInterval = wself.downloadTimeout; NSTimeInterval timeoutInterval = wself.downloadTimeout;
if (timeoutInterval == 0.0) { if (timeoutInterval == 0.0) {
timeoutInterval = 15.0; timeoutInterval = 15.0;
...@@ -142,8 +142,10 @@ static NSString *const kCompletedCallbackKey = @"completed"; ...@@ -142,8 +142,10 @@ static NSString *const kCompletedCallbackKey = @"completed";
callbacksForURL = [sself.URLCallbacks[url] copy]; callbacksForURL = [sself.URLCallbacks[url] copy];
}); });
for (NSDictionary *callbacks in callbacksForURL) { for (NSDictionary *callbacks in callbacksForURL) {
SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey]; dispatch_async(dispatch_get_main_queue(), ^{
if (callback) callback(receivedSize, expectedSize); SDWebImageDownloaderProgressBlock callback = callbacks[kProgressCallbackKey];
if (callback) callback(receivedSize, expectedSize);
});
} }
} }
completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) { completed:^(UIImage *image, NSData *data, NSError *error, BOOL finished) {
...@@ -170,7 +172,9 @@ static NSString *const kCompletedCallbackKey = @"completed"; ...@@ -170,7 +172,9 @@ static NSString *const kCompletedCallbackKey = @"completed";
}]; }];
operation.shouldDecompressImages = wself.shouldDecompressImages; operation.shouldDecompressImages = wself.shouldDecompressImages;
if (wself.username && wself.password) { if (wself.urlCredential) {
operation.credential = wself.urlCredential;
} else if (wself.username && wself.password) {
operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession]; operation.credential = [NSURLCredential credentialWithUser:wself.username password:wself.password persistence:NSURLCredentialPersistenceForSession];
} }
...@@ -191,7 +195,7 @@ static NSString *const kCompletedCallbackKey = @"completed"; ...@@ -191,7 +195,7 @@ static NSString *const kCompletedCallbackKey = @"completed";
return operation; return operation;
} }
- (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock andCompletedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageNoParamsBlock)createCallback { - (void)addProgressCallback:(SDWebImageDownloaderProgressBlock)progressBlock completedBlock:(SDWebImageDownloaderCompletedBlock)completedBlock forURL:(NSURL *)url createCallback:(SDWebImageNoParamsBlock)createCallback {
// The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data. // The URL will be used as the key to the callbacks dictionary so it cannot be nil. If it is nil immediately call the completed block with no image or data.
if (url == nil) { if (url == nil) {
if (completedBlock != nil) { if (completedBlock != nil) {
......
...@@ -41,7 +41,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { ...@@ -41,7 +41,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
* This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics. * This option helps deal with images changing behind the same request URL, e.g. Facebook graph api profile pics.
* If a cached image is refreshed, the completion block is called once with the cached image and again with the final image. * If a cached image is refreshed, the completion block is called once with the cached image and again with the final image.
* *
* Use this flag only if you can't make your URLs static with embeded cache busting parameter. * Use this flag only if you can't make your URLs static with embedded cache busting parameter.
*/ */
SDWebImageRefreshCached = 1 << 4, SDWebImageRefreshCached = 1 << 4,
...@@ -58,7 +58,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) { ...@@ -58,7 +58,7 @@ typedef NS_OPTIONS(NSUInteger, SDWebImageOptions) {
SDWebImageHandleCookies = 1 << 6, SDWebImageHandleCookies = 1 << 6,
/** /**
* Enable to allow untrusted SSL ceriticates. * Enable to allow untrusted SSL certificates.
* Useful for testing purposes. Use with caution in production. * Useful for testing purposes. Use with caution in production.
*/ */
SDWebImageAllowInvalidSSLCertificates = 1 << 7, SDWebImageAllowInvalidSSLCertificates = 1 << 7,
...@@ -195,11 +195,11 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; ...@@ -195,11 +195,11 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
* This block has no return value and takes the requested UIImage as first parameter. * This block has no return value and takes the requested UIImage as first parameter.
* In case of error the image parameter is nil and the second parameter may contain an NSError. * In case of error the image parameter is nil and the second parameter may contain an NSError.
* *
* The third parameter is an `SDImageCacheType` enum indicating if the image was retrived from the local cache * The third parameter is an `SDImageCacheType` enum indicating if the image was retrieved from the local cache
* or from the memory cache or from the network. * or from the memory cache or from the network.
* *
* The last parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is * The last parameter is set to NO when the SDWebImageProgressiveDownload option is used and the image is
* downloading. This block is thus called repetidly with a partial image. When image is fully downloaded, the * downloading. This block is thus called repeatedly with a partial image. When image is fully downloaded, the
* block is called a last time with the full image and the last parameter set to YES. * block is called a last time with the full image and the last parameter set to YES.
* *
* @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation * @return Returns an NSObject conforming to SDWebImageOperation. Should be an instance of SDWebImageDownloaderOperation
...@@ -220,7 +220,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager]; ...@@ -220,7 +220,7 @@ SDWebImageManager *manager = [SDWebImageManager sharedManager];
- (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url; - (void)saveImageToCache:(UIImage *)image forURL:(NSURL *)url;
/** /**
* Cancel all current opreations * Cancel all current operations
*/ */
- (void)cancelAll; - (void)cancelAll;
......
...@@ -133,7 +133,7 @@ ...@@ -133,7 +133,7 @@
isFailedUrl = [self.failedURLs containsObject:url]; isFailedUrl = [self.failedURLs containsObject:url];
} }
if (!url || (!(options & SDWebImageRetryFailed) && isFailedUrl)) { if (url.absoluteString.length == 0 || (!(options & SDWebImageRetryFailed) && isFailedUrl)) {
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil]; NSError *error = [NSError errorWithDomain:NSURLErrorDomain code:NSURLErrorFileDoesNotExist userInfo:nil];
completedBlock(nil, error, SDImageCacheTypeNone, YES, url); completedBlock(nil, error, SDImageCacheTypeNone, YES, url);
...@@ -158,7 +158,7 @@ ...@@ -158,7 +158,7 @@
if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) { if ((!image || options & SDWebImageRefreshCached) && (![self.delegate respondsToSelector:@selector(imageManager:shouldDownloadImageForURL:)] || [self.delegate imageManager:self shouldDownloadImageForURL:url])) {
if (image && options & SDWebImageRefreshCached) { if (image && options & SDWebImageRefreshCached) {
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
// If image was found in the cache bug SDWebImageRefreshCached is provided, notify about the cached image // If image was found in the cache but SDWebImageRefreshCached is provided, notify about the cached image
// AND try to re-download it in order to let a chance to NSURLCache to refresh it from server. // AND try to re-download it in order to let a chance to NSURLCache to refresh it from server.
completedBlock(image, nil, cacheType, YES, url); completedBlock(image, nil, cacheType, YES, url);
}); });
...@@ -180,21 +180,26 @@ ...@@ -180,21 +180,26 @@
downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse; downloaderOptions |= SDWebImageDownloaderIgnoreCachedResponse;
} }
id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) { id <SDWebImageOperation> subOperation = [self.imageDownloader downloadImageWithURL:url options:downloaderOptions progress:progressBlock completed:^(UIImage *downloadedImage, NSData *data, NSError *error, BOOL finished) {
if (weakOperation.isCancelled) { __strong __typeof(weakOperation) strongOperation = weakOperation;
if (!strongOperation || strongOperation.isCancelled) {
// Do nothing if the operation was cancelled // Do nothing if the operation was cancelled
// See #699 for more details // See #699 for more details
// if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data // if we would call the completedBlock, there could be a race condition between this block and another completedBlock for the same object, so if this one is called second, we will overwrite the new data
} }
else if (error) { else if (error) {
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!weakOperation.isCancelled) { if (strongOperation && !strongOperation.isCancelled) {
completedBlock(nil, error, SDImageCacheTypeNone, finished, url); completedBlock(nil, error, SDImageCacheTypeNone, finished, url);
} }
}); });
BOOL shouldBeFailedURLAlliOSVersion = (error.code != NSURLErrorNotConnectedToInternet && error.code != NSURLErrorCancelled && error.code != NSURLErrorTimedOut); if ( error.code != NSURLErrorNotConnectedToInternet
BOOL shouldBeFailedURLiOS7 = (NSFoundationVersionNumber > NSFoundationVersionNumber_iOS_6_1 && error.code != NSURLErrorInternationalRoamingOff && error.code != NSURLErrorCallIsActive && error.code != NSURLErrorDataNotAllowed); && error.code != NSURLErrorCancelled
if (shouldBeFailedURLAlliOSVersion || shouldBeFailedURLiOS7) { && error.code != NSURLErrorTimedOut
&& error.code != NSURLErrorInternationalRoamingOff
&& error.code != NSURLErrorDataNotAllowed
&& error.code != NSURLErrorCannotFindHost
&& error.code != NSURLErrorCannotConnectToHost) {
@synchronized (self.failedURLs) { @synchronized (self.failedURLs) {
[self.failedURLs addObject:url]; [self.failedURLs addObject:url];
} }
...@@ -222,7 +227,7 @@ ...@@ -222,7 +227,7 @@
} }
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!weakOperation.isCancelled) { if (strongOperation && !strongOperation.isCancelled) {
completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url); completedBlock(transformedImage, nil, SDImageCacheTypeNone, finished, url);
} }
}); });
...@@ -234,7 +239,7 @@ ...@@ -234,7 +239,7 @@
} }
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!weakOperation.isCancelled) { if (strongOperation && !strongOperation.isCancelled) {
completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url); completedBlock(downloadedImage, nil, SDImageCacheTypeNone, finished, url);
} }
}); });
...@@ -243,7 +248,9 @@ ...@@ -243,7 +248,9 @@
if (finished) { if (finished) {
@synchronized (self.runningOperations) { @synchronized (self.runningOperations) {
[self.runningOperations removeObject:operation]; if (strongOperation) {
[self.runningOperations removeObject:strongOperation];
}
} }
} }
}]; }];
...@@ -251,13 +258,17 @@ ...@@ -251,13 +258,17 @@
[subOperation cancel]; [subOperation cancel];
@synchronized (self.runningOperations) { @synchronized (self.runningOperations) {
[self.runningOperations removeObject:weakOperation]; __strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation) {
[self.runningOperations removeObject:strongOperation];
}
} }
}; };
} }
else if (image) { else if (image) {
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!weakOperation.isCancelled) { __strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation && !strongOperation.isCancelled) {
completedBlock(image, nil, cacheType, YES, url); completedBlock(image, nil, cacheType, YES, url);
} }
}); });
...@@ -268,7 +279,8 @@ ...@@ -268,7 +279,8 @@
else { else {
// Image not in cache and download disallowed by delegate // Image not in cache and download disallowed by delegate
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!weakOperation.isCancelled) { __strong __typeof(weakOperation) strongOperation = weakOperation;
if (strongOperation && !weakOperation.isCancelled) {
completedBlock(nil, nil, SDImageCacheTypeNone, YES, url); completedBlock(nil, nil, SDImageCacheTypeNone, YES, url);
} }
}); });
...@@ -297,7 +309,11 @@ ...@@ -297,7 +309,11 @@
} }
- (BOOL)isRunning { - (BOOL)isRunning {
return self.runningOperations.count > 0; BOOL isRunning = NO;
@synchronized(self.runningOperations) {
isRunning = (self.runningOperations.count > 0);
}
return isRunning;
} }
@end @end
......
...@@ -70,6 +70,11 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls, ...@@ -70,6 +70,11 @@ typedef void(^SDWebImagePrefetcherCompletionBlock)(NSUInteger noOfFinishedUrls,
*/ */
+ (SDWebImagePrefetcher *)sharedImagePrefetcher; + (SDWebImagePrefetcher *)sharedImagePrefetcher;
/**
* Allows you to instantiate a prefetcher with any arbitrary image manager.
*/
- (id)initWithImageManager:(SDWebImageManager *)manager;
/** /**
* Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching, * Assign list of URLs to let SDWebImagePrefetcher to queue the prefetching,
* currently one image is downloaded at a time, * currently one image is downloaded at a time,
......
...@@ -8,10 +8,6 @@ ...@@ -8,10 +8,6 @@
#import "SDWebImagePrefetcher.h" #import "SDWebImagePrefetcher.h"
#if (!defined(DEBUG) && !defined (SD_VERBOSE)) || defined(SD_LOG_NONE)
#define NSLog(...)
#endif
@interface SDWebImagePrefetcher () @interface SDWebImagePrefetcher ()
@property (strong, nonatomic) SDWebImageManager *manager; @property (strong, nonatomic) SDWebImageManager *manager;
...@@ -37,8 +33,12 @@ ...@@ -37,8 +33,12 @@
} }
- (id)init { - (id)init {
return [self initWithImageManager:[SDWebImageManager new]];
}
- (id)initWithImageManager:(SDWebImageManager *)manager {
if ((self = [super init])) { if ((self = [super init])) {
_manager = [SDWebImageManager new]; _manager = manager;
_options = SDWebImageLowPriority; _options = SDWebImageLowPriority;
_prefetcherQueue = dispatch_get_main_queue(); _prefetcherQueue = dispatch_get_main_queue();
self.maxConcurrentDownloads = 3; self.maxConcurrentDownloads = 3;
...@@ -65,14 +65,11 @@ ...@@ -65,14 +65,11 @@
if (self.progressBlock) { if (self.progressBlock) {
self.progressBlock(self.finishedCount,[self.prefetchURLs count]); self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
} }
NSLog(@"Prefetched %@ out of %@", @(self.finishedCount), @(self.prefetchURLs.count));
} }
else { else {
if (self.progressBlock) { if (self.progressBlock) {
self.progressBlock(self.finishedCount,[self.prefetchURLs count]); self.progressBlock(self.finishedCount,[self.prefetchURLs count]);
} }
NSLog(@"Prefetched %@ out of %@ (Failed)", @(self.finishedCount), @(self.prefetchURLs.count));
// Add last failed // Add last failed
self.skippedCount++; self.skippedCount++;
} }
...@@ -81,14 +78,13 @@ ...@@ -81,14 +78,13 @@
didPrefetchURL:self.prefetchURLs[index] didPrefetchURL:self.prefetchURLs[index]
finishedCount:self.finishedCount finishedCount:self.finishedCount
totalCount:self.prefetchURLs.count totalCount:self.prefetchURLs.count
]; ];
} }
if (self.prefetchURLs.count > self.requestedCount) { if (self.prefetchURLs.count > self.requestedCount) {
dispatch_async(self.prefetcherQueue, ^{ dispatch_async(self.prefetcherQueue, ^{
[self startPrefetchingAtIndex:self.requestedCount]; [self startPrefetchingAtIndex:self.requestedCount];
}); });
} } else if (self.finishedCount == self.requestedCount) {
else if (self.finishedCount == self.requestedCount) {
[self reportStatus]; [self reportStatus];
if (self.completionBlock) { if (self.completionBlock) {
self.completionBlock(self.finishedCount, self.skippedCount); self.completionBlock(self.finishedCount, self.skippedCount);
...@@ -101,12 +97,11 @@ ...@@ -101,12 +97,11 @@
- (void)reportStatus { - (void)reportStatus {
NSUInteger total = [self.prefetchURLs count]; NSUInteger total = [self.prefetchURLs count];
NSLog(@"Finished prefetching (%@ successful, %@ skipped, timeElasped %.2f)", @(total - self.skippedCount), @(self.skippedCount), CFAbsoluteTimeGetCurrent() - self.startedTime);
if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) { if ([self.delegate respondsToSelector:@selector(imagePrefetcher:didFinishWithTotalCount:skippedCount:)]) {
[self.delegate imagePrefetcher:self [self.delegate imagePrefetcher:self
didFinishWithTotalCount:(total - self.skippedCount) didFinishWithTotalCount:(total - self.skippedCount)
skippedCount:self.skippedCount skippedCount:self.skippedCount
]; ];
} }
} }
...@@ -121,11 +116,11 @@ ...@@ -121,11 +116,11 @@
self.completionBlock = completionBlock; self.completionBlock = completionBlock;
self.progressBlock = progressBlock; self.progressBlock = progressBlock;
if(urls.count == 0){ if (urls.count == 0) {
if(completionBlock){ if (completionBlock) {
completionBlock(0,0); completionBlock(0,0);
} }
}else{ } else {
// Starts prefetching from the very first image on the list with the max allowed concurrency // Starts prefetching from the very first image on the list with the max allowed concurrency
NSUInteger listCount = self.prefetchURLs.count; NSUInteger listCount = self.prefetchURLs.count;
for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) { for (NSUInteger i = 0; i < self.maxConcurrentDownloads && self.requestedCount < listCount; i++) {
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -86,7 +86,7 @@ ...@@ -86,7 +86,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -103,7 +103,7 @@ ...@@ -103,7 +103,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -152,7 +152,7 @@ ...@@ -152,7 +152,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -168,7 +168,7 @@ ...@@ -168,7 +168,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -184,7 +184,7 @@ ...@@ -184,7 +184,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
......
...@@ -57,8 +57,8 @@ static char imageURLStorageKey; ...@@ -57,8 +57,8 @@ static char imageURLStorageKey;
[self.imageURLStorage removeObjectForKey:@(state)]; [self.imageURLStorage removeObjectForKey:@(state)];
dispatch_main_async_safe(^{ dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
if (completedBlock) { if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url); completedBlock(nil, error, SDImageCacheTypeNone, url);
} }
}); });
...@@ -74,7 +74,12 @@ static char imageURLStorageKey; ...@@ -74,7 +74,12 @@ static char imageURLStorageKey;
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
__strong UIButton *sself = wself; __strong UIButton *sself = wself;
if (!sself) return; if (!sself) return;
if (image) { if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
[sself setImage:image forState:state]; [sself setImage:image forState:state];
} }
if (completedBlock && finished) { if (completedBlock && finished) {
...@@ -106,7 +111,7 @@ static char imageURLStorageKey; ...@@ -106,7 +111,7 @@ static char imageURLStorageKey;
} }
- (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock { - (void)sd_setBackgroundImageWithURL:(NSURL *)url forState:(UIControlState)state placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock {
[self sd_cancelImageLoadForState:state]; [self sd_cancelBackgroundImageLoadForState:state];
[self setBackgroundImage:placeholder forState:state]; [self setBackgroundImage:placeholder forState:state];
...@@ -117,7 +122,12 @@ static char imageURLStorageKey; ...@@ -117,7 +122,12 @@ static char imageURLStorageKey;
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
__strong UIButton *sself = wself; __strong UIButton *sself = wself;
if (!sself) return; if (!sself) return;
if (image) { if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
[sself setBackgroundImage:image forState:state]; [sself setBackgroundImage:image forState:state];
} }
if (completedBlock && finished) { if (completedBlock && finished) {
......
...@@ -141,17 +141,17 @@ ...@@ -141,17 +141,17 @@
NSMutableArray *scaledImages = [NSMutableArray array]; NSMutableArray *scaledImages = [NSMutableArray array];
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
for (UIImage *image in self.images) { for (UIImage *image in self.images) {
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
[image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)]; [image drawInRect:CGRectMake(thumbnailPoint.x, thumbnailPoint.y, scaledSize.width, scaledSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext(); UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
[scaledImages addObject:newImage]; [scaledImages addObject:newImage];
}
UIGraphicsEndImageContext();
UIGraphicsEndImageContext();
}
return [UIImage animatedImageWithImages:scaledImages duration:self.duration]; return [UIImage animatedImageWithImages:scaledImages duration:self.duration];
} }
......
...@@ -43,7 +43,7 @@ ...@@ -43,7 +43,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setHighlightedImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -58,7 +58,7 @@ ...@@ -58,7 +58,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -74,7 +74,7 @@ ...@@ -74,7 +74,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setHighlightedImageWithURL:(NSURL *)url options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
......
...@@ -39,7 +39,12 @@ ...@@ -39,7 +39,12 @@
dispatch_main_sync_safe (^ dispatch_main_sync_safe (^
{ {
if (!wself) return; if (!wself) return;
if (image) { if (image && (options & SDWebImageAvoidAutoSetImage) && completedBlock)
{
completedBlock(image, error, cacheType, url);
return;
}
else if (image) {
wself.highlightedImage = image; wself.highlightedImage = image;
[wself setNeedsLayout]; [wself setNeedsLayout];
} }
......
...@@ -92,7 +92,7 @@ ...@@ -92,7 +92,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -107,7 +107,7 @@ ...@@ -107,7 +107,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -123,7 +123,7 @@ ...@@ -123,7 +123,7 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options completed:(SDWebImageCompletionBlock)completedBlock;
...@@ -140,13 +140,13 @@ ...@@ -140,13 +140,13 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
/** /**
* Set the imageView `image` with an `url` and a optionaly placeholder image. * Set the imageView `image` with an `url` and optionally a placeholder image.
* *
* The download is asynchronous and cached. * The download is asynchronous and cached.
* *
...@@ -157,10 +157,10 @@ ...@@ -157,10 +157,10 @@
* @param completedBlock A block called when operation has been completed. This block has no return value * @param completedBlock A block called when operation has been completed. This block has no return value
* and takes the requested UIImage as first parameter. In case of error the image parameter * and takes the requested UIImage as first parameter. In case of error the image parameter
* is nil and the second parameter may contain an NSError. The third parameter is a Boolean * is nil and the second parameter may contain an NSError. The third parameter is a Boolean
* indicating if the image was retrived from the local cache or from the network. * indicating if the image was retrieved from the local cache or from the network.
* The fourth parameter is the original image url. * The fourth parameter is the original image url.
*/ */
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock; - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock;
/** /**
* Download an array of images and starts them in an animation loop * Download an array of images and starts them in an animation loop
...@@ -176,6 +176,18 @@ ...@@ -176,6 +176,18 @@
- (void)sd_cancelCurrentAnimationImagesLoad; - (void)sd_cancelCurrentAnimationImagesLoad;
/**
* Show activity UIActivityIndicatorView
*/
- (void)setShowActivityIndicatorView:(BOOL)show;
/**
* set desired UIActivityIndicatorViewStyle
*
* @param style The style of the UIActivityIndicatorView
*/
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style;
@end @end
......
...@@ -11,6 +11,9 @@ ...@@ -11,6 +11,9 @@
#import "UIView+WebCacheOperation.h" #import "UIView+WebCacheOperation.h"
static char imageURLKey; static char imageURLKey;
static char TAG_ACTIVITY_INDICATOR;
static char TAG_ACTIVITY_STYLE;
static char TAG_ACTIVITY_SHOW;
@implementation UIImageView (WebCache) @implementation UIImageView (WebCache)
...@@ -49,8 +52,15 @@ static char imageURLKey; ...@@ -49,8 +52,15 @@ static char imageURLKey;
} }
if (url) { if (url) {
// check if activityView is enabled or not
if ([self showActivityIndicatorView]) {
[self addActivityIndicator];
}
__weak __typeof(self)wself = self; __weak __typeof(self)wself = self;
id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) { id <SDWebImageOperation> operation = [SDWebImageManager.sharedManager downloadImageWithURL:url options:options progress:progressBlock completed:^(UIImage *image, NSError *error, SDImageCacheType cacheType, BOOL finished, NSURL *imageURL) {
[wself removeActivityIndicator];
if (!wself) return; if (!wself) return;
dispatch_main_sync_safe(^{ dispatch_main_sync_safe(^{
if (!wself) return; if (!wself) return;
...@@ -76,15 +86,16 @@ static char imageURLKey; ...@@ -76,15 +86,16 @@ static char imageURLKey;
[self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"]; [self sd_setImageLoadOperation:operation forKey:@"UIImageViewImageLoad"];
} else { } else {
dispatch_main_async_safe(^{ dispatch_main_async_safe(^{
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}]; [self removeActivityIndicator];
if (completedBlock) { if (completedBlock) {
NSError *error = [NSError errorWithDomain:SDWebImageErrorDomain code:-1 userInfo:@{NSLocalizedDescriptionKey : @"Trying to load a nil url"}];
completedBlock(nil, error, SDImageCacheTypeNone, url); completedBlock(nil, error, SDImageCacheTypeNone, url);
} }
}); });
} }
} }
- (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url andPlaceholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock { - (void)sd_setImageWithPreviousCachedImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletionBlock)completedBlock {
NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url]; NSString *key = [[SDWebImageManager sharedManager] cacheKeyForURL:url];
UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key]; UIImage *lastPreviousCachedImage = [[SDImageCache sharedImageCache] imageFromDiskCacheForKey:key];
...@@ -134,6 +145,70 @@ static char imageURLKey; ...@@ -134,6 +145,70 @@ static char imageURLKey;
[self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"]; [self sd_cancelImageLoadOperationWithKey:@"UIImageViewAnimationImages"];
} }
#pragma mark -
- (UIActivityIndicatorView *)activityIndicator {
return (UIActivityIndicatorView *)objc_getAssociatedObject(self, &TAG_ACTIVITY_INDICATOR);
}
- (void)setActivityIndicator:(UIActivityIndicatorView *)activityIndicator {
objc_setAssociatedObject(self, &TAG_ACTIVITY_INDICATOR, activityIndicator, OBJC_ASSOCIATION_RETAIN);
}
- (void)setShowActivityIndicatorView:(BOOL)show{
objc_setAssociatedObject(self, &TAG_ACTIVITY_SHOW, [NSNumber numberWithBool:show], OBJC_ASSOCIATION_RETAIN);
}
- (BOOL)showActivityIndicatorView{
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_SHOW) boolValue];
}
- (void)setIndicatorStyle:(UIActivityIndicatorViewStyle)style{
objc_setAssociatedObject(self, &TAG_ACTIVITY_STYLE, [NSNumber numberWithInt:style], OBJC_ASSOCIATION_RETAIN);
}
- (int)getIndicatorStyle{
return [objc_getAssociatedObject(self, &TAG_ACTIVITY_STYLE) intValue];
}
- (void)addActivityIndicator {
if (!self.activityIndicator) {
self.activityIndicator = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:[self getIndicatorStyle]];
self.activityIndicator.translatesAutoresizingMaskIntoConstraints = NO;
dispatch_main_async_safe(^{
[self addSubview:self.activityIndicator];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
attribute:NSLayoutAttributeCenterX
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterX
multiplier:1.0
constant:0.0]];
[self addConstraint:[NSLayoutConstraint constraintWithItem:self.activityIndicator
attribute:NSLayoutAttributeCenterY
relatedBy:NSLayoutRelationEqual
toItem:self
attribute:NSLayoutAttributeCenterY
multiplier:1.0
constant:0.0]];
});
}
dispatch_main_async_safe(^{
[self.activityIndicator startAnimating];
});
}
- (void)removeActivityIndicator {
if (self.activityIndicator) {
[self.activityIndicator removeFromSuperview];
self.activityIndicator = nil;
}
}
@end @end
......
...@@ -2868,6 +2868,7 @@ ...@@ -2868,6 +2868,7 @@
); );
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
TARGETED_DEVICE_FAMILY = 1;
}; };
name = Debug; name = Debug;
}; };
...@@ -2889,6 +2890,7 @@ ...@@ -2889,6 +2890,7 @@
); );
PRODUCT_NAME = "$(TARGET_NAME)"; PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE = ""; PROVISIONING_PROFILE = "";
TARGETED_DEVICE_FAMILY = 1;
}; };
name = Release; name = Release;
}; };
......
<?xml version="1.0" encoding="UTF-8" standalone="no"?> <?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9060" systemVersion="15B42" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM"> <document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="9532" systemVersion="15D21" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<dependencies> <dependencies>
<deployment identifier="iOS"/> <deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9051"/> <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="9530"/>
<capability name="Constraints to layout margins" minToolsVersion="6.0"/> <capability name="Constraints to layout margins" minToolsVersion="6.0"/>
</dependencies> </dependencies>
<scenes> <scenes>
...@@ -20,11 +20,9 @@ ...@@ -20,11 +20,9 @@
<subviews> <subviews>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_bg_4" translatesAutoresizingMaskIntoConstraints="NO" id="DpZ-WN-H0P"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="launch_bg_4" translatesAutoresizingMaskIntoConstraints="NO" id="DpZ-WN-H0P">
<rect key="frame" x="20" y="20" width="560" height="580"/> <rect key="frame" x="20" y="20" width="560" height="580"/>
<animations/>
</imageView> </imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="title_login" translatesAutoresizingMaskIntoConstraints="NO" id="A2i-wB-g8r"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="title_login" translatesAutoresizingMaskIntoConstraints="NO" id="A2i-wB-g8r">
<rect key="frame" x="0.0" y="0.0" width="240" height="128"/> <rect key="frame" x="0.0" y="0.0" width="240" height="128"/>
<animations/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="26" id="Euo-Fo-mch"/> <constraint firstAttribute="height" constant="26" id="Euo-Fo-mch"/>
<constraint firstAttribute="width" constant="171" id="itp-Ya-XEp"/> <constraint firstAttribute="width" constant="171" id="itp-Ya-XEp"/>
...@@ -44,7 +42,6 @@ ...@@ -44,7 +42,6 @@
</imageView> </imageView>
<imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_logo" translatesAutoresizingMaskIntoConstraints="NO" id="oO6-pH-ZSn"> <imageView userInteractionEnabled="NO" contentMode="scaleToFill" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="home_logo" translatesAutoresizingMaskIntoConstraints="NO" id="oO6-pH-ZSn">
<rect key="frame" x="0.0" y="0.0" width="240" height="128"/> <rect key="frame" x="0.0" y="0.0" width="240" height="128"/>
<animations/>
<constraints> <constraints>
<constraint firstAttribute="height" constant="54" id="YJp-uR-hyx"/> <constraint firstAttribute="height" constant="54" id="YJp-uR-hyx"/>
<constraint firstAttribute="width" constant="176" id="ssE-aF-0QO"/> <constraint firstAttribute="width" constant="176" id="ssE-aF-0QO"/>
...@@ -63,18 +60,17 @@ ...@@ -63,18 +60,17 @@
</variation> </variation>
</imageView> </imageView>
</subviews> </subviews>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/> <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<constraints> <constraints>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="Llm-lL-Icb" secondAttribute="bottom" id="4id-99-KLr"/>
<constraint firstAttribute="trailingMargin" secondItem="DpZ-WN-H0P" secondAttribute="trailing" constant="-20" id="6Cg-Wn-KOF"/> <constraint firstAttribute="trailingMargin" secondItem="DpZ-WN-H0P" secondAttribute="trailing" constant="-20" id="6Cg-Wn-KOF"/>
<constraint firstItem="oO6-pH-ZSn" firstAttribute="centerX" secondItem="DpZ-WN-H0P" secondAttribute="centerX" id="729-ca-TzT"/> <constraint firstItem="oO6-pH-ZSn" firstAttribute="centerX" secondItem="DpZ-WN-H0P" secondAttribute="centerX" id="729-ca-TzT"/>
<constraint firstItem="xb3-aO-Qok" firstAttribute="top" secondItem="DpZ-WN-H0P" secondAttribute="bottom" id="Bhr-0K-M5s"/> <constraint firstItem="xb3-aO-Qok" firstAttribute="top" secondItem="DpZ-WN-H0P" secondAttribute="bottom" id="F5o-MO-ege"/>
<constraint firstAttribute="trailingMargin" secondItem="DpZ-WN-H0P" secondAttribute="trailing" id="M0q-LH-WaU"/> <constraint firstAttribute="trailingMargin" secondItem="DpZ-WN-H0P" secondAttribute="trailing" id="M0q-LH-WaU"/>
<constraint firstItem="A2i-wB-g8r" firstAttribute="top" secondItem="oO6-pH-ZSn" secondAttribute="bottom" constant="34" id="Qd5-HS-fXa"/> <constraint firstItem="A2i-wB-g8r" firstAttribute="top" secondItem="oO6-pH-ZSn" secondAttribute="bottom" constant="34" id="Qd5-HS-fXa"/>
<constraint firstItem="xb3-aO-Qok" firstAttribute="top" secondItem="DpZ-WN-H0P" secondAttribute="bottom" id="VVT-Q7-nEb"/>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" id="YGe-3w-0mr"/> <constraint firstItem="DpZ-WN-H0P" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" id="YGe-3w-0mr"/>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="oO6-pH-ZSn" secondAttribute="bottom" constant="-268" id="eKJ-2Z-k4t"/> <constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="oO6-pH-ZSn" secondAttribute="bottom" constant="-268" id="eKJ-2Z-k4t"/>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="Llm-lL-Icb" secondAttribute="bottom" id="hwK-Ga-rqr"/>
<constraint firstItem="xb3-aO-Qok" firstAttribute="top" secondItem="DpZ-WN-H0P" secondAttribute="bottom" id="k1E-E8-LDE"/>
<constraint firstItem="A2i-wB-g8r" firstAttribute="centerX" secondItem="DpZ-WN-H0P" secondAttribute="centerX" id="mKu-nv-35U"/> <constraint firstItem="A2i-wB-g8r" firstAttribute="centerX" secondItem="DpZ-WN-H0P" secondAttribute="centerX" id="mKu-nv-35U"/>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="topMargin" id="pRk-mv-AsV"/> <constraint firstItem="DpZ-WN-H0P" firstAttribute="top" secondItem="Ze5-6b-2t3" secondAttribute="topMargin" id="pRk-mv-AsV"/>
<constraint firstItem="DpZ-WN-H0P" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" constant="-20" id="tTA-i8-RmJ"/> <constraint firstItem="DpZ-WN-H0P" firstAttribute="leading" secondItem="Ze5-6b-2t3" secondAttribute="leadingMargin" constant="-20" id="tTA-i8-RmJ"/>
...@@ -85,14 +81,13 @@ ...@@ -85,14 +81,13 @@
<exclude reference="oO6-pH-ZSn"/> <exclude reference="oO6-pH-ZSn"/>
</mask> </mask>
<mask key="constraints"> <mask key="constraints">
<exclude reference="Qd5-HS-fXa"/>
<exclude reference="mKu-nv-35U"/>
<exclude reference="729-ca-TzT"/>
<exclude reference="6Cg-Wn-KOF"/> <exclude reference="6Cg-Wn-KOF"/>
<exclude reference="eKJ-2Z-k4t"/> <exclude reference="eKJ-2Z-k4t"/>
<exclude reference="pRk-mv-AsV"/> <exclude reference="pRk-mv-AsV"/>
<exclude reference="tTA-i8-RmJ"/> <exclude reference="tTA-i8-RmJ"/>
<exclude reference="729-ca-TzT"/>
<exclude reference="Qd5-HS-fXa"/>
<exclude reference="mKu-nv-35U"/>
<exclude reference="Bhr-0K-M5s"/>
</mask> </mask>
</variation> </variation>
<variation key="heightClass=regular"> <variation key="heightClass=regular">
...@@ -101,18 +96,15 @@ ...@@ -101,18 +96,15 @@
<include reference="oO6-pH-ZSn"/> <include reference="oO6-pH-ZSn"/>
</mask> </mask>
<mask key="constraints"> <mask key="constraints">
<exclude reference="4id-99-KLr"/> <include reference="Qd5-HS-fXa"/>
<include reference="mKu-nv-35U"/>
<include reference="729-ca-TzT"/>
<include reference="6Cg-Wn-KOF"/> <include reference="6Cg-Wn-KOF"/>
<exclude reference="M0q-LH-WaU"/> <exclude reference="M0q-LH-WaU"/>
<exclude reference="YGe-3w-0mr"/> <exclude reference="YGe-3w-0mr"/>
<include reference="eKJ-2Z-k4t"/> <include reference="eKJ-2Z-k4t"/>
<include reference="pRk-mv-AsV"/> <include reference="pRk-mv-AsV"/>
<include reference="tTA-i8-RmJ"/> <include reference="tTA-i8-RmJ"/>
<include reference="729-ca-TzT"/>
<include reference="Qd5-HS-fXa"/>
<include reference="mKu-nv-35U"/>
<include reference="Bhr-0K-M5s"/>
<exclude reference="VVT-Q7-nEb"/>
</mask> </mask>
</variation> </variation>
</view> </view>
......
...@@ -140,7 +140,7 @@ ...@@ -140,7 +140,7 @@
[_sopDict setObject:@"FFKB-XCGL-04" forKey:@"现场管理商户撤场管理规定"]; [_sopDict setObject:@"FFKB-XCGL-04" forKey:@"现场管理商户撤场管理规定"];
[_sopDict setObject:@"FFKB-XCGL-05" forKey:@"现场管理红星美凯龙商户信用等级评定办法"]; [_sopDict setObject:@"FFKB-XCGL-05" forKey:@"现场管理红星美凯龙商户信用等级评定办法"];
[_sopDict setObject:@"FFKB-HJGL-01" forKey:@"400呼叫管理呼叫中心商场虚拟座席远程管理规定"]; [_sopDict setObject:@"FFKB-HJZX-01" forKey:@"400呼叫管理呼叫中心商场虚拟座席远程管理规定"];
[_sopDict setObject:@"FFKB-DPGL-01" forKey:@"单品管理商品信息管理规定"]; [_sopDict setObject:@"FFKB-DPGL-01" forKey:@"单品管理商品信息管理规定"];
......
...@@ -84,7 +84,7 @@ ...@@ -84,7 +84,7 @@
[self.progressLabel setAttributedText:strAttr]; [self.progressLabel setAttributedText:strAttr];
self.alreadyLabel.textColor = kProgressDealWithColor; self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor; self.allLabel.textColor = kProgressDealWithColor;
} else if ([taskList.state isEqualToString:@"reported"]) { } else if ([taskList.reported isEqualToNumber:@1]) {
NSString *str = [NSString stringWithFormat:@"巡检进度:已上报"]; NSString *str = [NSString stringWithFormat:@"巡检进度:已上报"];
NSMutableAttributedString *strAttr = [[NSMutableAttributedString alloc] initWithString:str]; NSMutableAttributedString *strAttr = [[NSMutableAttributedString alloc] initWithString:str];
[strAttr addAttributes:@{NSForegroundColorAttributeName:kCellDetailColor,NSFontAttributeName:[UIFont systemFontOfSize:14.0f]} range:NSMakeRange(0,5)]; [strAttr addAttributes:@{NSForegroundColorAttributeName:kCellDetailColor,NSFontAttributeName:[UIFont systemFontOfSize:14.0f]} range:NSMakeRange(0,5)];
...@@ -92,6 +92,14 @@ ...@@ -92,6 +92,14 @@
[self.progressLabel setAttributedText:strAttr]; [self.progressLabel setAttributedText:strAttr];
self.alreadyLabel.textColor = kProgressDealWithColor; self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor; self.allLabel.textColor = kProgressDealWithColor;
}else if ([taskList.reported isEqualToNumber:@0]) {
NSString *str = [NSString stringWithFormat:@"巡检进度:未上报"];
NSMutableAttributedString *strAttr = [[NSMutableAttributedString alloc] initWithString:str];
[strAttr addAttributes:@{NSForegroundColorAttributeName:kCellDetailColor,NSFontAttributeName:[UIFont systemFontOfSize:14.0f]} range:NSMakeRange(0,5)];
[strAttr addAttributes:@{NSForegroundColorAttributeName:kProgressDealWithColor,NSFontAttributeName:[UIFont systemFontOfSize:14.0f]} range:NSMakeRange(5,str.length - 5)];
[self.progressLabel setAttributedText:strAttr];
self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor;
} else if ([taskList.state isEqualToString:@"finished"]) { } else if ([taskList.state isEqualToString:@"finished"]) {
NSString *str = [NSString stringWithFormat:@"巡检进度:已评分"]; NSString *str = [NSString stringWithFormat:@"巡检进度:已评分"];
NSMutableAttributedString *strAttr = [[NSMutableAttributedString alloc] initWithString:str]; NSMutableAttributedString *strAttr = [[NSMutableAttributedString alloc] initWithString:str];
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
@property (nonatomic,copy) NSString *ranking; @property (nonatomic,copy) NSString *ranking;
@property (nonatomic, assign) int reportCount; @property (nonatomic, assign) int reportCount;
@property (nonatomic, copy) NSString *reportTime; @property (nonatomic, copy) NSString *reportTime;
@property (nonatomic, copy) NSString *reported; @property (nonatomic, copy) NSNumber *reported;
@property (nonatomic, copy) NSString *score; @property (nonatomic, copy) NSString *score;
@property (nonatomic, copy) NSString *state; @property (nonatomic, copy) NSString *state;
@property (nonatomic, copy) NSString *store_code; @property (nonatomic, copy) NSString *store_code;
......
...@@ -98,12 +98,18 @@ ...@@ -98,12 +98,18 @@
self.alreadyLabel.textColor = kProgressDealWithColor; self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor; self.allLabel.textColor = kProgressDealWithColor;
} else if ([taskDetail.state isEqualToString:@"reported"]) { } else if ([taskDetail.reported isEqualToNumber:@1]) {
self.progressLabel.text = [NSString stringWithFormat:@"已上报 %.0f%%", (CGFloat)taskDetail.reportCount / taskDetail.questionCount * 100]; self.progressLabel.text = [NSString stringWithFormat:@"已上报 %.0f%%", (CGFloat)taskDetail.reportCount / taskDetail.questionCount * 100];
self.progressLabel.textColor = kProgressDealWithColor; self.progressLabel.textColor = kProgressDealWithColor;
self.alreadyLabel.textColor = kProgressDealWithColor; self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor; self.allLabel.textColor = kProgressDealWithColor;
}else if ([taskDetail.reported isEqualToNumber:@0]) {
self.progressLabel.text = [NSString stringWithFormat:@"未上报 %.0f%%", (CGFloat)taskDetail.reportCount / taskDetail.questionCount * 100];
self.progressLabel.textColor = kProgressDealWithColor;
self.alreadyLabel.textColor = kProgressDealWithColor;
self.allLabel.textColor = kProgressDealWithColor;
} else if ([taskDetail.state isEqualToString:@"finished"]) { } else if ([taskDetail.state isEqualToString:@"finished"]) {
self.progressLabel.text = [NSString stringWithFormat:@"已评分 %.0f%%", (CGFloat)taskDetail.reportCount / taskDetail.questionCount * 100]; self.progressLabel.text = [NSString stringWithFormat:@"已评分 %.0f%%", (CGFloat)taskDetail.reportCount / taskDetail.questionCount * 100];
self.progressLabel.textColor = kProgressDealWithColor; self.progressLabel.textColor = kProgressDealWithColor;
......
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
@property (nonatomic,copy) NSString *ranking; @property (nonatomic,copy) NSString *ranking;
@property (nonatomic, assign) int reportCount; @property (nonatomic, assign) int reportCount;
@property (nonatomic, copy) NSString *reportTime; @property (nonatomic, copy) NSString *reportTime;
@property (nonatomic, copy) NSString *reported; @property (nonatomic, strong) NSNumber *reported;
//@property (nonatomic, copy) NSString *score; //@property (nonatomic, copy) NSString *score;
@property (nonatomic, assign) CGFloat score; @property (nonatomic, assign) CGFloat score;
@property (nonatomic, copy) NSString *state; @property (nonatomic, copy) NSString *state;
......
...@@ -20,11 +20,11 @@ ...@@ -20,11 +20,11 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>1.0.5</string> <string>1.0.7</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0.5</string> <string>1.0.7</string>
<key>LSRequiresIPhoneOS</key> <key>LSRequiresIPhoneOS</key>
<true/> <true/>
<key>NSAppTransportSecurity</key> <key>NSAppTransportSecurity</key>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment