convert to Swift 3

This commit is contained in:
Sami Samhuri 2016-08-26 16:15:32 -07:00
parent 45538b940c
commit 9f38497427
7 changed files with 101 additions and 57 deletions

View file

@ -211,16 +211,18 @@
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0730;
LastUpgradeCheck = 0800;
TargetAttributes = {
30D75C221C57CE1400F4E62D = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
30D75C331C57D17400F4E62D = {
CreatedOnToolsVersion = 7.2;
};
30D75C401C57D2CA00F4E62D = {
CreatedOnToolsVersion = 7.2;
LastSwiftMigration = 0800;
};
};
};
@ -310,7 +312,24 @@
30D75C1C1C57CD6100F4E62D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
ONLY_ACTIVE_ARCH = YES;
};
name = Debug;
@ -318,6 +337,24 @@
30D75C1D1C57CD6100F4E62D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
};
name = Release;
};
@ -338,7 +375,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
@ -373,6 +410,7 @@
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
@ -396,7 +434,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@ -423,6 +461,7 @@
PRODUCT_NAME = CacheCreek;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_VERSION = 3.0;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
@ -447,6 +486,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
@ -504,6 +544,7 @@
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=appletvos*]" = "";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
@ -582,6 +623,7 @@
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 3.0;
};
name = Debug;
};
@ -622,6 +664,7 @@
PRODUCT_BUNDLE_IDENTIFIER = com.nuudles.CacheCreekTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_VERSION = 3.0;
VALIDATE_PRODUCT = YES;
};
name = Release;

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0730"
LastUpgradeVersion = "0800"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"

View file

@ -54,41 +54,41 @@ class CacheCreekTests: XCTestCase {
let floatKey: Float = 123.456
cache.set(item: 123.456, forKey: floatKey)
XCTAssert(cache.item(forKey: floatKey) as Double? == .Some(123.456))
XCTAssert(cache.item(forKey: floatKey) as Double? == .some(123.456))
cache[floatKey] = 456.789
XCTAssert(cache.count == 1)
XCTAssert(cache[floatKey] as? Double == .Some(456.789))
XCTAssert(cache[floatKey] as? Double == .some(456.789))
cache.set(item: "123.456", forKey: "123.456")
XCTAssert(cache.count == 2)
XCTAssert(cache.item(forKey: "123.456") as String? == .Some("123.456"))
XCTAssert(cache.item(forKey: "123.456") as String? == .some("123.456"))
let boolKey = true
cache.set(item: true, forKey: boolKey)
XCTAssert(cache.count == 3)
XCTAssert(cache.item(forKey: boolKey) as Bool? == .Some(true))
XCTAssert(cache.item(forKey: boolKey) as Bool? == .some(true))
cache.removeItem(forKey: boolKey)
XCTAssert(cache.count == 2)
XCTAssert(cache.item(forKey: boolKey) as Bool? == .None)
XCTAssert(cache.item(forKey: boolKey) as Bool? == .none)
}
func testSettingAndGettingEnum() {
let cache = LRUCache()
cache["ABC"] = TestEnum.ABC
cache["DEF"] = TestEnum.DEF("BlahBlahBlah")
cache["GHI"] = TestEnum.GHI(-500)
cache["ABC"] = TestEnum.abc
cache["DEF"] = TestEnum.def("BlahBlahBlah")
cache["GHI"] = TestEnum.ghi(-500)
guard let abc: TestEnum = cache.item(forKey: "ABC"),
def: TestEnum = cache.item(forKey: "DEF"),
ghi: TestEnum = cache.item(forKey: "GHI")
let def: TestEnum = cache.item(forKey: "DEF"),
let ghi: TestEnum = cache.item(forKey: "GHI")
else {
XCTFail()
return
}
switch (abc, def, ghi) {
case (.ABC, .DEF(let stringValue), .GHI(let intValue)):
case (.abc, .def(let stringValue), .ghi(let intValue)):
XCTAssert(stringValue == "BlahBlahBlah")
XCTAssert(intValue == -500)
default:
@ -101,30 +101,30 @@ class CacheCreekTests: XCTestCase {
// Int subscript
cache[123] = 123
XCTAssert(cache[123] as? Int == .Some(123))
XCTAssert(cache[123] as? Int == .some(123))
XCTAssert(cache.count == 1)
cache[123] = nil
XCTAssert(cache[123] as? Int == .None)
XCTAssert(cache[123] as? Int == .none)
XCTAssert(cache.count == 0)
// String subscript
cache["123"] = 123
XCTAssert(cache["123"] as? Int == .Some(123))
XCTAssert(cache["123"] as? Int == .some(123))
XCTAssert(cache.count == 1)
cache["123"] = nil
XCTAssert(cache["123"] as? Int == .None)
XCTAssert(cache["123"] as? Int == .none)
XCTAssert(cache.count == 0)
// Float subscript
let floatKey: Float = 3.14
cache[floatKey] = 123
XCTAssert(cache[floatKey] as? Int == .Some(123))
XCTAssert(cache[floatKey] as? Int == .some(123))
XCTAssert(cache.count == 1)
cache[floatKey] = nil
XCTAssert(cache[floatKey] as? Int == .None)
XCTAssert(cache[floatKey] as? Int == .none)
XCTAssert(cache.count == 0)
}
@ -158,7 +158,7 @@ class CacheCreekTests: XCTestCase {
XCTAssert(cache.count == 4)
NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidReceiveMemoryWarningNotification, object: UIApplication.sharedApplication())
NotificationCenter.default.post(name: NSNotification.Name.UIApplicationDidReceiveMemoryWarning, object: UIApplication.shared)
XCTAssert(cache.count == 0)
@ -169,7 +169,7 @@ class CacheCreekTests: XCTestCase {
XCTAssert(cache.count == 4)
NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidEnterBackgroundNotification, object: UIApplication.sharedApplication())
NotificationCenter.default.post(name: NSNotification.Name.UIApplicationDidEnterBackground, object: UIApplication.shared)
XCTAssert(cache.count == 0)
@ -238,13 +238,14 @@ class CacheCreekTests: XCTestCase {
func testObjCObjects() {
let cache = LRUCache()
let oldCache = NSCache()
cache.set(item: oldCache, forKey: "InceptionCache")
let boxedInt = NSNumber(value: 42)
cache.set(item: boxedInt, forKey: "Answer")
guard let _: NSCache = cache.item(forKey: "InceptionCache") else {
XCTFail("Expected an NSCache object")
guard let answer: NSNumber = cache.item(forKey: "Answer") else {
XCTFail("Expected an NSNumber object")
return
}
XCTAssert(answer.intValue == 42)
}
}
@ -254,7 +255,7 @@ private struct TestStruct {
}
private enum TestEnum {
case ABC
case DEF(String)
case GHI(Int)
case abc
case def(String)
case ghi(Int)
}

View file

@ -14,11 +14,11 @@ import Foundation
/// `AnyKey` is a simple struct that conforms to `Hashable` to allow any other `Hashable` key to be used in the cache dictionary
struct AnyKey: Hashable {
/// The underlying value
private let underlying: Any
fileprivate let underlying: Any
/// The hashing function
private let hashValueFunc: () -> Int
fileprivate let hashValueFunc: () -> Int
/// The equality function
private let equalityFunc: (Any) -> Bool
fileprivate let equalityFunc: (Any) -> Bool
init<T: Hashable>(_ key: T) {
underlying = key

View file

@ -9,17 +9,17 @@ struct DoublyLinkedList {
typealias Node = DoublyLinkedListNode
private(set) var head: Node?
fileprivate(set) var head: Node?
private(set) var tail: Node?
fileprivate(set) var tail: Node?
private(set) var count = 0
fileprivate(set) var count = 0
var isEmpty: Bool {
return head == nil
}
mutating func prepend(key key: AnyKey, value: Any) -> Node {
mutating func prepend(key: AnyKey, value: Any) -> Node {
let node = Node(key: key, value: value)
node.next = head
head?.prev = node
@ -31,7 +31,7 @@ struct DoublyLinkedList {
return node
}
mutating func append(key key: AnyKey, value: Any) -> Node {
mutating func append(key: AnyKey, value: Any) -> Node {
let node = Node(key: key, value: value)
node.prev = tail
tail?.next = node
@ -57,7 +57,7 @@ struct DoublyLinkedList {
return nil
}
mutating func remove(node node: Node) {
mutating func remove(node: Node) {
if node === head {
head = node.next
}
@ -72,9 +72,9 @@ struct DoublyLinkedList {
count -= 1
}
mutating func moveToHead(node node: Node) {
mutating func moveToHead(node: Node) {
remove(node: node)
prepend(key: node.key, value: node.value)
let _ = prepend(key: node.key, value: node.value)
}
}

View file

@ -12,16 +12,16 @@ import UIKit
/// `LRUCache` is an LRU cache that can hold anything, including Swift structs, enums, and values.
/// It is designed to work similar to the `NSCache`, but with native Swift support.
///
public class LRUCache {
public final class LRUCache {
// MARK: - Private variables
/// An array of `NSNotificationCenter` observers that need to be removed upon deinitialization
private var notificationObservers: [NSObjectProtocol] = []
fileprivate var notificationObservers: [NSObjectProtocol] = []
/// The list of cached items. Most recently used item at head, least recently used item at tail.
private var items: DoublyLinkedList = DoublyLinkedList()
fileprivate var items: DoublyLinkedList = DoublyLinkedList()
/// Maps keys of cached items to nodes in the linked list.
private var keyToNodeMap: [AnyKey:DoublyLinkedListNode] = [:]
fileprivate var keyToNodeMap: [AnyKey:DoublyLinkedListNode] = [:]
// MARK: - Public variables
/// The number of items in the cache.
@ -39,27 +39,27 @@ public class LRUCache {
// MARK: - Initialization methods
public init() {
let removalBlock = { [unowned self] (_: NSNotification) in
let removalBlock = { [unowned self] (_: Notification) in
self.removeAllItems()
}
var notificationObserver = NSNotificationCenter.defaultCenter()
.addObserverForName(UIApplicationDidReceiveMemoryWarningNotification,
object: UIApplication.sharedApplication(),
var notificationObserver = NotificationCenter.default
.addObserver(forName: NSNotification.Name.UIApplicationDidReceiveMemoryWarning,
object: UIApplication.shared,
queue: nil,
usingBlock: removalBlock)
using: removalBlock)
notificationObservers.append(notificationObserver)
notificationObserver = NSNotificationCenter.defaultCenter()
.addObserverForName(UIApplicationDidEnterBackgroundNotification,
object: UIApplication.sharedApplication(),
notificationObserver = NotificationCenter.default
.addObserver(forName: NSNotification.Name.UIApplicationDidEnterBackground,
object: UIApplication.shared,
queue: nil,
usingBlock: removalBlock)
using: removalBlock)
notificationObservers.append(notificationObserver)
}
deinit {
notificationObservers.forEach {
NSNotificationCenter.defaultCenter().removeObserver($0)
NotificationCenter.default.removeObserver($0)
}
}
@ -81,7 +81,7 @@ public class LRUCache {
/// - parameter item: The item to be cached
/// - parameter key: The key with which to cache the item
///
public func set<K: Hashable>(item item: Any, forKey key: K) {
public func set<K: Hashable>(item: Any, forKey key: K) {
let key = AnyKey(key)
if let existingNode = keyToNodeMap[key] {
items.remove(node: existingNode)