├── .gitignore ├── Cartfile.private ├── Cartfile.resolved ├── Example └── MonakaExample │ ├── MonakaExample.xcodeproj │ ├── project.pbxproj │ └── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── MonakaExample │ ├── AppDelegate.swift │ ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json │ ├── Base.lproj │ └── LaunchScreen.storyboard │ ├── Info.plist │ ├── Sample.swift │ └── ViewController.swift ├── LICENSE ├── Logo.png ├── Logo2.png ├── Monaka.png ├── Monaka.podspec ├── Monaka.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata └── xcshareddata │ └── xcschemes │ └── Monaka.xcscheme ├── Monaka ├── Info.plist └── Monaka.h ├── MonakaTests ├── CustomPackableSpec.swift ├── Info.plist └── PackablesSpec.swift ├── README.md ├── Sources ├── CustomPackable.swift ├── Monaka.swift ├── Packable.swift └── Packables.swift └── WhatMonaka.png /.gitignore: -------------------------------------------------------------------------------- 1 | # Xcode 2 | # 3 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore 4 | 5 | ## Build generated 6 | build/ 7 | DerivedData/ 8 | 9 | ## Various settings 10 | *.pbxuser 11 | !default.pbxuser 12 | *.mode1v3 13 | !default.mode1v3 14 | *.mode2v3 15 | !default.mode2v3 16 | *.perspectivev3 17 | !default.perspectivev3 18 | xcuserdata/ 19 | 20 | ## Other 21 | *.moved-aside 22 | *.xcuserstate 23 | *.swp 24 | !.gitkeep 25 | .DS_Store 26 | 27 | ## Obj-C/Swift specific 28 | *.hmap 29 | *.ipa 30 | *.dSYM.zip 31 | *.dSYM 32 | 33 | # CocoaPods 34 | # Pods/ 35 | 36 | # Carthage 37 | Carthage/Checkouts 38 | Carthage/Build 39 | 40 | -------------------------------------------------------------------------------- /Cartfile.private: -------------------------------------------------------------------------------- 1 | github "Quick/Quick" 2 | github "Quick/Nimble" 3 | -------------------------------------------------------------------------------- /Cartfile.resolved: -------------------------------------------------------------------------------- 1 | github "Quick/Nimble" "v4.1.0" 2 | github "Quick/Quick" "v0.9.3" 3 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 437933551D64AB0E009C1D13 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933541D64AB0E009C1D13 /* AppDelegate.swift */; }; 11 | 437933571D64AB0E009C1D13 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933561D64AB0E009C1D13 /* ViewController.swift */; }; 12 | 4379335C1D64AB0E009C1D13 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 4379335B1D64AB0E009C1D13 /* Assets.xcassets */; }; 13 | 4379335F1D64AB0E009C1D13 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 4379335D1D64AB0E009C1D13 /* LaunchScreen.storyboard */; }; 14 | 4379338D1D656184009C1D13 /* CustomPackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933891D656184009C1D13 /* CustomPackable.swift */; }; 15 | 4379338E1D656184009C1D13 /* Monaka.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4379338A1D656184009C1D13 /* Monaka.swift */; }; 16 | 4379338F1D656184009C1D13 /* Packable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4379338B1D656184009C1D13 /* Packable.swift */; }; 17 | 437933901D656184009C1D13 /* Packables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4379338C1D656184009C1D13 /* Packables.swift */; }; 18 | 43B5F6B21D6FDB6A00399A8B /* Sample.swift in Sources */ = {isa = PBXBuildFile; fileRef = 43B5F6B11D6FDB6A00399A8B /* Sample.swift */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 437933511D64AB0E009C1D13 /* MonakaExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MonakaExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 437933541D64AB0E009C1D13 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 24 | 437933561D64AB0E009C1D13 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 25 | 4379335B1D64AB0E009C1D13 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 26 | 4379335E1D64AB0E009C1D13 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 27 | 437933601D64AB0E009C1D13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 28 | 437933891D656184009C1D13 /* CustomPackable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomPackable.swift; sourceTree = ""; }; 29 | 4379338A1D656184009C1D13 /* Monaka.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Monaka.swift; sourceTree = ""; }; 30 | 4379338B1D656184009C1D13 /* Packable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Packable.swift; sourceTree = ""; }; 31 | 4379338C1D656184009C1D13 /* Packables.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Packables.swift; sourceTree = ""; }; 32 | 43B5F6B11D6FDB6A00399A8B /* Sample.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Sample.swift; sourceTree = ""; }; 33 | /* End PBXFileReference section */ 34 | 35 | /* Begin PBXFrameworksBuildPhase section */ 36 | 4379334E1D64AB0E009C1D13 /* Frameworks */ = { 37 | isa = PBXFrameworksBuildPhase; 38 | buildActionMask = 2147483647; 39 | files = ( 40 | ); 41 | runOnlyForDeploymentPostprocessing = 0; 42 | }; 43 | /* End PBXFrameworksBuildPhase section */ 44 | 45 | /* Begin PBXGroup section */ 46 | 437933481D64AB0E009C1D13 = { 47 | isa = PBXGroup; 48 | children = ( 49 | 437933531D64AB0E009C1D13 /* MonakaExample */, 50 | 437933871D65615D009C1D13 /* Vender */, 51 | 437933521D64AB0E009C1D13 /* Products */, 52 | ); 53 | sourceTree = ""; 54 | }; 55 | 437933521D64AB0E009C1D13 /* Products */ = { 56 | isa = PBXGroup; 57 | children = ( 58 | 437933511D64AB0E009C1D13 /* MonakaExample.app */, 59 | ); 60 | name = Products; 61 | sourceTree = ""; 62 | }; 63 | 437933531D64AB0E009C1D13 /* MonakaExample */ = { 64 | isa = PBXGroup; 65 | children = ( 66 | 437933541D64AB0E009C1D13 /* AppDelegate.swift */, 67 | 437933561D64AB0E009C1D13 /* ViewController.swift */, 68 | 43B5F6B11D6FDB6A00399A8B /* Sample.swift */, 69 | 4379335B1D64AB0E009C1D13 /* Assets.xcassets */, 70 | 4379335D1D64AB0E009C1D13 /* LaunchScreen.storyboard */, 71 | 437933601D64AB0E009C1D13 /* Info.plist */, 72 | ); 73 | path = MonakaExample; 74 | sourceTree = ""; 75 | }; 76 | 437933871D65615D009C1D13 /* Vender */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 437933881D656184009C1D13 /* Sources */, 80 | ); 81 | name = Vender; 82 | path = MonakaExample; 83 | sourceTree = ""; 84 | }; 85 | 437933881D656184009C1D13 /* Sources */ = { 86 | isa = PBXGroup; 87 | children = ( 88 | 4379338A1D656184009C1D13 /* Monaka.swift */, 89 | 4379338B1D656184009C1D13 /* Packable.swift */, 90 | 4379338C1D656184009C1D13 /* Packables.swift */, 91 | 437933891D656184009C1D13 /* CustomPackable.swift */, 92 | ); 93 | name = Sources; 94 | path = ../../../Sources; 95 | sourceTree = ""; 96 | }; 97 | /* End PBXGroup section */ 98 | 99 | /* Begin PBXNativeTarget section */ 100 | 437933501D64AB0E009C1D13 /* MonakaExample */ = { 101 | isa = PBXNativeTarget; 102 | buildConfigurationList = 437933631D64AB0E009C1D13 /* Build configuration list for PBXNativeTarget "MonakaExample" */; 103 | buildPhases = ( 104 | 4379334D1D64AB0E009C1D13 /* Sources */, 105 | 4379334E1D64AB0E009C1D13 /* Frameworks */, 106 | 4379334F1D64AB0E009C1D13 /* Resources */, 107 | ); 108 | buildRules = ( 109 | ); 110 | dependencies = ( 111 | ); 112 | name = MonakaExample; 113 | productName = MonakaExample; 114 | productReference = 437933511D64AB0E009C1D13 /* MonakaExample.app */; 115 | productType = "com.apple.product-type.application"; 116 | }; 117 | /* End PBXNativeTarget section */ 118 | 119 | /* Begin PBXProject section */ 120 | 437933491D64AB0E009C1D13 /* Project object */ = { 121 | isa = PBXProject; 122 | attributes = { 123 | LastSwiftUpdateCheck = 0730; 124 | LastUpgradeCheck = 0730; 125 | ORGANIZATIONNAME = naru; 126 | TargetAttributes = { 127 | 437933501D64AB0E009C1D13 = { 128 | CreatedOnToolsVersion = 7.3.1; 129 | }; 130 | }; 131 | }; 132 | buildConfigurationList = 4379334C1D64AB0E009C1D13 /* Build configuration list for PBXProject "MonakaExample" */; 133 | compatibilityVersion = "Xcode 3.2"; 134 | developmentRegion = English; 135 | hasScannedForEncodings = 0; 136 | knownRegions = ( 137 | en, 138 | Base, 139 | ); 140 | mainGroup = 437933481D64AB0E009C1D13; 141 | productRefGroup = 437933521D64AB0E009C1D13 /* Products */; 142 | projectDirPath = ""; 143 | projectRoot = ""; 144 | targets = ( 145 | 437933501D64AB0E009C1D13 /* MonakaExample */, 146 | ); 147 | }; 148 | /* End PBXProject section */ 149 | 150 | /* Begin PBXResourcesBuildPhase section */ 151 | 4379334F1D64AB0E009C1D13 /* Resources */ = { 152 | isa = PBXResourcesBuildPhase; 153 | buildActionMask = 2147483647; 154 | files = ( 155 | 4379335F1D64AB0E009C1D13 /* LaunchScreen.storyboard in Resources */, 156 | 4379335C1D64AB0E009C1D13 /* Assets.xcassets in Resources */, 157 | ); 158 | runOnlyForDeploymentPostprocessing = 0; 159 | }; 160 | /* End PBXResourcesBuildPhase section */ 161 | 162 | /* Begin PBXSourcesBuildPhase section */ 163 | 4379334D1D64AB0E009C1D13 /* Sources */ = { 164 | isa = PBXSourcesBuildPhase; 165 | buildActionMask = 2147483647; 166 | files = ( 167 | 437933901D656184009C1D13 /* Packables.swift in Sources */, 168 | 437933571D64AB0E009C1D13 /* ViewController.swift in Sources */, 169 | 437933551D64AB0E009C1D13 /* AppDelegate.swift in Sources */, 170 | 43B5F6B21D6FDB6A00399A8B /* Sample.swift in Sources */, 171 | 4379338F1D656184009C1D13 /* Packable.swift in Sources */, 172 | 4379338E1D656184009C1D13 /* Monaka.swift in Sources */, 173 | 4379338D1D656184009C1D13 /* CustomPackable.swift in Sources */, 174 | ); 175 | runOnlyForDeploymentPostprocessing = 0; 176 | }; 177 | /* End PBXSourcesBuildPhase section */ 178 | 179 | /* Begin PBXVariantGroup section */ 180 | 4379335D1D64AB0E009C1D13 /* LaunchScreen.storyboard */ = { 181 | isa = PBXVariantGroup; 182 | children = ( 183 | 4379335E1D64AB0E009C1D13 /* Base */, 184 | ); 185 | name = LaunchScreen.storyboard; 186 | sourceTree = ""; 187 | }; 188 | /* End PBXVariantGroup section */ 189 | 190 | /* Begin XCBuildConfiguration section */ 191 | 437933611D64AB0E009C1D13 /* Debug */ = { 192 | isa = XCBuildConfiguration; 193 | buildSettings = { 194 | ALWAYS_SEARCH_USER_PATHS = NO; 195 | CLANG_ANALYZER_NONNULL = YES; 196 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 197 | CLANG_CXX_LIBRARY = "libc++"; 198 | CLANG_ENABLE_MODULES = YES; 199 | CLANG_ENABLE_OBJC_ARC = YES; 200 | CLANG_WARN_BOOL_CONVERSION = YES; 201 | CLANG_WARN_CONSTANT_CONVERSION = YES; 202 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 203 | CLANG_WARN_EMPTY_BODY = YES; 204 | CLANG_WARN_ENUM_CONVERSION = YES; 205 | CLANG_WARN_INT_CONVERSION = YES; 206 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 207 | CLANG_WARN_UNREACHABLE_CODE = YES; 208 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 209 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 210 | COPY_PHASE_STRIP = NO; 211 | DEBUG_INFORMATION_FORMAT = dwarf; 212 | ENABLE_STRICT_OBJC_MSGSEND = YES; 213 | ENABLE_TESTABILITY = YES; 214 | GCC_C_LANGUAGE_STANDARD = gnu99; 215 | GCC_DYNAMIC_NO_PIC = NO; 216 | GCC_NO_COMMON_BLOCKS = YES; 217 | GCC_OPTIMIZATION_LEVEL = 0; 218 | GCC_PREPROCESSOR_DEFINITIONS = ( 219 | "DEBUG=1", 220 | "$(inherited)", 221 | ); 222 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 223 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 224 | GCC_WARN_UNDECLARED_SELECTOR = YES; 225 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 226 | GCC_WARN_UNUSED_FUNCTION = YES; 227 | GCC_WARN_UNUSED_VARIABLE = YES; 228 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 229 | MTL_ENABLE_DEBUG_INFO = YES; 230 | ONLY_ACTIVE_ARCH = YES; 231 | SDKROOT = iphoneos; 232 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 233 | }; 234 | name = Debug; 235 | }; 236 | 437933621D64AB0E009C1D13 /* Release */ = { 237 | isa = XCBuildConfiguration; 238 | buildSettings = { 239 | ALWAYS_SEARCH_USER_PATHS = NO; 240 | CLANG_ANALYZER_NONNULL = YES; 241 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 242 | CLANG_CXX_LIBRARY = "libc++"; 243 | CLANG_ENABLE_MODULES = YES; 244 | CLANG_ENABLE_OBJC_ARC = YES; 245 | CLANG_WARN_BOOL_CONVERSION = YES; 246 | CLANG_WARN_CONSTANT_CONVERSION = YES; 247 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 248 | CLANG_WARN_EMPTY_BODY = YES; 249 | CLANG_WARN_ENUM_CONVERSION = YES; 250 | CLANG_WARN_INT_CONVERSION = YES; 251 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 252 | CLANG_WARN_UNREACHABLE_CODE = YES; 253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 254 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 255 | COPY_PHASE_STRIP = NO; 256 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 257 | ENABLE_NS_ASSERTIONS = NO; 258 | ENABLE_STRICT_OBJC_MSGSEND = YES; 259 | GCC_C_LANGUAGE_STANDARD = gnu99; 260 | GCC_NO_COMMON_BLOCKS = YES; 261 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 262 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 263 | GCC_WARN_UNDECLARED_SELECTOR = YES; 264 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 265 | GCC_WARN_UNUSED_FUNCTION = YES; 266 | GCC_WARN_UNUSED_VARIABLE = YES; 267 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 268 | MTL_ENABLE_DEBUG_INFO = NO; 269 | SDKROOT = iphoneos; 270 | VALIDATE_PRODUCT = YES; 271 | }; 272 | name = Release; 273 | }; 274 | 437933641D64AB0E009C1D13 /* Debug */ = { 275 | isa = XCBuildConfiguration; 276 | buildSettings = { 277 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 278 | INFOPLIST_FILE = MonakaExample/Info.plist; 279 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 280 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.MonakaExample; 281 | PRODUCT_NAME = "$(TARGET_NAME)"; 282 | }; 283 | name = Debug; 284 | }; 285 | 437933651D64AB0E009C1D13 /* Release */ = { 286 | isa = XCBuildConfiguration; 287 | buildSettings = { 288 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 289 | INFOPLIST_FILE = MonakaExample/Info.plist; 290 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 291 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.MonakaExample; 292 | PRODUCT_NAME = "$(TARGET_NAME)"; 293 | }; 294 | name = Release; 295 | }; 296 | /* End XCBuildConfiguration section */ 297 | 298 | /* Begin XCConfigurationList section */ 299 | 4379334C1D64AB0E009C1D13 /* Build configuration list for PBXProject "MonakaExample" */ = { 300 | isa = XCConfigurationList; 301 | buildConfigurations = ( 302 | 437933611D64AB0E009C1D13 /* Debug */, 303 | 437933621D64AB0E009C1D13 /* Release */, 304 | ); 305 | defaultConfigurationIsVisible = 0; 306 | defaultConfigurationName = Release; 307 | }; 308 | 437933631D64AB0E009C1D13 /* Build configuration list for PBXNativeTarget "MonakaExample" */ = { 309 | isa = XCConfigurationList; 310 | buildConfigurations = ( 311 | 437933641D64AB0E009C1D13 /* Debug */, 312 | 437933651D64AB0E009C1D13 /* Release */, 313 | ); 314 | defaultConfigurationIsVisible = 0; 315 | defaultConfigurationName = Release; 316 | }; 317 | /* End XCConfigurationList section */ 318 | }; 319 | rootObject = 437933491D64AB0E009C1D13 /* Project object */; 320 | } 321 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // MonakaExample 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 17 | 18 | Monaka.activate(Sample) 19 | 20 | let sample = Sample(id: NSUUID().UUIDString) 21 | let data = Monaka.pack(sample) 22 | debugPrint("sample: \(Monaka.unpack(data: data))") 23 | 24 | let samples = [Sample(id: NSUUID().UUIDString), Sample(id: NSUUID().UUIDString), Sample(id: NSUUID().UUIDString)] 25 | let data2 = Monaka.pack(samples) 26 | debugPrint("samples: \(Monaka.unpack(data: data2))") 27 | 28 | return true 29 | } 30 | 31 | func applicationWillResignActive(application: UIApplication) { 32 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state. 33 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game. 34 | } 35 | 36 | func applicationDidEnterBackground(application: UIApplication) { 37 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 38 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 39 | } 40 | 41 | func applicationWillEnterForeground(application: UIApplication) { 42 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background. 43 | } 44 | 45 | func applicationDidBecomeActive(application: UIApplication) { 46 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface. 47 | } 48 | 49 | func applicationWillTerminate(application: UIApplication) { 50 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 51 | } 52 | 53 | 54 | } 55 | 56 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "29x29", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "29x29", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "40x40", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "40x40", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "60x60", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "60x60", 31 | "scale" : "3x" 32 | } 33 | ], 34 | "info" : { 35 | "version" : 1, 36 | "author" : "xcode" 37 | } 38 | } -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/Sample.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Sample.swift 3 | // MonakaExample 4 | // 5 | // Created by naru on 2016/08/26. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | struct Sample: CustomPackable { 12 | 13 | let id: String 14 | 15 | static var restoreProcedure: ([String : Packable] -> Packable?) = { (properties: [String : Packable]) -> Packable? in 16 | guard let id = properties["id"] as? String else { 17 | return nil 18 | } 19 | return Sample(id: id) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /Example/MonakaExample/MonakaExample/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // MonakaExample 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | class ViewController: UIViewController { 12 | 13 | override func viewDidLoad() { 14 | super.viewDidLoad() 15 | // Do any additional setup after loading the view, typically from a nib. 16 | } 17 | 18 | override func didReceiveMemoryWarning() { 19 | super.didReceiveMemoryWarning() 20 | // Dispose of any resources that can be recreated. 21 | } 22 | 23 | } 24 | 25 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2016 naru-jpn 3 | 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: 4 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 5 | 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. 6 | -------------------------------------------------------------------------------- /Logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naru-jpn/Monaka/85cdb749b9b5680ce60cd1d43dfcc093753091b9/Logo.png -------------------------------------------------------------------------------- /Logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naru-jpn/Monaka/85cdb749b9b5680ce60cd1d43dfcc093753091b9/Logo2.png -------------------------------------------------------------------------------- /Monaka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naru-jpn/Monaka/85cdb749b9b5680ce60cd1d43dfcc093753091b9/Monaka.png -------------------------------------------------------------------------------- /Monaka.podspec: -------------------------------------------------------------------------------- 1 | @version = "0.0.2" 2 | 3 | Pod::Spec.new do |s| 4 | s.name = "Monaka" 5 | s.version = @version 6 | s.summary = "Monaka is a Library to convert swifty values and NSData each other to support immutable data handling." 7 | s.homepage = "https://github.com/naru-jpn/Monaka" 8 | s.license = { :type => 'MIT', :file => 'LICENSE' } 9 | s.author = { "naru" => "tus.naru@gmail.com" } 10 | s.source = { :git => "https://github.com/naru-jpn/Monaka.git", :tag => @version } 11 | s.source_files = 'Sources/*.swift' 12 | s.ios.deployment_target = '9.0' 13 | end 14 | -------------------------------------------------------------------------------- /Monaka.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 437933401D6498E7009C1D13 /* Monaka.h in Headers */ = {isa = PBXBuildFile; fileRef = 4379333F1D6498E7009C1D13 /* Monaka.h */; settings = {ATTRIBUTES = (Public, ); }; }; 11 | 437933671D64AB67009C1D13 /* Monaka.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933661D64AB67009C1D13 /* Monaka.swift */; }; 12 | 437933691D64AC51009C1D13 /* Packable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933681D64AC51009C1D13 /* Packable.swift */; }; 13 | 4379336B1D64ADCE009C1D13 /* Packables.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4379336A1D64ADCE009C1D13 /* Packables.swift */; }; 14 | 4379336D1D654EFF009C1D13 /* CustomPackable.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4379336C1D654EFF009C1D13 /* CustomPackable.swift */; }; 15 | 437933771D65510C009C1D13 /* Monaka.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4379333C1D6498E7009C1D13 /* Monaka.framework */; }; 16 | 4379337E1D655BD4009C1D13 /* Nimble.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 4379337D1D655BD4009C1D13 /* Nimble.framework */; }; 17 | 437933821D655BDF009C1D13 /* Quick.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 437933811D655BDF009C1D13 /* Quick.framework */; }; 18 | 437933861D655C5D009C1D13 /* PackablesSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933851D655C5D009C1D13 /* PackablesSpec.swift */; }; 19 | 437933921D6699B8009C1D13 /* CustomPackableSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 437933911D6699B8009C1D13 /* CustomPackableSpec.swift */; }; 20 | /* End PBXBuildFile section */ 21 | 22 | /* Begin PBXContainerItemProxy section */ 23 | 437933781D65510C009C1D13 /* PBXContainerItemProxy */ = { 24 | isa = PBXContainerItemProxy; 25 | containerPortal = 437933331D6498E7009C1D13 /* Project object */; 26 | proxyType = 1; 27 | remoteGlobalIDString = 4379333B1D6498E7009C1D13; 28 | remoteInfo = Monaka; 29 | }; 30 | /* End PBXContainerItemProxy section */ 31 | 32 | /* Begin PBXCopyFilesBuildPhase section */ 33 | 437933831D655BF8009C1D13 /* CopyFiles */ = { 34 | isa = PBXCopyFilesBuildPhase; 35 | buildActionMask = 2147483647; 36 | dstPath = ""; 37 | dstSubfolderSpec = 10; 38 | files = ( 39 | ); 40 | runOnlyForDeploymentPostprocessing = 0; 41 | }; 42 | /* End PBXCopyFilesBuildPhase section */ 43 | 44 | /* Begin PBXFileReference section */ 45 | 4379333C1D6498E7009C1D13 /* Monaka.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Monaka.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 46 | 4379333F1D6498E7009C1D13 /* Monaka.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Monaka.h; sourceTree = ""; }; 47 | 437933411D6498E7009C1D13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | 437933661D64AB67009C1D13 /* Monaka.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Monaka.swift; sourceTree = ""; }; 49 | 437933681D64AC51009C1D13 /* Packable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Packable.swift; sourceTree = ""; }; 50 | 4379336A1D64ADCE009C1D13 /* Packables.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Packables.swift; sourceTree = ""; }; 51 | 4379336C1D654EFF009C1D13 /* CustomPackable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomPackable.swift; sourceTree = ""; }; 52 | 437933721D65510C009C1D13 /* MonakaTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MonakaTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 53 | 437933761D65510C009C1D13 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 54 | 4379337D1D655BD4009C1D13 /* Nimble.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Nimble.framework; path = ../Carthage/Build/iOS/Nimble.framework; sourceTree = ""; }; 55 | 437933811D655BDF009C1D13 /* Quick.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Quick.framework; path = ../Carthage/Build/iOS/Quick.framework; sourceTree = ""; }; 56 | 437933851D655C5D009C1D13 /* PackablesSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PackablesSpec.swift; sourceTree = ""; }; 57 | 437933911D6699B8009C1D13 /* CustomPackableSpec.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CustomPackableSpec.swift; sourceTree = ""; }; 58 | /* End PBXFileReference section */ 59 | 60 | /* Begin PBXFrameworksBuildPhase section */ 61 | 437933381D6498E7009C1D13 /* Frameworks */ = { 62 | isa = PBXFrameworksBuildPhase; 63 | buildActionMask = 2147483647; 64 | files = ( 65 | ); 66 | runOnlyForDeploymentPostprocessing = 0; 67 | }; 68 | 4379336F1D65510C009C1D13 /* Frameworks */ = { 69 | isa = PBXFrameworksBuildPhase; 70 | buildActionMask = 2147483647; 71 | files = ( 72 | 437933771D65510C009C1D13 /* Monaka.framework in Frameworks */, 73 | 437933821D655BDF009C1D13 /* Quick.framework in Frameworks */, 74 | 4379337E1D655BD4009C1D13 /* Nimble.framework in Frameworks */, 75 | ); 76 | runOnlyForDeploymentPostprocessing = 0; 77 | }; 78 | /* End PBXFrameworksBuildPhase section */ 79 | 80 | /* Begin PBXGroup section */ 81 | 437933321D6498E7009C1D13 = { 82 | isa = PBXGroup; 83 | children = ( 84 | 4379333E1D6498E7009C1D13 /* Monaka */, 85 | 437933471D64A118009C1D13 /* Sources */, 86 | 437933731D65510C009C1D13 /* MonakaTests */, 87 | 4379333D1D6498E7009C1D13 /* Products */, 88 | ); 89 | sourceTree = ""; 90 | }; 91 | 4379333D1D6498E7009C1D13 /* Products */ = { 92 | isa = PBXGroup; 93 | children = ( 94 | 4379333C1D6498E7009C1D13 /* Monaka.framework */, 95 | 437933721D65510C009C1D13 /* MonakaTests.xctest */, 96 | ); 97 | name = Products; 98 | sourceTree = ""; 99 | }; 100 | 4379333E1D6498E7009C1D13 /* Monaka */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 4379333F1D6498E7009C1D13 /* Monaka.h */, 104 | 437933411D6498E7009C1D13 /* Info.plist */, 105 | ); 106 | path = Monaka; 107 | sourceTree = ""; 108 | }; 109 | 437933471D64A118009C1D13 /* Sources */ = { 110 | isa = PBXGroup; 111 | children = ( 112 | 437933661D64AB67009C1D13 /* Monaka.swift */, 113 | 437933681D64AC51009C1D13 /* Packable.swift */, 114 | 4379336A1D64ADCE009C1D13 /* Packables.swift */, 115 | 4379336C1D654EFF009C1D13 /* CustomPackable.swift */, 116 | ); 117 | path = Sources; 118 | sourceTree = ""; 119 | }; 120 | 437933731D65510C009C1D13 /* MonakaTests */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 437933841D655C1D009C1D13 /* Frameworks */, 124 | 437933851D655C5D009C1D13 /* PackablesSpec.swift */, 125 | 437933911D6699B8009C1D13 /* CustomPackableSpec.swift */, 126 | 437933761D65510C009C1D13 /* Info.plist */, 127 | ); 128 | path = MonakaTests; 129 | sourceTree = ""; 130 | }; 131 | 437933841D655C1D009C1D13 /* Frameworks */ = { 132 | isa = PBXGroup; 133 | children = ( 134 | 437933811D655BDF009C1D13 /* Quick.framework */, 135 | 4379337D1D655BD4009C1D13 /* Nimble.framework */, 136 | ); 137 | name = Frameworks; 138 | sourceTree = ""; 139 | }; 140 | /* End PBXGroup section */ 141 | 142 | /* Begin PBXHeadersBuildPhase section */ 143 | 437933391D6498E7009C1D13 /* Headers */ = { 144 | isa = PBXHeadersBuildPhase; 145 | buildActionMask = 2147483647; 146 | files = ( 147 | 437933401D6498E7009C1D13 /* Monaka.h in Headers */, 148 | ); 149 | runOnlyForDeploymentPostprocessing = 0; 150 | }; 151 | /* End PBXHeadersBuildPhase section */ 152 | 153 | /* Begin PBXNativeTarget section */ 154 | 4379333B1D6498E7009C1D13 /* Monaka */ = { 155 | isa = PBXNativeTarget; 156 | buildConfigurationList = 437933441D6498E7009C1D13 /* Build configuration list for PBXNativeTarget "Monaka" */; 157 | buildPhases = ( 158 | 437933371D6498E7009C1D13 /* Sources */, 159 | 437933381D6498E7009C1D13 /* Frameworks */, 160 | 437933391D6498E7009C1D13 /* Headers */, 161 | 4379333A1D6498E7009C1D13 /* Resources */, 162 | ); 163 | buildRules = ( 164 | ); 165 | dependencies = ( 166 | ); 167 | name = Monaka; 168 | productName = Monaka; 169 | productReference = 4379333C1D6498E7009C1D13 /* Monaka.framework */; 170 | productType = "com.apple.product-type.framework"; 171 | }; 172 | 437933711D65510C009C1D13 /* MonakaTests */ = { 173 | isa = PBXNativeTarget; 174 | buildConfigurationList = 4379337A1D65510C009C1D13 /* Build configuration list for PBXNativeTarget "MonakaTests" */; 175 | buildPhases = ( 176 | 4379336E1D65510C009C1D13 /* Sources */, 177 | 4379336F1D65510C009C1D13 /* Frameworks */, 178 | 437933701D65510C009C1D13 /* Resources */, 179 | 437933831D655BF8009C1D13 /* CopyFiles */, 180 | ); 181 | buildRules = ( 182 | ); 183 | dependencies = ( 184 | 437933791D65510C009C1D13 /* PBXTargetDependency */, 185 | ); 186 | name = MonakaTests; 187 | productName = MonakaTests; 188 | productReference = 437933721D65510C009C1D13 /* MonakaTests.xctest */; 189 | productType = "com.apple.product-type.bundle.unit-test"; 190 | }; 191 | /* End PBXNativeTarget section */ 192 | 193 | /* Begin PBXProject section */ 194 | 437933331D6498E7009C1D13 /* Project object */ = { 195 | isa = PBXProject; 196 | attributes = { 197 | LastSwiftUpdateCheck = 0730; 198 | LastUpgradeCheck = 0730; 199 | ORGANIZATIONNAME = naru; 200 | TargetAttributes = { 201 | 4379333B1D6498E7009C1D13 = { 202 | CreatedOnToolsVersion = 7.3.1; 203 | }; 204 | 437933711D65510C009C1D13 = { 205 | CreatedOnToolsVersion = 7.3.1; 206 | }; 207 | }; 208 | }; 209 | buildConfigurationList = 437933361D6498E7009C1D13 /* Build configuration list for PBXProject "Monaka" */; 210 | compatibilityVersion = "Xcode 3.2"; 211 | developmentRegion = English; 212 | hasScannedForEncodings = 0; 213 | knownRegions = ( 214 | en, 215 | ); 216 | mainGroup = 437933321D6498E7009C1D13; 217 | productRefGroup = 4379333D1D6498E7009C1D13 /* Products */; 218 | projectDirPath = ""; 219 | projectRoot = ""; 220 | targets = ( 221 | 4379333B1D6498E7009C1D13 /* Monaka */, 222 | 437933711D65510C009C1D13 /* MonakaTests */, 223 | ); 224 | }; 225 | /* End PBXProject section */ 226 | 227 | /* Begin PBXResourcesBuildPhase section */ 228 | 4379333A1D6498E7009C1D13 /* Resources */ = { 229 | isa = PBXResourcesBuildPhase; 230 | buildActionMask = 2147483647; 231 | files = ( 232 | ); 233 | runOnlyForDeploymentPostprocessing = 0; 234 | }; 235 | 437933701D65510C009C1D13 /* Resources */ = { 236 | isa = PBXResourcesBuildPhase; 237 | buildActionMask = 2147483647; 238 | files = ( 239 | ); 240 | runOnlyForDeploymentPostprocessing = 0; 241 | }; 242 | /* End PBXResourcesBuildPhase section */ 243 | 244 | /* Begin PBXSourcesBuildPhase section */ 245 | 437933371D6498E7009C1D13 /* Sources */ = { 246 | isa = PBXSourcesBuildPhase; 247 | buildActionMask = 2147483647; 248 | files = ( 249 | 437933691D64AC51009C1D13 /* Packable.swift in Sources */, 250 | 4379336D1D654EFF009C1D13 /* CustomPackable.swift in Sources */, 251 | 437933671D64AB67009C1D13 /* Monaka.swift in Sources */, 252 | 4379336B1D64ADCE009C1D13 /* Packables.swift in Sources */, 253 | ); 254 | runOnlyForDeploymentPostprocessing = 0; 255 | }; 256 | 4379336E1D65510C009C1D13 /* Sources */ = { 257 | isa = PBXSourcesBuildPhase; 258 | buildActionMask = 2147483647; 259 | files = ( 260 | 437933921D6699B8009C1D13 /* CustomPackableSpec.swift in Sources */, 261 | 437933861D655C5D009C1D13 /* PackablesSpec.swift in Sources */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXSourcesBuildPhase section */ 266 | 267 | /* Begin PBXTargetDependency section */ 268 | 437933791D65510C009C1D13 /* PBXTargetDependency */ = { 269 | isa = PBXTargetDependency; 270 | target = 4379333B1D6498E7009C1D13 /* Monaka */; 271 | targetProxy = 437933781D65510C009C1D13 /* PBXContainerItemProxy */; 272 | }; 273 | /* End PBXTargetDependency section */ 274 | 275 | /* Begin XCBuildConfiguration section */ 276 | 437933421D6498E7009C1D13 /* Debug */ = { 277 | isa = XCBuildConfiguration; 278 | buildSettings = { 279 | ALWAYS_SEARCH_USER_PATHS = NO; 280 | CLANG_ANALYZER_NONNULL = YES; 281 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 282 | CLANG_CXX_LIBRARY = "libc++"; 283 | CLANG_ENABLE_MODULES = YES; 284 | CLANG_ENABLE_OBJC_ARC = YES; 285 | CLANG_WARN_BOOL_CONVERSION = YES; 286 | CLANG_WARN_CONSTANT_CONVERSION = YES; 287 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 288 | CLANG_WARN_EMPTY_BODY = YES; 289 | CLANG_WARN_ENUM_CONVERSION = YES; 290 | CLANG_WARN_INT_CONVERSION = YES; 291 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 292 | CLANG_WARN_UNREACHABLE_CODE = YES; 293 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 294 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 295 | COPY_PHASE_STRIP = NO; 296 | CURRENT_PROJECT_VERSION = 1; 297 | DEBUG_INFORMATION_FORMAT = dwarf; 298 | ENABLE_STRICT_OBJC_MSGSEND = YES; 299 | ENABLE_TESTABILITY = YES; 300 | GCC_C_LANGUAGE_STANDARD = gnu99; 301 | GCC_DYNAMIC_NO_PIC = NO; 302 | GCC_NO_COMMON_BLOCKS = YES; 303 | GCC_OPTIMIZATION_LEVEL = 0; 304 | GCC_PREPROCESSOR_DEFINITIONS = ( 305 | "DEBUG=1", 306 | "$(inherited)", 307 | ); 308 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 309 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 310 | GCC_WARN_UNDECLARED_SELECTOR = YES; 311 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 312 | GCC_WARN_UNUSED_FUNCTION = YES; 313 | GCC_WARN_UNUSED_VARIABLE = YES; 314 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 315 | MTL_ENABLE_DEBUG_INFO = YES; 316 | ONLY_ACTIVE_ARCH = YES; 317 | SDKROOT = iphoneos; 318 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 319 | TARGETED_DEVICE_FAMILY = "1,2"; 320 | VERSIONING_SYSTEM = "apple-generic"; 321 | VERSION_INFO_PREFIX = ""; 322 | }; 323 | name = Debug; 324 | }; 325 | 437933431D6498E7009C1D13 /* Release */ = { 326 | isa = XCBuildConfiguration; 327 | buildSettings = { 328 | ALWAYS_SEARCH_USER_PATHS = NO; 329 | CLANG_ANALYZER_NONNULL = YES; 330 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 331 | CLANG_CXX_LIBRARY = "libc++"; 332 | CLANG_ENABLE_MODULES = YES; 333 | CLANG_ENABLE_OBJC_ARC = YES; 334 | CLANG_WARN_BOOL_CONVERSION = YES; 335 | CLANG_WARN_CONSTANT_CONVERSION = YES; 336 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 337 | CLANG_WARN_EMPTY_BODY = YES; 338 | CLANG_WARN_ENUM_CONVERSION = YES; 339 | CLANG_WARN_INT_CONVERSION = YES; 340 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 341 | CLANG_WARN_UNREACHABLE_CODE = YES; 342 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 343 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 344 | COPY_PHASE_STRIP = NO; 345 | CURRENT_PROJECT_VERSION = 1; 346 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 347 | ENABLE_NS_ASSERTIONS = NO; 348 | ENABLE_STRICT_OBJC_MSGSEND = YES; 349 | GCC_C_LANGUAGE_STANDARD = gnu99; 350 | GCC_NO_COMMON_BLOCKS = YES; 351 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 352 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 353 | GCC_WARN_UNDECLARED_SELECTOR = YES; 354 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 355 | GCC_WARN_UNUSED_FUNCTION = YES; 356 | GCC_WARN_UNUSED_VARIABLE = YES; 357 | IPHONEOS_DEPLOYMENT_TARGET = 9.3; 358 | MTL_ENABLE_DEBUG_INFO = NO; 359 | SDKROOT = iphoneos; 360 | TARGETED_DEVICE_FAMILY = "1,2"; 361 | VALIDATE_PRODUCT = YES; 362 | VERSIONING_SYSTEM = "apple-generic"; 363 | VERSION_INFO_PREFIX = ""; 364 | }; 365 | name = Release; 366 | }; 367 | 437933451D6498E7009C1D13 /* Debug */ = { 368 | isa = XCBuildConfiguration; 369 | buildSettings = { 370 | CLANG_ENABLE_MODULES = YES; 371 | DEFINES_MODULE = YES; 372 | DYLIB_COMPATIBILITY_VERSION = 1; 373 | DYLIB_CURRENT_VERSION = 1; 374 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 375 | INFOPLIST_FILE = Monaka/Info.plist; 376 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 377 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 378 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.Monaka; 379 | PRODUCT_NAME = "$(TARGET_NAME)"; 380 | SKIP_INSTALL = YES; 381 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 382 | }; 383 | name = Debug; 384 | }; 385 | 437933461D6498E7009C1D13 /* Release */ = { 386 | isa = XCBuildConfiguration; 387 | buildSettings = { 388 | CLANG_ENABLE_MODULES = YES; 389 | DEFINES_MODULE = YES; 390 | DYLIB_COMPATIBILITY_VERSION = 1; 391 | DYLIB_CURRENT_VERSION = 1; 392 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 393 | INFOPLIST_FILE = Monaka/Info.plist; 394 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 395 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 396 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.Monaka; 397 | PRODUCT_NAME = "$(TARGET_NAME)"; 398 | SKIP_INSTALL = YES; 399 | }; 400 | name = Release; 401 | }; 402 | 4379337B1D65510C009C1D13 /* Debug */ = { 403 | isa = XCBuildConfiguration; 404 | buildSettings = { 405 | FRAMEWORK_SEARCH_PATHS = ( 406 | "$(inherited)", 407 | "$(PROJECT_DIR)/Carthage/Build/iOS", 408 | ); 409 | INFOPLIST_FILE = MonakaTests/Info.plist; 410 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; 411 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.MonakaTests; 412 | PRODUCT_NAME = "$(TARGET_NAME)"; 413 | }; 414 | name = Debug; 415 | }; 416 | 4379337C1D65510C009C1D13 /* Release */ = { 417 | isa = XCBuildConfiguration; 418 | buildSettings = { 419 | FRAMEWORK_SEARCH_PATHS = ( 420 | "$(inherited)", 421 | "$(PROJECT_DIR)/Carthage/Build/iOS", 422 | ); 423 | INFOPLIST_FILE = MonakaTests/Info.plist; 424 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks $(FRAMEWORK_SEARCH_PATHS)"; 425 | PRODUCT_BUNDLE_IDENTIFIER = com.jpn.naru.MonakaTests; 426 | PRODUCT_NAME = "$(TARGET_NAME)"; 427 | }; 428 | name = Release; 429 | }; 430 | /* End XCBuildConfiguration section */ 431 | 432 | /* Begin XCConfigurationList section */ 433 | 437933361D6498E7009C1D13 /* Build configuration list for PBXProject "Monaka" */ = { 434 | isa = XCConfigurationList; 435 | buildConfigurations = ( 436 | 437933421D6498E7009C1D13 /* Debug */, 437 | 437933431D6498E7009C1D13 /* Release */, 438 | ); 439 | defaultConfigurationIsVisible = 0; 440 | defaultConfigurationName = Release; 441 | }; 442 | 437933441D6498E7009C1D13 /* Build configuration list for PBXNativeTarget "Monaka" */ = { 443 | isa = XCConfigurationList; 444 | buildConfigurations = ( 445 | 437933451D6498E7009C1D13 /* Debug */, 446 | 437933461D6498E7009C1D13 /* Release */, 447 | ); 448 | defaultConfigurationIsVisible = 0; 449 | defaultConfigurationName = Release; 450 | }; 451 | 4379337A1D65510C009C1D13 /* Build configuration list for PBXNativeTarget "MonakaTests" */ = { 452 | isa = XCConfigurationList; 453 | buildConfigurations = ( 454 | 4379337B1D65510C009C1D13 /* Debug */, 455 | 4379337C1D65510C009C1D13 /* Release */, 456 | ); 457 | defaultConfigurationIsVisible = 0; 458 | defaultConfigurationName = Release; 459 | }; 460 | /* End XCConfigurationList section */ 461 | }; 462 | rootObject = 437933331D6498E7009C1D13 /* Project object */; 463 | } 464 | -------------------------------------------------------------------------------- /Monaka.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Monaka.xcodeproj/xcshareddata/xcschemes/Monaka.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 55 | 61 | 62 | 63 | 64 | 65 | 66 | 72 | 73 | 79 | 80 | 81 | 82 | 84 | 85 | 88 | 89 | 90 | -------------------------------------------------------------------------------- /Monaka/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(CURRENT_PROJECT_VERSION) 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Monaka/Monaka.h: -------------------------------------------------------------------------------- 1 | // 2 | // Monaka.h 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | //! Project version number for Monaka. 12 | FOUNDATION_EXPORT double MonakaVersionNumber; 13 | 14 | //! Project version string for Monaka. 15 | FOUNDATION_EXPORT const unsigned char MonakaVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /MonakaTests/CustomPackableSpec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPackableSpec.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/19. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Quick 11 | import Nimble 12 | @testable import Monaka 13 | 14 | private struct SampleStruct1: CustomPackable, Equatable { 15 | 16 | let name: String 17 | let number: Int 18 | 19 | static var restoreProcedure: [String : Packable] -> Packable? = { (dictionary: [String : Packable]) in 20 | guard let name = dictionary["name"] as? String, let number = dictionary["number"] as? Int else { 21 | return nil 22 | } 23 | return SampleStruct1(name: name, number: number) 24 | } 25 | } 26 | 27 | private func ==(lhs: SampleStruct1, rhs: SampleStruct1) -> Bool { 28 | return lhs.name == rhs.name && lhs.number == rhs.number 29 | } 30 | 31 | private struct SampleStruct2: CustomPackable, Equatable { 32 | 33 | let name: String 34 | let numbers: [Int] 35 | 36 | static var restoreProcedure: [String : Packable] -> Packable? = { (dictionary: [String : Packable]) in 37 | guard let name = dictionary["name"] as? String, let numbers = dictionary["numbers"] as? [Packable] else { 38 | return nil 39 | } 40 | return SampleStruct2(name: name, numbers: numbers.flatMap{ $0 as? Int }) 41 | } 42 | } 43 | 44 | private func ==(lhs: SampleStruct2, rhs: SampleStruct2) -> Bool { 45 | return lhs.name == rhs.name && lhs.numbers == rhs.numbers 46 | } 47 | 48 | class CustomPackableSpec: QuickSpec { 49 | 50 | override func spec() { 51 | 52 | describe("SampleStruct1", { 53 | 54 | beforeEach { 55 | Monaka.activate(SampleStruct1) 56 | } 57 | 58 | it("can be packed and unpacked", closure: { 59 | let name: String = "name" 60 | let number: Int = 10 61 | let value: SampleStruct1 = SampleStruct1(name: name, number: number) 62 | let unpacked: SampleStruct1? = Monaka.unpack(data: (Monaka.pack(value))) as? SampleStruct1 63 | expect(unpacked!).to(equal(value)) 64 | }) 65 | }) 66 | 67 | describe("SampleStruct2", { 68 | 69 | beforeEach { 70 | Monaka.activate(SampleStruct2) 71 | } 72 | 73 | it("can be packed and unpacked", closure: { 74 | let name: String = "name" 75 | let numbers: [Int] = [1, 2, 3] 76 | let value: SampleStruct2 = SampleStruct2(name: name, numbers: numbers) 77 | let unpacked: SampleStruct2? = Monaka.unpack(data: (Monaka.pack(value))) as? SampleStruct2 78 | expect(unpacked!).to(equal(value)) 79 | }) 80 | }) 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /MonakaTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | BNDL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1 23 | 24 | 25 | -------------------------------------------------------------------------------- /MonakaTests/PackablesSpec.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PackablesSpec.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/18. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | import Quick 11 | import Nimble 12 | @testable import Monaka 13 | 14 | class PackablesSpec: QuickSpec { 15 | 16 | override func spec() { 17 | 18 | describe("packables", closure: { 19 | 20 | describe("Int", closure: { 21 | 22 | context("for positive", { 23 | it("can be packed and unpacked", closure: { 24 | let value: Int = 10 25 | let unpacked: Int? = Monaka.unpack(data: (Monaka.pack(value))) as? Int 26 | expect(unpacked).to(equal(value)) 27 | }) 28 | }) 29 | 30 | context("for negative", { 31 | it("can be packed and unpacked", closure: { 32 | let value: Int = -10 33 | let unpacked: Int? = Monaka.unpack(data: (Monaka.pack(value))) as? Int 34 | expect(unpacked).to(equal(value)) 35 | }) 36 | }) 37 | 38 | context("for zero", { 39 | it("can be packed and unpacked", closure: { 40 | let value: Int = 0 41 | let unpacked: Int? = Monaka.unpack(data: (Monaka.pack(value))) as? Int 42 | expect(unpacked).to(equal(value)) 43 | }) 44 | }) 45 | }) 46 | 47 | describe("UInt", closure: { 48 | 49 | it("can be packed and unpacked", closure: { 50 | let value: UInt = 10 51 | let unpacked: UInt? = Monaka.unpack(data: (Monaka.pack(value))) as? UInt 52 | expect(unpacked).to(equal(value)) 53 | }) 54 | }) 55 | 56 | describe("Float", closure: { 57 | 58 | context("for positive", { 59 | it("can be packed and unpacked", closure: { 60 | let value: Float = 10.0 61 | let unpacked: Float? = Monaka.unpack(data: (Monaka.pack(value))) as? Float 62 | expect(unpacked).to(equal(value)) 63 | }) 64 | }) 65 | 66 | context("for negative", { 67 | it("can be packed and unpacked", closure: { 68 | let value: Float = -10.0 69 | let unpacked: Float? = Monaka.unpack(data: (Monaka.pack(value))) as? Float 70 | expect(unpacked).to(equal(value)) 71 | }) 72 | }) 73 | 74 | context("for zero", { 75 | it("can be packed and unpacked", closure: { 76 | let value: Float = 0.0 77 | let unpacked: Float? = Monaka.unpack(data: (Monaka.pack(value))) as? Float 78 | expect(unpacked).to(equal(value)) 79 | }) 80 | }) 81 | }) 82 | 83 | describe("Double", closure: { 84 | 85 | context("for positive", { 86 | it("can be packed and unpacked", closure: { 87 | let value: Double = 10.0 88 | let unpacked: Double? = Monaka.unpack(data: (Monaka.pack(value))) as? Double 89 | expect(unpacked).to(equal(value)) 90 | }) 91 | }) 92 | 93 | context("for negative", { 94 | it("can be packed and unpacked", closure: { 95 | let value: Double = -10.0 96 | let unpacked: Double? = Monaka.unpack(data: (Monaka.pack(value))) as? Double 97 | expect(unpacked).to(equal(value)) 98 | }) 99 | }) 100 | 101 | context("for zero", { 102 | it("can be packed and unpacked", closure: { 103 | let value: Double = 0.0 104 | let unpacked: Double? = Monaka.unpack(data: (Monaka.pack(value))) as? Double 105 | expect(unpacked).to(equal(value)) 106 | }) 107 | }) 108 | }) 109 | 110 | describe("String", closure: { 111 | 112 | context("for normal", { 113 | it("can be packed and unpacked", closure: { 114 | let value: String = "packed string" 115 | let unpacked: String? = Monaka.unpack(data: (Monaka.pack(value))) as? String 116 | expect(unpacked).to(equal(value)) 117 | }) 118 | }) 119 | 120 | context("for zero length", { 121 | it("can be packed and unpacked", closure: { 122 | let value: String = "" 123 | let unpacked: String? = Monaka.unpack(data: (Monaka.pack(value))) as? String 124 | expect(unpacked).to(equal(value)) 125 | }) 126 | }) 127 | }) 128 | 129 | describe("Array", closure: { 130 | 131 | context("for 1-dimension array", { 132 | it("can be packed and unpacked", closure: { 133 | let value: [Packable] = [1, 2, 3, 4, 5] 134 | let unpacked: [Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [Packable] 135 | expect("\(unpacked!)").to(equal("\(value)")) 136 | }) 137 | }) 138 | 139 | context("for multi-dimension array", { 140 | it("can be packed and unpacked", closure: { 141 | let value: [Packable] = [[1], [1, 2], [1, 2, 3]] 142 | let unpacked: [Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [Packable] 143 | expect("\(unpacked!)").to(equal("\(value)")) 144 | }) 145 | }) 146 | 147 | context("for complicated 1-dimension array", { 148 | it("can be packed and unpacked", closure: { 149 | let value: [Packable] = [1, "2", "3"] 150 | let unpacked: [Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [Packable] 151 | expect("\(unpacked!)").to(equal("\(value)")) 152 | }) 153 | }) 154 | 155 | context("for complicated multi-dimension array", { 156 | it("can be packed and unpacked", closure: { 157 | 158 | let element0: String = "1" 159 | let element1: [Int] = [1, 2] 160 | let element2: [Any] = [1, "2", "3"] 161 | let element3: Float = 4.0 162 | let value: [Packable] = [element0, element1, element2, element3] 163 | let unpacked: [Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [Packable] 164 | 165 | expect("\(unpacked![0])").to(equal("\(element0)")) 166 | expect("\(unpacked![1])").to(equal("\(element1)")) 167 | expect("\(unpacked![2])").to(equal("\(element2)")) 168 | expect("\(unpacked![3])").to(equal("\(element3)")) 169 | }) 170 | }) 171 | }) 172 | 173 | describe("Dictionary", closure: { 174 | 175 | context("for simple one", { 176 | it("can be packed and unpacked", closure: { 177 | let value: [String: Packable] = ["1": 1, "2": 2, "3": 3] 178 | let unpacked: [String: Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [String: Packable] 179 | expect("\(unpacked!)").to(equal("\(value)")) 180 | }) 181 | }) 182 | 183 | context("for complicated one", { 184 | it("can be packed and unpacked", closure: { 185 | let value: [String: Packable] = ["1": 1, "2": ["2.1": 2.1, "2.2": 2.2], "3": 3.0] 186 | let unpacked: [String: Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [String: Packable] 187 | expect("\(unpacked!)").to(equal("\(value)")) 188 | }) 189 | }) 190 | 191 | context("for complicated one containing array", { 192 | it("can be packed and unpacked", closure: { 193 | let value: [String: Packable] = ["1": 1, "2": [1, 2, 3], "3": 3.0] 194 | let unpacked: [String: Packable]? = Monaka.unpack(data: (Monaka.pack(value))) as? [String: Packable] 195 | expect("\(unpacked!)").to(equal("\(value)")) 196 | }) 197 | }) 198 | }) 199 | }) 200 | } 201 | } 202 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # Monaka 4 | 5 | [![Swift](https://img.shields.io/badge/swift-2.2-orange.svg?style=flat)](#) 6 | [![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 7 | [![Platform](https://img.shields.io/badge/platform-ios-lightgrey.svg?style=flat)](#) 8 | [![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](https://opensource.org/licenses/MIT) 9 | 10 | ## Overview 11 | 12 | Monaka convert custom struct and fundamental values to NSData (also nested array and dictionary). 13 | 14 | 15 | 16 | ## Purpose 17 | 18 | You can persistent store of your defined struct. Your defined struct is for example 'latest selected tab index', 'array of struct fetched from API' or 'current application state'. I think these should be represented as simple struct and can be stored in application. Converted data can be written in file or NSUserDefault. 19 | 20 | ## Installation 21 | 22 | ### Carthage 23 | 24 | ``` 25 | github "naru-jpn/Monaka" 26 | ``` 27 | 28 | ### CocoaPods 29 | 30 | ``` 31 | pod 'Monaka' 32 | ``` 33 | 34 | ## Usage 35 | 36 | ### For Standard Variables 37 | 38 | `Packable` variable ⇄ NSData. 39 | 40 | ```swift 41 | // Pack 42 | let value: Int = 10 43 | let data: NSData = Monaka.pack(value) 44 | 45 | // Unpack 46 | let unpacked = Monaka.unpack(data) as? Int 47 | ``` 48 | 49 | ### For Custom Struct 50 | 51 | #### 1.Make a custom struct confirming protocol `CustomPackable` 52 | 53 | ```swift 54 | struct Sample: CustomPackable { 55 | 56 | let id: String 57 | 58 | // Return new struct from applied properties. 59 | static var restoreProcedure: ([String : Packable] -> Packable?) = { (properties: [String : Packable]) -> Packable? in 60 | guard let id = properties["id"] as? String else { 61 | return nil 62 | } 63 | return Sample(id: id) 64 | } 65 | } 66 | ``` 67 | 68 | #### 2.Activate your custom struct. 69 | 70 | ```swift 71 | func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool { 72 | 73 | Monaka.activate(Sample) 74 | 75 | // Other codes... 76 | 77 | return true 78 | } 79 | ``` 80 | 81 | #### 3.Pack/Unpack 82 | 83 | You can Pack/Unpack as standard types. 84 | 85 | ```swift 86 | // Pack 87 | let value: SampleStruct = SampleStruct(id: NSUUID().UUIDString) 88 | let data: NSData = Monaka.pack(value) 89 | // Unpack 90 | let unpacked = Monaka.unpack(data) as? SampleStruct 91 | ``` 92 | 93 | ## License 94 | 95 | Monaka is released under the MIT license. See LICENSE for details. 96 | -------------------------------------------------------------------------------- /Sources/CustomPackable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // CustomPackable.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/18. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// Protocol for custom packable struct 12 | public protocol CustomPackable: Packable { 13 | 14 | /// Closure to restore struct from unpackable dictionary. 15 | static var restoreProcedure: ([String: Packable] -> Packable?) { get } 16 | } 17 | 18 | public extension CustomPackable { 19 | 20 | func packable() -> [String: Packable] { 21 | 22 | var children: [String: Packable] = [:] 23 | Mirror(reflecting: self).children.forEach { label, value in 24 | if let label = label, value = value as? Packable { 25 | children[label] = value 26 | } 27 | } 28 | return children 29 | } 30 | 31 | public final var packedIdentifier: String { 32 | return "\(Mirror(reflecting: self).subjectType)" 33 | } 34 | 35 | public static var packedIdentifier: String { 36 | return "\(self)" 37 | } 38 | 39 | public var packedDataLength: Int { 40 | 41 | let packable: [String: Packable] = self.packable() 42 | 43 | let elementsLength: Int = packable.keys.reduce(0) { (length, key) in 44 | length + key.packedDataLength 45 | } + packable.values.reduce(0) { (length, value) in 46 | length + value.packedDataLength 47 | } 48 | 49 | return self.packedIDLength + Int.PackedDataLength*(1+packable.keys.count*2) + elementsLength 50 | } 51 | 52 | public var packedHeaderData: [NSData] { 53 | let packable: [String: Packable] = self.packable() 54 | return packable.packedHeaderData 55 | } 56 | 57 | public var packedBodyData: [NSData] { 58 | let packable: [String: Packable] = self.packable() 59 | return packable.packedBodyData 60 | } 61 | 62 | public static var unpackProcedure: ((data: NSData) -> Packable?) { 63 | return [String: Packable].unpackProcedure 64 | } 65 | 66 | /// Store procedure to unpack and restore data on memory. 67 | public static func activatePack() { 68 | Monaka.registerUnpackProcedure(identifier: self.packedIdentifier, procedure: self.unpackProcedure) 69 | Monaka.registerRestoreProcedure(identifier: self.packedIdentifier, procedure: self.restoreProcedure) 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Sources/Monaka.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Monaka.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | /// **Monaka** is Delicious Library. 12 | public class Monaka { 13 | 14 | /// Shared Instance. 15 | private static let sharedInstance = Monaka() 16 | 17 | /// Store procedure to unpack data. 18 | private var unpackProcedures: [String: ((data: NSData) -> Packable?)] = [:] 19 | 20 | /// Store procedure to restore data. 21 | private var restoreProcedures: [String: ((dictionary: [String: Packable]) -> Packable?)] = [:] 22 | 23 | /// Once token 24 | private static var token: dispatch_once_t = 0 25 | 26 | /// Register procedure to unpack data. 27 | /// - parameter identifier: string to specify struct 28 | /// - parameter procedure: procedure to store 29 | public class func registerUnpackProcedure(identifier identifier: String, procedure: ((data: NSData) -> Packable?)) { 30 | self.sharedInstance.unpackProcedures[identifier] = procedure 31 | } 32 | 33 | /// Register procedure to restore data. 34 | /// - parameter identifier: string to specify struct 35 | /// - parameter procedure: procedure to store 36 | public class func registerRestoreProcedure(identifier identifier: String, procedure: ((dictionary: [String: Packable]) -> Packable?)) { 37 | self.sharedInstance.restoreProcedures[identifier] = procedure 38 | } 39 | 40 | /// Return stored procedure to unpack. 41 | /// - parameter identifier: string to specify struct 42 | /// - returns: stored procedure or nil if procedure for identifier is not stored 43 | private func unpackProcedure(identifier identifier: String) -> ((data: NSData) -> Packable?)? { 44 | guard let procedure: ((data: NSData) -> Packable?) = self.unpackProcedures[identifier] else { 45 | return nil 46 | } 47 | return procedure 48 | } 49 | 50 | /// Return stored procedure to retore struct. 51 | /// - parameter identifier: string to specify struct 52 | /// - returns: stored procedure or nil if procedure for identifier is not stored 53 | private func restoreProcedure(identifier identifier: String) -> ((dictionary: [String: Packable]) -> Packable?)? { 54 | guard let procedure: ((dictionary: [String: Packable]) -> Packable?) = self.restoreProcedures[identifier] else { 55 | return nil 56 | } 57 | return procedure 58 | } 59 | 60 | /// Unpack data. 61 | /// - parameter data: data to unpack 62 | /// - returns: unpacked object 63 | private func unpack(data data: NSData) -> Packable? { 64 | 65 | // length_of_identifier / others 66 | let splitData1: NSData.SplitData = data.split(length: sizeof(UInt8)) 67 | var count: UInt8 = 0 68 | splitData1.former.getBytes(&count, length: sizeof(UInt8)) 69 | 70 | // identifier / others 71 | let splitData2: NSData.SplitData = splitData1.latter.split(length: Int(count)) 72 | let identifier = NSString(data: splitData2.former, encoding: NSUTF8StringEncoding) as? String ?? "" 73 | 74 | guard let procedure = self.unpackProcedure(identifier: identifier) else { 75 | return nil 76 | } 77 | 78 | let unpacked: Packable? = procedure(data: splitData2.latter) 79 | 80 | if let dictionary = unpacked as? [String: Packable], let restoreProcedure = self.restoreProcedure(identifier: identifier) { 81 | return restoreProcedure(dictionary: dictionary) 82 | } else { 83 | return unpacked 84 | } 85 | } 86 | 87 | /// Pack data. 88 | /// - parameter data: data to pack 89 | /// - returns: packed data 90 | public class func pack(packable: Packable) -> NSData { 91 | return packable.packedData 92 | } 93 | 94 | /// Unpack data. 95 | /// - parameter data: data to unpack 96 | /// - returns: unpacked object 97 | public class func unpack(data data: NSData) -> Packable? { 98 | 99 | dispatch_once(&token) { 100 | self.activateStandardPackables() 101 | } 102 | 103 | return self.sharedInstance.unpack(data: data) 104 | } 105 | 106 | public class func activate(class: T.Type) -> Void { 107 | T.activatePack() 108 | } 109 | 110 | /// Register procedures for unpacking and restoring struct. 111 | /// - parameter withCustomStructActivations: closure to register procedures for custom struct 112 | public class func activateStandardPackables() -> Void { 113 | Int.activatePack() 114 | UInt.activatePack() 115 | Float.activatePack() 116 | Double.activatePack() 117 | String.activatePack() 118 | [Packable].activatePack() 119 | [String: Packable].activatePack() 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /Sources/Packable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Packable.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: Packable 12 | 13 | /// Protocol for mutual conversion of struct and NSData 14 | public protocol Packable { 15 | 16 | /// Identifier. (Implemented default behavior.) 17 | // static var packedIdentifier: String { get } 18 | 19 | /// Identifier. (Implemented default behavior.) 20 | // var packedIdentifier: String { get } 21 | 22 | /// Number of bytes of identifier. (Implemented default behavior.) 23 | // var packedIDLength: Int { get } 24 | 25 | /// Number of bytes of the whole packed data. 26 | var packedDataLength: Int { get } 27 | 28 | /// Metadata for the packed data. 29 | var packedHeaderData: [NSData] { get } 30 | 31 | /// Body data for the packed data. 32 | var packedBodyData: [NSData] { get } 33 | 34 | /// The whole of packed data. (Implemented default behavior.) 35 | // var packedData: NSData { get } 36 | 37 | /// Closure to un-pack data. 38 | static var unpackProcedure: (data: NSData) -> Packable? { get } 39 | } 40 | 41 | /// Define default implementation for the Packable. 42 | public extension Packable { 43 | 44 | /// Return name of type. 45 | public static var packedIdentifier: String { 46 | switch self { 47 | case is ArrayType: 48 | return "Array" 49 | case is DictionaryType: 50 | return "Dictionary" 51 | default: 52 | return "\(self)" 53 | } 54 | } 55 | 56 | /// Return name of type. 57 | public var packedIdentifier: String { 58 | switch self { 59 | case is ArrayType: 60 | return "Array" 61 | case is DictionaryType: 62 | return "Dictionary" 63 | default: 64 | return "\(Mirror(reflecting: self).subjectType)" 65 | } 66 | } 67 | 68 | /// Length of identifier data 69 | public var packedIDLength: Int { 70 | return sizeof(UInt8) + self.packedIdentifier.characters.count 71 | } 72 | 73 | /// Identifier data 74 | public var packedIdentifierData: NSData { 75 | // count 76 | let identifier: String = self.packedIdentifier 77 | var count: UInt8 = UInt8(identifier.characters.count) 78 | // + identifier string 79 | let identifierData: NSMutableData = NSMutableData(bytes: &count, length: sizeof(UInt8)) 80 | if let data = identifier.dataUsingEncoding(NSUTF8StringEncoding) { 81 | identifierData.appendData(data) 82 | } 83 | return identifierData 84 | } 85 | 86 | /// Whole of packed data 87 | public var packedData: NSData { 88 | let data: NSMutableData = NSMutableData(data: self.packedIdentifierData) 89 | for subdata in self.packedHeaderData + self.packedBodyData { 90 | data.appendData(subdata) 91 | } 92 | return NSData(data: data) 93 | } 94 | 95 | /// Store procedure to unarchive data on memory. 96 | public static func activatePack() { 97 | Monaka.registerUnpackProcedure(identifier: self.packedIdentifier, procedure: self.unpackProcedure) 98 | } 99 | } 100 | 101 | 102 | -------------------------------------------------------------------------------- /Sources/Packables.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PackableTypes.swift 3 | // Monaka 4 | // 5 | // Created by naru on 2016/08/17. 6 | // Copyright © 2016年 naru. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: Standard Packable Types 12 | 13 | extension Int: Packable { 14 | 15 | public static let PackedDataLength: Int = sizeof(UInt8) + "Int".characters.count + sizeof(Int) 16 | 17 | public var packedDataLength: Int { 18 | return Int.PackedDataLength 19 | } 20 | 21 | public var packedHeaderData: [NSData] { 22 | return [NSData()] 23 | } 24 | 25 | public var packedBodyData: [NSData] { 26 | var num: Int = self 27 | return [NSData(bytes: &num, length: sizeof(Int))] 28 | } 29 | 30 | public static var unpackProcedure: (data: NSData) -> Packable? { 31 | 32 | return { data in 33 | // unpack data as Int 34 | var value: Int = 0 35 | let data: NSData = data.subdataWithRange(NSMakeRange(0, sizeof(Int))) 36 | data.getBytes(&value, length: sizeof(Int)) 37 | return value 38 | } 39 | } 40 | } 41 | 42 | extension UInt: Packable { 43 | 44 | public var packedDataLength: Int { 45 | return self.packedIDLength + sizeof(UInt) 46 | } 47 | 48 | public var packedHeaderData: [NSData] { 49 | return [NSData()] 50 | } 51 | 52 | public var packedBodyData: [NSData] { 53 | var value: UInt = self 54 | return [NSData(bytes: &value, length: sizeof(UInt))] 55 | } 56 | 57 | public static var unpackProcedure: (data: NSData) -> Packable? { 58 | 59 | return { data in 60 | // unpack data as UInt 61 | var value: UInt = 0 62 | let data: NSData = data.subdataWithRange(NSMakeRange(0, sizeof(UInt))) 63 | data.getBytes(&value, length: sizeof(UInt)) 64 | return value 65 | } 66 | } 67 | } 68 | 69 | extension Float: Packable { 70 | 71 | public var packedDataLength: Int { 72 | return self.packedIDLength + sizeof(Float) 73 | } 74 | 75 | public var packedHeaderData: [NSData] { 76 | return [NSData()] 77 | } 78 | 79 | public var packedBodyData: [NSData] { 80 | var value: Float = self 81 | return [NSData(bytes: &value, length: sizeof(Float))] 82 | } 83 | 84 | public static var unpackProcedure: (data: NSData) -> Packable? { 85 | 86 | return { data in 87 | // unpack data as Float 88 | var value: Float = 0 89 | let data: NSData = data.subdataWithRange(NSMakeRange(0, sizeof(Float))) 90 | data.getBytes(&value, length: sizeof(Float)) 91 | return value 92 | } 93 | } 94 | } 95 | 96 | extension Double: Packable { 97 | 98 | public var packedDataLength: Int { 99 | return self.packedIDLength + sizeof(Double) 100 | } 101 | 102 | public var packedHeaderData: [NSData] { 103 | return [NSData()] 104 | } 105 | 106 | public var packedBodyData: [NSData] { 107 | var value: Double = self 108 | return [NSData(bytes: &value, length: sizeof(Double))] 109 | } 110 | 111 | public static var unpackProcedure: (data: NSData) -> Packable? { 112 | 113 | return { data in 114 | // unpack data as Double 115 | var value: Double = 0 116 | let data: NSData = data.subdataWithRange(NSMakeRange(0, sizeof(Double))) 117 | data.getBytes(&value, length: sizeof(Double)) 118 | return value 119 | } 120 | } 121 | } 122 | 123 | extension String: Packable { 124 | 125 | public var packedDataLength: Int { 126 | return self.packedIDLength + Int.PackedDataLength + self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) 127 | } 128 | 129 | public var packedHeaderData: [NSData] { 130 | let length: Int = self.lengthOfBytesUsingEncoding(NSUTF8StringEncoding) 131 | return [length.packedData] 132 | } 133 | 134 | public var packedBodyData: [NSData] { 135 | guard let data = self.dataUsingEncoding(NSUTF8StringEncoding) else { 136 | return [NSData()] 137 | } 138 | return [data] 139 | } 140 | 141 | public static var unpackProcedure: (data: NSData) -> Packable? { 142 | 143 | return { data in 144 | 145 | // get length of string 146 | let lengthData: NSData = data.subdataWithRange(NSMakeRange(0, Int.PackedDataLength)) 147 | let length: Int = Monaka.unpack(data: lengthData) as! Int 148 | 149 | // unpack data as String 150 | let textRange = NSMakeRange(Int.PackedDataLength, length) 151 | let textData = data.subdataWithRange(textRange) 152 | let text = NSString(data: textData, encoding: NSUTF8StringEncoding) as? String ?? "" 153 | return text 154 | } 155 | } 156 | } 157 | 158 | protocol ArrayType { } 159 | 160 | extension Array: Packable, ArrayType { 161 | 162 | public static var packedIdentifier: String { 163 | return "Array" 164 | } 165 | 166 | public var packedIdentifier: String { 167 | return "Array" 168 | } 169 | 170 | public func packable() -> [Packable] { 171 | return self.flatMap { 172 | switch $0 { 173 | case is NSNumber: 174 | return ($0 as! NSNumber).swiftyValue as? Packable 175 | case is NSString: 176 | return ($0 as! NSString) as String 177 | default: 178 | return $0 as? Packable 179 | } 180 | } 181 | } 182 | 183 | public var packedDataLength: Int { 184 | let packables: [Packable] = self.packable() 185 | let elementsLength: Int = packables.reduce(0, combine: { 186 | $0 + $1.packedDataLength 187 | }) 188 | return self.packedIDLength + Int.PackedDataLength*(1+packables.count) + elementsLength 189 | } 190 | 191 | public var packedIDLength: Int { 192 | return sizeof(UInt8) + self.packedIdentifier.characters.count 193 | } 194 | 195 | public var packedHeaderData: [NSData] { 196 | let packables: [Packable] = self.packable() 197 | let count: NSData = packables.count.packedData 198 | let data: [NSData] = packables.map { element in 199 | return element.packedDataLength 200 | }.map { length in 201 | return length.packedData 202 | } 203 | return [count] + data 204 | } 205 | 206 | public var packedBodyData: [NSData] { 207 | let packables: [Packable] = self.packable() 208 | let data: [NSData] = packables.map { element in 209 | return element.packedData 210 | } 211 | return data 212 | } 213 | 214 | public var packedData: NSData { 215 | let data: NSMutableData = NSMutableData(data: self.packedIdentifierData) 216 | for subdata in self.packedHeaderData + self.packedBodyData { 217 | data.appendData(subdata) 218 | } 219 | return NSData(data: data) 220 | } 221 | 222 | public static var unpackProcedure: (data: NSData) -> Packable? { 223 | 224 | return { data in 225 | 226 | // get number of elements 227 | let countData = data.subdataWithRange(NSMakeRange(0, Int.PackedDataLength)) 228 | let count: Int = Monaka.unpack(data: countData) as! Int 229 | 230 | let subdata: NSData = data.subdataWithRange(NSMakeRange(Int.PackedDataLength, data.length - Int.PackedDataLength)) 231 | let splitData: NSData.SplitData = subdata.split(length: Int.PackedDataLength*count) 232 | 233 | // get lengths of each elements 234 | let lengths: [Int] = splitData.former.splitIntoSubdata(lengths: [Int](count: count, repeatedValue: Int.PackedDataLength)).map { element in 235 | return Monaka.unpack(data: element) as! Int 236 | } 237 | 238 | // unpack each elements 239 | let elements: [Packable] = splitData.latter.splitIntoSubdata(lengths: lengths).flatMap { element in 240 | return Monaka.unpack(data: element) 241 | } 242 | 243 | return elements 244 | } 245 | } 246 | 247 | public static func activatePack() { 248 | Monaka.registerUnpackProcedure(identifier: self.packedIdentifier, procedure: self.unpackProcedure) 249 | } 250 | } 251 | 252 | protocol DictionaryType { } 253 | 254 | extension Dictionary: Packable, DictionaryType { 255 | 256 | public static var packedIdentifier: String { 257 | return "Dictionary" 258 | } 259 | 260 | public var packedIdentifier: String { 261 | return "Dictionary" 262 | } 263 | 264 | public func packable() -> [String: Packable] { 265 | 266 | var packable: [String: Packable] = [:] 267 | for (label, value) in self { 268 | if let label = label as? String, value = value as? Packable { 269 | packable[label] = value 270 | } 271 | } 272 | return packable 273 | } 274 | 275 | public var packedDataLength: Int { 276 | 277 | let packable: [String: Packable] = self.packable() 278 | 279 | let elementsLength: Int = packable.keys.reduce(0) { (length, key) in 280 | length + key.packedDataLength 281 | } + packable.values.reduce(0) { (length, value) in 282 | length + value.packedDataLength 283 | } 284 | 285 | return self.packedIDLength + Int.PackedDataLength*(1+packable.keys.count*2) + elementsLength 286 | } 287 | 288 | public var packedHeaderData: [NSData] { 289 | 290 | let packable: [String: Packable] = self.packable() 291 | 292 | // number of pair of key, value 293 | let count: NSData = Int(packable.keys.count).packedData 294 | 295 | // lengths of each key data 296 | let keys: [NSData] = packable.keys.map { key in 297 | return key.packedDataLength 298 | }.map { (length: Int) in 299 | return length.packedData 300 | } 301 | 302 | // lengths of each value data 303 | let values: [NSData] = packable.values.map { value in 304 | return value.packedDataLength 305 | }.map { (length: Int) in 306 | return length.packedData 307 | } 308 | 309 | return [count] + keys + values 310 | } 311 | 312 | public var packedBodyData: [NSData] { 313 | 314 | let packable: [String: Packable] = self.packable() 315 | 316 | let keys: [NSData] = packable.keys.map { key in 317 | return key.packedData 318 | } 319 | let values: [NSData] = packable.values.map { value in 320 | return value.packedData 321 | } 322 | return keys + values 323 | } 324 | 325 | public static var unpackProcedure: (data: NSData) -> Packable? { 326 | 327 | return { data in 328 | 329 | // get number of pair of key, value 330 | let countData = data.subdataWithRange(NSMakeRange(0, Int.PackedDataLength)) 331 | let count: Int = Monaka.unpack(data: countData) as! Int 332 | 333 | let subdata: NSData = data.subdataWithRange(NSMakeRange(Int.PackedDataLength, data.length - Int.PackedDataLength)) 334 | let splitData: NSData.SplitData = subdata.split(length: Int.PackedDataLength*count*2) 335 | 336 | // get lengths of each data 337 | let lengths: [Int] = splitData.former.splitIntoSubdata(lengths: [Int](count: count*2, repeatedValue: Int.PackedDataLength)).map { element in 338 | return Monaka.unpack(data: element) as! Int 339 | } 340 | 341 | let bodyParts: [NSData] = splitData.latter.splitIntoSubdata(lengths: lengths) 342 | 343 | // get keys and values 344 | let keys: [String] = bodyParts[0.. SplitData { 401 | let former: NSData = self.subdataWithRange(NSMakeRange(0, length)) 402 | let latter: NSData = self.subdataWithRange(NSMakeRange(length, self.length - length)) 403 | return (former: former, latter: latter) 404 | } 405 | 406 | func splitIntoSubdata(lengths lengths: [Int]) -> [NSData] { 407 | 408 | let data: NSData = NSData(data: self) 409 | var result: [NSData] = [NSData]() 410 | 411 | var position: Int = 0 412 | for length in lengths { 413 | let range: NSRange = NSMakeRange(position, length) 414 | result.append(data.subdataWithRange(range)) 415 | position = position + length 416 | } 417 | return result 418 | } 419 | } 420 | -------------------------------------------------------------------------------- /WhatMonaka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/naru-jpn/Monaka/85cdb749b9b5680ce60cd1d43dfcc093753091b9/WhatMonaka.png --------------------------------------------------------------------------------