diff --git a/.gitignore b/.gitignore index 86871492..275b0402 100644 --- a/.gitignore +++ b/.gitignore @@ -50,3 +50,5 @@ Carthage/Build .swiftpm/ .build/ Package.resolved + +bazel-* diff --git a/BUILD.bazel b/BUILD.bazel new file mode 100644 index 00000000..48082ad0 --- /dev/null +++ b/BUILD.bazel @@ -0,0 +1,33 @@ +objc_library( + name = "PINRemoteImage", + srcs = glob( + ["Source/Classes/**/*.m"], + allow_empty = False, + ), + hdrs = glob( + ["Source/Classes/**/*.h"], + allow_empty = False, + ), + copts = [ + "-Wno-deprecated-declarations", + "-Wno-shadow-ivar", + ], + defines = [ + "PIN_WEBP", + "USE_PINCACHE", + "BAZEL" + ], + sdk_frameworks = [ + "Accelerate", + "CoreServices", + "ImageIO", + ], + visibility = [ + "//visibility:public", + ], + deps = [ + "@PINCache", + "@PINOperation", + "@libwebp//:webp", + ], +) diff --git a/Source/Classes/AnimatedImages/PINAnimatedImage.m b/Source/Classes/AnimatedImages/PINAnimatedImage.m index 9204b4e5..3abd7a2e 100644 --- a/Source/Classes/AnimatedImages/PINAnimatedImage.m +++ b/Source/Classes/AnimatedImages/PINAnimatedImage.m @@ -6,7 +6,7 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINAnimatedImage.h" NSErrorDomain const kPINAnimatedImageErrorDomain = @"kPINAnimatedImageErrorDomain"; @@ -25,7 +25,7 @@ + (NSInteger)maximumFramesPerSecond { static dispatch_once_t onceToken; static NSInteger maximumFramesPerSecond = 60; - + dispatch_once(&onceToken, ^{ #if PIN_TARGET_IOS if (@available(iOS 10.3, tvOS 10.3, *)) { @@ -87,7 +87,7 @@ - (NSTimeInterval)minimumFrameInterval dispatch_once(&onceToken, ^{ kGreatestCommonDivisorPrecision = 2.0 / (1.0 / [PINAnimatedImage maximumFramesPerSecond]); }); - + // Scales the frame delays by `kGreatestCommonDivisorPrecision` // then converts it to an UInteger for in order to calculate the GCD. NSUInteger scaledGCD = lrint([self durationAtIndex:0] * kGreatestCommonDivisorPrecision); @@ -95,7 +95,7 @@ - (NSTimeInterval)minimumFrameInterval CFTimeInterval duration = [self durationAtIndex:durationIdx]; scaledGCD = gcd(lrint(duration * kGreatestCommonDivisorPrecision), scaledGCD); } - + // Reverse to scale to get the value back into seconds. return (scaledGCD / kGreatestCommonDivisorPrecision); } @@ -106,7 +106,7 @@ static NSUInteger gcd(NSUInteger a, NSUInteger b) { // http://en.wikipedia.org/wiki/Greatest_common_divisor NSCAssert(a > 0 && b > 0, @"A and B must be greater than 0"); - + while (a != b) { if (a > b) { a = a - b; diff --git a/Source/Classes/AnimatedImages/PINAnimatedImageView.m b/Source/Classes/AnimatedImages/PINAnimatedImageView.m index e54fa7ea..211bfabb 100644 --- a/Source/Classes/AnimatedImages/PINAnimatedImageView.m +++ b/Source/Classes/AnimatedImages/PINAnimatedImageView.m @@ -5,12 +5,12 @@ // Created by Garrett Moon on 4/17/18. // -#import "PINAnimatedImageView.h" +#import "Source/Classes/include/PINAnimatedImageView.h" -#import "PINRemoteLock.h" -#import "PINDisplayLink.h" -#import "PINImage+DecodedImage.h" -#import "PINRemoteWeakProxy.h" +#import "Source/Classes/PINRemoteLock.h" +#import "Source/Classes/PINDisplayLink.h" +#import "Source/Classes/Categories/PINImage+DecodedImage.h" +#import "Source/Classes/PINRemoteWeakProxy.h" @interface PINAnimatedImageView () { @@ -63,7 +63,7 @@ - (void)commonInit:(PINCachedAnimatedImage *)animatedImage _animatedImage = animatedImage; _animatedImageRunLoopMode = NSRunLoopCommonModes; _durations = NULL; - + if (animatedImage) { [self initializeAnimatedImage:animatedImage]; } @@ -79,7 +79,7 @@ - (void)initializeAnimatedImage:(nonnull PINCachedAnimatedImage *)animatedImage [self coverImageCompleted:coverImage]; }); }; - + animatedImage.playbackReadyCallback = ^{ dispatch_async(dispatch_get_main_queue(), ^{ // In this case the lock is already gone we have to call the unlocked version therefore @@ -90,7 +90,7 @@ - (void)initializeAnimatedImage:(nonnull PINCachedAnimatedImage *)animatedImage if (animatedImage.playbackReady) { [self checkIfShouldAnimate]; } - + [self resetDurationsWithAnimatedImage:animatedImage]; } @@ -112,11 +112,11 @@ - (void)setAnimatedImage:(PINCachedAnimatedImage *)animatedImage if (_animatedImage == animatedImage && animatedImage.playbackReady) { return; } - + PINCachedAnimatedImage *previousAnimatedImage = _animatedImage; - + _animatedImage = animatedImage; - + if (animatedImage != nil) { [self initializeAnimatedImage:animatedImage]; } else { @@ -124,7 +124,7 @@ - (void)setAnimatedImage:(PINCachedAnimatedImage *)animatedImage self.layer.contents = nil; [self setCoverImage:nil]; } - + // Animated Image can take a while to dealloc, let's try and do it off main. __block PINCachedAnimatedImage *strongAnimatedImage = previousAnimatedImage; dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -147,9 +147,9 @@ - (NSString *)animatedImageRunLoopMode - (void)setAnimatedImageRunLoopMode:(NSString *)newRunLoopMode { PINAssertMain(); - + NSString *runLoopMode = newRunLoopMode ?: NSRunLoopCommonModes; - + if (_displayLink != nil) { [_displayLink removeFromRunLoop:[NSRunLoop mainRunLoop] forMode:_animatedImageRunLoopMode]; [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:runLoopMode]; @@ -166,7 +166,7 @@ - (BOOL)isPlaybackPaused - (void)setPlaybackPaused:(BOOL)playbackPaused { PINAssertMain(); - + _playbackPaused = playbackPaused; [self checkIfShouldAnimate]; } @@ -175,7 +175,7 @@ - (void)coverImageCompleted:(PINImage *)coverImage { PINAssertMain(); BOOL setCoverImage = (_displayLink == nil) || _displayLink.paused; - + if (setCoverImage) { [self setCoverImage:coverImage]; } @@ -206,21 +206,21 @@ - (void)checkIfShouldAnimate - (void)startAnimating { PINAssertMain(); - + if (_playbackPaused) { return; } - + if (_animatedImage.playbackReady == NO) { return; } - + if ([self canBeVisible] == NO) { return; } - + NSUInteger frameInterval = self.animatedImage.frameInterval; - + if (_displayLink == nil) { _playHead = 0; _displayLink = [PINDisplayLink displayLinkWithTarget:[PINRemoteWeakProxy weakProxyWithTarget:self] selector:@selector(displayLinkFired:)]; @@ -236,7 +236,7 @@ - (void)startAnimating } #endif _lastSuccessfulFrameIndex = NSUIntegerMax; - + [_displayLink addToRunLoop:[NSRunLoop mainRunLoop] forMode:self.animatedImageRunLoopMode]; } else { _displayLink.paused = NO; @@ -249,7 +249,7 @@ - (void)stopAnimating _displayLink.paused = YES; _lastDisplayLinkFire = 0; - + [_animatedImage clearAnimatedImageCache]; } @@ -282,7 +282,7 @@ - (void)setImage:(PINImage *)image if (image) { self.animatedImage = nil; } - + super.image = image; } @@ -367,28 +367,28 @@ - (void)displayLinkFired:(PINDisplayLink *)displayLink } else { timeBetweenLastFire = CACurrentMediaTime() - self.lastDisplayLinkFire; } - + self.lastDisplayLinkFire = CACurrentMediaTime(); - + _playHead += timeBetweenLastFire; - + while (_playHead > self.animatedImage.totalDuration) { // Set playhead to zero to keep from showing different frames on different playthroughs _playHead = 0; _playedLoops++; } - + if (self.animatedImage.loopCount > 0 && _playedLoops >= self.animatedImage.loopCount) { [self stopAnimating]; return; } - + NSUInteger frameIndex = [self frameIndexAtPlayHeadPosition:_playHead]; if (frameIndex == _lastSuccessfulFrameIndex) { return; } CGImageRef frameImage = [self.animatedImage imageAtIndex:frameIndex]; - + if (frameImage == nil) { //Pause the display link until we get a file ready notification displayLink.paused = YES; @@ -428,7 +428,7 @@ - (NSUInteger)frameIndexAtPlayHeadPosition:(CFTimeInterval)playHead { PINAssertMain(); int low = 0, high = (int)_animatedImage.frameCount - 1; - + while (low <= high) { int mid = low + (high - low) / 2; if (_durations[mid] < playHead) { diff --git a/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m b/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m index 8f410639..cb75f506 100644 --- a/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m +++ b/Source/Classes/AnimatedImages/PINCachedAnimatedImage.m @@ -6,21 +6,21 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINCachedAnimatedImage.h" +#import "Source/Classes/include/PINCachedAnimatedImage.h" -#import "PINRemoteLock.h" -#import "PINGIFAnimatedImage.h" +#import "Source/Classes/PINRemoteLock.h" +#import "Source/Classes/include/PINGIFAnimatedImage.h" #if PIN_WEBP -#import "PINWebPAnimatedImage.h" +#import "Source/Classes/include/PINWebPAnimatedImage.h" #endif #if SWIFT_PACKAGE @import PINOperation; #else -#import +#import "../_main~non_module_dependencies~PINOperation/Source/PINOperation.h" #endif -#import "NSData+ImageDetectors.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" static const NSUInteger kFramesToRenderForLargeFrames = 4; static const NSUInteger kFramesToRenderMinimum = 2; @@ -36,7 +36,7 @@ @interface PINCachedAnimatedImage () { // Since _animatedImage is set on init it is thread-safe. id _animatedImage; - + PINImage *_coverImage; PINAnimatedImageInfoReady _coverImageReadyCallback; dispatch_block_t _playbackReadyCallback; @@ -45,7 +45,7 @@ @interface PINCachedAnimatedImage () BOOL _playbackReady; PINOperationQueue *_operationQueue; dispatch_queue_t _cachingQueue; - + NSUInteger _playhead; BOOL _notifyOnReady; NSMutableIndexSet *_cachedOrCachingFrames; @@ -85,7 +85,7 @@ - (instancetype)initWithAnimatedImage:(id )animatedImage _notifyOnReady = YES; _cachedOrCachingFrames = [[NSMutableIndexSet alloc] init]; _lock = [[PINRemoteLock alloc] initWithName:@"PINCachedAnimatedImage Lock"]; - + #if PIN_TARGET_IOS _lastMemoryWarning = [NSDate distantPast]; [[NSNotificationCenter defaultCenter] addObserver:self @@ -93,10 +93,10 @@ - (instancetype)initWithAnimatedImage:(id )animatedImage name:UIApplicationDidReceiveMemoryWarningNotification object:nil]; #endif - + _operationQueue = [[PINOperationQueue alloc] initWithMaxConcurrentOperations:kFramesToRenderForLargeFrames]; _cachingQueue = dispatch_queue_create("Caching Queue", DISPATCH_QUEUE_SERIAL); - + // dispatch later so that blocks can be set after init this runloop PINWeakify(self); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -224,7 +224,7 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index // Reset cache cleared flag if it's been set. self->_cacheCleared = NO; imageRef = (__bridge CGImageRef)[self->_frameCache objectForKey:@(index)]; - + self->_playhead = index; if (imageRef == NULL) { if ([self framesToCache] == 0) { @@ -235,7 +235,7 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index self->_notifyOnReady = YES; } } - + // Retain and autorelease while we have the lock, another thread could remove it from the cache // and allow it to be released. if (imageRef) { @@ -243,7 +243,7 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index CFAutorelease(imageRef); } }]; - + if (cachingDisabled && imageRef == NULL) { imageRef = [_animatedImage imageAtIndex:index cacheProvider:self]; } else { @@ -292,7 +292,7 @@ - (void)updateCache [self _updateCacheOnQueue]; }]; } - + [_operationQueue scheduleOperation:^{ PINStrongify(self); [self cleanupFrames]; @@ -303,9 +303,9 @@ - (void)getKeepRanges:(nonnull out NSRange *)endKeepRangeIn beginningKeepRange:( { __block NSRange endKeepRange; __block NSRange beginningKeepRange; - + NSUInteger framesToCache = [self framesToCache]; - + [self->_lock lockWithBlock:^{ // find the range of frames we want to keep endKeepRange = NSMakeRange(self->_playhead, framesToCache); @@ -315,7 +315,7 @@ - (void)getKeepRanges:(nonnull out NSRange *)endKeepRangeIn beginningKeepRange:( endKeepRange.length = self->_animatedImage.frameCount - self->_playhead; } }]; - + if (endKeepRangeIn) { *endKeepRangeIn = endKeepRange; } @@ -329,7 +329,7 @@ - (void)cleanupFrames NSRange endKeepRange; NSRange beginningKeepRange; [self getKeepRanges:&endKeepRange beginningKeepRange:&beginningKeepRange]; - + [_lock lockWithBlock:^{ NSMutableIndexSet *removedFrames = [[NSMutableIndexSet alloc] init]; PINLog(@"Checking if frames need removing: %lu", _cachedOrCachingFrames.count); @@ -394,7 +394,7 @@ - (void)_locked_cacheFrame:(NSUInteger)frameIndex PINLog(@"Requesting: %lu", (unsigned long)frameIndex); [_cachedOrCachingFrames addIndex:frameIndex]; _frameRenderCount++; - + PINWeakify(self); dispatch_async(_cachingQueue, ^{ PINStrongify(self); @@ -408,7 +408,7 @@ - (NSUInteger)framesToCache { unsigned long long totalBytes = [NSProcessInfo processInfo].physicalMemory; NSUInteger framesToCache = 0; - + NSUInteger frameCost = _animatedImage.bytesPerFrame; if (frameCost * _animatedImage.frameCount < totalBytes / 250) { // If the total number of bytes takes up less than a 250th of total memory, lets just cache 'em all. @@ -423,7 +423,7 @@ - (NSUInteger)framesToCache // No caching :( framesToCache = 0; } - + // If it's been less than 5 seconds, we're not caching CFTimeInterval timeSinceLastWarning = -[self.lastMemoryWarning timeIntervalSinceNow]; if (self.cachingFramesCausingMemoryWarnings || timeSinceLastWarning < kSecondsAfterMemWarningToMinimumCache) { @@ -433,7 +433,7 @@ - (NSUInteger)framesToCache } else if (timeSinceLastWarning < kSecondsAfterMemWarningToAllCache) { framesToCache = MIN(framesToCache, kFramesToRenderForLargeFrames); } - + return framesToCache; } diff --git a/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m b/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m index 2b5016f9..daf0a2bc 100644 --- a/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m +++ b/Source/Classes/AnimatedImages/PINGIFAnimatedImage.m @@ -6,7 +6,7 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINGIFAnimatedImage.h" +#import "Source/Classes/include/PINGIFAnimatedImage.h" #import #if PIN_TARGET_IOS @@ -15,8 +15,8 @@ #import #endif -#import "PINImage+DecodedImage.h" -#import "NSData+ImageDetectors.h" +#import "Source/Classes/Categories/PINImage+DecodedImage.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" @interface PINGIFAnimatedImage () { @@ -57,7 +57,7 @@ - (instancetype)initWithAnimatedImageData:(NSData *)animatedImageData (__bridge NSNumber *)kCFBooleanFalse}); _width = (uint32_t)[(NSNumber *)imageProperties[(__bridge NSString *)kCGImagePropertyPixelWidth] unsignedIntegerValue]; _height = (uint32_t)[(NSNumber *)imageProperties[(__bridge NSString *)kCGImagePropertyPixelHeight] unsignedIntegerValue]; - + for (NSUInteger frameIdx = 0; frameIdx < _frameCount; frameIdx++) { _durations[frameIdx] = [PINGIFAnimatedImage frameDurationAtIndex:frameIdx source:_imageSource]; } @@ -82,17 +82,17 @@ + (Float32)frameDurationAtIndex:(NSUInteger)index source:(CGImageSourceRef)sourc frameDuration = [delayTime floatValue]; } } - + static dispatch_once_t onceToken; static Float32 maximumFrameDuration; dispatch_once(&onceToken, ^{ maximumFrameDuration = 1.0 / [PINAnimatedImage maximumFramesPerSecond]; }); - + if (frameDuration < maximumFrameDuration) { frameDuration = kPINAnimatedImageDefaultDuration; } - + return frameDuration; } @@ -159,7 +159,7 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id 0) { if (WebPDemuxGetFrame(_demux, (int)index, &previousIterator) == NO) { return nil; @@ -256,12 +256,12 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id 0) ? &previousIterator : nil]; - + CGImageRef imageRef = [self rawImageWithIterator:iterator]; CGImageRef canvas = NULL; - + if (imageRef) { if (isKeyFrame) { // If the current frame is a keyframe, we can just copy it into a blank @@ -305,7 +305,7 @@ - (CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id 0) { WebPDemuxReleaseIterator(&previousIterator); } - + return canvas; } @@ -371,11 +371,11 @@ - (BOOL)isKeyFrame:(WebPIterator *)iterator previousIterator:(WebPIterator *)pre // Check if we're a key frame regardless of previous frame. return YES; } - + if (previousIterator == nil) { return NO; } - + BOOL previousFrameMadeThisKeyFrame = previousIterator->dispose_method == WEBP_MUX_DISPOSE_BACKGROUND; BOOL foundKeyframe = NO; while (foundKeyframe == NO) { @@ -394,7 +394,7 @@ - (BOOL)isKeyFrame:(WebPIterator *)iterator previousIterator:(WebPIterator *)pre } } } - + return previousFrameMadeThisKeyFrame; } diff --git a/Source/Classes/Categories/NSData+ImageDetectors.m b/Source/Classes/Categories/NSData+ImageDetectors.m index f58f5571..54704165 100644 --- a/Source/Classes/Categories/NSData+ImageDetectors.m +++ b/Source/Classes/Categories/NSData+ImageDetectors.m @@ -6,7 +6,7 @@ // // -#import "NSData+ImageDetectors.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" #if PIN_WEBP #if SWIFT_PACKAGE @@ -40,7 +40,7 @@ static inline BOOL advancePositionWithCount(NSUInteger *position, NSUInteger len return NO; } *position = *position + count; - + return YES; } @@ -60,13 +60,13 @@ static inline BOOL advancePositionWithBytes(NSUInteger *position, Byte *bytes, N } // Advance the byte read as well. bytesToAdvance++; - + if (*position + bytesToAdvance >= length) { return NO; } *position = *position + bytesToAdvance; } while (readAgain); - + return YES; } @@ -75,12 +75,12 @@ - (BOOL)pin_isAnimatedGIF if ([self pin_isGIF] == NO) { return NO; } - + Byte *bytes = (Byte *)self.bytes; NSUInteger length = self.length; NSUInteger position = 0; NSUInteger GCECount = 0; - + while (bytes && position < length) { // Look for Graphic Control Extension if (*(bytes + position) == 0x21) { @@ -105,7 +105,7 @@ - (BOOL)pin_isAnimatedGIF } if (!advancePositionWithCount(&position, length, 1)) break; } - + return GCECount > 1; } @@ -130,7 +130,7 @@ - (BOOL)pin_isAnimatedWebP if (WebPGetFeatures([self bytes], [self length], &features) == VP8_STATUS_OK) { return features.has_animation; } - + return NO; } diff --git a/Source/Classes/Categories/PINImage+DecodedImage.h b/Source/Classes/Categories/PINImage+DecodedImage.h index 08d0e5a0..733e3505 100644 --- a/Source/Classes/Categories/PINImage+DecodedImage.h +++ b/Source/Classes/Categories/PINImage+DecodedImage.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import diff --git a/Source/Classes/Categories/PINImage+DecodedImage.m b/Source/Classes/Categories/PINImage+DecodedImage.m index da75e5bc..aae2ea73 100644 --- a/Source/Classes/Categories/PINImage+DecodedImage.m +++ b/Source/Classes/Categories/PINImage+DecodedImage.m @@ -14,7 +14,7 @@ #import "PINImage+WebP.h" #endif -#import "NSData+ImageDetectors.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" NS_INLINE BOOL pin_CGImageRefIsOpaque(CGImageRef imageRef) { CGImageAlphaInfo alpha = CGImageGetAlphaInfo(imageRef); @@ -121,17 +121,17 @@ + (PINImage *)pin_decodedImageWithData:(NSData *)data skipDecodeIfPossible:(BOOL if (data == nil) { return nil; } - + #if PIN_WEBP if ([data pin_isWebP]) { return [PINImage pin_imageWithWebPData:data]; } #endif - + PINImage *decodedImage = nil; - + CGImageSourceRef imageSourceRef = CGImageSourceCreateWithData((CFDataRef)data, NULL); - + if (imageSourceRef) { CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSourceRef, 0, (CFDictionaryRef)@{(NSString *)kCGImageSourceShouldCache : (NSNumber *)kCFBooleanFalse}); if (imageRef) { @@ -152,10 +152,10 @@ + (PINImage *)pin_decodedImageWithData:(NSData *)data skipDecodeIfPossible:(BOOL #endif CGImageRelease(imageRef); } - + CFRelease(imageSourceRef); } - + return decodedImage; } @@ -189,14 +189,14 @@ + (PINImage *)pin_decodedImageUsingGraphicsImageRendererRefWithCGImageRef:(CGIma } else { format = [UIGraphicsImageRendererFormat defaultFormat]; } - + format.scale = scale; format.opaque = pin_CGImageRefIsOpaque(imageRef); - + __block CGFloat radians = 0.0; __block BOOL doHorizontalFlip = NO; __block BOOL doVerticalFlip = NO; - + pin_degreesFromOrientation(orientation, ^(CGFloat degrees, BOOL horizontalFlip, BOOL verticalFlip) { // Convert degrees to radians radians = [[[NSMeasurement alloc] initWithDoubleValue:degrees @@ -205,29 +205,29 @@ + (PINImage *)pin_decodedImageUsingGraphicsImageRendererRefWithCGImageRef:(CGIma doHorizontalFlip = horizontalFlip; doVerticalFlip = verticalFlip; }); - + // Create rotation out of radians CGAffineTransform transform = CGAffineTransformMakeRotation(radians); - + // Grab image size CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); - + // Rotate rect by transformation CGRect rotatedRect = CGRectApplyAffineTransform(CGRectMake(0.0, 0.0, imageSize.width, imageSize.height), transform); - + // Use graphics renderer to render image UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:rotatedRect.size format:format]; - + return [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) { CGContextRef ctx = rendererContext.CGContext; - + // Flip the default coordinate system for iOS/tvOS: https://developer.apple.com/library/archive/documentation/2DDrawing/Conceptual/DrawingPrintingiOS/GraphicsDrawingOverview/GraphicsDrawingOverview.html#//apple_ref/doc/uid/TP40010156-CH14-SW4 CGContextTranslateCTM(ctx, rotatedRect.size.width / 2.0, rotatedRect.size.height / 2.0); CGContextScaleCTM(ctx, (doHorizontalFlip ? -1.0 : 1.0), (doVerticalFlip ? 1.0 : -1.0)); - + // Apply transformation CGContextConcatCTM(ctx, transform); - + // Draw image CGContextDrawImage(ctx, CGRectMake(-(imageSize.width / 2.0), -(imageSize.height / 2.0), imageSize.width, imageSize.height), imageRef); }]; @@ -237,86 +237,86 @@ + (PINImage *)pin_decodedImageUsingGraphicsImageRendererRefWithCGImageRef:(CGIma + (CGImageRef)pin_decodedImageRefWithCGImageRef:(CGImageRef)imageRef { CGSize imageSize = CGSizeMake(CGImageGetWidth(imageRef), CGImageGetHeight(imageRef)); - + CGBitmapInfo info = pin_CGImageRefIsOpaque(imageRef) ? (kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host) : (kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host); CGColorSpaceRef colorspace = CGColorSpaceCreateDeviceRGB(); - + //Use UIGraphicsBeginImageContext parameters from docs: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIKitFunctionReference/#//apple_ref/c/func/UIGraphicsBeginImageContextWithOptions CGContextRef ctx = CGBitmapContextCreate(NULL, imageSize.width, imageSize.height, 8, 0, colorspace, info); - + CGColorSpaceRelease(colorspace); - + if (ctx) { CGContextSetBlendMode(ctx, kCGBlendModeCopy); CGContextDrawImage(ctx, CGRectMake(0, 0, imageSize.width, imageSize.height), imageRef); - + CGImageRef decodedImageRef = CGBitmapContextCreateImage(ctx); if (decodedImageRef) { CFAutorelease(decodedImageRef); } CGContextRelease(ctx); return decodedImageRef; - + } - + return imageRef; } #if PIN_TARGET_IOS UIImageOrientation pin_UIImageOrientationFromImageSource(CGImageSourceRef imageSourceRef) { UIImageOrientation orientation = UIImageOrientationUp; - + if (imageSourceRef != nil) { NSDictionary *dict = (NSDictionary *)CFBridgingRelease(CGImageSourceCopyPropertiesAtIndex(imageSourceRef, 0, NULL)); - + if (dict != nil) { - + NSNumber* exifOrientation = dict[(id)kCGImagePropertyOrientation]; if (exifOrientation != nil) { - + switch (exifOrientation.intValue) { case 1: /*kCGImagePropertyOrientationUp*/ orientation = UIImageOrientationUp; break; - + case 2: /*kCGImagePropertyOrientationUpMirrored*/ orientation = UIImageOrientationUpMirrored; break; - + case 3: /*kCGImagePropertyOrientationDown*/ orientation = UIImageOrientationDown; break; - + case 4: /*kCGImagePropertyOrientationDownMirrored*/ orientation = UIImageOrientationDownMirrored; break; case 5: /*kCGImagePropertyOrientationLeftMirrored*/ orientation = UIImageOrientationLeftMirrored; break; - + case 6: /*kCGImagePropertyOrientationRight*/ orientation = UIImageOrientationRight; break; - + case 7: /*kCGImagePropertyOrientationRightMirrored*/ orientation = UIImageOrientationRightMirrored; break; - + case 8: /*kCGImagePropertyOrientationLeft*/ orientation = UIImageOrientationLeft; break; - + default: break; } } } } - + return orientation; } diff --git a/Source/Classes/Categories/PINImage+ScaledImage.h b/Source/Classes/Categories/PINImage+ScaledImage.h index b82f9313..854573d6 100644 --- a/Source/Classes/Categories/PINImage+ScaledImage.h +++ b/Source/Classes/Categories/PINImage+ScaledImage.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import diff --git a/Source/Classes/Categories/PINImage+WebP.h b/Source/Classes/Categories/PINImage+WebP.h index 8c384076..33a975b0 100644 --- a/Source/Classes/Categories/PINImage+WebP.h +++ b/Source/Classes/Categories/PINImage+WebP.h @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_WEBP diff --git a/Source/Classes/Categories/PINRemoteImageTask+Subclassing.h b/Source/Classes/Categories/PINRemoteImageTask+Subclassing.h index 8e0c6005..97a294f9 100644 --- a/Source/Classes/Categories/PINRemoteImageTask+Subclassing.h +++ b/Source/Classes/Categories/PINRemoteImageTask+Subclassing.h @@ -6,7 +6,7 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINRemoteImageTask.h" +#import "Source/Classes/PINRemoteImageTask.h" NS_ASSUME_NONNULL_BEGIN diff --git a/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m b/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m index 34edd842..e9f0c426 100644 --- a/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m +++ b/Source/Classes/ImageCategories/PINAnimatedImageView+PINRemoteImage.m @@ -5,9 +5,9 @@ // Created by Garrett Moon on 4/19/18. // -#import "PINAnimatedImageView+PINRemoteImage.h" +#import "Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h" -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINAnimatedImage.h" @implementation PINAnimatedImageView (PINRemoteImage) diff --git a/Source/Classes/ImageCategories/PINButton+PINRemoteImage.m b/Source/Classes/ImageCategories/PINButton+PINRemoteImage.m index 50f5d802..9eda5b80 100644 --- a/Source/Classes/ImageCategories/PINButton+PINRemoteImage.m +++ b/Source/Classes/ImageCategories/PINButton+PINRemoteImage.m @@ -6,7 +6,7 @@ // // -#import "PINButton+PINRemoteImage.h" +#import "Source/Classes/include/PINButton+PINRemoteImage.h" @implementation PINButton (PINRemoteImage) diff --git a/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m b/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m index 1e6a6ab2..2d90c340 100644 --- a/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m +++ b/Source/Classes/ImageCategories/PINImageView+PINRemoteImage.m @@ -6,7 +6,7 @@ // // -#import "PINImageView+PINRemoteImage.h" +#import "Source/Classes/include/PINImageView+PINRemoteImage.h" @implementation PINImageView (PINRemoteImage) @@ -111,7 +111,7 @@ - (void)pin_updateUIWithRemoteImageManagerResult:(PINRemoteImageManagerResult *) - (void)pin_clearImages { self.image = nil; - + #if PIN_TARGET_IOS [self setNeedsLayout]; #elif PIN_TARGET_MAC diff --git a/Source/Classes/PINAlternateRepresentationProvider.m b/Source/Classes/PINAlternateRepresentationProvider.m index ea87911e..390249d5 100644 --- a/Source/Classes/PINAlternateRepresentationProvider.m +++ b/Source/Classes/PINAlternateRepresentationProvider.m @@ -6,10 +6,10 @@ // // -#import "PINAlternateRepresentationProvider.h" +#import "Source/Classes/include/PINAlternateRepresentationProvider.h" -#import "PINCachedAnimatedImage.h" -#import "NSData+ImageDetectors.h" +#import "Source/Classes/include/PINCachedAnimatedImage.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" @implementation PINAlternateRepresentationProvider diff --git a/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m b/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m index 5641d784..eb0548ea 100644 --- a/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m +++ b/Source/Classes/PINCache/PINCache+PINRemoteImageCaching.m @@ -6,7 +6,7 @@ // // -#import "PINCache+PINRemoteImageCaching.h" +#import "Source/Classes/include/PINCache+PINRemoteImageCaching.h" @implementation PINCache (PINRemoteImageCaching) diff --git a/Source/Classes/PINDisplayLink.h b/Source/Classes/PINDisplayLink.h index 0b43e7bf..36f9bc53 100644 --- a/Source/Classes/PINDisplayLink.h +++ b/Source/Classes/PINDisplayLink.h @@ -7,7 +7,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #define PINDisplayLink CADisplayLink diff --git a/Source/Classes/PINDisplayLink.m b/Source/Classes/PINDisplayLink.m index 8235265f..7193d47d 100644 --- a/Source/Classes/PINDisplayLink.m +++ b/Source/Classes/PINDisplayLink.m @@ -5,7 +5,7 @@ // Created by Garrett Moon on 4/23/18. // -#import "PINDisplayLink.h" +#import "Source/Classes/PINDisplayLink.h" #if PIN_TARGET_MAC @@ -41,7 +41,7 @@ static CVReturn displayLinkFired (CVDisplayLinkRef displayLink, @implementation PINDisplayLink { CVDisplayLinkRef _displayLinkRef; - + BOOL _paused; NSInteger _frameInterval; } @@ -108,7 +108,7 @@ - (void)setPaused:(BOOL)paused if (_paused == paused) { return; } - + _paused = paused; if (paused) { CVDisplayLinkStop(_displayLinkRef); diff --git a/Source/Classes/PINProgressiveImage.m b/Source/Classes/PINProgressiveImage.m index 8d530b98..8f2eeead 100644 --- a/Source/Classes/PINProgressiveImage.m +++ b/Source/Classes/PINProgressiveImage.m @@ -6,15 +6,15 @@ // // -#import "PINProgressiveImage.h" +#import "Source/Classes/include/PINProgressiveImage.h" #import #import -#import "PINRemoteImage.h" -#import "PINImage+DecodedImage.h" -#import "PINRemoteImageDownloadTask.h" -#import "PINSpeedRecorder.h" +#import "Source/Classes/include/PINRemoteImage.h" +#import "Source/Classes/Categories/PINImage+DecodedImage.h" +#import "Source/Classes/PINRemoteImageDownloadTask.h" +#import "Source/Classes/PINSpeedRecorder.h" @interface PINProgressiveImage () @@ -44,7 +44,7 @@ - (nonnull instancetype)initWithDataTask:(nonnull NSURLSessionDataTask *)dataTas { if (self = [super init]) { self.lock = [[PINRemoteLock alloc] initWithName:@"PINProgressiveImage"]; - + _dataTask = dataTask; _imageSource = CGImageSourceCreateIncremental(NULL);; self.size = CGSizeZero; @@ -123,7 +123,7 @@ - (CFTimeInterval)l_estimatedRemainingTime if (remainingBytes == 0) { return 0; } - + float bytesPerSecond = [[PINSpeedRecorder sharedRecorder] weightedAdjustedBytesPerSecondForHost:[_dataTask.currentRequest.URL host]]; if (bytesPerSecond == -1) { return MAXFLOAT; @@ -138,7 +138,7 @@ - (void)updateProgressiveImageWithData:(nonnull NSData *)data expectedNumberOfBy NSAssert(self.mutableData == nil, @"If we're resuming, data shouldn't be setup yet."); self.startingBytes = data.length; } - + if (self.mutableData == nil) { NSUInteger bytesToAlloc = 0; if (expectedNumberOfBytes > 0) { @@ -148,7 +148,7 @@ - (void)updateProgressiveImageWithData:(nonnull NSData *)data expectedNumberOfBy self.expectedNumberOfBytes = expectedNumberOfBytes; } [self.mutableData appendData:data]; - + while ([self l_hasCompletedFirstScan] == NO && self.scannedByte < self.mutableData.length) { #if DEBUG CFTimeInterval start = CACurrentMediaTime(); @@ -165,7 +165,7 @@ - (void)updateProgressiveImageWithData:(nonnull NSData *)data expectedNumberOfBy self.scanTime += total; #endif } - + if (self.imageSource) { CGImageSourceUpdateData(self.imageSource, (CFDataRef)self.mutableData, NO); } @@ -179,31 +179,31 @@ - (PINImage *)currentImageBlurred:(BOOL)blurred maxProgressiveRenderSize:(CGSize [self.lock unlock]; return nil; } - + if (self.currentThreshold == _progressThresholds.count) { [self.lock unlock]; return nil; } - + if (_estimatedRemainingTimeThreshold > 0 && [self l_estimatedRemainingTime] < _estimatedRemainingTimeThreshold) { [self.lock unlock]; return nil; } - + if ([self l_hasCompletedFirstScan] == NO) { [self.lock unlock]; return nil; } - + #if DEBUG if (self.scanTime > 0) { PINLog(@"scan time: %f", self.scanTime); self.scanTime = 0; } #endif - + PINImage *currentImage = nil; - + //Size information comes after JFIF so jpeg properties should be available at or before size? if (self.size.width <= 0 || self.size.height <= 0) { //attempt to get size info @@ -212,28 +212,28 @@ - (PINImage *)currentImageBlurred:(BOOL)blurred maxProgressiveRenderSize:(CGSize if (size.width <= 0 && imageProperties[(NSString *)kCGImagePropertyPixelWidth]) { size.width = [imageProperties[(NSString *)kCGImagePropertyPixelWidth] floatValue]; } - + if (size.height <= 0 && imageProperties[(NSString *)kCGImagePropertyPixelHeight]) { size.height = [imageProperties[(NSString *)kCGImagePropertyPixelHeight] floatValue]; } - + self.size = size; - + NSDictionary *jpegProperties = imageProperties[(NSString *)kCGImagePropertyJFIFDictionary]; NSNumber *isProgressive = jpegProperties[(NSString *)kCGImagePropertyJFIFIsProgressive]; self.isProgressiveJPEG = jpegProperties && [isProgressive boolValue]; } - + if (self.size.width > maxProgressiveRenderSize.width || self.size.height > maxProgressiveRenderSize.height) { [self.lock unlock]; return nil; } - + float progress = 0; if (self.expectedNumberOfBytes > 0) { progress = (float)self.mutableData.length / (float)self.expectedNumberOfBytes; } - + //Don't bother if we're basically done if (progress >= 0.99) { [self.lock unlock]; @@ -258,7 +258,7 @@ - (PINImage *)currentImageBlurred:(BOOL)blurred maxProgressiveRenderSize:(CGSize } } } - + [self.lock unlock]; return currentImage; } @@ -280,7 +280,7 @@ - (BOOL)l_scanForSOSinData:(NSData *)data startByte:(NSUInteger)startByte scanne //SOS marker scanMarker[0] = 0xFF; scanMarker[1] = 0xDA; - + //scan one byte back in case we only got half the SOS on the last data append NSRange scanRange; scanRange.location = startByte; @@ -311,7 +311,7 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog if (inputImageRef == nil) { return nil; } - + CGSize inputSize = inputImage.size; if (inputSize.width < 1 || inputSize.height < 1) { @@ -325,16 +325,16 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog // TODO: What scale factor should be used here? CGFloat imageScale = [[NSScreen mainScreen] backingScaleFactor]; #endif - + CGFloat radius = (inputImage.size.width / 25.0) * MAX(0, 1.0 - progress); radius *= imageScale; - + //we'll round the radius to a whole number below anyway, if (radius < FLT_EPSILON) { CGImageRelease(inputImageRef); return inputImage; } - + CGContextRef ctx; #if PIN_TARGET_IOS UIGraphicsBeginImageContextWithOptions(inputSize, YES, imageScale); @@ -342,19 +342,19 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog #elif PIN_TARGET_MAC ctx = CGBitmapContextCreate(0, inputSize.width, inputSize.height, 8, 0, [NSColorSpace genericRGBColorSpace].CGColorSpace, kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Little); #endif - + if (ctx) { #if PIN_TARGET_IOS CGContextScaleCTM(ctx, 1.0, -1.0); CGContextTranslateCTM(ctx, 0, -inputSize.height); #endif - + vImage_Buffer effectInBuffer; vImage_Buffer scratchBuffer; - + vImage_Buffer *inputBuffer; vImage_Buffer *outputBuffer; - + vImage_CGImageFormat format = { .bitsPerComponent = 8, .bitsPerPixel = 32, @@ -366,7 +366,7 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog .decode = NULL, .renderingIntent = kCGRenderingIntentDefault }; - + vImage_Error e = vImageBuffer_InitWithCGImage(&effectInBuffer, &format, NULL, inputImage.CGImage, kvImagePrintDiagnosticsToConsole); if (e == kvImageNoError) { @@ -374,7 +374,7 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog if (e == kvImageNoError) { inputBuffer = &effectInBuffer; outputBuffer = &scratchBuffer; - + // A description of how to compute the box kernel width from the Gaussian // radius (aka standard deviation) appears in the SVG spec: // http://www.w3.org/TR/SVG/filters.html#feGaussianBlurElement @@ -390,26 +390,26 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog if (radius - 2. < __FLT_EPSILON__) radius = 2.; uint32_t wholeRadius = floor((radius * 3. * sqrt(2 * M_PI) / 4 + 0.5) / 2); - + wholeRadius |= 1; // force wholeRadius to be odd so that the three box-blur methodology works. - + //calculate the size necessary for vImageBoxConvolve_ARGB8888, this does not actually do any operations. NSInteger tempBufferSize = vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, NULL, 0, 0, wholeRadius, wholeRadius, NULL, kvImageGetTempBufferSize | kvImageEdgeExtend); void *tempBuffer = malloc(tempBufferSize); - + if (tempBuffer) { //errors can be ignored because we've passed in allocated memory vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, tempBuffer, 0, 0, wholeRadius, wholeRadius, NULL, kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(outputBuffer, inputBuffer, tempBuffer, 0, 0, wholeRadius, wholeRadius, NULL, kvImageEdgeExtend); vImageBoxConvolve_ARGB8888(inputBuffer, outputBuffer, tempBuffer, 0, 0, wholeRadius, wholeRadius, NULL, kvImageEdgeExtend); - + free(tempBuffer); - + //switch input and output vImage_Buffer *temp = inputBuffer; inputBuffer = outputBuffer; outputBuffer = temp; - + CGImageRef effectCGImage = vImageCreateCGImageFromBuffer(inputBuffer, &format, &cleanupBuffer, NULL, kvImageNoAllocate, NULL); if (effectCGImage == NULL) { //if creating the cgimage failed, the cleanup buffer on input buffer will not be called, we must dealloc ourselves @@ -421,7 +421,7 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog CGContextRestoreGState(ctx); CGImageRelease(effectCGImage); } - + // Cleanup free(outputBuffer->data); #if PIN_TARGET_IOS @@ -431,7 +431,7 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog outputImage = [[NSImage alloc] initWithCGImage:outputImageRef size:inputSize]; CFRelease(outputImageRef); #endif - + } } else { if (scratchBuffer.data) { @@ -445,13 +445,13 @@ - (PINImage *)l_postProcessImage:(PINImage *)inputImage withProgress:(float)prog } } } - + #if PIN_TARGET_IOS UIGraphicsEndImageContext(); #endif CGImageRelease(inputImageRef); - + return outputImage; } diff --git a/Source/Classes/PINRemoteImageBasicCache.h b/Source/Classes/PINRemoteImageBasicCache.h index c669c3c3..1c59b125 100644 --- a/Source/Classes/PINRemoteImageBasicCache.h +++ b/Source/Classes/PINRemoteImageBasicCache.h @@ -7,7 +7,7 @@ // #import -#import "PINRemoteImageCaching.h" +#import "Source/Classes/include/PINRemoteImageCaching.h" /** * Simplistic wrapper based on NSCache. diff --git a/Source/Classes/PINRemoteImageBasicCache.m b/Source/Classes/PINRemoteImageBasicCache.m index a3953ce8..836e4eaa 100644 --- a/Source/Classes/PINRemoteImageBasicCache.m +++ b/Source/Classes/PINRemoteImageBasicCache.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageBasicCache.h" +#import "Source/Classes/PINRemoteImageBasicCache.h" @interface PINRemoteImageBasicCache() @property (nonatomic, strong) NSCache *cache; @@ -62,7 +62,7 @@ -(void)objectFromDiskForKey:(NSString *)key completion:(PINRemoteImageCachingObj -(void)setObjectOnDisk:(id)object forKey:(NSString *)key { - + } //****************************************************************************************************** diff --git a/Source/Classes/PINRemoteImageCallbacks.h b/Source/Classes/PINRemoteImageCallbacks.h index ebfbfc2d..8e6e09b1 100644 --- a/Source/Classes/PINRemoteImageCallbacks.h +++ b/Source/Classes/PINRemoteImageCallbacks.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @interface PINRemoteImageCallbacks : NSObject diff --git a/Source/Classes/PINRemoteImageCallbacks.m b/Source/Classes/PINRemoteImageCallbacks.m index f64795bc..cd42e66e 100644 --- a/Source/Classes/PINRemoteImageCallbacks.m +++ b/Source/Classes/PINRemoteImageCallbacks.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageCallbacks.h" +#import "Source/Classes/PINRemoteImageCallbacks.h" @implementation PINRemoteImageCallbacks diff --git a/Source/Classes/PINRemoteImageCategoryManager.m b/Source/Classes/PINRemoteImageCategoryManager.m index 54635d6c..8628be79 100644 --- a/Source/Classes/PINRemoteImageCategoryManager.m +++ b/Source/Classes/PINRemoteImageCategoryManager.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageCategoryManager.h" +#import "Source/Classes/include/PINRemoteImageCategoryManager.h" #import @@ -162,31 +162,31 @@ + (void)setImageOnView:(id )view }); return; } - + [self cancelImageDownloadOnView:view]; - + if (placeholderImage) { [view pin_setPlaceholderWithImage:placeholderImage]; } - + if (urls == nil || urls.count == 0) { if (!placeholderImage) { [view pin_clearImages]; } return; } - + PINRemoteImageManagerDownloadOptions options; if([view respondsToSelector:@selector(pin_defaultOptions)]) { options = [view pin_defaultOptions]; } else { options = PINRemoteImageManagerDownloadOptionsNone; } - + if ([view pin_ignoreGIFs]) { options |= PINRemoteImageManagerDisallowAlternateRepresentations; } - + PINRemoteImageManagerImageCompletion internalProgress = nil; if ([self updateWithProgressOnView:view] && processorKey.length <= 0 && processor == nil) { internalProgress = ^(PINRemoteImageManagerResult *result) @@ -211,7 +211,7 @@ + (void)setImageOnView:(id )view } }; } - + PINRemoteImageManagerImageCompletion internalCompletion = ^(PINRemoteImageManagerResult *result) { void (^mainQueue)(void) = ^{ @@ -227,9 +227,9 @@ + (void)setImageOnView:(id )view } return; } - + [view pin_updateUIWithRemoteImageManagerResult:result]; - + if (completion) { completion(result); } @@ -242,7 +242,7 @@ + (void)setImageOnView:(id )view }); } }; - + NSUUID *downloadImageOperationUUID = nil; if (urls.count > 1) { downloadImageOperationUUID = [[PINRemoteImageManager sharedImageManager] downloadImageWithURLs:urls @@ -261,7 +261,7 @@ + (void)setImageOnView:(id )view progressImage:internalProgress completion:internalCompletion]; } - + [self setDownloadImageOperationUUID:downloadImageOperationUUID onView:view]; } diff --git a/Source/Classes/PINRemoteImageDownloadQueue.h b/Source/Classes/PINRemoteImageDownloadQueue.h index 574a2800..8006f0f1 100644 --- a/Source/Classes/PINRemoteImageDownloadQueue.h +++ b/Source/Classes/PINRemoteImageDownloadQueue.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @class PINURLSessionManager; @@ -31,8 +31,8 @@ typedef void (^PINRemoteImageDownloadCompletion)(NSURLResponse * _Nullable respo /*** This prevents a task from being run if it hasn't already started yet. It is the caller's responsibility to cancel the task if it has already been started. - - @return BOOL Returns YES if the task was in the queue. + + @return BOOL Returns YES if the task was in the queue. */ - (BOOL)removeDownloadTaskFromQueue:(NSURLSessionDataTask *)downloadTask; diff --git a/Source/Classes/PINRemoteImageDownloadQueue.m b/Source/Classes/PINRemoteImageDownloadQueue.m index 07e70f2e..257d7047 100644 --- a/Source/Classes/PINRemoteImageDownloadQueue.m +++ b/Source/Classes/PINRemoteImageDownloadQueue.m @@ -6,15 +6,15 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINRemoteImageDownloadQueue.h" +#import "Source/Classes/PINRemoteImageDownloadQueue.h" -#import "PINURLSessionManager.h" -#import "PINRemoteLock.h" +#import "Source/Classes/include/PINURLSessionManager.h" +#import "Source/Classes/PINRemoteLock.h" @interface PINRemoteImageDownloadQueue () { PINRemoteLock *_lock; - + NSMutableOrderedSet *_highPriorityQueuedOperations; NSMutableOrderedSet *_defaultPriorityQueuedOperations; NSMutableOrderedSet *_lowPriorityQueuedOperations; @@ -59,7 +59,7 @@ - (void)setMaxNumberOfConcurrentDownloads:(NSUInteger)maxNumberOfConcurrentDownl [self lock]; _maxNumberOfConcurrentDownloads = maxNumberOfConcurrentDownloads; [self unlock]; - + [self scheduleDownloadsIfNeeded]; } @@ -98,15 +98,15 @@ - (void)scheduleDownloadsIfNeeded } else if (_lowPriorityQueuedOperations.count > 0) { queue = _lowPriorityQueuedOperations; } - + if (!queue) { break; } - + NSURLSessionDataTask *task = [queue firstObject]; [queue removeObjectAtIndex:0]; [task resume]; - + [_runningTasks addObject:task]; } [self unlock]; @@ -138,7 +138,7 @@ - (void)setQueuePriority:(PINRemoteImageManagerPriority)priority forTask:(NSURLS - (void)setQueuePriority:(PINRemoteImageManagerPriority)priority forTask:(NSURLSessionDataTask *)downloadTask addIfNecessary:(BOOL)addIfNecessary { BOOL containsTask = [self removeDownloadTaskFromQueue:downloadTask]; - + if (containsTask || addIfNecessary) { NSMutableOrderedSet *queue = nil; [self lock]; @@ -146,15 +146,15 @@ - (void)setQueuePriority:(PINRemoteImageManagerPriority)priority forTask:(NSURLS case PINRemoteImageManagerPriorityLow: queue = _lowPriorityQueuedOperations; break; - + case PINRemoteImageManagerPriorityDefault: queue = _defaultPriorityQueuedOperations; break; - + case PINRemoteImageManagerPriorityHigh: queue = _highPriorityQueuedOperations; break; - + default: NSAssert(NO, @"invalid priority: %tu", priority); break; diff --git a/Source/Classes/PINRemoteImageDownloadTask.h b/Source/Classes/PINRemoteImageDownloadTask.h index bcd434d4..e0df5ad4 100644 --- a/Source/Classes/PINRemoteImageDownloadTask.h +++ b/Source/Classes/PINRemoteImageDownloadTask.h @@ -9,13 +9,13 @@ #if SWIFT_PACKAGE @import PINOperation; #else -#import +#import "../_main~non_module_dependencies~PINOperation/Source/PINOperation.h" #endif #import "PINRemoteImageManager+Private.h" -#import "PINRemoteImageTask.h" -#import "PINProgressiveImage.h" -#import "PINResume.h" +#import "Source/Classes/PINRemoteImageTask.h" +#import "Source/Classes/include/PINProgressiveImage.h" +#import "Source/Classes/PINResume.h" @interface PINRemoteImageDownloadTask : PINRemoteImageTask diff --git a/Source/Classes/PINRemoteImageDownloadTask.m b/Source/Classes/PINRemoteImageDownloadTask.m index b1b261dc..f6f20166 100644 --- a/Source/Classes/PINRemoteImageDownloadTask.m +++ b/Source/Classes/PINRemoteImageDownloadTask.m @@ -6,13 +6,13 @@ // // -#import "PINRemoteImageDownloadTask.h" +#import "Source/Classes/PINRemoteImageDownloadTask.h" -#import "PINRemoteImageTask+Subclassing.h" -#import "PINRemoteImage.h" -#import "PINRemoteImageCallbacks.h" -#import "PINRemoteLock.h" -#import "PINSpeedRecorder.h" +#import "Source/Classes/Categories/PINRemoteImageTask+Subclassing.h" +#import "Source/Classes/include/PINRemoteImage.h" +#import "Source/Classes/PINRemoteImageCallbacks.h" +#import "Source/Classes/PINRemoteLock.h" +#import "Source/Classes/PINSpeedRecorder.h" @interface PINRemoteImageDownloadTask () { @@ -39,15 +39,15 @@ - (void)callProgressDownload #if PINRemoteImageLogging NSString *key = self.key; #endif - + __block int64_t completedBytes; __block int64_t totalBytes; - + [self.lock lockWithBlock:^{ completedBytes = self->_progressImage.dataTask.countOfBytesReceived; totalBytes = self->_progressImage.dataTask.countOfBytesExpectedToReceive; }]; - + [callbackBlocks enumerateKeysAndObjectsUsingBlock:^(NSUUID *UUID, PINRemoteImageCallbacks *callback, BOOL *stop) { PINRemoteImageManagerProgressDownload progressDownloadBlock = callback.progressDownloadBlock; if (progressDownloadBlock != nil) { @@ -66,8 +66,8 @@ - (void)callProgressImageWithImage:(nonnull PINImage *)image renderedImageQualit #if PINRemoteImageLogging NSString *key = self.key; #endif - - + + [callbackBlocks enumerateKeysAndObjectsUsingBlock:^(NSUUID *UUID, PINRemoteImageCallbacks *callback, BOOL *stop) { PINRemoteImageManagerImageCompletion progressImageBlock = callback.progressImageBlock; if (progressImageBlock != nil) { @@ -104,20 +104,20 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume return; } } - + noMoreCompletions = [super l_cancelWithUUID:UUID]; - + if (noMoreCompletions) { [self.manager.urlSessionTaskQueue removeDownloadTaskFromQueue:self->_progressImage.dataTask]; [self->_progressImage.dataTask cancel]; - + if (hasResume && self->_ifRange && self->_progressImage.dataTask.countOfBytesExpectedToReceive > 0 && self->_progressImage.dataTask.countOfBytesExpectedToReceive != NSURLSessionTransferSizeUnknown) { NSData *progressData = self->_progressImage.data; if (progressData.length > 0) { strongResume = [PINResume resumeData:progressData ifRange:self->_ifRange totalBytes:self->_progressImage.dataTask.countOfBytesExpectedToReceive]; } } - + PINLog(@"Canceling download of URL: %@, UUID: %@", _progressImage.dataTask.originalRequest.URL, UUID); } #if PINRemoteImageLogging @@ -126,11 +126,11 @@ - (BOOL)cancelWithUUID:(NSUUID *)UUID resume:(PINResume **)resume } #endif }]; - + if (hasResume) { *resume = strongResume; } - + return noMoreCompletions; } @@ -182,12 +182,12 @@ - (nonnull PINRemoteImageManagerResult *)imageResultWithImage:(nullable PINImage - (void)didReceiveData:(NSData *_Nonnull)data { [self callProgressDownload]; - + __block int64_t expectedNumberOfBytes; [self.lock lockWithBlock:^{ expectedNumberOfBytes = self->_progressImage.dataTask.countOfBytesExpectedToReceive; }]; - + [self updateData:data isResume:NO expectedBytes:expectedNumberOfBytes]; } @@ -204,9 +204,9 @@ - (void)updateData:(NSData *)data isResume:(BOOL)isResume expectedBytes:(int64_t } }]; }]; - + [progressImage updateProgressiveImageWithData:data expectedNumberOfBytes:expectedBytes isResume:isResume]; - + if (hasProgressBlocks) { if (PINNSOperationSupportsBlur) { [self.manager.concurrentOperationQueue scheduleOperation:^{ @@ -224,14 +224,14 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response { if ([response isKindOfClass:[NSHTTPURLResponse class]]) { NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response; - + // Got partial data back for a resume if (httpResponse.statusCode == 206) { __block PINResume *resume; [self.lock lockWithBlock:^{ resume = self->_resume; }]; - + [self updateData:resume.resumeData isResume:YES expectedBytes:resume.totalBytes]; } else { //Check if there's resume data and we didn't get back a 206, get rid of it @@ -239,12 +239,12 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response self->_resume = nil; }]; } - + // Check to see if the server supports resume if ([[httpResponse allHeaderFields][@"Accept-Ranges"] isEqualToString:@"bytes"]) { NSString *ifRange = nil; NSString *etag = nil; - + if ((etag = [httpResponse allHeaderFields][@"ETag"])) { if ([etag hasPrefix:@"W/"] == NO) { ifRange = etag; @@ -252,7 +252,7 @@ - (void)didReceiveResponse:(nonnull NSURLResponse *)response } else { ifRange = [httpResponse allHeaderFields][@"Last-Modified"]; } - + if (ifRange.length > 0) { [self.lock lockWithBlock:^{ self->_ifRange = ifRange; @@ -283,7 +283,7 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request return; } self->_resume = resume; - + NSURLRequest *adjustedRequest = request; if (self->_resume) { NSMutableURLRequest *mutableRequest = [request mutableCopy]; @@ -293,7 +293,7 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request mutableRequest.allHTTPHeaderFields = headers; adjustedRequest = mutableRequest; } - + self->_progressImage = [[PINProgressiveImage alloc] initWithDataTask:[self.manager.urlSessionTaskQueue addDownloadWithSessionManager:self.manager.sessionManager request:adjustedRequest priority:priority @@ -310,16 +310,16 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request PINLog(@"Finished downloading image: %@", request.URL); } #endif - + if (error.code != NSURLErrorCancelled) { NSData *data = self.progressImage.data; - + if (error == nil && data == nil) { error = [NSError errorWithDomain:PINRemoteImageManagerErrorDomain code:PINRemoteImageManagerErrorImageEmpty userInfo:nil]; } - + __block BOOL retry = NO; __block int64_t delay = 0; [self.lock lockWithBlock:^{ @@ -338,7 +338,7 @@ - (void)scheduleDownloadWithRequest:(NSURLRequest *)request }); return; } - + completionHandler(data, response, error); } }]; diff --git a/Source/Classes/PINRemoteImageManager+Private.h b/Source/Classes/PINRemoteImageManager+Private.h index 39550e32..29459684 100644 --- a/Source/Classes/PINRemoteImageManager+Private.h +++ b/Source/Classes/PINRemoteImageManager+Private.h @@ -9,7 +9,7 @@ #ifndef PINRemoteImageManager_Private_h #define PINRemoteImageManager_Private_h -#import "PINRemoteImageDownloadQueue.h" +#import "Source/Classes/PINRemoteImageDownloadQueue.h" typedef void (^PINRemoteImageManagerDataCompletion)(NSData *data, NSURLResponse *response, NSError *error); diff --git a/Source/Classes/PINRemoteImageManager.m b/Source/Classes/PINRemoteImageManager.m index 5ef8ac17..19315e8d 100644 --- a/Source/Classes/PINRemoteImageManager.m +++ b/Source/Classes/PINRemoteImageManager.m @@ -6,46 +6,45 @@ // // -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" #import #if SWIFT_PACKAGE @import PINOperation; #else -#import +#import "../_main~non_module_dependencies~PINOperation/Source/PINOperation.h" #endif #import -#import "PINAlternateRepresentationProvider.h" -#import "PINRemoteImage.h" -#import "PINRemoteImageManagerConfiguration.h" -#import "PINRemoteLock.h" -#import "PINProgressiveImage.h" -#import "PINRemoteImageCallbacks.h" -#import "PINRemoteImageTask.h" -#import "PINRemoteImageProcessorTask.h" -#import "PINRemoteImageDownloadTask.h" -#import "PINResume.h" -#import "PINRemoteImageMemoryContainer.h" -#import "PINRemoteImageCaching.h" -#import "PINRequestRetryStrategy.h" -#import "PINRemoteImageDownloadQueue.h" -#import "PINRequestRetryStrategy.h" -#import "PINSpeedRecorder.h" -#import "PINURLSessionManager.h" - -#import "NSData+ImageDetectors.h" -#import "PINImage+DecodedImage.h" -#import "PINImage+ScaledImage.h" -#import "PINRemoteImageManager+Private.h" -#import "NSHTTPURLResponse+MaxAge.h" +#import "Source/Classes/include/PINAlternateRepresentationProvider.h" +#import "Source/Classes/include/PINRemoteImage.h" +#import "Source/Classes/PINRemoteImageManagerConfiguration.h" +#import "Source/Classes/PINRemoteLock.h" +#import "Source/Classes/include/PINProgressiveImage.h" +#import "Source/Classes/PINRemoteImageCallbacks.h" +#import "Source/Classes/PINRemoteImageTask.h" +#import "Source/Classes/PINRemoteImageProcessorTask.h" +#import "Source/Classes/PINRemoteImageDownloadTask.h" +#import "Source/Classes/PINResume.h" +#import "Source/Classes/PINRemoteImageMemoryContainer.h" +#import "Source/Classes/include/PINRemoteImageCaching.h" +#import "Source/Classes/include/PINRequestRetryStrategy.h" +#import "Source/Classes/PINRemoteImageDownloadQueue.h" +#import "Source/Classes/PINSpeedRecorder.h" +#import "Source/Classes/include/PINURLSessionManager.h" + +#import "Source/Classes/include/NSData+ImageDetectors.h" +#import "Source/Classes/Categories/PINImage+DecodedImage.h" +#import "Source/Classes/Categories/PINImage+ScaledImage.h" +#import "Source/Classes/PINRemoteImageManager+Private.h" +#import "Source/Classes/Categories/NSHTTPURLResponse+MaxAge.h" #if USE_PINCACHE -#import "PINCache+PINRemoteImageCaching.h" +#import "Source/Classes/include/PINCache+PINRemoteImageCaching.h" #else -#import "PINRemoteImageBasicCache.h" +#import "Source/Classes/include/PINRemoteImageBasicCache.h" #endif @@ -60,11 +59,11 @@ PINOperationQueuePriority operationPriorityWithImageManagerPriority(PINRemoteIma case PINRemoteImageManagerPriorityLow: return PINOperationQueuePriorityLow; break; - + case PINRemoteImageManagerPriorityDefault: return PINOperationQueuePriorityDefault; break; - + case PINRemoteImageManagerPriorityHigh: return PINOperationQueuePriorityHigh; break; @@ -76,11 +75,11 @@ float dataTaskPriorityWithImageManagerPriority(PINRemoteImageManagerPriority pri case PINRemoteImageManagerPriorityLow: return 0.0; break; - + case PINRemoteImageManagerPriorityDefault: return 0.5; break; - + case PINRemoteImageManagerPriorityHigh: return 1.0; break; @@ -128,7 +127,7 @@ @interface PINRemoteImageManager () PINRemoteLock *_lock; PINOperationQueue *_concurrentOperationQueue; PINRemoteImageDownloadQueue *_urlSessionTaskQueue; - + // Necessary to have a strong reference to _defaultAlternateRepresentationProvider because _alternateRepProvider is __weak PINAlternateRepresentationProvider *_defaultAlternateRepresentationProvider; __weak PINAlternateRepresentationProvider *_alternateRepProvider; @@ -219,7 +218,7 @@ -(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration * if (!configuration) { configuration = [[PINRemoteImageManagerConfiguration alloc] init]; } - + if (imageCache) { self.cache = imageCache; } else if (PINRemoteImageManagerSubclassOverridesSelector([self class], @selector(defaultImageCache))) { @@ -230,7 +229,7 @@ -(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration * } else { self.cache = [[self class] defaultImageCache]; } - + if ([self.cache respondsToSelector:@selector(setObjectOnDisk:forKey:withAgeLimit:)] && [self.cache respondsToSelector:@selector(setObjectInMemory:forKey:withCost:withAgeLimit:)] && [self.cache respondsToSelector:@selector(diskCacheIsTTLCache)] && @@ -238,7 +237,7 @@ -(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration * _diskCacheTTLIsEnabled = [self.cache diskCacheIsTTLCache]; _memoryCacheTTLIsEnabled = [self.cache memoryCacheIsTTLCache]; } - + _sessionConfiguration = [sessionConfiguration copy]; if (!_sessionConfiguration) { _sessionConfiguration = [NSURLSessionConfiguration ephemeralSessionConfiguration]; @@ -247,18 +246,18 @@ -(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration * _sessionConfiguration.URLCache = nil; _sessionConfiguration.HTTPMaximumConnectionsPerHost = PINRemoteImageHTTPMaximumConnectionsPerHost; } - + _callbackQueue = dispatch_queue_create("PINRemoteImageManagerCallbackQueue", DISPATCH_QUEUE_CONCURRENT); _lock = [[PINRemoteLock alloc] initWithName:@"PINRemoteImageManager"]; - + _concurrentOperationQueue = [[PINOperationQueue alloc] initWithMaxConcurrentOperations: configuration.maxConcurrentOperations]; _urlSessionTaskQueue = [PINRemoteImageDownloadQueue queueWithMaxConcurrentDownloads:configuration.maxConcurrentDownloads]; - + self.sessionManager = [[PINURLSessionManager alloc] initWithSessionConfiguration:_sessionConfiguration]; self.sessionManager.delegate = self; - + self.estimatedRemainingTimeThreshold = configuration.estimatedRemainingTimeThreshold; - + _highQualityBPSThreshold = configuration.highQualityBPSThreshold; _lowQualityBPSThreshold = configuration.lowQualityBPSThreshold; _shouldUpgradeLowQualityImages = configuration.shouldUpgradeLowQualityImages; @@ -267,7 +266,7 @@ -(nonnull instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration * self.tasks = [[NSMutableDictionary alloc] init]; self.canceledTasks = [[NSHashTable alloc] initWithOptions:NSHashTableWeakMemory capacity:5]; self.UUIDToTask = [NSMapTable weakToWeakObjectsMapTable]; - + if (alternateRepProvider == nil) { _defaultAlternateRepresentationProvider = [[PINAlternateRepresentationProvider alloc] init]; alternateRepProvider = _defaultAlternateRepresentationProvider; @@ -310,9 +309,9 @@ - (void)dealloc NSString * const kPINRemoteImageDiskCacheVersionKey = @"kPINRemoteImageDiskCacheVersionKey"; const NSInteger kPINRemoteImageDiskCacheVersion = 1; NSUserDefaults *pinDefaults = [[NSUserDefaults alloc] init]; - + NSString *cacheURLRoot = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) objectAtIndex:0]; - + if ([pinDefaults integerForKey:kPINRemoteImageDiskCacheVersionKey] != kPINRemoteImageDiskCacheVersion) { //remove the old version of the disk cache NSURL *diskCacheURL = [PINDiskCache cacheURLWithRootPath:cacheURLRoot prefix:PINDiskCachePrefix name:kPINRemoteImageDiskCacheName]; @@ -654,21 +653,21 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url inputUUID:(NSUUID *)UUID { NSAssert((processor != nil && processorKey.length > 0) || (processor == nil && processorKey == nil), @"processor must not be nil and processorKey length must be greater than zero OR processor must be nil and processorKey must be nil"); - + Class taskClass; if (processor && processorKey.length > 0) { taskClass = [PINRemoteImageProcessorTask class]; } else { taskClass = [PINRemoteImageDownloadTask class]; } - + NSString *key = [self cacheKeyForURL:url processorKey:processorKey]; if (url == nil) { [self earlyReturnWithOptions:options url:nil key:key object:nil completion:completion]; return nil; } - + NSAssert([url isKindOfClass:[NSURL class]], @"url must be of type NSURL, if it's an NSString, we'll try to correct"); if ([url isKindOfClass:[NSString class]]) { url = [NSURL URLWithString:(NSString *)url]; @@ -688,7 +687,7 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url } } } - + if ([url.scheme isEqualToString:@"data"]) { NSData *data = [NSData dataWithContentsOfURL:url]; if (data) { @@ -697,7 +696,7 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url } } } - + [_concurrentOperationQueue scheduleOperation:^ { [self lock]; @@ -707,7 +706,7 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url [self unlock]; return; } - + PINRemoteImageTask *task = [self.tasks objectForKey:key]; BOOL taskExisted = NO; if (task == nil) { @@ -722,10 +721,10 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url [self.tasks setObject:task forKey:key]; // Relax :), task retain the UUID for us, it's ok to have a weak reference to UUID here. [self.UUIDToTask setObject:task forKey:UUID]; - + NSAssert(taskClass == [task class], @"Task class should be the same!"); [self unlock]; - + if (taskExisted == NO) { [self.concurrentOperationQueue scheduleOperation:^ { @@ -742,7 +741,7 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url [self.tasks removeObjectForKey:key]; } [self unlock]; - + //Skip early check [self downloadImageWithURL:url options:options | PINRemoteImageManagerDownloadOptionsSkipEarlyCheck @@ -777,7 +776,7 @@ - (NSUUID *)downloadImageWithURL:(NSURL *)url } withPriority:operationPriorityWithImageManagerPriority(priority)]; } } withPriority:operationPriorityWithImageManagerPriority(priority)]; - + return UUID; } @@ -796,7 +795,7 @@ - (void)downloadImageWithURL:(NSURL *)url [self unlock]; return; } - + __weak typeof(self) weakSelf = self; NSUUID *downloadTaskUUID = [self downloadImageWithURL:url options:options | PINRemoteImageManagerDownloadOptionsSkipEarlyCheck @@ -816,14 +815,14 @@ - (void)downloadImageWithURL:(NSURL *)url if (result.image && error == nil) { //If completionBlocks.count == 0, we've canceled before we were even able to start. PINImage *image = processor(result, &processCost); - + if (image == nil) { error = [NSError errorWithDomain:PINRemoteImageManagerErrorDomain code:PINRemoteImageManagerErrorFailedToProcessImage userInfo:nil]; } [strongSelf callCompletionsWithKey:key image:image alternativeRepresentation:nil cached:NO response:result.response error:error finalized:NO]; - + if (error == nil && image != nil) { BOOL saveAsJPEG = (options & PINRemoteImageManagerSaveProcessedImageAsJPEG) != 0; NSData *diskData = nil; @@ -832,10 +831,10 @@ - (void)downloadImageWithURL:(NSURL *)url } else { diskData = PINImagePNGRepresentation(image); } - + [strongSelf materializeAndCacheObject:image cacheInDisk:diskData additionalCost:processCost url:url key:key options:options outImage:nil outAltRep:nil]; } - + [strongSelf callCompletionsWithKey:key image:image alternativeRepresentation:nil cached:NO response:result.response error:error finalized:YES]; } else { if (error == nil) { @@ -864,11 +863,11 @@ - (void)downloadImageWithURL:(NSURL *)url resume = [self.cache objectFromDiskForKey:resumeKey]; [self.cache removeObjectForKey:resumeKey completion:nil]; } - + [self lock]; PINRemoteImageDownloadTask *task = [self.tasks objectForKey:key]; [self unlock]; - + [task scheduleDownloadWithRequest:[self requestWithURL:url task:task] resume:resume skipRetry:(options & PINRemoteImageManagerDownloadOptionsSkipRetry) @@ -910,17 +909,17 @@ -(BOOL)insertImageDataIntoCache:(nonnull NSData*)data processorKey:(nullable NSString *)processorKey additionalCost:(NSUInteger)additionalCost { - + if (url != nil) { NSString *key = [self cacheKeyForURL:url processorKey:processorKey]; - + PINRemoteImageManagerDownloadOptions options = PINRemoteImageManagerDownloadOptionsSkipDecode | PINRemoteImageManagerDownloadOptionsSkipEarlyCheck; PINRemoteImageMemoryContainer *container = [[PINRemoteImageMemoryContainer alloc] init]; container.data = data; - + return [self materializeAndCacheObject:container cacheInDisk:data additionalCost:additionalCost url:url key:key options:options outImage: nil outAltRep: nil]; } - + return NO; } @@ -936,7 +935,7 @@ - (BOOL)earlyReturnWithOptions:(PINRemoteImageManagerDownloadOptions)options url resultType = PINRemoteImageResultTypeMemoryCache; [self materializeAndCacheObject:object url:url key:key options:options outImage:&image outAltRep:&alternativeRepresentation]; } - + if (completion && ((image || alternativeRepresentation) || (url == nil))) { //If we're on the main thread, special case to call completion immediately NSError *error = nil; @@ -969,18 +968,18 @@ - (NSURLRequest *)requestWithURL:(NSURL *)url task:(PINRemoteImageTask *)task NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; NSMutableDictionary *headers = [self.httpHeaderFields mutableCopy]; - + if (headers.count > 0) { request.allHTTPHeaderFields = headers; } - + if (_requestConfigurationHandler) { request = [_requestConfigurationHandler(request) mutableCopy]; } - + PINRemoteImageWeakTask *weakTask = [[PINRemoteImageWeakTask alloc] initWithTask:task]; [NSURLProtocol setProperty:weakTask forKey:PINRemoteImageWeakTaskKey inRequest:request]; - + return request; } @@ -1070,12 +1069,12 @@ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID storeResumeData:(BOOL)storeRes //there's no need to ever remove a UUID from canceledTasks because it is weak. [self.canceledTasks addObject:UUID]; } - + if ([taskToEvaluate cancelWithUUID:UUID resume:storeResumeData ? &resume : NULL]) { [self.tasks removeObjectForKey:taskToEvaluate.key]; } [self unlock]; - + if (resume) { //store resume data away, only download tasks currently return resume data [self storeResumeData:resume forURL:[(PINRemoteImageDownloadTask *)taskToEvaluate URL]]; @@ -1120,7 +1119,7 @@ - (void)setProgressImageCallback:(nullable PINRemoteImageManagerImageCompletion) if (UUID == nil) { return; } - + PINLog(@"setting progress block of UUID: %@ progressBlock: %@", UUID, progressImageCallback); [_concurrentOperationQueue scheduleOperation:^{ [self lock]; @@ -1171,7 +1170,7 @@ - (void)imageFromCacheWithURL:(NSURL *)url completion:(PINRemoteImageManagerImageCompletion)completion { CFTimeInterval requestTime = CACurrentMediaTime(); - + if ((PINRemoteImageManagerDownloadOptionsSkipEarlyCheck & options) == NO && [NSThread isMainThread]) { PINRemoteImageManagerResult *result = [self synchronousImageFromCacheWithURL:url processorKey:processorKey cacheKey:cacheKey options:options]; if (result.image && result.error == nil) { @@ -1179,7 +1178,7 @@ - (void)imageFromCacheWithURL:(NSURL *)url return; } } - + [self objectForURL:url processorKey:processorKey key:cacheKey options:options completion:^(BOOL found, BOOL valid, PINImage *image, id alternativeRepresentation) { NSError *error = nil; if (valid == NO) { @@ -1187,7 +1186,7 @@ - (void)imageFromCacheWithURL:(NSURL *)url code:PINRemoteImageManagerErrorInvalidItemInCache userInfo:nil]; } - + dispatch_async(self.callbackQueue, ^{ completion([PINRemoteImageManagerResult imageResultWithImage:image alternativeRepresentation:alternativeRepresentation @@ -1213,13 +1212,13 @@ - (nonnull PINRemoteImageManagerResult *)synchronousImageFromCacheWithURL:(NSURL - (PINRemoteImageManagerResult *)synchronousImageFromCacheWithURL:(NSURL *)url processorKey:(NSString *)processorKey cacheKey:(NSString *)cacheKey options:(PINRemoteImageManagerDownloadOptions)options { CFTimeInterval requestTime = CACurrentMediaTime(); - + if (cacheKey == nil && url == nil) { return nil; } - + cacheKey = cacheKey ?: [self cacheKeyForURL:url processorKey:processorKey]; - + id object = [self.cache objectFromMemoryForKey:cacheKey]; PINImage *image; id alternativeRepresentation; @@ -1232,7 +1231,7 @@ - (PINRemoteImageManagerResult *)synchronousImageFromCacheWithURL:(NSURL *)url p code:PINRemoteImageManagerErrorInvalidItemInCache userInfo:nil]; } - + return [PINRemoteImageManagerResult imageResultWithImage:image alternativeRepresentation:alternativeRepresentation requestLength:CACurrentMediaTime() - requestTime @@ -1315,10 +1314,10 @@ - (nullable NSUUID *)downloadImageWithURLs:(nonnull NSArray *)urls inputUUID:UUID]; return UUID; } - + [self.concurrentOperationQueue scheduleOperation:^{ __block NSInteger highestQualityDownloadedIdx = -1; - + //check for the highest quality image already in cache. It's possible that an image is in the process of being //cached when this is being run. In which case two things could happen: // - If network conditions dictate that a lower quality image should be downloaded than the one that is currently @@ -1330,39 +1329,39 @@ - (nullable NSUUID *)downloadImageWithURLs:(nonnull NSArray *)urls [urls enumerateObjectsWithOptions:NSEnumerationReverse usingBlock:^(NSURL *url, NSUInteger idx, BOOL *stop) { NSAssert([url isKindOfClass:[NSURL class]], @"url must be of type URL"); NSString *cacheKey = [self cacheKeyForURL:url processorKey:nil]; - + //we don't actually need the object, just need to know it exists so that we can request it later BOOL hasObject = [self.cache objectExistsForKey:cacheKey]; - + if (hasObject) { highestQualityDownloadedIdx = idx; *stop = YES; } }]; - + [self lock]; float highQualityQPSThreshold = [self highQualityBPSThreshold]; float lowQualityQPSThreshold = [self lowQualityBPSThreshold]; BOOL shouldUpgradeLowQualityImages = [self shouldUpgradeLowQualityImages]; [self unlock]; - + NSUInteger desiredImageURLIdx = [PINSpeedRecorder appropriateImageIdxForURLsGivenHistoricalNetworkConditions:urls lowQualityQPSThreshold:lowQualityQPSThreshold highQualityQPSThreshold:highQualityQPSThreshold]; - + NSUInteger downloadIdx; //if the highest quality already downloaded is less than what currentBPS would dictate and shouldUpgrade is //set, download the new higher quality image. If no image has been cached, download the image dictated by //current bps - + if ((highestQualityDownloadedIdx < desiredImageURLIdx && shouldUpgradeLowQualityImages) || highestQualityDownloadedIdx == -1) { downloadIdx = desiredImageURLIdx; } else { downloadIdx = highestQualityDownloadedIdx; } - + NSURL *downloadURL = [urls objectAtIndex:downloadIdx]; - + [self downloadImageWithURL:downloadURL options:options priority:PINRemoteImageManagerPriorityDefault @@ -1375,7 +1374,7 @@ - (nullable NSUUID *)downloadImageWithURLs:(nonnull NSArray *)urls for (NSInteger idx = downloadIdx - 1; idx >= 0; idx--) { [[self cache] removeObjectForKey:[self cacheKeyForURL:[urls objectAtIndex:idx] processorKey:nil]]; } - + if (completion) { completion(result); } @@ -1430,7 +1429,7 @@ - (BOOL)materializeAndCacheObject:(id)object __block PINImage *image = nil; __block NSData *data = nil; __block BOOL updateMemoryCache = NO; - + PINRemoteImageMemoryContainer *container = nil; if ([object isKindOfClass:[PINRemoteImageMemoryContainer class]]) { container = (PINRemoteImageMemoryContainer *)object; @@ -1439,10 +1438,10 @@ - (BOOL)materializeAndCacheObject:(id)object }]; } else { updateMemoryCache = YES; - + // don't need to lock the container here because we just init it. container = [[PINRemoteImageMemoryContainer alloc] init]; - + if ([object isKindOfClass:[PINImage class]]) { data = diskData; container.image = (PINImage *)object; @@ -1454,14 +1453,14 @@ - (BOOL)materializeAndCacheObject:(id)object data = nil; container = nil; } - + container.data = data; } - + if (alternateRepresentationsAllowed) { alternateRepresentation = [_alternateRepProvider alternateRepresentationWithData:data options:options]; } - + if (alternateRepresentation == nil) { //we need the image [container.lock lockWithBlock:^{ @@ -1469,11 +1468,11 @@ - (BOOL)materializeAndCacheObject:(id)object }]; if (image == nil && container.data) { image = [PINImage pin_decodedImageWithData:container.data skipDecodeIfPossible:skipDecode]; - + if (url != nil) { image = [PINImage pin_scaledImageForImage:image withKey:key]; } - + if (skipDecode == NO) { [container.lock lockWithBlock:^{ updateMemoryCache = YES; @@ -1496,7 +1495,7 @@ - (BOOL)materializeAndCacheObject:(id)object NSUInteger cacheCost = additionalCost; cacheCost += [container.data length]; CGImageRef imageRef = container.image.CGImage; - NSAssert(container.image == nil || imageRef != NULL, @"We only cache a decompressed image if we decompressed it ourselves. In that case, it should be backed by a CGImageRef."); +// NSAssert(container.image == nil || imageRef != NULL, @"We only cache a decompressed image if we decompressed it ourselves. In that case, it should be backed by a CGImageRef."); if (imageRef) { cacheCost += CGImageGetHeight(imageRef) * CGImageGetBytesPerRow(imageRef); } @@ -1517,15 +1516,15 @@ - (BOOL)materializeAndCacheObject:(id)object } } } - + if (outImage) { *outImage = image; } - + if (outAlternateRepresentation) { *outAlternateRepresentation = alternateRepresentation; } - + if (image == nil && alternateRepresentation == nil) { PINLog(@"Invalid item in cache"); [self.cache removeObjectForKey:key completion:nil]; @@ -1587,12 +1586,12 @@ - (void)objectForURL:(NSURL *)url processorKey:(NSString *)processorKey key:(NSS completion(NO, YES, nil, nil); return; } - + if (key == nil && url == nil) { completion(NO, YES, nil, nil); return; } - + key = key ?: [self cacheKeyForURL:url processorKey:processorKey]; void (^materialize)(id object) = ^(id object) { @@ -1604,10 +1603,10 @@ - (void)objectForURL:(NSURL *)url processorKey:(NSString *)processorKey key:(NSS options:options outImage:&image outAltRep:&alternativeRepresentation]; - + completion(YES, valid, image, alternativeRepresentation); }; - + PINRemoteImageMemoryContainer *container = [self.cache objectFromMemoryForKey:key]; if (container) { materialize(container); diff --git a/Source/Classes/PINRemoteImageManagerConfiguration.h b/Source/Classes/PINRemoteImageManagerConfiguration.h index b1509038..4e3f1aca 100644 --- a/Source/Classes/PINRemoteImageManagerConfiguration.h +++ b/Source/Classes/PINRemoteImageManagerConfiguration.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import diff --git a/Source/Classes/PINRemoteImageManagerConfiguration.m b/Source/Classes/PINRemoteImageManagerConfiguration.m index ecdad946..9469004a 100644 --- a/Source/Classes/PINRemoteImageManagerConfiguration.m +++ b/Source/Classes/PINRemoteImageManagerConfiguration.m @@ -6,9 +6,9 @@ // // -#import "PINRemoteImageManagerConfiguration.h" +#import "Source/Classes/PINRemoteImageManagerConfiguration.h" -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @implementation PINRemoteImageManagerConfiguration diff --git a/Source/Classes/PINRemoteImageManagerResult.m b/Source/Classes/PINRemoteImageManagerResult.m index 8076abd5..28f560ef 100644 --- a/Source/Classes/PINRemoteImageManagerResult.m +++ b/Source/Classes/PINRemoteImageManagerResult.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageManagerResult.h" +#import "Source/Classes/include/PINRemoteImageManagerResult.h" @implementation PINRemoteImageManagerResult diff --git a/Source/Classes/PINRemoteImageMemoryContainer.h b/Source/Classes/PINRemoteImageMemoryContainer.h index 2d1d62bf..8bf4bc64 100644 --- a/Source/Classes/PINRemoteImageMemoryContainer.h +++ b/Source/Classes/PINRemoteImageMemoryContainer.h @@ -8,8 +8,8 @@ #import -#import "PINRemoteImageMacros.h" -#import "PINRemoteLock.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" +#import "Source/Classes/PINRemoteLock.h" @class PINImage; diff --git a/Source/Classes/PINRemoteImageMemoryContainer.m b/Source/Classes/PINRemoteImageMemoryContainer.m index 3da6b27a..4bfb7b19 100644 --- a/Source/Classes/PINRemoteImageMemoryContainer.m +++ b/Source/Classes/PINRemoteImageMemoryContainer.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageMemoryContainer.h" +#import "Source/Classes/PINRemoteImageMemoryContainer.h" @implementation PINRemoteImageMemoryContainer diff --git a/Source/Classes/PINRemoteImageProcessorTask.h b/Source/Classes/PINRemoteImageProcessorTask.h index a36fe3ac..6497d306 100644 --- a/Source/Classes/PINRemoteImageProcessorTask.h +++ b/Source/Classes/PINRemoteImageProcessorTask.h @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageTask.h" +#import "Source/Classes/PINRemoteImageTask.h" @interface PINRemoteImageProcessorTask : PINRemoteImageTask diff --git a/Source/Classes/PINRemoteImageProcessorTask.m b/Source/Classes/PINRemoteImageProcessorTask.m index 2f950227..adda42f9 100644 --- a/Source/Classes/PINRemoteImageProcessorTask.m +++ b/Source/Classes/PINRemoteImageProcessorTask.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageProcessorTask.h" +#import "Source/Classes/PINRemoteImageProcessorTask.h" @implementation PINRemoteImageProcessorTask diff --git a/Source/Classes/PINRemoteImageTask.h b/Source/Classes/PINRemoteImageTask.h index 8026bfdf..c167dbad 100644 --- a/Source/Classes/PINRemoteImageTask.h +++ b/Source/Classes/PINRemoteImageTask.h @@ -11,14 +11,14 @@ #if SWIFT_PACKAGE @import PINOperation; #else -#import +#import "../_main~non_module_dependencies~PINOperation/Source/PINOperation.h" #endif -#import "PINRemoteImageCallbacks.h" -#import "PINRemoteImageManager.h" -#import "PINRemoteImageMacros.h" -#import "PINRemoteLock.h" -#import "PINResume.h" +#import "Source/Classes/PINRemoteImageCallbacks.h" +#import "Source/Classes/include/PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" +#import "Source/Classes/PINRemoteLock.h" +#import "Source/Classes/PINResume.h" @interface PINRemoteImageTask : NSObject diff --git a/Source/Classes/PINRemoteImageTask.m b/Source/Classes/PINRemoteImageTask.m index 043a6280..079353a3 100644 --- a/Source/Classes/PINRemoteImageTask.m +++ b/Source/Classes/PINRemoteImageTask.m @@ -6,9 +6,9 @@ // // -#import "PINRemoteImageTask.h" +#import "Source/Classes/PINRemoteImageTask.h" -#import "PINRemoteImageCallbacks.h" +#import "Source/Classes/PINRemoteImageCallbacks.h" #import "PINRemoteImageManager+Private.h" @interface PINRemoteImageTask () @@ -46,7 +46,7 @@ - (void)addCallbacksWithCompletionBlock:(PINRemoteImageManagerImageCompletion)co completion.completionBlock = completionBlock; completion.progressImageBlock = progressImageBlock; completion.progressDownloadBlock = progressDownloadBlock; - + [self.lock lockWithBlock:^{ [self->_callbackBlocks setObject:completion forKey:UUID]; }]; @@ -87,7 +87,7 @@ - (void)callCompletionsWithImage:(PINImage *)image if (completionBlock != nil) { PINLog(@"calling completion for UUID: %@ key: %@", UUID, strongSelf.key); CFTimeInterval requestTime = callback.requestTime; - + dispatch_async(self.manager.callbackQueue, ^ { PINRemoteImageResultType result; @@ -132,7 +132,7 @@ - (BOOL)l_cancelWithUUID:(NSUUID *)UUID - (void)setPriority:(PINRemoteImageManagerPriority)priority { - + } - (nonnull PINRemoteImageManagerResult *)imageResultWithImage:(nullable PINImage *)image diff --git a/Source/Classes/PINRemoteLock.m b/Source/Classes/PINRemoteLock.m index 6cf74d62..1afb6663 100644 --- a/Source/Classes/PINRemoteLock.m +++ b/Source/Classes/PINRemoteLock.m @@ -6,7 +6,7 @@ // // -#import "PINRemoteLock.h" +#import "Source/Classes/PINRemoteLock.h" #import @@ -42,14 +42,14 @@ - (instancetype)initWithName:(NSString *)lockName lockType:(PINRemoteLockType)lo } else { _recursiveLock = [[NSRecursiveLock alloc] init]; } - + if (lockName) { [_lock setName:lockName]; [_recursiveLock setName:lockName]; } #else pthread_mutexattr_t attr; - + pthread_mutexattr_init(&attr); if (lockType == PINRemoteLockTypeRecursive) { pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); diff --git a/Source/Classes/PINRemoteWeakProxy.m b/Source/Classes/PINRemoteWeakProxy.m index a7049328..2aa0507f 100644 --- a/Source/Classes/PINRemoteWeakProxy.m +++ b/Source/Classes/PINRemoteWeakProxy.m @@ -6,7 +6,7 @@ // Copyright © 2018 Pinterest. All rights reserved. // -#import "PINRemoteWeakProxy.h" +#import "Source/Classes/PINRemoteWeakProxy.h" @interface PINRemoteWeakProxy () { diff --git a/Source/Classes/PINRequestRetryStrategy.m b/Source/Classes/PINRequestRetryStrategy.m index 92d6ecf5..086d0841 100644 --- a/Source/Classes/PINRequestRetryStrategy.m +++ b/Source/Classes/PINRequestRetryStrategy.m @@ -6,9 +6,9 @@ // // -#import "PINRequestRetryStrategy.h" -#import "PINURLSessionManager.h" -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRequestRetryStrategy.h" +#import "Source/Classes/include/PINURLSessionManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @interface PINRequestExponentialRetryStrategy () diff --git a/Source/Classes/PINResume.m b/Source/Classes/PINResume.m index cfcbd165..a231e00e 100644 --- a/Source/Classes/PINResume.m +++ b/Source/Classes/PINResume.m @@ -6,7 +6,7 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINResume.h" +#import "Source/Classes/PINResume.h" @implementation PINResume diff --git a/Source/Classes/PINSpeedRecorder.m b/Source/Classes/PINSpeedRecorder.m index 8e02fb26..a7ae18c3 100644 --- a/Source/Classes/PINSpeedRecorder.m +++ b/Source/Classes/PINSpeedRecorder.m @@ -6,12 +6,12 @@ // Copyright © 2017 Pinterest. All rights reserved. // -#import "PINSpeedRecorder.h" +#import "Source/Classes/PINSpeedRecorder.h" #import #import -#import "PINRemoteLock.h" +#import "Source/Classes/PINRemoteLock.h" @interface PINSpeedMeasurement : NSObject @@ -47,7 +47,7 @@ + (PINSpeedRecorder *)sharedRecorder dispatch_once(&onceToken, ^{ sharedRecorder = [[self alloc] init]; }); - + return sharedRecorder; } @@ -57,7 +57,7 @@ - (instancetype)init _lock = [[PINRemoteLock alloc] initWithName:@"PINSpeedRecorder lock"]; _speedMeasurements = [[NSCache alloc] init]; _speedMeasurements.countLimit = 25; - + struct sockaddr_in zeroAddress; bzero(&zeroAddress, sizeof(zeroAddress)); zeroAddress.sin_len = sizeof(zeroAddress); @@ -73,22 +73,22 @@ - (void)processMetrics:(NSURLSessionTaskMetrics *)metrics forTask:(NSURLSessionT NSDate *firstByte = [NSDate distantFuture]; NSDate *requestEnd = [NSDate distantPast]; int64_t contentLength = task.countOfBytesReceived; - + for (NSURLSessionTaskTransactionMetrics *metric in metrics.transactionMetrics) { if (metric.requestStartDate == nil || metric.responseStartDate == nil) { //Only evaluate requests which completed their first byte. return; } - + requestStart = [requestStart earlierDate:metric.requestStartDate]; firstByte = [firstByte earlierDate:metric.responseStartDate]; requestEnd = [requestEnd laterDate:metric.responseEndDate]; } - + if ([requestStart isEqual:[NSDate distantFuture]] || [firstByte isEqual:[NSDate distantFuture]] || [requestEnd isEqual:[NSDate distantPast]] || contentLength == 0) { return; } - + [self updateSpeedsForHost:task.currentRequest.URL.host bytesPerSecond:contentLength / [requestEnd timeIntervalSinceDate:requestStart] startAdjustedBytesPerSecond:contentLength / [requestEnd timeIntervalSinceDate:firstByte] @@ -174,7 +174,7 @@ - (PINSpeedRecorderConnectionStatus)connectionStatus { PINSpeedRecorderConnectionStatus status = PINSpeedRecorderConnectionStatusNotReachable; SCNetworkReachabilityFlags flags; - + // _reachability is set on init and therefore safe to access outside the lock if (SCNetworkReachabilityGetFlags(_reachability, &flags)) { return [self networkStatusForFlags:flags]; @@ -188,21 +188,21 @@ - (PINSpeedRecorderConnectionStatus)networkStatusForFlags:(SCNetworkReachability // The target host is not reachable. return PINSpeedRecorderConnectionStatusNotReachable; } - + PINSpeedRecorderConnectionStatus connectionStatus = PINSpeedRecorderConnectionStatusNotReachable; - + if ((flags & kSCNetworkReachabilityFlagsConnectionRequired) == 0) { /* If the target host is reachable and no connection is required then we'll assume (for now) that you're on Wi-Fi... */ connectionStatus = PINSpeedRecorderConnectionStatusWiFi; } - + if ((((flags & kSCNetworkReachabilityFlagsConnectionOnDemand ) != 0) || (flags & kSCNetworkReachabilityFlagsConnectionOnTraffic) != 0)) { /* ... and the connection is on-demand (or on-traffic) if the calling application is using the CFSocketStream or higher APIs... */ - + if ((flags & kSCNetworkReachabilityFlagsInterventionRequired) == 0) { /* ... and no [user] intervention is needed... @@ -210,7 +210,7 @@ - (PINSpeedRecorderConnectionStatus)networkStatusForFlags:(SCNetworkReachability connectionStatus = PINSpeedRecorderConnectionStatusWiFi; } } - + #if PIN_TARGET_IOS if ((flags & kSCNetworkReachabilityFlagsIsWWAN) == kSCNetworkReachabilityFlagsIsWWAN) { /* @@ -219,7 +219,7 @@ - (PINSpeedRecorderConnectionStatus)networkStatusForFlags:(SCNetworkReachability connectionStatus = PINSpeedRecorderConnectionStatusWWAN; } #endif - + return connectionStatus; } @@ -228,16 +228,16 @@ + (NSUInteger)appropriateImageIdxForURLsGivenHistoricalNetworkConditions:(NSArra highQualityQPSThreshold:(float)highQualityQPSThreshold { float currentBytesPerSecond = [[PINSpeedRecorder sharedRecorder] weightedAdjustedBytesPerSecondForHost:[[urls firstObject] host]]; - + NSUInteger desiredImageURLIdx; - + if (currentBytesPerSecond == -1) { // Base it on reachability switch ([[PINSpeedRecorder sharedRecorder] connectionStatus]) { case PINSpeedRecorderConnectionStatusWiFi: desiredImageURLIdx = urls.count - 1; break; - + case PINSpeedRecorderConnectionStatusWWAN: case PINSpeedRecorderConnectionStatusNotReachable: desiredImageURLIdx = 0; @@ -254,7 +254,7 @@ + (NSUInteger)appropriateImageIdxForURLsGivenHistoricalNetworkConditions:(NSArra desiredImageURLIdx = ceilf((currentBytesPerSecond - lowQualityQPSThreshold) / ((highQualityQPSThreshold - lowQualityQPSThreshold) / (float)(urls.count - 2))); } } - + return desiredImageURLIdx; } diff --git a/Source/Classes/PINURLSessionManager.m b/Source/Classes/PINURLSessionManager.m index e83601cb..883c6fdf 100644 --- a/Source/Classes/PINURLSessionManager.m +++ b/Source/Classes/PINURLSessionManager.m @@ -6,9 +6,9 @@ // // -#import "PINURLSessionManager.h" +#import "Source/Classes/include/PINURLSessionManager.h" -#import "PINSpeedRecorder.h" +#import "Source/Classes/PINSpeedRecorder.h" NSErrorDomain const PINURLErrorDomain = @"PINURLErrorDomain"; @@ -31,7 +31,7 @@ - (instancetype)initWithSessionConfiguration:(NSURLSessionConfiguration *)config self.sessionManagerLock.name = @"PINURLSessionManager"; self.operationQueue = [[NSOperationQueue alloc] init]; self.operationQueue.name = @"PINURLSessionManager Operation Queue"; - + //queue must be serial to ensure proper ordering [self.operationQueue setMaxConcurrentOperationCount:1]; self.session = [NSURLSession sessionWithConfiguration:configuration delegate:self delegateQueue:self.operationQueue]; @@ -49,9 +49,9 @@ - (void)invalidateSessionAndCancelTasks } - (nonnull NSURLSessionDataTask *)dataTaskWithRequest:(nonnull NSURLRequest *)request - completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler + completionHandler:(nonnull PINURLSessionDataTaskCompletion)completionHandler { - return [self dataTaskWithRequest:request + return [self dataTaskWithRequest:request priority:PINRemoteImageManagerPriorityDefault completionHandler:completionHandler]; } @@ -92,12 +92,12 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)task [self lock]; dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; [self unlock]; - + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); if (delegateQueue == nil) { return; } - + __weak typeof(self) weakSelf = self; dispatch_async(delegateQueue, ^{ typeof(self) strongSelf = weakSelf; @@ -128,12 +128,12 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didRece [self lock]; dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; [self unlock]; - + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); if (delegateQueue == nil) { return; } - + __weak typeof(self) weakSelf = self; dispatch_async(delegateQueue, ^{ typeof(self) strongSelf = weakSelf; @@ -153,12 +153,12 @@ - (void)URLSession:(NSURLSession *)session dataTask:(NSURLSessionDataTask *)task [self lock]; dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; [self unlock]; - + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); if (delegateQueue == nil) { return; } - + __weak typeof(self) weakSelf = self; dispatch_async(delegateQueue, ^{ typeof(self) strongSelf = weakSelf; @@ -171,12 +171,12 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp [self lock]; dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; [self unlock]; - + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); if (delegateQueue == nil) { return; } - + if (!error && [task.response isKindOfClass:[NSHTTPURLResponse class]]) { NSHTTPURLResponse *response = (NSHTTPURLResponse *)task.response; NSInteger statusCode = [response statusCode]; @@ -191,17 +191,17 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didComp __weak typeof(self) weakSelf = self; dispatch_async(delegateQueue, ^{ typeof(self) strongSelf = weakSelf; - + [strongSelf lock]; PINURLSessionDataTaskCompletion completionHandler = strongSelf.completions[@(task.taskIdentifier)]; [strongSelf.completions removeObjectForKey:@(task.taskIdentifier)]; [strongSelf.delegateQueues removeObjectForKey:@(task.taskIdentifier)]; [strongSelf unlock]; - + if (completionHandler) { completionHandler(task, error); } - + if ([strongSelf.delegate respondsToSelector:@selector(didCompleteTask:withError:)]) { [strongSelf.delegate didCompleteTask:task withError:error]; } @@ -214,16 +214,16 @@ - (void)URLSession:(NSURLSession *)session task:(NSURLSessionTask *)task didFini { if (@available(iOS 10.0, macOS 10.12, *)) { [[PINSpeedRecorder sharedRecorder] processMetrics:metrics forTask:task]; - + [self lock]; dispatch_queue_t delegateQueue = self.delegateQueues[@(task.taskIdentifier)]; [self unlock]; - + NSAssert(delegateQueue != nil, @"There seems to be an issue in iOS 9 where this can be nil. If you can reliably reproduce hitting this, *please* open an issue: https://github.com/pinterest/PINRemoteImage/issues"); if (delegateQueue == nil) { return; } - + __weak typeof(self) weakSelf = self; dispatch_async(delegateQueue, ^{ typeof(self) strongSelf = weakSelf; diff --git a/Source/Classes/include/NSData+ImageDetectors.h b/Source/Classes/include/NSData+ImageDetectors.h index b5d91d9f..dfbe0808 100644 --- a/Source/Classes/include/NSData+ImageDetectors.h +++ b/Source/Classes/include/NSData+ImageDetectors.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" @interface NSData (PINImageDetectors) diff --git a/Source/Classes/include/PINAlternateRepresentationProvider.h b/Source/Classes/include/PINAlternateRepresentationProvider.h index d3506096..a970a6bb 100644 --- a/Source/Classes/include/PINAlternateRepresentationProvider.h +++ b/Source/Classes/include/PINAlternateRepresentationProvider.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @protocol PINRemoteImageManagerAlternateRepresentationProvider @required diff --git a/Source/Classes/include/PINAnimatedImage.h b/Source/Classes/include/PINAnimatedImage.h index 4f96b154..14b575a8 100644 --- a/Source/Classes/include/PINAnimatedImage.h +++ b/Source/Classes/include/PINAnimatedImage.h @@ -7,7 +7,7 @@ // #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -73,14 +73,14 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); /** @abstract Return the duration at a given index. - + @warning *Must be overridden by subclass */ - (CFTimeInterval)durationAtIndex:(NSUInteger)index; /** @abstract Return the total number of frames in the animated image. - + @warning *Must be overridden by subclass */ @property (nonatomic, readonly) size_t frameCount; @@ -155,7 +155,7 @@ typedef void(^PINAnimatedImageInfoReady)(PINImage * _Nonnull coverImage); */ - (nullable CGImageRef)imageAtIndex:(NSUInteger)index cacheProvider:(nullable id)cacheProvider; /** - + @abstract Return the duration at a given index. */ - (CFTimeInterval)durationAtIndex:(NSUInteger)index; diff --git a/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h b/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h index 9dbfbc96..443cc602 100644 --- a/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h +++ b/Source/Classes/include/PINAnimatedImageView+PINRemoteImage.h @@ -5,9 +5,9 @@ // Created by Garrett Moon on 4/19/18. // -#import "PINAnimatedImageView.h" +#import "Source/Classes/include/PINAnimatedImageView.h" -#import "PINRemoteImageCategoryManager.h" +#import "Source/Classes/include/PINRemoteImageCategoryManager.h" @interface PINAnimatedImageView (PINRemoteImage) diff --git a/Source/Classes/include/PINAnimatedImageView.h b/Source/Classes/include/PINAnimatedImageView.h index b224f025..740cfe25 100644 --- a/Source/Classes/include/PINAnimatedImageView.h +++ b/Source/Classes/include/PINAnimatedImageView.h @@ -5,7 +5,7 @@ // Created by Garrett Moon on 4/17/18. // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -13,7 +13,7 @@ #import #endif -#import "PINCachedAnimatedImage.h" +#import "Source/Classes/include/PINCachedAnimatedImage.h" @interface PINAnimatedImageView : PINImageView diff --git a/Source/Classes/include/PINButton+PINRemoteImage.h b/Source/Classes/include/PINButton+PINRemoteImage.h index 1659db95..acee2705 100644 --- a/Source/Classes/include/PINButton+PINRemoteImage.h +++ b/Source/Classes/include/PINButton+PINRemoteImage.h @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -14,8 +14,8 @@ #import #endif -#import "PINRemoteImageManager.h" -#import "PINRemoteImageCategoryManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageCategoryManager.h" @interface PINButton (PINRemoteImage) diff --git a/Source/Classes/include/PINCache+PINRemoteImageCaching.h b/Source/Classes/include/PINCache+PINRemoteImageCaching.h index f8a5eb13..5d10755c 100644 --- a/Source/Classes/include/PINCache+PINRemoteImageCaching.h +++ b/Source/Classes/include/PINCache+PINRemoteImageCaching.h @@ -6,14 +6,16 @@ // // -#if SWIFT_PACKAGE -@import PINCache; +#ifdef BAZEL +#import "../_main~non_module_dependencies~PINCache/Source/PINCache.h" #else -#import +#ifdef SWIFT_PACKAGE +@import PINCache; +#endif #endif -#import "PINRemoteImageCaching.h" -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageCaching.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @interface PINCache (PINRemoteImageCaching) diff --git a/Source/Classes/include/PINCachedAnimatedImage.h b/Source/Classes/include/PINCachedAnimatedImage.h index b3b66815..db8b4215 100644 --- a/Source/Classes/include/PINCachedAnimatedImage.h +++ b/Source/Classes/include/PINCachedAnimatedImage.h @@ -8,8 +8,8 @@ #import -#import "PINRemoteImageMacros.h" -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" +#import "Source/Classes/include/PINAnimatedImage.h" @interface PINCachedAnimatedImage : NSObject diff --git a/Source/Classes/include/PINGIFAnimatedImage.h b/Source/Classes/include/PINGIFAnimatedImage.h index e106f9e4..96273891 100644 --- a/Source/Classes/include/PINGIFAnimatedImage.h +++ b/Source/Classes/include/PINGIFAnimatedImage.h @@ -1,5 +1,5 @@ // -// PINGIFAnimatedImage.h +// #import "Source/Classes/include/PINGIFAnimatedImage.h" // PINRemoteImage // // Created by Garrett Moon on 9/17/17. @@ -8,7 +8,7 @@ #import -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINAnimatedImage.h" @interface PINGIFAnimatedImage : PINAnimatedImage diff --git a/Source/Classes/include/PINImageView+PINRemoteImage.h b/Source/Classes/include/PINImageView+PINRemoteImage.h index f5c4b7ed..6ef5922a 100644 --- a/Source/Classes/include/PINImageView+PINRemoteImage.h +++ b/Source/Classes/include/PINImageView+PINRemoteImage.h @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -14,8 +14,8 @@ #import #endif -#import "PINRemoteImageManager.h" -#import "PINRemoteImageCategoryManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageCategoryManager.h" @interface PINImageView (PINRemoteImage) diff --git a/Source/Classes/include/PINProgressiveImage.h b/Source/Classes/include/PINProgressiveImage.h index 1c68b1a1..d9e06886 100644 --- a/Source/Classes/include/PINProgressiveImage.h +++ b/Source/Classes/include/PINProgressiveImage.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -33,7 +33,7 @@ /** Returns the latest image based on thresholds, returns nil if no new image is generated. - + @param blurred A boolean to indicate if the image should be blurred. @param maxProgressiveRenderSize The maximum dimensions at which to apply a blur. If an image exceeds either the height. or width of this dimension, the image will *not* be blurred regardless of the blurred parameter. @@ -44,7 +44,7 @@ /** Returns the current data for the image. - + @return NSData The current data for the image. */ - (nullable NSData *)data; diff --git a/Source/Classes/include/PINRemoteImage.h b/Source/Classes/include/PINRemoteImage.h index 140e1430..c85a2989 100644 --- a/Source/Classes/include/PINRemoteImage.h +++ b/Source/Classes/include/PINRemoteImage.h @@ -5,21 +5,21 @@ // // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if USE_PINCACHE - #import "PINCache+PINRemoteImageCaching.h" + #import "Source/Classes/include/PINCache+PINRemoteImageCaching.h" #endif -#import "NSData+ImageDetectors.h" -#import "PINAlternateRepresentationProvider.h" -#import "PINCachedAnimatedImage.h" -#import "PINGIFAnimatedImage.h" -#import "PINWebPAnimatedImage.h" -#import "PINRemoteImageManager.h" -#import "PINRemoteImageCategoryManager.h" -#import "PINRemoteImageManagerResult.h" -#import "PINRemoteImageCaching.h" -#import "PINProgressiveImage.h" -#import "PINURLSessionManager.h" -#import "PINRequestRetryStrategy.h" +#import "Source/Classes/include/NSData+ImageDetectors.h" +#import "Source/Classes/include/PINAlternateRepresentationProvider.h" +#import "Source/Classes/include/PINCachedAnimatedImage.h" +#import "Source/Classes/include/PINGIFAnimatedImage.h" +#import "Source/Classes/include/PINWebPAnimatedImage.h" +#import "Source/Classes/include/PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageCategoryManager.h" +#import "Source/Classes/include/PINRemoteImageManagerResult.h" +#import "Source/Classes/include/PINRemoteImageCaching.h" +#import "Source/Classes/include/PINProgressiveImage.h" +#import "Source/Classes/include/PINURLSessionManager.h" +#import "Source/Classes/include/PINRequestRetryStrategy.h" diff --git a/Source/Classes/include/PINRemoteImageCategoryManager.h b/Source/Classes/include/PINRemoteImageCategoryManager.h index ec941242..be4e82a6 100644 --- a/Source/Classes/include/PINRemoteImageCategoryManager.h +++ b/Source/Classes/include/PINRemoteImageCategoryManager.h @@ -6,7 +6,7 @@ // // -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -14,7 +14,7 @@ #import #endif -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" @protocol PINRemoteImageCategory; @@ -97,14 +97,14 @@ /** Set the image from the given URL. - + @param url NSURL to fetch from. */ - (void)pin_setImageFromURL:(nullable NSURL *)url; /** Set the image from the given URL and set placeholder image while image at URL is being retrieved. - + @param url NSURL to fetch from. @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. */ @@ -112,7 +112,7 @@ /** Set the image from the given URL and call completion when finished. - + @param url NSURL to fetch from. @param completion Called when url has been retrieved and set on view. */ @@ -120,7 +120,7 @@ /** Set the image from the given URL, set placeholder while image at url is being retrieved and call completion when finished. - + @param url NSURL to fetch from. @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. @param completion Called when url has been retrieved and set on view. @@ -129,7 +129,7 @@ /** Retrieve the image from the given URL, process it using the passed in processor block and set result on view. - + @param url NSURL to fetch from. @param processorKey NSString key to uniquely identify processor. Used in caching. @param processor PINRemoteImageManagerImageProcessor processor block which should return the processed image. @@ -138,7 +138,7 @@ /** Set placeholder on view and retrieve the image from the given URL, process it using the passed in processor block and set result on view. - + @param url NSURL to fetch from. @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. @param processorKey NSString key to uniquely identify processor. Used in caching. @@ -148,7 +148,7 @@ /** Retrieve the image from the given URL, process it using the passed in processor block and set result on view. Call completion after image has been fetched, processed and set on view. - + @param url NSURL to fetch from. @param processorKey NSString key to uniquely identify processor. Used in caching. @param processor PINRemoteImageManagerImageProcessor processor block which should return the processed image. @@ -158,7 +158,7 @@ /** Set placeholder on view and retrieve the image from the given URL, process it using the passed in processor block and set result on view. Call completion after image has been fetched, processed and set on view. - + @param url NSURL to fetch from. @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. @param processorKey NSString key to uniquely identify processor. Used in caching. @@ -169,14 +169,14 @@ /** Retrieve one of the images at the passed in URLs depending on previous network performance and set result on view. - + @param urls NSArray of NSURLs sorted in increasing quality */ - (void)pin_setImageFromURLs:(nullable NSArray *)urls; /** Set placeholder on view and retrieve one of the images at the passed in URLs depending on previous network performance and set result on view. - + @param urls NSArray of NSURLs sorted in increasing quality @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. */ @@ -184,7 +184,7 @@ /** Set placeholder on view and retrieve one of the images at the passed in URLs depending on previous network performance and set result on view. Call completion after image has been fetched and set on view. - + @param urls NSArray of NSURLs sorted in increasing quality @param placeholderImage PINImage to set on the view while the image at URL is being retrieved. @param completion Called when url has been retrieved and set on view. @@ -198,21 +198,21 @@ /** Returns the NSUUID associated with any PINRemoteImage task currently running on the view. - + @return NSUUID associated with any PINRemoteImage task currently running on the view. */ - (nullable NSUUID *)pin_downloadImageOperationUUID; /** Set the current NSUUID associated with a PINRemoteImage task running on the view. - + @param downloadImageOperationUUID NSUUID associated with a PINRemoteImage task. */ - (void)pin_setDownloadImageOperationUUID:(nullable NSUUID *)downloadImageOperationUUID; /** Whether the view should update with progress images (such as those provided by progressive JPEG images). - + @return BOOL value indicating whether the view should update with progress images */ @property (nonatomic, assign) BOOL pin_updateWithProgress; diff --git a/Source/Classes/include/PINRemoteImageManager.h b/Source/Classes/include/PINRemoteImageManager.h index 83907078..b0a358ac 100644 --- a/Source/Classes/include/PINRemoteImageManager.h +++ b/Source/Classes/include/PINRemoteImageManager.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import @@ -16,7 +16,7 @@ #import #endif -#import "PINRemoteImageManagerResult.h" +#import "Source/Classes/include/PINRemoteImageManagerResult.h" #define PINRemoteImageHTTPMaximumConnectionsPerHost UINT16_MAX @@ -94,17 +94,17 @@ float dataTaskPriorityWithImageManagerPriority(PINRemoteImageManagerPriority pri /** Completion called for many PINRemoteImage tasks as well as progress updates. Passed in a PINRemoteImageManagerResult. - + @param result PINRemoteImageManagerResult which contains the downloaded image. */ typedef void (^PINRemoteImageManagerImageCompletion)(PINRemoteImageManagerResult * __nonnull result); /** Processor block to post-process a downloaded image. Passed in a PINRemoteImageManagerResult and a pointer to an NSUInteger which can be updated to indicate the cost of processing the image. - + @param result PINRemoteImageManagerResult which contains the downloaded image. @param cost NSUInteger point which can be modified to indicate the cost of processing the image. This is used when determining which cache objects to evict on memory pressure. - + @return return the processed UIImage */ typedef PINImage * _Nullable(^PINRemoteImageManagerImageProcessor)(PINRemoteImageManagerResult * __nonnull result, NSUInteger * __nonnull cost); @@ -112,15 +112,15 @@ typedef PINImage * _Nullable(^PINRemoteImageManagerImageProcessor)(PINRemoteIma /** PINRemoteImageManager is the main workhorse of PINRemoteImage. It is unnecessary to access directly if you simply wish to download images and have them rendered in a UIImageView, UIButton or PINAnimatedImageView. - + However, if you wish to download images directly, this class is your guy / gal. - + You can use this class to download images, postprocess downloaded images, prefetch images, download images progressively, or download one image in a set of images depending on network performance. */ /** Completion Handler block which will be forwarded to NSURLSessionTaskDelegate's completion handler - + @param disposition One of several constants that describes how the challenge should be handled. @param credential The credential that should be used for authentication if disposition is NSURLSessionAuthChallengeUseCredential; otherwise, NULL. */ @@ -128,7 +128,7 @@ typedef void(^PINRemoteImageManagerAuthenticationChallengeCompletionHandler)(NSU /** Authentication challenge handler - + @param task The task whose request requires authentication. @param challenge An object that contains the request for authentication. @param aHandler A PINRemoteImageManagerAuthenticationChallengeCompletionHandler, see example for further details. @@ -139,7 +139,7 @@ typedef void(^PINRemoteImageManagerAuthenticationChallenge)(NSURLSessionTask * _ /** Request configuration handler. Used to modify a network request before it is executed. Useful for adding custom, per-request headers. - + @param request The request about to be executed */ typedef NSURLRequest * _Nonnull(^PINRemoteImageManagerRequestConfigurationHandler)(NSURLRequest * __nonnull request); @@ -147,7 +147,7 @@ typedef NSURLRequest * _Nonnull(^PINRemoteImageManagerRequestConfigurationHandle /** Handler called for many PINRemoteImage tasks providing the progress of the download. - + @param completedBytes Amount of bytes that have been downloaded so far. @param totalBytes Total amount of bytes in the image being downloaded. */ @@ -155,7 +155,7 @@ typedef void(^PINRemoteImageManagerProgressDownload)(int64_t completedBytes, int /** Reports NSURLSessionTaskMetrics for download requests - + */ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSessionTaskMetrics * __nonnull metrics) API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0)); @@ -210,7 +210,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Get the shared instance of PINRemoteImageManager - + @return Shared instance of PINRemoteImageManager */ + (nonnull instancetype)sharedImageManager; @@ -257,14 +257,14 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Sets the Request Configuration Block. - + @param configurationBlock A PINRemoteImageManagerRequestConfigurationHandler block. */ - (void)setRequestConfiguration:(nullable PINRemoteImageManagerRequestConfigurationHandler)configurationBlock; /** Set the Authentication Challenge Block. - + @param challengeBlock A PINRemoteImageManagerAuthenticationChallenge block. */ - (void)setAuthenticationChallenge:(nullable PINRemoteImageManagerAuthenticationChallenge)challengeBlock; @@ -272,7 +272,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set the minimum BPS to download the highest quality image in a set. @see downloadImageWithURLs:options:progressImage:completion: - + @param highQualityBPSThreshold bytes per second minimum. Defaults to 500000. @param completion Completion to be called once highQualityBPSThreshold has been set. */ @@ -291,7 +291,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set whether high quality images should be downloaded when a low quality image is cached if network connectivity has improved. @see downloadImageWithURLs:options:progressImage:completion: - + @param shouldUpgradeLowQualityImages if YES, low quality images will be 'upgraded'. @param completion Completion to be called once shouldUpgradeLowQualityImages has been set. */ @@ -300,7 +300,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set the maximum number of concurrent operations (decompressing images, creating gifs, etc). - + @param maxNumberOfConcurrentOperations The maximum number of concurrent operations. Defaults to NSOperationQueueDefaultMaxConcurrentOperationCount. @param completion Completion to be called once maxNumberOfConcurrentOperations is set. */ @@ -309,7 +309,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set the maximum number of concurrent downloads. - + @param maxNumberOfConcurrentDownloads The maximum number of concurrent downloads. Defaults to 10, maximum 65535. @param completion Completion to be called once maxNumberOfConcurrentDownloads is set. */ @@ -318,7 +318,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set the estimated time remaining to download threshold at which to generate progressive images. Progressive images previews will only be generated if the estimated remaining time on a download is greater than estimatedTimeRemainingThreshold. If estimatedTimeRemainingThreshold is less than or equal to zero, this check is skipped. - + @param estimatedRemainingTimeThreshold The estimated remaining time threshold used to decide to skip progressive rendering. Defaults to 0.1. @param completion Completion to be called once estimatedTimeRemainingTimeThreshold is set. */ @@ -327,7 +327,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Sets the progress at which progressive images are generated. By default this is @[@0.00, @0.35, @0.65] which generates at most, 3 progressive images. The first progressive image will only be generated when at least one scan has been completed (so you never see half an image). - + @param progressThresholds an array of progress thresholds at which to generate progressive images. progress thresholds should range from 0.00 - 1.00. Defaults to @[@0.00, @0.35, @0.65] @param completion Completion to be called once progressThresholds is set. */ @@ -336,7 +336,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Sets whether PINRemoteImage should blur progressive render results - + @param shouldBlur A bool value indicating whether PINRemoteImage should blur progressive render results @param completion Completion to be called once progressThresholds is set. */ @@ -345,7 +345,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Sets the maximum size of an image that PINRemoteImage will render progessively. If the image is too large, progressive rendering is skipped. - + @param maxProgressiveRenderSize A CGSize which indicates the max size PINRemoteImage will render a progressive image. If an image is larger in either dimension, progressive rendering will be skipped @param completion Completion to be called once maxProgressiveRenderSize is set. */ @@ -354,7 +354,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Sets a metrics callback block to be called when NSURLSessionTaskMetrics are reported for downloads. - + @warning PINRemoteImageManager will hold a strong reference to metricsCallback. Avoid retain cycles by using weak references in the block! */ - (void)setMetricsCallback:(nullable PINRemoteImageManagerMetrics)metricsCallback @@ -362,14 +362,14 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Prefetch an image at the given URL. - + @param url NSURL where the image to prefetch resides. */ - (nullable NSUUID *)prefetchImageWithURL:(nonnull NSURL *)url; /** Prefetch an image at the given URL with given options. - + @param url NSURL where the image to prefetch resides. @param options PINRemoteImageManagerDownloadOptions options with which to pefetch the image. */ @@ -377,7 +377,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Prefetch an image at the given URL with given options. - + @param url NSURL where the image to prefetch resides. @param options PINRemoteImageManagerDownloadOptions options with which to prefetch the image. @param priority PINRemoteImageManagerPriority priority of the operation when to prefetch the image. @@ -386,14 +386,14 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Prefetch images at the given URLs. - + @param urls An array of NSURLs where the images to prefetch reside. */ - (nonnull NSArray *)prefetchImagesWithURLs:(nonnull NSArray *)urls; /** Prefetch images at the given URLs with given options. - + @param urls An array of NSURLs where the images to prefetch reside. @param options PINRemoteImageManagerDownloadOptions options with which to pefetch the image. */ @@ -401,7 +401,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Prefetch images at the given URLs with given options. - + @param urls An array of NSURLs where the images to prefetch reside. @param options PINRemoteImageManagerDownloadOptions options with which to pefetch the image. @param priority PINRemoteImageManagerPriority priority of the operation to prefetch the image. @@ -410,7 +410,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). @@ -419,7 +419,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. @@ -431,12 +431,12 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param progressImage PINRemoteImageManagerImageCompletion block which will be called to update progress of the image download. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url @@ -446,12 +446,12 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param progressDownload PINRemoteImageManagerDownloadProgress block which will be called to update progress in bytes of the image download. NOTE: For performance reasons, this block is not called on the main thread every time, if you need to update your UI ensure that you dispatch to the main thread first. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url @@ -461,13 +461,13 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param progressImage PINRemoteImageManagerImageCompletion block which will be called to update progress of the image download. @param progressDownload PINRemoteImageManagerDownloadProgress block which will be called to update progress in bytes of the image download. NOTE: For performance reasons, this block is not called on the main thread every time, if you need to update your UI ensure that you dispatch to the main thread first. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url @@ -497,13 +497,13 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url and process it before calling completion. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param processorKey NSString key to uniquely identify processor and process. Will be used for caching processed images. @param processor PINRemoteImageManagerImageProcessor block which will be called to post-process downloaded image. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url @@ -514,14 +514,14 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache the image found at the url and process it before calling completion. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + @param url NSURL where the image to download resides. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param processorKey NSString key to uniquely identify processor and process. Will be used for caching processed images. @param progressDownload PINRemoteImageManagerDownloadProgress block which will be called to update progress in bytes of the image download. NOTE: For performance reasons, this block is not called on the main thread every time, if you need to update your UI ensure that you dispatch to the main thread first. @param processor PINRemoteImageManagerImageProcessor block which will be called to post-process downloaded image. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURL:(nonnull NSURL *)url @@ -533,14 +533,14 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache one of the images found at the urls in the passed in array based on current network performance. URLs should be sorted from lowest quality image URL to highest. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + Unless setShouldUpgradeLowQualityImages is set to YES, this method checks the cache for all URLs and returns the highest quality version stored. It is possible though unlikely for a cached image to not be returned if it is still being cached while a call is made to this method and if network conditions have changed. See source for more details. - + @param urls An array of NSURLs of increasing cost to download. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param progressImage PINRemoteImageManagerImageCompletion block which will be called to update progress of the image download. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURLs:(nonnull NSArray *)urls @@ -550,15 +550,15 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Download or retrieve from cache one of the images found at the urls in the passed in array based on current network performance. URLs should be sorted from lowest quality image URL to highest. All completions are called on an arbitrary callback queue unless called on the main thread and the result is in the memory cache (this is an optimization to allow synchronous results for the UI when an object is cached in memory). - + Unless setShouldUpgradeLowQualityImages is set to YES, this method checks the cache for all URLs and returns the highest quality version stored. It is possible though unlikely for a cached image to not be returned if it is still being cached while a call is made to this method and if network conditions have changed. See source for more details. - + @param urls An array of NSURLs of increasing cost to download. @param options PINRemoteImageManagerDownloadOptions options with which to fetch the image. @param progressImage PINRemoteImageManagerImageCompletion block which will be called to update progress of the image download. @param progressDownload PINRemoteImageManagerDownloadProgress block which will be called to update progress in bytes of the image download. NOTE: For performance reasons, this block is not called on the main thread every time, if you need to update your UI ensure that you dispatch to the main thread first. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache or downloaded. - + @return An NSUUID which uniquely identifies this request. To be used for canceling requests and verifying that the callback is for the request you expect (see categories for example). */ - (nullable NSUUID *)downloadImageWithURLs:(nonnull NSArray *)urls @@ -570,12 +570,12 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Adds an image manually into the memory and disk cache. - + @param data NSData with the raw image data. @param url NSURL where the image resides. @param processorKey NSString key to uniquely identify processor and process. Will be used for caching processed images. @param additionalCost NSUInteger the additional cost (for cache eviction purposes) to generate the processed image - + @return A BOOL indicating if the image was successfully added to the cache. */ - (BOOL) insertImageDataIntoCache:(nonnull NSData*)data @@ -586,10 +586,10 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Returns the cacheKey for a given URL and processorKey. Exposed to be overridden if necessary or to be used with imageFromCacheWithCacheKey @see imageFromCacheWithCacheKey:completion: - + @param url NSURL that was used to download image @param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image. - + @return returns an NSString which is the key used for caching. */ - (nonnull NSString *)cacheKeyForURL:(nonnull NSURL *)url processorKey:(nullable NSString *)processorKey; @@ -597,7 +597,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** @see imageFromCacheWithURL:processorKey:options:completion: @deprecated - + @param cacheKey NSString key to look up image in the cache. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache. */ @@ -606,7 +606,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** @see imageFromCacheWithURL:processorKey:options:completion: @deprecated - + @param cacheKey NSString key to look up image in the cache. @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @param completion PINRemoteImageManagerImageCompletion block to call when image has been fetched from the cache. @@ -615,7 +615,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Directly get an image from the underlying cache. - + @param url NSURL that was used to download image @param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image. @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. @@ -626,37 +626,37 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** @deprecated @see synchronousImageFromCacheWithURL:processorKey:options: - + @param cacheKey NSString obtained from @c cacheKeyForURL:processorKey @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. - + @return A PINRemoteImageManagerResult */ - (nonnull PINRemoteImageManagerResult *)synchronousImageFromCacheWithCacheKey:(nonnull NSString *)cacheKey options:(PINRemoteImageManagerDownloadOptions)options __attribute__((deprecated)); /** Directly get an image from the underlying memory cache synchronously. - + @param url NSURL that was used to download image @param processorKey An optional key to uniquely identify the processor used to post-process the downloaded image. @param options options will be used to determine if the cached image should be decompressed or PINCachedAnimatedImages should be returned. - + @return A PINRemoteImageManagerResult */ - (nonnull PINRemoteImageManagerResult *)synchronousImageFromCacheWithURL:(nonnull NSURL *)url processorKey:(nullable NSString *)processorKey options:(PINRemoteImageManagerDownloadOptions)options; /** - Cancel a download. Canceling will only cancel the download if all other downloads are also canceled with their associated UUIDs. + Cancel a download. Canceling will only cancel the download if all other downloads are also canceled with their associated UUIDs. Canceling *does not* guarantee that your completion will not be called. You can use the UUID provided on the result object to verify the completion you want called is being called. @see PINRemoteImageCategoryManager - + @param UUID NSUUID of the task to cancel. */ - (void)cancelTaskWithUUID:(nonnull NSUUID *)UUID; /** - Cancel a download. Canceling will only cancel the download if all other downloads are also canceled with their associated UUIDs. + Cancel a download. Canceling will only cancel the download if all other downloads are also canceled with their associated UUIDs. Canceling *does not* guarantee that your completion will not be called. You can use the UUID provided on the result object to verify the completion you want called is being called. @param storeResumeData if YES and the server indicates it supports resuming downloads, downloaded data will be stored in the disk @@ -677,7 +677,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set the priority of a download task. Since there is only one task per download, the priority of the download task will always be the last priority this method was called with. - + @param priority priority to set on the task. @param UUID NSUUID of the task to set the priority on. */ @@ -693,7 +693,7 @@ typedef void(^PINRemoteImageManagerMetrics)(NSURL * __nonnull url, NSURLSession /** Set retry strategy for all requests - + @param retryStrategyCreationBlock a block which should create new instance of PINRequestRetryStrategy when called. */ - (void)setRetryStrategyCreationBlock:(_Nonnull id (^_Nonnull)(void))retryStrategyCreationBlock; diff --git a/Source/Classes/include/PINRemoteImageManagerResult.h b/Source/Classes/include/PINRemoteImageManagerResult.h index 41ff8c5a..12bd7580 100644 --- a/Source/Classes/include/PINRemoteImageManagerResult.h +++ b/Source/Classes/include/PINRemoteImageManagerResult.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageMacros.h" +#import "Source/Classes/include/PINRemoteImageMacros.h" #if PIN_TARGET_IOS #import diff --git a/Source/Classes/include/PINURLSessionManager.h b/Source/Classes/include/PINURLSessionManager.h index 5b25ff17..631ade83 100644 --- a/Source/Classes/include/PINURLSessionManager.h +++ b/Source/Classes/include/PINURLSessionManager.h @@ -8,7 +8,7 @@ #import -#import "PINRemoteImageManager.h" +#import "Source/Classes/include/PINRemoteImageManager.h" extern NSErrorDomain _Nonnull const PINURLErrorDomain; diff --git a/Source/Classes/include/PINWebPAnimatedImage.h b/Source/Classes/include/PINWebPAnimatedImage.h index 6bad969e..880e0f6f 100644 --- a/Source/Classes/include/PINWebPAnimatedImage.h +++ b/Source/Classes/include/PINWebPAnimatedImage.h @@ -9,7 +9,7 @@ #import #import -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINAnimatedImage.h" @interface PINWebPAnimatedImage : PINAnimatedImage diff --git a/Tests/TestAnimatedImage.h b/Tests/TestAnimatedImage.h index 705ca774..68bc48ad 100644 --- a/Tests/TestAnimatedImage.h +++ b/Tests/TestAnimatedImage.h @@ -6,7 +6,7 @@ // Copyright © 2020 Pinterest. All rights reserved. // -#import "PINAnimatedImage.h" +#import "Source/Classes/include/PINAnimatedImage.h" NS_ASSUME_NONNULL_BEGIN diff --git a/WORKSPACE b/WORKSPACE new file mode 100644 index 00000000..48829350 --- /dev/null +++ b/WORKSPACE @@ -0,0 +1,35 @@ +load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive") + +http_archive( + name = "libwebp", + build_file_content = """ +PUBLIC_HEADERS = [ + "src/webp/**/decode.h", + "src/webp/**/encode.h", + "src/webp/**/types.h", + "src/webp/**/mux_types.h", + "src/webp/**/format_constants.h", + "src/webp/**/demux.h", + "src/webp/**/mux.h" +] + +objc_library( + name = "webp", + srcs = glob(["src/**/*.c", "src/**/*.h"], PUBLIC_HEADERS, allow_empty = False), + hdrs = glob(PUBLIC_HEADERS, allow_empty = False), + includes = [ + "src", + "src/dec", + ], + defines = [ + "_THREAD_SAFE" + ], + visibility = [ + "//visibility:public" + ] +) + """, + sha256 = "01bcde6a40a602294994050b81df379d71c40b7e39c819c024d079b3c56307f4", + strip_prefix = "libwebp-1.2.1", + url = "https://github.com/webmproject/libwebp/archive/refs/tags/v1.2.1.tar.gz", +)