Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Comprehensive coverage #57

Merged
merged 18 commits into from
Dec 4, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 37 additions & 11 deletions ImageLoader.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,20 +7,26 @@
objects = {

/* Begin PBXBuildFile section */
650F993C1C0DA09B00540E8D /* DiskcachedTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650F993B1C0DA09B00540E8D /* DiskcachedTests.swift */; };
650F99401C0DBD5B00540E8D /* ManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650F993F1C0DBD5B00540E8D /* ManagerTests.swift */; };
650F99421C0EC16E00540E8D /* UIImageViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 650F99411C0EC16E00540E8D /* UIImageViewTests.swift */; };
650F99481C0EC45D00540E8D /* black.png in Resources */ = {isa = PBXBuildFile; fileRef = 650F99471C0EC45D00540E8D /* black.png */; };
650F994A1C0EC46300540E8D /* white.png in Resources */ = {isa = PBXBuildFile; fileRef = 650F99491C0EC46300540E8D /* white.png */; };
6529075C1BA19BEE002B8D89 /* OHHTTPStubs.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = 6529075B1BA19BEE002B8D89 /* OHHTTPStubs.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6529075D1BA19D5F002B8D89 /* ImageLoader.framework in Copy Files */ = {isa = PBXBuildFile; fileRef = 65B2CF1119EF9F6600DA3605 /* ImageLoader.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
6529075E1BA19DB2002B8D89 /* OHHTTPStubs.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6529075B1BA19BEE002B8D89 /* OHHTTPStubs.framework */; };
65677D061C0EF4F300120684 /* UIImageView+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65677D051C0EF4F300120684 /* UIImageView+ImageLoader.swift */; };
65B2CF1719EF9F6600DA3605 /* ImageLoader.h in Headers */ = {isa = PBXBuildFile; fileRef = 65B2CF1619EF9F6600DA3605 /* ImageLoader.h */; settings = {ATTRIBUTES = (Public, ); }; };
65B2CF1D19EF9F6600DA3605 /* ImageLoader.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 65B2CF1119EF9F6600DA3605 /* ImageLoader.framework */; };
65B2CF2419EF9F6600DA3605 /* ImageLoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65B2CF2319EF9F6600DA3605 /* ImageLoaderTests.swift */; };
65C68E5E19F501CF0053E66D /* UIImageView+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E5D19F501CF0053E66D /* UIImageView+ImageLoader.swift */; };
65C68E5F19F501CF0053E66D /* UIImageView+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E5D19F501CF0053E66D /* UIImageView+ImageLoader.swift */; };
65C68E6119F502B20053E66D /* ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E6019F502B20053E66D /* ImageLoader.swift */; };
65C68E6219F502B20053E66D /* ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 65C68E6019F502B20053E66D /* ImageLoader.swift */; };
A166A16B1C0B918700E71C42 /* URLLiteralConvertibleTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A166A16A1C0B918700E71C42 /* URLLiteralConvertibleTests.swift */; };
A166A16D1C0C2A4000E71C42 /* LoaderTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A166A16C1C0C2A4000E71C42 /* LoaderTests.swift */; };
A17327831A45D793000D10E0 /* Diskcached.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17327821A45D793000D10E0 /* Diskcached.swift */; };
A1B7FEBF1A480F1800819BD1 /* Diskcached.swift in Sources */ = {isa = PBXBuildFile; fileRef = A17327821A45D793000D10E0 /* Diskcached.swift */; };
A1E989321BCEC9BB00948F82 /* ImageLoaderExtensionTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E989311BCEC9BB00948F82 /* ImageLoaderExtensionTests.swift */; settings = {ASSET_TAGS = (); }; };
A1FC211C1BDFEB19003FD093 /* UIImage+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FC211B1BDFEB19003FD093 /* UIImage+ImageLoader.swift */; settings = {ASSET_TAGS = (); }; };
A1E989321BCEC9BB00948F82 /* UIImageTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1E989311BCEC9BB00948F82 /* UIImageTests.swift */; };
A1FC211C1BDFEB19003FD093 /* UIImage+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FC211B1BDFEB19003FD093 /* UIImage+ImageLoader.swift */; };
A1FC211D1BDFF5CB003FD093 /* UIImage+ImageLoader.swift in Sources */ = {isa = PBXBuildFile; fileRef = A1FC211B1BDFEB19003FD093 /* UIImage+ImageLoader.swift */; };
/* End PBXBuildFile section */

Expand Down Expand Up @@ -50,17 +56,24 @@
/* End PBXCopyFilesBuildPhase section */

/* Begin PBXFileReference section */
650F993B1C0DA09B00540E8D /* DiskcachedTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DiskcachedTests.swift; sourceTree = "<group>"; };
650F993F1C0DBD5B00540E8D /* ManagerTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ManagerTests.swift; sourceTree = "<group>"; };
650F99411C0EC16E00540E8D /* UIImageViewTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageViewTests.swift; sourceTree = "<group>"; };
650F99471C0EC45D00540E8D /* black.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = black.png; sourceTree = "<group>"; };
650F99491C0EC46300540E8D /* white.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = white.png; sourceTree = "<group>"; };
6529075B1BA19BEE002B8D89 /* OHHTTPStubs.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OHHTTPStubs.framework; path = ../Carthage/Build/iOS/OHHTTPStubs.framework; sourceTree = "<group>"; };
65677D051C0EF4F300120684 /* UIImageView+ImageLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+ImageLoader.swift"; sourceTree = "<group>"; };
65B2CF1119EF9F6600DA3605 /* ImageLoader.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = ImageLoader.framework; sourceTree = BUILT_PRODUCTS_DIR; };
65B2CF1519EF9F6600DA3605 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
65B2CF1619EF9F6600DA3605 /* ImageLoader.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ImageLoader.h; sourceTree = "<group>"; };
65B2CF1C19EF9F6600DA3605 /* ImageLoaderTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ImageLoaderTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
65B2CF2219EF9F6600DA3605 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
65B2CF2319EF9F6600DA3605 /* ImageLoaderTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageLoaderTests.swift; sourceTree = "<group>"; };
65C68E5D19F501CF0053E66D /* UIImageView+ImageLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImageView+ImageLoader.swift"; sourceTree = "<group>"; };
65C68E6019F502B20053E66D /* ImageLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoader.swift; sourceTree = "<group>"; };
A166A16A1C0B918700E71C42 /* URLLiteralConvertibleTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLLiteralConvertibleTests.swift; sourceTree = "<group>"; };
A166A16C1C0C2A4000E71C42 /* LoaderTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LoaderTests.swift; sourceTree = "<group>"; };
A17327821A45D793000D10E0 /* Diskcached.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Diskcached.swift; sourceTree = "<group>"; };
A1E989311BCEC9BB00948F82 /* ImageLoaderExtensionTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ImageLoaderExtensionTests.swift; sourceTree = "<group>"; };
A1E989311BCEC9BB00948F82 /* UIImageTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UIImageTests.swift; sourceTree = "<group>"; };
A1FC211B1BDFEB19003FD093 /* UIImage+ImageLoader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "UIImage+ImageLoader.swift"; sourceTree = "<group>"; };
/* End PBXFileReference section */

Expand Down Expand Up @@ -108,8 +121,8 @@
65B2CF1619EF9F6600DA3605 /* ImageLoader.h */,
A17327821A45D793000D10E0 /* Diskcached.swift */,
65C68E6019F502B20053E66D /* ImageLoader.swift */,
65C68E5D19F501CF0053E66D /* UIImageView+ImageLoader.swift */,
A1FC211B1BDFEB19003FD093 /* UIImage+ImageLoader.swift */,
65677D051C0EF4F300120684 /* UIImageView+ImageLoader.swift */,
65B2CF1419EF9F6600DA3605 /* Supporting Files */,
);
path = ImageLoader;
Expand All @@ -126,8 +139,13 @@
65B2CF2019EF9F6600DA3605 /* ImageLoaderTests */ = {
isa = PBXGroup;
children = (
650F993B1C0DA09B00540E8D /* DiskcachedTests.swift */,
65B2CF2319EF9F6600DA3605 /* ImageLoaderTests.swift */,
A1E989311BCEC9BB00948F82 /* ImageLoaderExtensionTests.swift */,
A166A16C1C0C2A4000E71C42 /* LoaderTests.swift */,
650F993F1C0DBD5B00540E8D /* ManagerTests.swift */,
A1E989311BCEC9BB00948F82 /* UIImageTests.swift */,
650F99411C0EC16E00540E8D /* UIImageViewTests.swift */,
A166A16A1C0B918700E71C42 /* URLLiteralConvertibleTests.swift */,
65B2CF2119EF9F6600DA3605 /* Supporting Files */,
);
path = ImageLoaderTests;
Expand All @@ -136,6 +154,8 @@
65B2CF2119EF9F6600DA3605 /* Supporting Files */ = {
isa = PBXGroup;
children = (
650F99471C0EC45D00540E8D /* black.png */,
650F99491C0EC46300540E8D /* white.png */,
6529075B1BA19BEE002B8D89 /* OHHTTPStubs.framework */,
65B2CF2219EF9F6600DA3605 /* Info.plist */,
);
Expand Down Expand Up @@ -242,6 +262,8 @@
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
650F99481C0EC45D00540E8D /* black.png in Resources */,
650F994A1C0EC46300540E8D /* white.png in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -253,22 +275,26 @@
buildActionMask = 2147483647;
files = (
A17327831A45D793000D10E0 /* Diskcached.swift in Sources */,
65677D061C0EF4F300120684 /* UIImageView+ImageLoader.swift in Sources */,
65C68E6119F502B20053E66D /* ImageLoader.swift in Sources */,
A1FC211C1BDFEB19003FD093 /* UIImage+ImageLoader.swift in Sources */,
65C68E5E19F501CF0053E66D /* UIImageView+ImageLoader.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
65B2CF1819EF9F6600DA3605 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
650F99421C0EC16E00540E8D /* UIImageViewTests.swift in Sources */,
A166A16B1C0B918700E71C42 /* URLLiteralConvertibleTests.swift in Sources */,
650F99401C0DBD5B00540E8D /* ManagerTests.swift in Sources */,
A1FC211D1BDFF5CB003FD093 /* UIImage+ImageLoader.swift in Sources */,
A1B7FEBF1A480F1800819BD1 /* Diskcached.swift in Sources */,
650F993C1C0DA09B00540E8D /* DiskcachedTests.swift in Sources */,
65B2CF2419EF9F6600DA3605 /* ImageLoaderTests.swift in Sources */,
65C68E5F19F501CF0053E66D /* UIImageView+ImageLoader.swift in Sources */,
65C68E6219F502B20053E66D /* ImageLoader.swift in Sources */,
A1E989321BCEC9BB00948F82 /* ImageLoaderExtensionTests.swift in Sources */,
A166A16D1C0C2A4000E71C42 /* LoaderTests.swift in Sources */,
A1E989321BCEC9BB00948F82 /* UIImageTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
26 changes: 21 additions & 5 deletions ImageLoader/Diskcached.swift
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ extension String {

class Diskcached {

private var storedData = [NSURL: NSData]()
var storedData = [NSURL: NSData]()

class Directory {
init() {
Expand Down Expand Up @@ -58,10 +58,23 @@ class Diskcached {
private let _subscript_queue = dispatch_queue_create("swift.imageloader.queues.diskcached.subscript", DISPATCH_QUEUE_CONCURRENT)
}

// MARK: accessor

extension Diskcached {

class func removeAllObjects() {
Diskcached().removeAllObjects()
}

func removeAllObjects() {
let manager = NSFileManager.defaultManager()
for subpath in manager.subpathsAtPath(directory.path) ?? [] {
let path = directory.path + "/" + subpath
do {
try manager.removeItemAtPath(path)
} catch _ {
}
}
}

private func objectForKey(aKey: NSURL) -> NSData? {
if let data = storedData[aKey] {
return data
Expand Down Expand Up @@ -92,9 +105,12 @@ extension Diskcached {
extension Diskcached: ImageLoaderCache {

subscript (aKey: NSURL) -> NSData? {

get {
return self.objectForKey(aKey)
var data : NSData?
dispatch_sync(_subscript_queue) {
data = self.objectForKey(aKey)
}
return data
}

set {
Expand Down
33 changes: 15 additions & 18 deletions ImageLoader/ImageLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,13 +63,11 @@ class Block: NSObject {
/**
Use to check state of loaders that manager has.
Ready: The manager have no loaders
Running: The manager has loaders, and they are running
Suspended: The manager has loaders, and their states are all suspended
Running: The manager has loaders
*/
public enum State {
case Ready
case Running
case Suspended
}

/**
Expand Down Expand Up @@ -109,21 +107,7 @@ public class Manager {
// MARK: state

var state: State {

var status = State.Ready
for loader in delegate.loaders.values {
switch loader.state {
case .Running:
status = .Running
case .Suspended:
if status == .Ready {
status = .Suspended
}
default:
break
}
}
return status
return delegate.isEmpty ? .Ready : .Running
}

// MARK: loading
Expand Down Expand Up @@ -190,6 +174,15 @@ public class Manager {
}
}

var isEmpty: Bool {
var isEmpty = false
dispatch_sync(_queue) {
isEmpty = self.loaders.isEmpty
}

return isEmpty
}

private func remove(URL: NSURL) -> Loader? {
if let loader = loaders[URL] {
loaders[URL] = nil
Expand Down Expand Up @@ -220,6 +213,10 @@ public class Manager {
completionHandler(nil)
}
}

deinit {
session.invalidateAndCancel()
}
}

/**
Expand Down
78 changes: 36 additions & 42 deletions ImageLoader/UIImage+ImageLoader.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,6 @@ import UIKit

// MARK: Optimize image

extension CGBitmapInfo {
private var alphaInfo: CGImageAlphaInfo? {
let info = intersect(.AlphaInfoMask)
return CGImageAlphaInfo(rawValue: info.rawValue)
}
}

extension UIImage {

func adjusts(size: CGSize, scale: CGFloat, contentMode: UIViewContentMode) -> UIImage {
Expand Down Expand Up @@ -55,6 +48,10 @@ extension UIImage {
}

private func render(size: CGSize) -> UIImage {
if size.width == 0 || size.height == 0 {
return self
}

UIGraphicsBeginImageContext(size)
drawInRect(CGRect(x: 0, y: 0, width: size.width, height: size.height))

Expand All @@ -80,49 +77,46 @@ extension UIImage {
return self
}

var image: UIImage?

autoreleasepool {
var bitmapInfoValue = CGImageGetBitmapInfo(CGImage).rawValue
let alphaInfo = CGImageGetAlphaInfo(CGImage)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorSpaceModel = CGColorSpaceGetModel(colorSpace)
switch (colorSpaceModel.rawValue) {
case CGColorSpaceModel.RGB.rawValue:

// Reference: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
var info = CGImageAlphaInfo.PremultipliedFirst
switch alphaInfo {
case .None:
info = CGImageAlphaInfo.NoneSkipFirst
default:
break
}
bitmapInfoValue &= ~CGBitmapInfo.AlphaInfoMask.rawValue
bitmapInfoValue |= info.rawValue
var bitmapInfoValue = CGImageGetBitmapInfo(CGImage).rawValue
let alphaInfo = CGImageGetAlphaInfo(CGImage)
let colorSpace = CGColorSpaceCreateDeviceRGB()
let colorSpaceModel = CGColorSpaceGetModel(colorSpace)
switch (colorSpaceModel.rawValue) {
case CGColorSpaceModel.RGB.rawValue:

// Reference: http://stackoverflow.com/questions/23723564/which-cgimagealphainfo-should-we-use
var info = CGImageAlphaInfo.PremultipliedFirst
switch alphaInfo {
case .None:
info = CGImageAlphaInfo.NoneSkipFirst
default:
break
}
bitmapInfoValue &= ~CGBitmapInfo.AlphaInfoMask.rawValue
bitmapInfoValue |= info.rawValue
default:
break
}

let context = CGBitmapContextCreate(
nil,
width,
height,
bitsPerComponent,
0,
colorSpace,
bitmapInfoValue
)
let context = CGBitmapContextCreate(
nil,
width,
height,
bitsPerComponent,
0,
colorSpace,
bitmapInfoValue
)

let frame = CGRect(x: 0, y: 0, width: width, height: height)
let frame = CGRect(x: 0, y: 0, width: width, height: height)

CGContextDrawImage(context, frame, CGImage)
CGContextDrawImage(context, frame, CGImage)

if let cgImage = CGBitmapContextCreateImage(context) {
image = UIImage(CGImage: cgImage)
}
CGContextClearRect(context, frame)
var image: UIImage?
if let cgImage = CGBitmapContextCreateImage(context) {
image = UIImage(CGImage: cgImage)
}
CGContextClearRect(context, frame)

return image ?? self
}
Expand Down
Loading