Initial source commit

This commit is contained in:
Christopher Luu 2016-01-26 15:05:06 -05:00
commit f93527d8cc
15 changed files with 1511 additions and 0 deletions

View file

@ -0,0 +1,19 @@
//
// CacheIsKing-iOS.h
// CacheIsKing-iOS
//
// Created by Christopher Luu on 1/26/16.
//
//
#import <UIKit/UIKit.h>
//! Project version number for CacheIsKing-iOS.
FOUNDATION_EXPORT double CacheIsKingVersionNumber;
//! Project version string for CacheIsKing-iOS.
FOUNDATION_EXPORT const unsigned char CacheIsKingVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <CacheIsKing_iOS/PublicHeader.h>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

View file

@ -0,0 +1,19 @@
//
// CacheIsKing-tvOS.h
// CacheIsKing-tvOS
//
// Created by Christopher Luu on 1/26/16.
//
//
#import <UIKit/UIKit.h>
//! Project version number for CacheIsKing-tvOS.
FOUNDATION_EXPORT double CacheIsKingsVersionNumber;
//! Project version string for CacheIsKing-tvOS.
FOUNDATION_EXPORT const unsigned char CacheIsKingVersionString[];
// In this header, you should import all the public headers of your framework using statements like #import <CacheIsKing_tvOS/PublicHeader.h>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>$(CURRENT_PROJECT_VERSION)</string>
<key>NSPrincipalClass</key>
<string></string>
</dict>
</plist>

16
CacheIsKing.podspec Normal file
View file

@ -0,0 +1,16 @@
Pod::Spec.new do |s|
s.name = 'CacheIsKing'
s.version = '0.0.1'
s.license = 'MIT'
s.summary = 'A simple cache that can hold Swift items'
s.homepage = 'https://github.com/nuudles/CacheIsKing'
s.authors = { 'Christopher Luu' => 'nuudles@gmail.com' }
s.source = { :git => 'https://github.com/nuudles/CacheIsKing.git', :tag => s.version }
s.ios.deployment_target = '8.0'
s.tvos.deployment_target = '9.0'
s.source_files = 'Source/*.swift'
s.requires_arc = true
end

View file

@ -0,0 +1,663 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 46;
objects = {
/* Begin PBXBuildFile section */
30D75C271C57CE1400F4E62D /* CacheIsKing.h in Headers */ = {isa = PBXBuildFile; fileRef = 30D75C261C57CE1400F4E62D /* CacheIsKing.h */; settings = {ATTRIBUTES = (Public, ); }; };
30D75C2E1C57CEC500F4E62D /* KingCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D75C2D1C57CEC500F4E62D /* KingCache.swift */; };
30D75C371C57D17400F4E62D /* CacheIsKing.h in Headers */ = {isa = PBXBuildFile; fileRef = 30D75C361C57D17400F4E62D /* CacheIsKing.h */; settings = {ATTRIBUTES = (Public, ); }; };
30D75C3C1C57D1A300F4E62D /* KingCache.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D75C2D1C57CEC500F4E62D /* KingCache.swift */; };
30D75C441C57D2CA00F4E62D /* CacheIsKingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D75C431C57D2CA00F4E62D /* CacheIsKingTests.swift */; };
30D75C461C57D2CA00F4E62D /* CacheIsKing.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 30D75C231C57CE1400F4E62D /* CacheIsKing.framework */; };
30D75C4D1C57F1C800F4E62D /* AnyKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D75C4C1C57F1C800F4E62D /* AnyKey.swift */; };
30D75C4E1C58033B00F4E62D /* AnyKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = 30D75C4C1C57F1C800F4E62D /* AnyKey.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
30D75C471C57D2CA00F4E62D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 30D75C181C57CD6100F4E62D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 30D75C221C57CE1400F4E62D;
remoteInfo = "CacheIsKing-iOS";
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
30D75C231C57CE1400F4E62D /* CacheIsKing.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CacheIsKing.framework; sourceTree = BUILT_PRODUCTS_DIR; };
30D75C261C57CE1400F4E62D /* CacheIsKing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheIsKing.h; sourceTree = "<group>"; };
30D75C281C57CE1400F4E62D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
30D75C2D1C57CEC500F4E62D /* KingCache.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KingCache.swift; sourceTree = "<group>"; };
30D75C341C57D17400F4E62D /* CacheIsKing.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = CacheIsKing.framework; sourceTree = BUILT_PRODUCTS_DIR; };
30D75C361C57D17400F4E62D /* CacheIsKing.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = CacheIsKing.h; sourceTree = "<group>"; };
30D75C381C57D17400F4E62D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
30D75C411C57D2CA00F4E62D /* CacheIsKingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = CacheIsKingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
30D75C431C57D2CA00F4E62D /* CacheIsKingTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CacheIsKingTests.swift; sourceTree = "<group>"; };
30D75C451C57D2CA00F4E62D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
30D75C4C1C57F1C800F4E62D /* AnyKey.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AnyKey.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
30D75C1F1C57CE1400F4E62D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C301C57D17400F4E62D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C3E1C57D2CA00F4E62D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C461C57D2CA00F4E62D /* CacheIsKing.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
30D75C171C57CD6100F4E62D = {
isa = PBXGroup;
children = (
30D75C2C1C57CEB600F4E62D /* Source */,
30D75C251C57CE1400F4E62D /* CacheIsKing-iOS */,
30D75C351C57D17400F4E62D /* CacheIsKing-tvOS */,
30D75C421C57D2CA00F4E62D /* CacheIsKingTests */,
30D75C241C57CE1400F4E62D /* Products */,
);
sourceTree = "<group>";
};
30D75C241C57CE1400F4E62D /* Products */ = {
isa = PBXGroup;
children = (
30D75C231C57CE1400F4E62D /* CacheIsKing.framework */,
30D75C341C57D17400F4E62D /* CacheIsKing.framework */,
30D75C411C57D2CA00F4E62D /* CacheIsKingTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
30D75C251C57CE1400F4E62D /* CacheIsKing-iOS */ = {
isa = PBXGroup;
children = (
30D75C261C57CE1400F4E62D /* CacheIsKing.h */,
30D75C281C57CE1400F4E62D /* Info.plist */,
);
path = "CacheIsKing-iOS";
sourceTree = "<group>";
};
30D75C2C1C57CEB600F4E62D /* Source */ = {
isa = PBXGroup;
children = (
30D75C2D1C57CEC500F4E62D /* KingCache.swift */,
30D75C4C1C57F1C800F4E62D /* AnyKey.swift */,
);
path = Source;
sourceTree = "<group>";
};
30D75C351C57D17400F4E62D /* CacheIsKing-tvOS */ = {
isa = PBXGroup;
children = (
30D75C361C57D17400F4E62D /* CacheIsKing.h */,
30D75C381C57D17400F4E62D /* Info.plist */,
);
path = "CacheIsKing-tvOS";
sourceTree = "<group>";
};
30D75C421C57D2CA00F4E62D /* CacheIsKingTests */ = {
isa = PBXGroup;
children = (
30D75C431C57D2CA00F4E62D /* CacheIsKingTests.swift */,
30D75C451C57D2CA00F4E62D /* Info.plist */,
);
path = CacheIsKingTests;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
30D75C201C57CE1400F4E62D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C271C57CE1400F4E62D /* CacheIsKing.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C311C57D17400F4E62D /* Headers */ = {
isa = PBXHeadersBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C371C57D17400F4E62D /* CacheIsKing.h in Headers */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXHeadersBuildPhase section */
/* Begin PBXNativeTarget section */
30D75C221C57CE1400F4E62D /* CacheIsKing-iOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 30D75C291C57CE1400F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKing-iOS" */;
buildPhases = (
30D75C1E1C57CE1400F4E62D /* Sources */,
30D75C1F1C57CE1400F4E62D /* Frameworks */,
30D75C201C57CE1400F4E62D /* Headers */,
30D75C211C57CE1400F4E62D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "CacheIsKing-iOS";
productName = "CacheIsKing-iOS";
productReference = 30D75C231C57CE1400F4E62D /* CacheIsKing.framework */;
productType = "com.apple.product-type.framework";
};
30D75C331C57D17400F4E62D /* CacheIsKing-tvOS */ = {
isa = PBXNativeTarget;
buildConfigurationList = 30D75C391C57D17400F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKing-tvOS" */;
buildPhases = (
30D75C2F1C57D17400F4E62D /* Sources */,
30D75C301C57D17400F4E62D /* Frameworks */,
30D75C311C57D17400F4E62D /* Headers */,
30D75C321C57D17400F4E62D /* Resources */,
);
buildRules = (
);
dependencies = (
);
name = "CacheIsKing-tvOS";
productName = "CacheIsKing-tvOS";
productReference = 30D75C341C57D17400F4E62D /* CacheIsKing.framework */;
productType = "com.apple.product-type.framework";
};
30D75C401C57D2CA00F4E62D /* CacheIsKingTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 30D75C491C57D2CA00F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKingTests" */;
buildPhases = (
30D75C3D1C57D2CA00F4E62D /* Sources */,
30D75C3E1C57D2CA00F4E62D /* Frameworks */,
30D75C3F1C57D2CA00F4E62D /* Resources */,
);
buildRules = (
);
dependencies = (
30D75C481C57D2CA00F4E62D /* PBXTargetDependency */,
);
name = CacheIsKingTests;
productName = CacheIsKingTests;
productReference = 30D75C411C57D2CA00F4E62D /* CacheIsKingTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
30D75C181C57CD6100F4E62D /* Project object */ = {
isa = PBXProject;
attributes = {
LastSwiftUpdateCheck = 0720;
LastUpgradeCheck = 0720;
TargetAttributes = {
30D75C221C57CE1400F4E62D = {
CreatedOnToolsVersion = 7.2;
};
30D75C331C57D17400F4E62D = {
CreatedOnToolsVersion = 7.2;
};
30D75C401C57D2CA00F4E62D = {
CreatedOnToolsVersion = 7.2;
};
};
};
buildConfigurationList = 30D75C1B1C57CD6100F4E62D /* Build configuration list for PBXProject "CacheIsKing" */;
compatibilityVersion = "Xcode 3.2";
developmentRegion = English;
hasScannedForEncodings = 0;
knownRegions = (
en,
);
mainGroup = 30D75C171C57CD6100F4E62D;
productRefGroup = 30D75C241C57CE1400F4E62D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
30D75C221C57CE1400F4E62D /* CacheIsKing-iOS */,
30D75C331C57D17400F4E62D /* CacheIsKing-tvOS */,
30D75C401C57D2CA00F4E62D /* CacheIsKingTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
30D75C211C57CE1400F4E62D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C321C57D17400F4E62D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C3F1C57D2CA00F4E62D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
30D75C1E1C57CE1400F4E62D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C4D1C57F1C800F4E62D /* AnyKey.swift in Sources */,
30D75C2E1C57CEC500F4E62D /* KingCache.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C2F1C57D17400F4E62D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C4E1C58033B00F4E62D /* AnyKey.swift in Sources */,
30D75C3C1C57D1A300F4E62D /* KingCache.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
30D75C3D1C57D2CA00F4E62D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
30D75C441C57D2CA00F4E62D /* CacheIsKingTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
30D75C481C57D2CA00F4E62D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 30D75C221C57CE1400F4E62D /* CacheIsKing-iOS */;
targetProxy = 30D75C471C57D2CA00F4E62D /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
30D75C1C1C57CD6100F4E62D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Debug;
};
30D75C1D1C57CD6100F4E62D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
};
name = Release;
};
30D75C2A1C57CE1400F4E62D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
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";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "CacheIsKing-iOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.nuudles.CacheIsKing-iOS";
PRODUCT_NAME = CacheIsKing;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = "1,2";
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
30D75C2B1C57CE1400F4E62D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
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";
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "CacheIsKing-iOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.nuudles.CacheIsKing-iOS";
PRODUCT_NAME = CacheIsKing;
SDKROOT = iphoneos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
30D75C3A1C57D17400F4E62D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = dwarf;
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "CacheIsKing-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = "com.nuudles.CacheIsKing-tvOS";
PRODUCT_NAME = CacheIsKing;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Debug;
};
30D75C3B1C57D17400F4E62D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
COPY_PHASE_STRIP = NO;
CURRENT_PROJECT_VERSION = 1;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
DEFINES_MODULE = YES;
DYLIB_COMPATIBILITY_VERSION = 1;
DYLIB_CURRENT_VERSION = 1;
DYLIB_INSTALL_NAME_BASE = "@rpath";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = "CacheIsKing-tvOS/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = "com.nuudles.CacheIsKing-tvOS";
PRODUCT_NAME = CacheIsKing;
SDKROOT = appletvos;
SKIP_INSTALL = YES;
TARGETED_DEVICE_FAMILY = 3;
TVOS_DEPLOYMENT_TARGET = 9.0;
VALIDATE_PRODUCT = YES;
VERSIONING_SYSTEM = "apple-generic";
VERSION_INFO_PREFIX = "";
};
name = Release;
};
30D75C4A1C57D2CA00F4E62D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
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";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = CacheIsKingTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
PRODUCT_BUNDLE_IDENTIFIER = com.nuudles.CacheIsKingTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
};
name = Debug;
};
30D75C4B1C57D2CA00F4E62D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
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";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
INFOPLIST_FILE = CacheIsKingTests/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.2;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MTL_ENABLE_DEBUG_INFO = NO;
PRODUCT_BUNDLE_IDENTIFIER = com.nuudles.CacheIsKingTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
VALIDATE_PRODUCT = YES;
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
30D75C1B1C57CD6100F4E62D /* Build configuration list for PBXProject "CacheIsKing" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30D75C1C1C57CD6100F4E62D /* Debug */,
30D75C1D1C57CD6100F4E62D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
30D75C291C57CE1400F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKing-iOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30D75C2A1C57CE1400F4E62D /* Debug */,
30D75C2B1C57CE1400F4E62D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
30D75C391C57D17400F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKing-tvOS" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30D75C3A1C57D17400F4E62D /* Debug */,
30D75C3B1C57D17400F4E62D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
30D75C491C57D2CA00F4E62D /* Build configuration list for PBXNativeTarget "CacheIsKingTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
30D75C4A1C57D2CA00F4E62D /* Debug */,
30D75C4B1C57D2CA00F4E62D /* Release */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 30D75C181C57CD6100F4E62D /* Project object */;
}

View file

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:CacheIsKing.xcodeproj">
</FileRef>
</Workspace>

View file

@ -0,0 +1,100 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C221C57CE1400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-iOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
codeCoverageEnabled = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C401C57D2CA00F4E62D"
BuildableName = "CacheIsKingTests.xctest"
BlueprintName = "CacheIsKingTests"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C221C57CE1400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-iOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C221C57CE1400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-iOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C221C57CE1400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-iOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,80 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0720"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C331C57D17400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-tvOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C331C57D17400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-tvOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "30D75C331C57D17400F4E62D"
BuildableName = "CacheIsKing.framework"
BlueprintName = "CacheIsKing-tvOS"
ReferencedContainer = "container:CacheIsKing.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View file

@ -0,0 +1,246 @@
//
// CacheIsKingTests.swift
// CacheIsKingTests
//
// Created by Christopher Luu on 1/26/16.
//
//
import XCTest
@testable import CacheIsKing
class CacheIsKingTests: XCTestCase {
func testSettingAndGettingItems() {
let cache = KingCache()
cache.setItem(123, forKey: "123")
XCTAssert(cache.cacheDictionary.count == 1)
XCTAssert(cache.count == 1)
XCTAssert(cache.itemForKey("123") == 123)
XCTAssert(cache.cacheDictionary[AnyKey("123")] as? Int == .Some(123))
XCTAssert(cache[123] == nil)
cache[234] = "234"
XCTAssert(cache.cacheDictionary.count == 2)
XCTAssert(cache.count == 2)
XCTAssert(cache.itemForKey(234) == "234")
XCTAssert(cache.cacheDictionary[AnyKey(234)] as? String == .Some("234"))
// Test setting/getting an array
let array = [1, 2, 3, 4, 5]
cache[5] = array
XCTAssert(cache.cacheDictionary.count == 3)
XCTAssert(cache.count == 3)
if let fetchedArray: [Int] = cache.itemForKey(5) {
XCTAssert(fetchedArray == array)
}
else {
XCTFail("Expected an int array")
}
let testStruct = TestStruct(name: "Testing", value: Int(arc4random_uniform(100000)))
cache["TestingStruct"] = testStruct
guard let fetchedStruct: TestStruct = cache.itemForKey("TestingStruct") else {
XCTFail()
return
}
XCTAssert(testStruct.name == fetchedStruct.name)
XCTAssert(testStruct.value == fetchedStruct.value)
}
func testDifferentKindsOfKeys() {
let cache = KingCache()
let floatKey: Float = 123.456
cache.setItem(123.456, forKey: floatKey)
XCTAssert(cache.itemForKey(floatKey) as Double? == .Some(123.456))
cache[floatKey] = 456.789
XCTAssert(cache.count == 1)
XCTAssert(cache[floatKey] as? Double == .Some(456.789))
cache.setItem("123.456", forKey: "123.456")
XCTAssert(cache.count == 2)
XCTAssert(cache.itemForKey("123.456") as String? == .Some("123.456"))
let boolKey = true
cache.setItem(true, forKey: boolKey)
XCTAssert(cache.count == 3)
XCTAssert(cache.itemForKey(boolKey) as Bool? == .Some(true))
cache.removeItemForKey(boolKey)
XCTAssert(cache.count == 2)
XCTAssert(cache.itemForKey(boolKey) as Bool? == .None)
}
func testSettingAndGettingEnum() {
let cache = KingCache()
cache["ABC"] = TestEnum.ABC
cache["DEF"] = TestEnum.DEF("BlahBlahBlah")
cache["GHI"] = TestEnum.GHI(-500)
guard let abc: TestEnum = cache.itemForKey("ABC"),
def: TestEnum = cache.itemForKey("DEF"),
ghi: TestEnum = cache.itemForKey("GHI")
else {
XCTFail()
return
}
switch (abc, def, ghi) {
case (.ABC, .DEF(let stringValue), .GHI(let intValue)):
XCTAssert(stringValue == "BlahBlahBlah")
XCTAssert(intValue == -500)
default:
XCTFail()
}
}
func testSubscripts() {
let cache = KingCache()
// Int subscript
cache[123] = 123
XCTAssert(cache[123] as? Int == .Some(123))
XCTAssert(cache.count == 1)
cache[123] = nil
XCTAssert(cache[123] as? Int == .None)
XCTAssert(cache.count == 0)
// String subscript
cache["123"] = 123
XCTAssert(cache["123"] as? Int == .Some(123))
XCTAssert(cache.count == 1)
cache["123"] = nil
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.count == 1)
cache[floatKey] = nil
XCTAssert(cache[floatKey] as? Int == .None)
XCTAssert(cache.count == 0)
}
func testRemovingItems() {
let cache = KingCache()
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
XCTAssert(cache.count == 4)
cache.removeItemForKey(123)
XCTAssert(cache.count == 3)
XCTAssert(cache[123] == nil)
cache[234] = nil
XCTAssert(cache.count == 2)
XCTAssert(cache[234] == nil)
cache.removeAllItems()
XCTAssert(cache.count == 0)
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
XCTAssert(cache.count == 4)
NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidReceiveMemoryWarningNotification, object: nil)
XCTAssert(cache.count == 0)
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
XCTAssert(cache.count == 4)
NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidEnterBackgroundNotification, object: nil)
XCTAssert(cache.count == 0)
}
func testCountLimit() {
let cache = KingCache()
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
XCTAssert(cache.count == 4)
cache.countLimit = 3
XCTAssert(cache.count == 3)
cache.removeAllItems()
XCTAssert(cache.count == 0)
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
XCTAssert(cache.count == 3)
cache[567] = 567
XCTAssert(cache.count == 3)
cache.removeAllItems()
cache.setItem(123, forKey: 123)
cache.setItem(234, forKey: 234)
cache.setItem(345, forKey: 345)
cache.setItem(456, forKey: 456)
cache.countLimit = 2
XCTAssert(cache.count == 2)
}
func testEmptyEviction() {
// Make sure that an eviction on an empty dictionary doesn't crash
let cache = KingCache()
cache.evictItemsIfNeeded()
}
func testObjCObjects() {
let cache = KingCache()
let oldCache = NSCache()
cache.setItem(oldCache, forKey: "InceptionCache")
guard let _: NSCache = cache.itemForKey("InceptionCache") else {
XCTFail("Expected an NSCache object")
return
}
}
}
private struct TestStruct {
let name: String
let value: Int
}
private enum TestEnum {
case ABC
case DEF(String)
case GHI(Int)
}

View file

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
<string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>$(PRODUCT_NAME)</string>
<key>CFBundlePackageType</key>
<string>BNDL</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1</string>
</dict>
</plist>

21
LICENSE Normal file
View file

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Christopher Luu
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

94
README.md Normal file
View file

@ -0,0 +1,94 @@
# CacheIsKing
<a href="https://github.com/Carthage/Carthage/issues/179">
<img src="https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat">
</a>
`CacheIsKing` is a simple cache that allows you to store any item, including objects, pure Swift structs, enums (with associated values), etc. Simply put, it's designed to act like an `NSCache` for everything, including Swift variables.
## Features
- Simply set, get, and remove items based on any key that is `Hashable`
- The cache is cleared when the app receives a memory warning
- Similar to `NSCache`, the cache is cleared when the app enters the background
- Subscripts are supported for `String`, `Int`, and `Float` keys
- `itemForKey` uses generics so you don't have to cast the return value when the type is inferred correctly
- Similar to `NSCache`, the cache can have a `countLimit` set to ensure that the cache doesn't get too large
## Requirements
- iOS 8.0+
- tvOS 9.0+
- Xcode 7+
## Installation using CocoaPods
[CocoaPods](http://cocoapods.org) is a dependency manager for Cocoa projects.
Because `CacheIsKing ` is written in Swift, you must use frameworks.
To integrate `CacheIsKing ` into your Xcode project using CocoaPods, specify it in your `Podfile`:
```ruby
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
pod 'CacheIsKing'
```
Then, run the following command:
```bash
$ pod install
```
## Installation using Carthage
Add this to your `Cartfile`:
```
github "nuudles/CacheIsKing"
```
## Usage
Simply use the `KingCache` class similar to how you'd use a `NSCache`. Using the `setItem` and `itemForKey` methods allow you to use type inference to get the values you want.
```swift
let cache = KingCache()
cache.setItem(123, forKey: "123")
if let item: Int = cache.itemForKey(456) {
doSomethingWithItem(item)
}
```
You can also use subscripts to set/get items from the cache. Unfortunately since Swift doesn't support subscript methods with generics yet, you'll have to cast your items as necessary. Also currently only `String`, `Int`, and `Float` keys are supported:
```swift
let cache = KingCache()
cache["123"] = 123
if let item = cache[456] as? Int {
doSomethingWithItem(item)
}
```
The `KingCache` also has a `countLimit` property, which allows you to set the maximum number of items in the cache. It currently evicts randomly until the `countLimit` is met.
```swift
let cache = KingCache()
cache.countLimit = 2
cache[123] = 123
cache[234] = 234
cache[345] = 345
print("\(cache.count)") // shows a count of 2
```
## TODO
- Refine eviction algorithm (currently evicts randomly)
- Update with better subscript support once Swift supports subscripts with generics

39
Source/AnyKey.swift Normal file
View file

@ -0,0 +1,39 @@
//
// AnyKey.swift
// CacheIsKing
//
// Created by Christopher Luu on 1/26/16.
//
//
import Foundation
/// This code was taken from:
/// http://stackoverflow.com/questions/24119624/how-to-create-dictionary-that-can-hold-anything-in-key-or-all-the-possible-type
struct AnyKey: Hashable {
private let underlying: Any
private let hashValueFunc: () -> Int
private let equalityFunc: (Any) -> Bool
init<T: Hashable>(_ key: T) {
underlying = key
// Capture the key's hashability and equatability using closures.
// The Key shares the hash of the underlying value.
hashValueFunc = { key.hashValue }
// The Key is equal to a Key of the same underlying type,
// whose underlying value is "==" to ours.
equalityFunc = {
if let other = $0 as? T {
return key == other
}
return false
}
}
var hashValue: Int { return hashValueFunc() }
}
func ==(x: AnyKey, y: AnyKey) -> Bool {
return x.equalityFunc(y.underlying)
}

131
Source/KingCache.swift Normal file
View file

@ -0,0 +1,131 @@
//
// KingCache.swift
// CacheIsKing
//
// Created by Christopher Luu on 1/26/16.
//
//
import Foundation
public class KingCache {
// MARK: - Private variables
private var notificationObservers: [NSObjectProtocol] = []
// MARK: - Internal variables
var cacheDictionary: [AnyKey: Any] = [:]
// MARK: - Public variables
public var count: Int {
return cacheDictionary.count
}
public var countLimit: UInt = 0 {
didSet {
evictItemsIfNeeded()
}
}
// MARK: - Initialization methods
public init() {
let removalBlock = { [unowned self] (_: NSNotification) in
self.cacheDictionary.removeAll()
}
var notificationObserver = NSNotificationCenter.defaultCenter()
.addObserverForName(UIApplicationDidReceiveMemoryWarningNotification,
object: nil,
queue: nil,
usingBlock: removalBlock)
notificationObservers.append(notificationObserver)
notificationObserver = NSNotificationCenter.defaultCenter()
.addObserverForName(UIApplicationDidEnterBackgroundNotification,
object: nil,
queue: nil,
usingBlock: removalBlock)
notificationObservers.append(notificationObserver)
}
deinit {
notificationObservers.forEach {
NSNotificationCenter.defaultCenter().removeObserver($0)
}
}
// MARK: - Internal methods
func evictItemsIfNeeded() {
if countLimit > 0 && cacheDictionary.count > Int(countLimit) {
// TODO: Evict items with more rhyme or reason
var keys = cacheDictionary.keys.flatMap { $0 }
while cacheDictionary.count > Int(countLimit) {
let randomIndex = Int(arc4random_uniform(UInt32(keys.count)))
let key = keys.removeAtIndex(randomIndex)
cacheDictionary.removeValueForKey(key)
}
}
}
// MARK: - Public methods
public func setItem<K: Hashable>(item: Any, forKey key: K) {
cacheDictionary[AnyKey(key)] = item
evictItemsIfNeeded()
}
public func itemForKey<T, K: Hashable>(key: K) -> T? {
if let item = cacheDictionary[AnyKey(key)] as? T {
return item
}
return nil
}
public func removeItemForKey<K: Hashable>(key: K) {
cacheDictionary[AnyKey(key)] = nil
}
public func removeAllItems() {
cacheDictionary.removeAll()
}
// MARK: - Subscript methods
// TODO: Consolidate these subscript methods once subscript generics with constraints are supported
public subscript(key: Int) -> Any? {
get {
return itemForKey(key)
}
set {
if let newValue = newValue {
setItem(newValue, forKey: key)
}
else {
removeItemForKey(key)
}
}
}
public subscript(key: Float) -> Any? {
get {
return itemForKey(key)
}
set {
if let newValue = newValue {
setItem(newValue, forKey: key)
}
else {
removeItemForKey(key)
}
}
}
public subscript(key: String) -> Any? {
get {
return itemForKey(key)
}
set {
if let newValue = newValue {
setItem(newValue, forKey: key)
}
else {
removeItemForKey(key)
}
}
}
}