├── .gitignore ├── LICENSE ├── Mapping.xcodeproj ├── project.pbxproj ├── project.xcworkspace │ └── contents.xcworkspacedata ├── xcshareddata │ └── xcschemes │ │ └── MappingAce.xcscheme └── xcuserdata │ └── Binglin.xcuserdatad │ └── xcschemes │ ├── Mapping.xcscheme │ └── MappingTests.xcscheme ├── Mapping.xcworkspace └── contents.xcworkspacedata ├── Mapping ├── AppDelegate.swift ├── Assets.xcassets │ └── AppIcon.appiconset │ │ └── Contents.json ├── Base.lproj │ ├── LaunchScreen.storyboard │ └── Main.storyboard ├── Info.plist └── ViewController.swift ├── MappingAce.podspec ├── MappingAce ├── ArrayMapping.swift ├── EnumIntMapping.swift ├── EnumStringMapping.swift ├── Info.plist ├── InitMapping.swift ├── Initializable.swift ├── IntegerMapping.swift ├── KeyMapping.swift ├── Mapping.swift ├── MappingAce.h ├── MappingError.swift ├── Metadata.swift ├── ObjectMetadata.swift ├── OptionalMapping.swift ├── PropertyMapping.swift ├── Serializable.swift ├── StringMapping.swift ├── Updatable.swift └── ValueMapping.swift ├── MappingTests ├── ArrayMappingTests.swift ├── Info.plist ├── JSONSerializationTests.swift ├── NumericalConvertTests.swift ├── PerformanceTests.swift ├── SwiftClassMappingTests.swift ├── SwiftStructNonilTests.swift └── SwiftStructNullableTests.swift ├── Podfile ├── Podfile.lock ├── README.md └── logo.png /.gitignore: -------------------------------------------------------------------------------- 1 | Build/ 2 | xcuserdata/ 3 | Pods/ -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 IcyButterfly 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Mapping.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 007C8BA84AD8A97145F7DB05 /* Pods_MappingTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 01FA43298E039AFE8CBA3EF4 /* Pods_MappingTests.framework */; }; 11 | 45ABD5B91DABC12F00670593 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45ABD5B81DABC12F00670593 /* AppDelegate.swift */; }; 12 | 45ABD5BB1DABC12F00670593 /* ViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 45ABD5BA1DABC12F00670593 /* ViewController.swift */; }; 13 | 45ABD5BE1DABC12F00670593 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 45ABD5BC1DABC12F00670593 /* Main.storyboard */; }; 14 | 45ABD5C01DABC12F00670593 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 45ABD5BF1DABC12F00670593 /* Assets.xcassets */; }; 15 | 45ABD5C31DABC12F00670593 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 45ABD5C11DABC12F00670593 /* LaunchScreen.storyboard */; }; 16 | C8D2CAD7BAB4E4627924CED8 /* Pods_Mapping.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 7B512C1E3E8ADAA318A3780C /* Pods_Mapping.framework */; }; 17 | D439BA5E1DBEF78E00528B71 /* NumericalConvertTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D439BA5D1DBEF78E00528B71 /* NumericalConvertTests.swift */; }; 18 | D455EA561DC097C600656EC2 /* MappingAce.h in Headers */ = {isa = PBXBuildFile; fileRef = D455EA541DC097C600656EC2 /* MappingAce.h */; settings = {ATTRIBUTES = (Public, ); }; }; 19 | D455EA591DC097C600656EC2 /* MappingAce.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = D455EA521DC097C600656EC2 /* MappingAce.framework */; }; 20 | D455EA5A1DC097C600656EC2 /* MappingAce.framework in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D455EA521DC097C600656EC2 /* MappingAce.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; }; 21 | D455EA6F1DC0981E00656EC2 /* ArrayMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA5F1DC0981E00656EC2 /* ArrayMapping.swift */; }; 22 | D455EA701DC0981E00656EC2 /* EnumIntMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA601DC0981E00656EC2 /* EnumIntMapping.swift */; }; 23 | D455EA711DC0981E00656EC2 /* EnumStringMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA611DC0981E00656EC2 /* EnumStringMapping.swift */; }; 24 | D455EA721DC0981E00656EC2 /* Initializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA621DC0981E00656EC2 /* Initializable.swift */; }; 25 | D455EA731DC0981E00656EC2 /* InitMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA631DC0981E00656EC2 /* InitMapping.swift */; }; 26 | D455EA741DC0981E00656EC2 /* IntegerMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA641DC0981E00656EC2 /* IntegerMapping.swift */; }; 27 | D455EA751DC0981E00656EC2 /* KeyMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA651DC0981E00656EC2 /* KeyMapping.swift */; }; 28 | D455EA761DC0981E00656EC2 /* Mapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA661DC0981E00656EC2 /* Mapping.swift */; }; 29 | D455EA771DC0981E00656EC2 /* Metadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA671DC0981E00656EC2 /* Metadata.swift */; }; 30 | D455EA781DC0981E00656EC2 /* ObjectMetadata.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA681DC0981E00656EC2 /* ObjectMetadata.swift */; }; 31 | D455EA791DC0981E00656EC2 /* OptionalMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA691DC0981E00656EC2 /* OptionalMapping.swift */; }; 32 | D455EA7A1DC0981E00656EC2 /* PropertyMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA6A1DC0981E00656EC2 /* PropertyMapping.swift */; }; 33 | D455EA7B1DC0981E00656EC2 /* Serializable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA6B1DC0981E00656EC2 /* Serializable.swift */; }; 34 | D455EA7C1DC0981E00656EC2 /* StringMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA6C1DC0981E00656EC2 /* StringMapping.swift */; }; 35 | D455EA7D1DC0981E00656EC2 /* Updatable.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA6D1DC0981E00656EC2 /* Updatable.swift */; }; 36 | D455EA7E1DC0981E00656EC2 /* ValueMapping.swift in Sources */ = {isa = PBXBuildFile; fileRef = D455EA6E1DC0981E00656EC2 /* ValueMapping.swift */; }; 37 | D4960D251DBF4A630017FE76 /* JSONSerializationTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4960D241DBF4A630017FE76 /* JSONSerializationTests.swift */; }; 38 | D4A454711DBDE06600551ADC /* SwiftClassMappingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A454701DBDE06600551ADC /* SwiftClassMappingTests.swift */; }; 39 | D4A454751DBDE37800551ADC /* SwiftStructNonilTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A454741DBDE37800551ADC /* SwiftStructNonilTests.swift */; }; 40 | D4A454771DBDE4DF00551ADC /* SwiftStructNullableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4A454761DBDE4DF00551ADC /* SwiftStructNullableTests.swift */; }; 41 | D4C3F2671E56CB3200B44218 /* PerformanceTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4C3F2661E56CB3200B44218 /* PerformanceTests.swift */; }; 42 | D4D92A6F1DEEA90B009513B8 /* MappingError.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4D92A6E1DEEA90B009513B8 /* MappingError.swift */; }; 43 | D4D92A711DEEABF2009513B8 /* ArrayMappingTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D4D92A701DEEABF2009513B8 /* ArrayMappingTests.swift */; }; 44 | FC829683AFE7A4096B6924FF /* Pods_MappingAce.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 91838D03C86603E19990ECDA /* Pods_MappingAce.framework */; }; 45 | /* End PBXBuildFile section */ 46 | 47 | /* Begin PBXContainerItemProxy section */ 48 | D455EA571DC097C600656EC2 /* PBXContainerItemProxy */ = { 49 | isa = PBXContainerItemProxy; 50 | containerPortal = 45ABD5AD1DABC12E00670593 /* Project object */; 51 | proxyType = 1; 52 | remoteGlobalIDString = D455EA511DC097C600656EC2; 53 | remoteInfo = MappingAce; 54 | }; 55 | D4A454631DBDDFB100551ADC /* PBXContainerItemProxy */ = { 56 | isa = PBXContainerItemProxy; 57 | containerPortal = 45ABD5AD1DABC12E00670593 /* Project object */; 58 | proxyType = 1; 59 | remoteGlobalIDString = 45ABD5B41DABC12E00670593; 60 | remoteInfo = Mapping; 61 | }; 62 | /* End PBXContainerItemProxy section */ 63 | 64 | /* Begin PBXCopyFilesBuildPhase section */ 65 | D455EA5E1DC097C600656EC2 /* Embed Frameworks */ = { 66 | isa = PBXCopyFilesBuildPhase; 67 | buildActionMask = 2147483647; 68 | dstPath = ""; 69 | dstSubfolderSpec = 10; 70 | files = ( 71 | D455EA5A1DC097C600656EC2 /* MappingAce.framework in Embed Frameworks */, 72 | ); 73 | name = "Embed Frameworks"; 74 | runOnlyForDeploymentPostprocessing = 0; 75 | }; 76 | /* End PBXCopyFilesBuildPhase section */ 77 | 78 | /* Begin PBXFileReference section */ 79 | 01FA43298E039AFE8CBA3EF4 /* Pods_MappingTests.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MappingTests.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 80 | 45ABD5B51DABC12F00670593 /* Mapping.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Mapping.app; sourceTree = BUILT_PRODUCTS_DIR; }; 81 | 45ABD5B81DABC12F00670593 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 82 | 45ABD5BA1DABC12F00670593 /* ViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ViewController.swift; sourceTree = ""; }; 83 | 45ABD5BD1DABC12F00670593 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 84 | 45ABD5BF1DABC12F00670593 /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 85 | 45ABD5C21DABC12F00670593 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 86 | 45ABD5C41DABC12F00670593 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 87 | 57431D8EEFB65B445E376955 /* Pods-Mapping.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mapping.release.xcconfig"; path = "Pods/Target Support Files/Pods-Mapping/Pods-Mapping.release.xcconfig"; sourceTree = ""; }; 88 | 5D017C043650DE84CD755E36 /* Pods-MappingTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MappingTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MappingTests/Pods-MappingTests.debug.xcconfig"; sourceTree = ""; }; 89 | 7B512C1E3E8ADAA318A3780C /* Pods_Mapping.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mapping.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 90 | 91838D03C86603E19990ECDA /* Pods_MappingAce.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MappingAce.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 91 | A4656A4310BB812D6AB9ADA2 /* Pods-Mapping.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mapping.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Mapping/Pods-Mapping.debug.xcconfig"; sourceTree = ""; }; 92 | AC4432B2321BE85D7605DE2B /* Pods-MappingAce.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MappingAce.release.xcconfig"; path = "Pods/Target Support Files/Pods-MappingAce/Pods-MappingAce.release.xcconfig"; sourceTree = ""; }; 93 | C39237252CD3301C5995D2E8 /* Pods-MappingAce.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MappingAce.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MappingAce/Pods-MappingAce.debug.xcconfig"; sourceTree = ""; }; 94 | D439BA5D1DBEF78E00528B71 /* NumericalConvertTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = NumericalConvertTests.swift; sourceTree = ""; }; 95 | D455EA521DC097C600656EC2 /* MappingAce.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = MappingAce.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 96 | D455EA541DC097C600656EC2 /* MappingAce.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = MappingAce.h; sourceTree = ""; }; 97 | D455EA551DC097C600656EC2 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 98 | D455EA5F1DC0981E00656EC2 /* ArrayMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayMapping.swift; sourceTree = ""; }; 99 | D455EA601DC0981E00656EC2 /* EnumIntMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumIntMapping.swift; sourceTree = ""; }; 100 | D455EA611DC0981E00656EC2 /* EnumStringMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = EnumStringMapping.swift; sourceTree = ""; }; 101 | D455EA621DC0981E00656EC2 /* Initializable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Initializable.swift; sourceTree = ""; }; 102 | D455EA631DC0981E00656EC2 /* InitMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = InitMapping.swift; sourceTree = ""; }; 103 | D455EA641DC0981E00656EC2 /* IntegerMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = IntegerMapping.swift; sourceTree = ""; }; 104 | D455EA651DC0981E00656EC2 /* KeyMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = KeyMapping.swift; sourceTree = ""; }; 105 | D455EA661DC0981E00656EC2 /* Mapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Mapping.swift; sourceTree = ""; }; 106 | D455EA671DC0981E00656EC2 /* Metadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Metadata.swift; sourceTree = ""; }; 107 | D455EA681DC0981E00656EC2 /* ObjectMetadata.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ObjectMetadata.swift; sourceTree = ""; }; 108 | D455EA691DC0981E00656EC2 /* OptionalMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OptionalMapping.swift; sourceTree = ""; }; 109 | D455EA6A1DC0981E00656EC2 /* PropertyMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PropertyMapping.swift; sourceTree = ""; }; 110 | D455EA6B1DC0981E00656EC2 /* Serializable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Serializable.swift; sourceTree = ""; }; 111 | D455EA6C1DC0981E00656EC2 /* StringMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = StringMapping.swift; sourceTree = ""; }; 112 | D455EA6D1DC0981E00656EC2 /* Updatable.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Updatable.swift; sourceTree = ""; }; 113 | D455EA6E1DC0981E00656EC2 /* ValueMapping.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ValueMapping.swift; sourceTree = ""; }; 114 | D4960D241DBF4A630017FE76 /* JSONSerializationTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONSerializationTests.swift; sourceTree = ""; }; 115 | D4A4545E1DBDDFB100551ADC /* MappingTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = MappingTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; 116 | D4A454621DBDDFB100551ADC /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 117 | D4A454701DBDE06600551ADC /* SwiftClassMappingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftClassMappingTests.swift; sourceTree = ""; }; 118 | D4A454741DBDE37800551ADC /* SwiftStructNonilTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftStructNonilTests.swift; sourceTree = ""; }; 119 | D4A454761DBDE4DF00551ADC /* SwiftStructNullableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = SwiftStructNullableTests.swift; sourceTree = ""; }; 120 | D4C3F2661E56CB3200B44218 /* PerformanceTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PerformanceTests.swift; sourceTree = ""; }; 121 | D4D92A6E1DEEA90B009513B8 /* MappingError.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MappingError.swift; sourceTree = ""; }; 122 | D4D92A701DEEABF2009513B8 /* ArrayMappingTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ArrayMappingTests.swift; sourceTree = ""; }; 123 | D6E3785810537A1C9CE88235 /* Pods-MappingTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MappingTests.release.xcconfig"; path = "Pods/Target Support Files/Pods-MappingTests/Pods-MappingTests.release.xcconfig"; sourceTree = ""; }; 124 | /* End PBXFileReference section */ 125 | 126 | /* Begin PBXFrameworksBuildPhase section */ 127 | 45ABD5B21DABC12E00670593 /* Frameworks */ = { 128 | isa = PBXFrameworksBuildPhase; 129 | buildActionMask = 2147483647; 130 | files = ( 131 | D455EA591DC097C600656EC2 /* MappingAce.framework in Frameworks */, 132 | C8D2CAD7BAB4E4627924CED8 /* Pods_Mapping.framework in Frameworks */, 133 | ); 134 | runOnlyForDeploymentPostprocessing = 0; 135 | }; 136 | D455EA4E1DC097C600656EC2 /* Frameworks */ = { 137 | isa = PBXFrameworksBuildPhase; 138 | buildActionMask = 2147483647; 139 | files = ( 140 | FC829683AFE7A4096B6924FF /* Pods_MappingAce.framework in Frameworks */, 141 | ); 142 | runOnlyForDeploymentPostprocessing = 0; 143 | }; 144 | D4A4545B1DBDDFB100551ADC /* Frameworks */ = { 145 | isa = PBXFrameworksBuildPhase; 146 | buildActionMask = 2147483647; 147 | files = ( 148 | 007C8BA84AD8A97145F7DB05 /* Pods_MappingTests.framework in Frameworks */, 149 | ); 150 | runOnlyForDeploymentPostprocessing = 0; 151 | }; 152 | /* End PBXFrameworksBuildPhase section */ 153 | 154 | /* Begin PBXGroup section */ 155 | 0883B22993D322C801E4B0D8 /* Pods */ = { 156 | isa = PBXGroup; 157 | children = ( 158 | A4656A4310BB812D6AB9ADA2 /* Pods-Mapping.debug.xcconfig */, 159 | 57431D8EEFB65B445E376955 /* Pods-Mapping.release.xcconfig */, 160 | C39237252CD3301C5995D2E8 /* Pods-MappingAce.debug.xcconfig */, 161 | AC4432B2321BE85D7605DE2B /* Pods-MappingAce.release.xcconfig */, 162 | 5D017C043650DE84CD755E36 /* Pods-MappingTests.debug.xcconfig */, 163 | D6E3785810537A1C9CE88235 /* Pods-MappingTests.release.xcconfig */, 164 | ); 165 | name = Pods; 166 | sourceTree = ""; 167 | }; 168 | 3BB57AF325D2F55B7395F633 /* Frameworks */ = { 169 | isa = PBXGroup; 170 | children = ( 171 | 7B512C1E3E8ADAA318A3780C /* Pods_Mapping.framework */, 172 | 91838D03C86603E19990ECDA /* Pods_MappingAce.framework */, 173 | 01FA43298E039AFE8CBA3EF4 /* Pods_MappingTests.framework */, 174 | ); 175 | name = Frameworks; 176 | sourceTree = ""; 177 | }; 178 | 45ABD5AC1DABC12E00670593 = { 179 | isa = PBXGroup; 180 | children = ( 181 | 45ABD5B71DABC12F00670593 /* Mapping */, 182 | D4A4545F1DBDDFB100551ADC /* MappingTests */, 183 | D455EA531DC097C600656EC2 /* MappingAce */, 184 | 45ABD5B61DABC12F00670593 /* Products */, 185 | 0883B22993D322C801E4B0D8 /* Pods */, 186 | 3BB57AF325D2F55B7395F633 /* Frameworks */, 187 | ); 188 | sourceTree = ""; 189 | }; 190 | 45ABD5B61DABC12F00670593 /* Products */ = { 191 | isa = PBXGroup; 192 | children = ( 193 | 45ABD5B51DABC12F00670593 /* Mapping.app */, 194 | D4A4545E1DBDDFB100551ADC /* MappingTests.xctest */, 195 | D455EA521DC097C600656EC2 /* MappingAce.framework */, 196 | ); 197 | name = Products; 198 | sourceTree = ""; 199 | }; 200 | 45ABD5B71DABC12F00670593 /* Mapping */ = { 201 | isa = PBXGroup; 202 | children = ( 203 | 45ABD5B81DABC12F00670593 /* AppDelegate.swift */, 204 | 45ABD5BA1DABC12F00670593 /* ViewController.swift */, 205 | 45ABD5BC1DABC12F00670593 /* Main.storyboard */, 206 | 45ABD5BF1DABC12F00670593 /* Assets.xcassets */, 207 | 45ABD5C11DABC12F00670593 /* LaunchScreen.storyboard */, 208 | 45ABD5C41DABC12F00670593 /* Info.plist */, 209 | ); 210 | path = Mapping; 211 | sourceTree = ""; 212 | }; 213 | D455EA531DC097C600656EC2 /* MappingAce */ = { 214 | isa = PBXGroup; 215 | children = ( 216 | D455EA5F1DC0981E00656EC2 /* ArrayMapping.swift */, 217 | D455EA601DC0981E00656EC2 /* EnumIntMapping.swift */, 218 | D455EA611DC0981E00656EC2 /* EnumStringMapping.swift */, 219 | D455EA621DC0981E00656EC2 /* Initializable.swift */, 220 | D455EA631DC0981E00656EC2 /* InitMapping.swift */, 221 | D455EA641DC0981E00656EC2 /* IntegerMapping.swift */, 222 | D455EA651DC0981E00656EC2 /* KeyMapping.swift */, 223 | D455EA661DC0981E00656EC2 /* Mapping.swift */, 224 | D455EA671DC0981E00656EC2 /* Metadata.swift */, 225 | D455EA681DC0981E00656EC2 /* ObjectMetadata.swift */, 226 | D455EA691DC0981E00656EC2 /* OptionalMapping.swift */, 227 | D455EA6A1DC0981E00656EC2 /* PropertyMapping.swift */, 228 | D455EA6B1DC0981E00656EC2 /* Serializable.swift */, 229 | D455EA6C1DC0981E00656EC2 /* StringMapping.swift */, 230 | D455EA6D1DC0981E00656EC2 /* Updatable.swift */, 231 | D455EA6E1DC0981E00656EC2 /* ValueMapping.swift */, 232 | D455EA541DC097C600656EC2 /* MappingAce.h */, 233 | D455EA551DC097C600656EC2 /* Info.plist */, 234 | D4D92A6E1DEEA90B009513B8 /* MappingError.swift */, 235 | ); 236 | path = MappingAce; 237 | sourceTree = ""; 238 | }; 239 | D4A4545F1DBDDFB100551ADC /* MappingTests */ = { 240 | isa = PBXGroup; 241 | children = ( 242 | D4A454741DBDE37800551ADC /* SwiftStructNonilTests.swift */, 243 | D4A454761DBDE4DF00551ADC /* SwiftStructNullableTests.swift */, 244 | D4A454701DBDE06600551ADC /* SwiftClassMappingTests.swift */, 245 | D439BA5D1DBEF78E00528B71 /* NumericalConvertTests.swift */, 246 | D4D92A701DEEABF2009513B8 /* ArrayMappingTests.swift */, 247 | D4A454621DBDDFB100551ADC /* Info.plist */, 248 | D4960D241DBF4A630017FE76 /* JSONSerializationTests.swift */, 249 | D4C3F2661E56CB3200B44218 /* PerformanceTests.swift */, 250 | ); 251 | path = MappingTests; 252 | sourceTree = ""; 253 | }; 254 | /* End PBXGroup section */ 255 | 256 | /* Begin PBXHeadersBuildPhase section */ 257 | D455EA4F1DC097C600656EC2 /* Headers */ = { 258 | isa = PBXHeadersBuildPhase; 259 | buildActionMask = 2147483647; 260 | files = ( 261 | D455EA561DC097C600656EC2 /* MappingAce.h in Headers */, 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | }; 265 | /* End PBXHeadersBuildPhase section */ 266 | 267 | /* Begin PBXNativeTarget section */ 268 | 45ABD5B41DABC12E00670593 /* Mapping */ = { 269 | isa = PBXNativeTarget; 270 | buildConfigurationList = 45ABD5C71DABC12F00670593 /* Build configuration list for PBXNativeTarget "Mapping" */; 271 | buildPhases = ( 272 | 3DDB2A9114EA77B4682E29D2 /* [CP] Check Pods Manifest.lock */, 273 | 45ABD5B11DABC12E00670593 /* Sources */, 274 | 45ABD5B21DABC12E00670593 /* Frameworks */, 275 | 45ABD5B31DABC12E00670593 /* Resources */, 276 | D455EA5E1DC097C600656EC2 /* Embed Frameworks */, 277 | 5C23AC47E6974C9C8265A293 /* [CP] Embed Pods Frameworks */, 278 | D8DA1884BD36C6E651E0F4A1 /* [CP] Copy Pods Resources */, 279 | ); 280 | buildRules = ( 281 | ); 282 | dependencies = ( 283 | D455EA581DC097C600656EC2 /* PBXTargetDependency */, 284 | ); 285 | name = Mapping; 286 | productName = Mapping; 287 | productReference = 45ABD5B51DABC12F00670593 /* Mapping.app */; 288 | productType = "com.apple.product-type.application"; 289 | }; 290 | D455EA511DC097C600656EC2 /* MappingAce */ = { 291 | isa = PBXNativeTarget; 292 | buildConfigurationList = D455EA5D1DC097C600656EC2 /* Build configuration list for PBXNativeTarget "MappingAce" */; 293 | buildPhases = ( 294 | 65B684250986329AEAA1821B /* [CP] Check Pods Manifest.lock */, 295 | D455EA4D1DC097C600656EC2 /* Sources */, 296 | D455EA4E1DC097C600656EC2 /* Frameworks */, 297 | D455EA4F1DC097C600656EC2 /* Headers */, 298 | D455EA501DC097C600656EC2 /* Resources */, 299 | 0FA075EC339E11C2F76005A2 /* [CP] Copy Pods Resources */, 300 | ); 301 | buildRules = ( 302 | ); 303 | dependencies = ( 304 | ); 305 | name = MappingAce; 306 | productName = MappingAce; 307 | productReference = D455EA521DC097C600656EC2 /* MappingAce.framework */; 308 | productType = "com.apple.product-type.framework"; 309 | }; 310 | D4A4545D1DBDDFB100551ADC /* MappingTests */ = { 311 | isa = PBXNativeTarget; 312 | buildConfigurationList = D4A454651DBDDFB100551ADC /* Build configuration list for PBXNativeTarget "MappingTests" */; 313 | buildPhases = ( 314 | B7146F75742E32D9E227B9C7 /* [CP] Check Pods Manifest.lock */, 315 | D4A4545A1DBDDFB100551ADC /* Sources */, 316 | D4A4545B1DBDDFB100551ADC /* Frameworks */, 317 | D4A4545C1DBDDFB100551ADC /* Resources */, 318 | 6A8635308846B57BACF53DE1 /* [CP] Embed Pods Frameworks */, 319 | 48D8CE1C3287729EB937574C /* [CP] Copy Pods Resources */, 320 | ); 321 | buildRules = ( 322 | ); 323 | dependencies = ( 324 | D4A454641DBDDFB100551ADC /* PBXTargetDependency */, 325 | ); 326 | name = MappingTests; 327 | productName = MappingTests; 328 | productReference = D4A4545E1DBDDFB100551ADC /* MappingTests.xctest */; 329 | productType = "com.apple.product-type.bundle.unit-test"; 330 | }; 331 | /* End PBXNativeTarget section */ 332 | 333 | /* Begin PBXProject section */ 334 | 45ABD5AD1DABC12E00670593 /* Project object */ = { 335 | isa = PBXProject; 336 | attributes = { 337 | LastSwiftUpdateCheck = 0800; 338 | LastUpgradeCheck = 0830; 339 | ORGANIZATIONNAME = "Ice Butterfly"; 340 | TargetAttributes = { 341 | 45ABD5B41DABC12E00670593 = { 342 | CreatedOnToolsVersion = 8.0; 343 | DevelopmentTeam = VSXKPZWN4F; 344 | ProvisioningStyle = Automatic; 345 | }; 346 | D455EA511DC097C600656EC2 = { 347 | CreatedOnToolsVersion = 8.0; 348 | DevelopmentTeam = VSXKPZWN4F; 349 | LastSwiftMigration = 0800; 350 | ProvisioningStyle = Automatic; 351 | }; 352 | D4A4545D1DBDDFB100551ADC = { 353 | CreatedOnToolsVersion = 8.0; 354 | DevelopmentTeam = VSXKPZWN4F; 355 | ProvisioningStyle = Automatic; 356 | TestTargetID = 45ABD5B41DABC12E00670593; 357 | }; 358 | }; 359 | }; 360 | buildConfigurationList = 45ABD5B01DABC12E00670593 /* Build configuration list for PBXProject "Mapping" */; 361 | compatibilityVersion = "Xcode 3.2"; 362 | developmentRegion = English; 363 | hasScannedForEncodings = 0; 364 | knownRegions = ( 365 | en, 366 | Base, 367 | ); 368 | mainGroup = 45ABD5AC1DABC12E00670593; 369 | productRefGroup = 45ABD5B61DABC12F00670593 /* Products */; 370 | projectDirPath = ""; 371 | projectRoot = ""; 372 | targets = ( 373 | 45ABD5B41DABC12E00670593 /* Mapping */, 374 | D4A4545D1DBDDFB100551ADC /* MappingTests */, 375 | D455EA511DC097C600656EC2 /* MappingAce */, 376 | ); 377 | }; 378 | /* End PBXProject section */ 379 | 380 | /* Begin PBXResourcesBuildPhase section */ 381 | 45ABD5B31DABC12E00670593 /* Resources */ = { 382 | isa = PBXResourcesBuildPhase; 383 | buildActionMask = 2147483647; 384 | files = ( 385 | 45ABD5C31DABC12F00670593 /* LaunchScreen.storyboard in Resources */, 386 | 45ABD5C01DABC12F00670593 /* Assets.xcassets in Resources */, 387 | 45ABD5BE1DABC12F00670593 /* Main.storyboard in Resources */, 388 | ); 389 | runOnlyForDeploymentPostprocessing = 0; 390 | }; 391 | D455EA501DC097C600656EC2 /* Resources */ = { 392 | isa = PBXResourcesBuildPhase; 393 | buildActionMask = 2147483647; 394 | files = ( 395 | ); 396 | runOnlyForDeploymentPostprocessing = 0; 397 | }; 398 | D4A4545C1DBDDFB100551ADC /* Resources */ = { 399 | isa = PBXResourcesBuildPhase; 400 | buildActionMask = 2147483647; 401 | files = ( 402 | ); 403 | runOnlyForDeploymentPostprocessing = 0; 404 | }; 405 | /* End PBXResourcesBuildPhase section */ 406 | 407 | /* Begin PBXShellScriptBuildPhase section */ 408 | 0FA075EC339E11C2F76005A2 /* [CP] Copy Pods Resources */ = { 409 | isa = PBXShellScriptBuildPhase; 410 | buildActionMask = 2147483647; 411 | files = ( 412 | ); 413 | inputPaths = ( 414 | ); 415 | name = "[CP] Copy Pods Resources"; 416 | outputPaths = ( 417 | ); 418 | runOnlyForDeploymentPostprocessing = 0; 419 | shellPath = /bin/sh; 420 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MappingAce/Pods-MappingAce-resources.sh\"\n"; 421 | showEnvVarsInLog = 0; 422 | }; 423 | 3DDB2A9114EA77B4682E29D2 /* [CP] Check Pods Manifest.lock */ = { 424 | isa = PBXShellScriptBuildPhase; 425 | buildActionMask = 2147483647; 426 | files = ( 427 | ); 428 | inputPaths = ( 429 | ); 430 | name = "[CP] Check Pods Manifest.lock"; 431 | outputPaths = ( 432 | ); 433 | runOnlyForDeploymentPostprocessing = 0; 434 | shellPath = /bin/sh; 435 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 436 | showEnvVarsInLog = 0; 437 | }; 438 | 48D8CE1C3287729EB937574C /* [CP] Copy Pods Resources */ = { 439 | isa = PBXShellScriptBuildPhase; 440 | buildActionMask = 2147483647; 441 | files = ( 442 | ); 443 | inputPaths = ( 444 | ); 445 | name = "[CP] Copy Pods Resources"; 446 | outputPaths = ( 447 | ); 448 | runOnlyForDeploymentPostprocessing = 0; 449 | shellPath = /bin/sh; 450 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MappingTests/Pods-MappingTests-resources.sh\"\n"; 451 | showEnvVarsInLog = 0; 452 | }; 453 | 5C23AC47E6974C9C8265A293 /* [CP] Embed Pods Frameworks */ = { 454 | isa = PBXShellScriptBuildPhase; 455 | buildActionMask = 2147483647; 456 | files = ( 457 | ); 458 | inputPaths = ( 459 | ); 460 | name = "[CP] Embed Pods Frameworks"; 461 | outputPaths = ( 462 | ); 463 | runOnlyForDeploymentPostprocessing = 0; 464 | shellPath = /bin/sh; 465 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mapping/Pods-Mapping-frameworks.sh\"\n"; 466 | showEnvVarsInLog = 0; 467 | }; 468 | 65B684250986329AEAA1821B /* [CP] Check Pods Manifest.lock */ = { 469 | isa = PBXShellScriptBuildPhase; 470 | buildActionMask = 2147483647; 471 | files = ( 472 | ); 473 | inputPaths = ( 474 | ); 475 | name = "[CP] Check Pods Manifest.lock"; 476 | outputPaths = ( 477 | ); 478 | runOnlyForDeploymentPostprocessing = 0; 479 | shellPath = /bin/sh; 480 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 481 | showEnvVarsInLog = 0; 482 | }; 483 | 6A8635308846B57BACF53DE1 /* [CP] Embed Pods Frameworks */ = { 484 | isa = PBXShellScriptBuildPhase; 485 | buildActionMask = 2147483647; 486 | files = ( 487 | ); 488 | inputPaths = ( 489 | ); 490 | name = "[CP] Embed Pods Frameworks"; 491 | outputPaths = ( 492 | ); 493 | runOnlyForDeploymentPostprocessing = 0; 494 | shellPath = /bin/sh; 495 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-MappingTests/Pods-MappingTests-frameworks.sh\"\n"; 496 | showEnvVarsInLog = 0; 497 | }; 498 | B7146F75742E32D9E227B9C7 /* [CP] Check Pods Manifest.lock */ = { 499 | isa = PBXShellScriptBuildPhase; 500 | buildActionMask = 2147483647; 501 | files = ( 502 | ); 503 | inputPaths = ( 504 | ); 505 | name = "[CP] Check Pods Manifest.lock"; 506 | outputPaths = ( 507 | ); 508 | runOnlyForDeploymentPostprocessing = 0; 509 | shellPath = /bin/sh; 510 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n"; 511 | showEnvVarsInLog = 0; 512 | }; 513 | D8DA1884BD36C6E651E0F4A1 /* [CP] Copy Pods Resources */ = { 514 | isa = PBXShellScriptBuildPhase; 515 | buildActionMask = 2147483647; 516 | files = ( 517 | ); 518 | inputPaths = ( 519 | ); 520 | name = "[CP] Copy Pods Resources"; 521 | outputPaths = ( 522 | ); 523 | runOnlyForDeploymentPostprocessing = 0; 524 | shellPath = /bin/sh; 525 | shellScript = "\"${SRCROOT}/Pods/Target Support Files/Pods-Mapping/Pods-Mapping-resources.sh\"\n"; 526 | showEnvVarsInLog = 0; 527 | }; 528 | /* End PBXShellScriptBuildPhase section */ 529 | 530 | /* Begin PBXSourcesBuildPhase section */ 531 | 45ABD5B11DABC12E00670593 /* Sources */ = { 532 | isa = PBXSourcesBuildPhase; 533 | buildActionMask = 2147483647; 534 | files = ( 535 | 45ABD5BB1DABC12F00670593 /* ViewController.swift in Sources */, 536 | 45ABD5B91DABC12F00670593 /* AppDelegate.swift in Sources */, 537 | ); 538 | runOnlyForDeploymentPostprocessing = 0; 539 | }; 540 | D455EA4D1DC097C600656EC2 /* Sources */ = { 541 | isa = PBXSourcesBuildPhase; 542 | buildActionMask = 2147483647; 543 | files = ( 544 | D455EA6F1DC0981E00656EC2 /* ArrayMapping.swift in Sources */, 545 | D455EA751DC0981E00656EC2 /* KeyMapping.swift in Sources */, 546 | D455EA701DC0981E00656EC2 /* EnumIntMapping.swift in Sources */, 547 | D455EA711DC0981E00656EC2 /* EnumStringMapping.swift in Sources */, 548 | D455EA761DC0981E00656EC2 /* Mapping.swift in Sources */, 549 | D455EA7C1DC0981E00656EC2 /* StringMapping.swift in Sources */, 550 | D455EA7E1DC0981E00656EC2 /* ValueMapping.swift in Sources */, 551 | D455EA741DC0981E00656EC2 /* IntegerMapping.swift in Sources */, 552 | D455EA731DC0981E00656EC2 /* InitMapping.swift in Sources */, 553 | D455EA7B1DC0981E00656EC2 /* Serializable.swift in Sources */, 554 | D4D92A6F1DEEA90B009513B8 /* MappingError.swift in Sources */, 555 | D455EA781DC0981E00656EC2 /* ObjectMetadata.swift in Sources */, 556 | D455EA791DC0981E00656EC2 /* OptionalMapping.swift in Sources */, 557 | D455EA7A1DC0981E00656EC2 /* PropertyMapping.swift in Sources */, 558 | D455EA7D1DC0981E00656EC2 /* Updatable.swift in Sources */, 559 | D455EA771DC0981E00656EC2 /* Metadata.swift in Sources */, 560 | D455EA721DC0981E00656EC2 /* Initializable.swift in Sources */, 561 | ); 562 | runOnlyForDeploymentPostprocessing = 0; 563 | }; 564 | D4A4545A1DBDDFB100551ADC /* Sources */ = { 565 | isa = PBXSourcesBuildPhase; 566 | buildActionMask = 2147483647; 567 | files = ( 568 | D4C3F2671E56CB3200B44218 /* PerformanceTests.swift in Sources */, 569 | D4D92A711DEEABF2009513B8 /* ArrayMappingTests.swift in Sources */, 570 | D4A454711DBDE06600551ADC /* SwiftClassMappingTests.swift in Sources */, 571 | D4A454771DBDE4DF00551ADC /* SwiftStructNullableTests.swift in Sources */, 572 | D439BA5E1DBEF78E00528B71 /* NumericalConvertTests.swift in Sources */, 573 | D4960D251DBF4A630017FE76 /* JSONSerializationTests.swift in Sources */, 574 | D4A454751DBDE37800551ADC /* SwiftStructNonilTests.swift in Sources */, 575 | ); 576 | runOnlyForDeploymentPostprocessing = 0; 577 | }; 578 | /* End PBXSourcesBuildPhase section */ 579 | 580 | /* Begin PBXTargetDependency section */ 581 | D455EA581DC097C600656EC2 /* PBXTargetDependency */ = { 582 | isa = PBXTargetDependency; 583 | target = D455EA511DC097C600656EC2 /* MappingAce */; 584 | targetProxy = D455EA571DC097C600656EC2 /* PBXContainerItemProxy */; 585 | }; 586 | D4A454641DBDDFB100551ADC /* PBXTargetDependency */ = { 587 | isa = PBXTargetDependency; 588 | target = 45ABD5B41DABC12E00670593 /* Mapping */; 589 | targetProxy = D4A454631DBDDFB100551ADC /* PBXContainerItemProxy */; 590 | }; 591 | /* End PBXTargetDependency section */ 592 | 593 | /* Begin PBXVariantGroup section */ 594 | 45ABD5BC1DABC12F00670593 /* Main.storyboard */ = { 595 | isa = PBXVariantGroup; 596 | children = ( 597 | 45ABD5BD1DABC12F00670593 /* Base */, 598 | ); 599 | name = Main.storyboard; 600 | sourceTree = ""; 601 | }; 602 | 45ABD5C11DABC12F00670593 /* LaunchScreen.storyboard */ = { 603 | isa = PBXVariantGroup; 604 | children = ( 605 | 45ABD5C21DABC12F00670593 /* Base */, 606 | ); 607 | name = LaunchScreen.storyboard; 608 | sourceTree = ""; 609 | }; 610 | /* End PBXVariantGroup section */ 611 | 612 | /* Begin XCBuildConfiguration section */ 613 | 45ABD5C51DABC12F00670593 /* Debug */ = { 614 | isa = XCBuildConfiguration; 615 | buildSettings = { 616 | ALWAYS_SEARCH_USER_PATHS = NO; 617 | CLANG_ANALYZER_NONNULL = YES; 618 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 619 | CLANG_CXX_LIBRARY = "libc++"; 620 | CLANG_ENABLE_MODULES = YES; 621 | CLANG_ENABLE_OBJC_ARC = YES; 622 | CLANG_WARN_BOOL_CONVERSION = YES; 623 | CLANG_WARN_CONSTANT_CONVERSION = YES; 624 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 625 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 626 | CLANG_WARN_EMPTY_BODY = YES; 627 | CLANG_WARN_ENUM_CONVERSION = YES; 628 | CLANG_WARN_INFINITE_RECURSION = YES; 629 | CLANG_WARN_INT_CONVERSION = YES; 630 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 631 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 632 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 633 | CLANG_WARN_UNREACHABLE_CODE = YES; 634 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 635 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 636 | COPY_PHASE_STRIP = NO; 637 | DEBUG_INFORMATION_FORMAT = dwarf; 638 | ENABLE_STRICT_OBJC_MSGSEND = YES; 639 | ENABLE_TESTABILITY = YES; 640 | GCC_C_LANGUAGE_STANDARD = gnu99; 641 | GCC_DYNAMIC_NO_PIC = NO; 642 | GCC_NO_COMMON_BLOCKS = YES; 643 | GCC_OPTIMIZATION_LEVEL = 0; 644 | GCC_PREPROCESSOR_DEFINITIONS = ( 645 | "DEBUG=1", 646 | "$(inherited)", 647 | ); 648 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 649 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 650 | GCC_WARN_UNDECLARED_SELECTOR = YES; 651 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 652 | GCC_WARN_UNUSED_FUNCTION = YES; 653 | GCC_WARN_UNUSED_VARIABLE = YES; 654 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 655 | MTL_ENABLE_DEBUG_INFO = YES; 656 | ONLY_ACTIVE_ARCH = YES; 657 | SDKROOT = iphoneos; 658 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; 659 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 660 | SWIFT_VERSION = 2.3; 661 | TARGETED_DEVICE_FAMILY = "1,2"; 662 | }; 663 | name = Debug; 664 | }; 665 | 45ABD5C61DABC12F00670593 /* Release */ = { 666 | isa = XCBuildConfiguration; 667 | buildSettings = { 668 | ALWAYS_SEARCH_USER_PATHS = NO; 669 | CLANG_ANALYZER_NONNULL = YES; 670 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 671 | CLANG_CXX_LIBRARY = "libc++"; 672 | CLANG_ENABLE_MODULES = YES; 673 | CLANG_ENABLE_OBJC_ARC = YES; 674 | CLANG_WARN_BOOL_CONVERSION = YES; 675 | CLANG_WARN_CONSTANT_CONVERSION = YES; 676 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 677 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES; 678 | CLANG_WARN_EMPTY_BODY = YES; 679 | CLANG_WARN_ENUM_CONVERSION = YES; 680 | CLANG_WARN_INFINITE_RECURSION = YES; 681 | CLANG_WARN_INT_CONVERSION = YES; 682 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 683 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 684 | CLANG_WARN_SUSPICIOUS_MOVES = YES; 685 | CLANG_WARN_UNREACHABLE_CODE = YES; 686 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 687 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 688 | COPY_PHASE_STRIP = NO; 689 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 690 | ENABLE_NS_ASSERTIONS = NO; 691 | ENABLE_STRICT_OBJC_MSGSEND = YES; 692 | GCC_C_LANGUAGE_STANDARD = gnu99; 693 | GCC_NO_COMMON_BLOCKS = YES; 694 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 695 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 696 | GCC_WARN_UNDECLARED_SELECTOR = YES; 697 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 698 | GCC_WARN_UNUSED_FUNCTION = YES; 699 | GCC_WARN_UNUSED_VARIABLE = YES; 700 | IPHONEOS_DEPLOYMENT_TARGET = 10.0; 701 | MTL_ENABLE_DEBUG_INFO = NO; 702 | SDKROOT = iphoneos; 703 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 704 | SWIFT_VERSION = 2.3; 705 | TARGETED_DEVICE_FAMILY = "1,2"; 706 | VALIDATE_PRODUCT = YES; 707 | }; 708 | name = Release; 709 | }; 710 | 45ABD5C81DABC12F00670593 /* Debug */ = { 711 | isa = XCBuildConfiguration; 712 | baseConfigurationReference = A4656A4310BB812D6AB9ADA2 /* Pods-Mapping.debug.xcconfig */; 713 | buildSettings = { 714 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 715 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 716 | DEVELOPMENT_TEAM = VSXKPZWN4F; 717 | INFOPLIST_FILE = Mapping/Info.plist; 718 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 719 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 720 | PRODUCT_BUNDLE_IDENTIFIER = Bl.Mapping; 721 | PRODUCT_NAME = "$(TARGET_NAME)"; 722 | SWIFT_VERSION = 3.0; 723 | }; 724 | name = Debug; 725 | }; 726 | 45ABD5C91DABC12F00670593 /* Release */ = { 727 | isa = XCBuildConfiguration; 728 | baseConfigurationReference = 57431D8EEFB65B445E376955 /* Pods-Mapping.release.xcconfig */; 729 | buildSettings = { 730 | ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES; 731 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 732 | DEVELOPMENT_TEAM = VSXKPZWN4F; 733 | INFOPLIST_FILE = Mapping/Info.plist; 734 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 735 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 736 | PRODUCT_BUNDLE_IDENTIFIER = Bl.Mapping; 737 | PRODUCT_NAME = "$(TARGET_NAME)"; 738 | SWIFT_VERSION = 3.0; 739 | }; 740 | name = Release; 741 | }; 742 | D455EA5B1DC097C600656EC2 /* Debug */ = { 743 | isa = XCBuildConfiguration; 744 | baseConfigurationReference = C39237252CD3301C5995D2E8 /* Pods-MappingAce.debug.xcconfig */; 745 | buildSettings = { 746 | CLANG_ENABLE_MODULES = YES; 747 | CODE_SIGN_IDENTITY = ""; 748 | CURRENT_PROJECT_VERSION = 1; 749 | DEFINES_MODULE = YES; 750 | DEVELOPMENT_TEAM = VSXKPZWN4F; 751 | DYLIB_COMPATIBILITY_VERSION = 1; 752 | DYLIB_CURRENT_VERSION = 1; 753 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 754 | INFOPLIST_FILE = MappingAce/Info.plist; 755 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 756 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 757 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 758 | PRODUCT_BUNDLE_IDENTIFIER = IB.MappingAce; 759 | PRODUCT_NAME = "$(TARGET_NAME)"; 760 | SKIP_INSTALL = YES; 761 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 762 | SWIFT_VERSION = 3.0; 763 | VERSIONING_SYSTEM = "apple-generic"; 764 | VERSION_INFO_PREFIX = ""; 765 | }; 766 | name = Debug; 767 | }; 768 | D455EA5C1DC097C600656EC2 /* Release */ = { 769 | isa = XCBuildConfiguration; 770 | baseConfigurationReference = AC4432B2321BE85D7605DE2B /* Pods-MappingAce.release.xcconfig */; 771 | buildSettings = { 772 | CLANG_ENABLE_MODULES = YES; 773 | CODE_SIGN_IDENTITY = ""; 774 | CURRENT_PROJECT_VERSION = 1; 775 | DEFINES_MODULE = YES; 776 | DEVELOPMENT_TEAM = VSXKPZWN4F; 777 | DYLIB_COMPATIBILITY_VERSION = 1; 778 | DYLIB_CURRENT_VERSION = 1; 779 | DYLIB_INSTALL_NAME_BASE = "@rpath"; 780 | INFOPLIST_FILE = MappingAce/Info.plist; 781 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks"; 782 | IPHONEOS_DEPLOYMENT_TARGET = 8.0; 783 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 784 | PRODUCT_BUNDLE_IDENTIFIER = IB.MappingAce; 785 | PRODUCT_NAME = "$(TARGET_NAME)"; 786 | SKIP_INSTALL = YES; 787 | SWIFT_VERSION = 3.0; 788 | VERSIONING_SYSTEM = "apple-generic"; 789 | VERSION_INFO_PREFIX = ""; 790 | }; 791 | name = Release; 792 | }; 793 | D4A454661DBDDFB100551ADC /* Debug */ = { 794 | isa = XCBuildConfiguration; 795 | baseConfigurationReference = 5D017C043650DE84CD755E36 /* Pods-MappingTests.debug.xcconfig */; 796 | buildSettings = { 797 | BUNDLE_LOADER = "$(TEST_HOST)"; 798 | DEVELOPMENT_TEAM = VSXKPZWN4F; 799 | INFOPLIST_FILE = MappingTests/Info.plist; 800 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 801 | PRODUCT_BUNDLE_IDENTIFIER = IB.MappingTests; 802 | PRODUCT_NAME = "$(TARGET_NAME)"; 803 | SWIFT_VERSION = 3.0; 804 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mapping.app/Mapping"; 805 | }; 806 | name = Debug; 807 | }; 808 | D4A454671DBDDFB100551ADC /* Release */ = { 809 | isa = XCBuildConfiguration; 810 | baseConfigurationReference = D6E3785810537A1C9CE88235 /* Pods-MappingTests.release.xcconfig */; 811 | buildSettings = { 812 | BUNDLE_LOADER = "$(TEST_HOST)"; 813 | DEVELOPMENT_TEAM = VSXKPZWN4F; 814 | INFOPLIST_FILE = MappingTests/Info.plist; 815 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks"; 816 | PRODUCT_BUNDLE_IDENTIFIER = IB.MappingTests; 817 | PRODUCT_NAME = "$(TARGET_NAME)"; 818 | SWIFT_VERSION = 3.0; 819 | TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Mapping.app/Mapping"; 820 | }; 821 | name = Release; 822 | }; 823 | /* End XCBuildConfiguration section */ 824 | 825 | /* Begin XCConfigurationList section */ 826 | 45ABD5B01DABC12E00670593 /* Build configuration list for PBXProject "Mapping" */ = { 827 | isa = XCConfigurationList; 828 | buildConfigurations = ( 829 | 45ABD5C51DABC12F00670593 /* Debug */, 830 | 45ABD5C61DABC12F00670593 /* Release */, 831 | ); 832 | defaultConfigurationIsVisible = 0; 833 | defaultConfigurationName = Release; 834 | }; 835 | 45ABD5C71DABC12F00670593 /* Build configuration list for PBXNativeTarget "Mapping" */ = { 836 | isa = XCConfigurationList; 837 | buildConfigurations = ( 838 | 45ABD5C81DABC12F00670593 /* Debug */, 839 | 45ABD5C91DABC12F00670593 /* Release */, 840 | ); 841 | defaultConfigurationIsVisible = 0; 842 | defaultConfigurationName = Release; 843 | }; 844 | D455EA5D1DC097C600656EC2 /* Build configuration list for PBXNativeTarget "MappingAce" */ = { 845 | isa = XCConfigurationList; 846 | buildConfigurations = ( 847 | D455EA5B1DC097C600656EC2 /* Debug */, 848 | D455EA5C1DC097C600656EC2 /* Release */, 849 | ); 850 | defaultConfigurationIsVisible = 0; 851 | defaultConfigurationName = Release; 852 | }; 853 | D4A454651DBDDFB100551ADC /* Build configuration list for PBXNativeTarget "MappingTests" */ = { 854 | isa = XCConfigurationList; 855 | buildConfigurations = ( 856 | D4A454661DBDDFB100551ADC /* Debug */, 857 | D4A454671DBDDFB100551ADC /* Release */, 858 | ); 859 | defaultConfigurationIsVisible = 0; 860 | defaultConfigurationName = Release; 861 | }; 862 | /* End XCConfigurationList section */ 863 | }; 864 | rootObject = 45ABD5AD1DABC12E00670593 /* Project object */; 865 | } 866 | -------------------------------------------------------------------------------- /Mapping.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Mapping.xcodeproj/xcshareddata/xcschemes/MappingAce.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 34 | 35 | 45 | 46 | 52 | 53 | 54 | 55 | 56 | 57 | 63 | 64 | 70 | 71 | 72 | 73 | 75 | 76 | 79 | 80 | 81 | -------------------------------------------------------------------------------- /Mapping.xcodeproj/xcuserdata/Binglin.xcuserdatad/xcschemes/Mapping.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 49 | 50 | 51 | 52 | 53 | 54 | 64 | 66 | 72 | 73 | 74 | 75 | 79 | 80 | 81 | 82 | 83 | 84 | 90 | 92 | 98 | 99 | 100 | 101 | 103 | 104 | 107 | 108 | 109 | -------------------------------------------------------------------------------- /Mapping.xcodeproj/xcuserdata/Binglin.xcuserdatad/xcschemes/MappingTests.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 14 | 15 | 17 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 39 | 40 | 41 | 42 | 48 | 49 | 51 | 52 | 55 | 56 | 57 | -------------------------------------------------------------------------------- /Mapping.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Mapping/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.swift 3 | // Mapping 4 | // 5 | // Created by 郑林琴 on 16/10/10. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | 11 | @UIApplicationMain 12 | class AppDelegate: UIResponder, UIApplicationDelegate { 13 | 14 | var window: UIWindow? 15 | 16 | 17 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { 18 | // Override point for customization after application launch. 19 | return true 20 | } 21 | 22 | func applicationWillResignActive(_ application: UIApplication) { 23 | // 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. 24 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 25 | } 26 | 27 | func applicationDidEnterBackground(_ application: UIApplication) { 28 | // 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. 29 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 30 | } 31 | 32 | func applicationWillEnterForeground(_ application: UIApplication) { 33 | // Called as part of the transition from the background to the active state; here you can undo many of the changes made on entering the background. 34 | } 35 | 36 | func applicationDidBecomeActive(_ application: UIApplication) { 37 | // 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. 38 | } 39 | 40 | func applicationWillTerminate(_ application: UIApplication) { 41 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 42 | } 43 | 44 | 45 | } 46 | 47 | -------------------------------------------------------------------------------- /Mapping/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 | "idiom" : "ipad", 35 | "size" : "29x29", 36 | "scale" : "1x" 37 | }, 38 | { 39 | "idiom" : "ipad", 40 | "size" : "29x29", 41 | "scale" : "2x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "40x40", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "40x40", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "76x76", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "76x76", 61 | "scale" : "2x" 62 | } 63 | ], 64 | "info" : { 65 | "version" : 1, 66 | "author" : "xcode" 67 | } 68 | } -------------------------------------------------------------------------------- /Mapping/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 | -------------------------------------------------------------------------------- /Mapping/Base.lproj/Main.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 | -------------------------------------------------------------------------------- /Mapping/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 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /Mapping/ViewController.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.swift 3 | // Mapping 4 | // 5 | // Created by 郑林琴 on 16/10/10. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import UIKit 10 | import MappingAce 11 | 12 | class ViewController: UIViewController { 13 | 14 | struct PhoneNumber: Mapping { 15 | var tel: String 16 | var type: String 17 | } 18 | 19 | override func viewDidLoad() { 20 | super.viewDidLoad() 21 | 22 | self.testStructMapping() 23 | self.testStructMappingWithDefaultValue() 24 | } 25 | 26 | 27 | func testStructMapping(){ 28 | 29 | struct UserArrayPhoneEntity: Mapping{ 30 | var age: Int? 31 | var name: String? 32 | var phone: PhoneNumber 33 | var phones: [PhoneNumber] 34 | } 35 | 36 | 37 | let phone: [String : Any] = [ 38 | "tel": "186xxxxxxxx", 39 | "type": "work" 40 | ] 41 | 42 | let phones = Array(repeating: phone, count: 10) 43 | let dic: [String : Any] = [ 44 | "age" : 14.0, 45 | "name": "Binglin", 46 | "phone": phone, 47 | "phones": phones 48 | ] 49 | 50 | let user = UserArrayPhoneEntity(fromDic: dic) 51 | 52 | let serialized = user.toDictionary() 53 | 54 | print(serialized) 55 | 56 | } 57 | 58 | func testStructMappingWithDefaultValue(){ 59 | 60 | struct UserArrayPhoneEntity: InitMapping{ 61 | var age: Int? 62 | var name: String = "default" 63 | var phone: PhoneNumber? 64 | var phones: [PhoneNumber] = [] 65 | } 66 | 67 | struct PhoneNumber: Mapping { 68 | var tel: String 69 | var type: String 70 | } 71 | 72 | 73 | let phone: [String : Any] = [ 74 | "tel": "186xxxxxxxx", 75 | "type": "work" 76 | ] 77 | 78 | let phones = Array(repeating: phone, count: 10) 79 | let dic: [String : Any] = [ 80 | "age" : 14.0, 81 | "phone": phone, 82 | "phones": phones 83 | ] 84 | 85 | let user = UserArrayPhoneEntity(fromDic: dic) 86 | let serialized = user.toDictionary() 87 | print(serialized) 88 | 89 | } 90 | 91 | 92 | } 93 | 94 | 95 | 96 | 97 | -------------------------------------------------------------------------------- /MappingAce.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # Be sure to run `pod spec lint MappingAce.podspec' to ensure this is a 3 | # valid spec and to remove all comments including this before submitting the spec. 4 | # 5 | # To learn more about Podspec attributes see http://docs.cocoapods.org/specification.html 6 | # To see working Podspecs in the CocoaPods repo see https://github.com/CocoaPods/Specs/ 7 | # 8 | 9 | Pod::Spec.new do |s| 10 | 11 | s.name = "MappingAce" 12 | s.version = "1.0.4" 13 | s.summary = "MappingAce is Tool about JSON <-> Model" 14 | 15 | 16 | s.description = "MappingAce allows rapid creation of struct , Swift class, OC class . Automatic transform dictionary to model(model could be struct), forget to manually write property mapping code" 17 | 18 | s.homepage = "https://github.com/Binglin/MappingAce" 19 | 20 | s.license = "MIT" 21 | 22 | s.author = { "Binglin" => "269042025@qq.com" } 23 | 24 | s.platform = :ios, "8.0" 25 | 26 | # When using multiple platforms 27 | # s.ios.deployment_target = "5.0" 28 | # s.osx.deployment_target = "10.7" 29 | # s.watchos.deployment_target = "2.0" 30 | # s.tvos.deployment_target = "9.0" 31 | 32 | s.source = { :git => "https://github.com/Binglin/MappingAce.git", :tag => "#{s.version}" } 33 | s.source_files = "MappingAce/*.swift" 34 | 35 | 36 | #s.requires_arc = true 37 | 38 | end 39 | -------------------------------------------------------------------------------- /MappingAce/ArrayMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArrayMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Array: ValueMapping{ 13 | 14 | public static func mappingWith(any: Any?) -> Any?{ 15 | 16 | if let elementType = Element.self as? ValueMapping.Type , let value = any as? [Any]{ 17 | 18 | var result = [Element]() 19 | for i in 0.. Any? { 44 | 45 | let resultAny: [Any] = self 46 | 47 | if let values = resultAny as? [ValueMapping]{ 48 | 49 | var result = [Any]() 50 | for i in 0.. 0{ 56 | return result 57 | } 58 | } 59 | return resultAny 60 | } 61 | } 62 | 63 | extension Array: Initializable{ 64 | 65 | public static func initialize(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?){ 66 | 67 | let p = pointer.advanced(by: offset) 68 | 69 | if let value = self.mappingWith(any: value) as? [Element]{ 70 | let bind = p.bindMemory(to: [Element].self, capacity: 1) 71 | bind.initialize(to: value) 72 | } 73 | else{ 74 | let bind = p.bindMemory(to: [Element].self, capacity: 1) 75 | bind.initialize(to: []) 76 | } 77 | } 78 | } 79 | 80 | extension Array: Updatable{} 81 | 82 | 83 | extension Array where Element: ValueMapping{ 84 | 85 | public init(JSON: String) throws{ 86 | let jsonData = JSON.data(using: String.Encoding.utf8) 87 | guard let data = jsonData else { 88 | throw MappingError.nilData 89 | } 90 | let jsonObj = try JSONSerialization.jsonObject(with: data, options: .allowFragments) 91 | 92 | guard let jsonObjArr = jsonObj as? [[String: Any]] else{ 93 | throw MappingError.jsonInvalidate; 94 | } 95 | 96 | self = jsonObjArr.map{ Element.mappingWith(any: $0) as! Element } 97 | } 98 | 99 | public init(jsonObjArray: [[String : Any]]){ 100 | self = jsonObjArray.map{ Element.mappingWith(any: $0) as! Element } 101 | } 102 | } 103 | 104 | -------------------------------------------------------------------------------- /MappingAce/EnumIntMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnumIntMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | 13 | public protocol EnumInt: ValueMapping, Initializable, Updatable { 14 | init?(rawValue: Int) 15 | var rawValue: Int { get } 16 | } 17 | 18 | 19 | 20 | extension EnumInt { 21 | 22 | public static func mappingWith(any: Any?) -> Any? { 23 | if let int = any as? Int{ 24 | return Self.init(rawValue: int) 25 | } 26 | if let intStr = any as? String{ 27 | let int = Int(intStr) 28 | return Self.init(rawValue: int!) 29 | } 30 | return nil 31 | } 32 | 33 | public func serializedValue() -> Any? { 34 | return self.rawValue 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /MappingAce/EnumStringMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // EnumStringMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | 13 | public protocol EnumString: ValueMapping, Initializable, Updatable { 14 | init?(rawValue: String) 15 | var rawValue: String { get } 16 | } 17 | 18 | extension EnumString{ 19 | public static func mappingWith(any: Any?) -> Any? { 20 | if let any = any{ 21 | let str = String(describing: any) 22 | return Self.init(rawValue: str) 23 | } 24 | return nil 25 | } 26 | public func serializedValue() -> Any? { 27 | return self.rawValue 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /MappingAce/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 | CFBundleVersion 20 | $(CURRENT_PROJECT_VERSION) 21 | NSPrincipalClass 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /MappingAce/InitMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // InitMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | public protocol InitMapping: ValueMapping, Updatable, Serializable { 13 | // should be implement 14 | init() 15 | // default implemented 16 | init(fromDic: [String : Any]) 17 | } 18 | 19 | public extension InitMapping{ 20 | public init(fromDic d: [String : Any]){ 21 | var item = Self.init() 22 | item.mapFrom(dic: d) 23 | self = item 24 | } 25 | } 26 | 27 | extension InitMapping{ 28 | 29 | public static func mappingWith(any: Any?) -> Any?{ 30 | guard let v = any as? [String : Any] else{ 31 | return nil 32 | } 33 | return Self.init(fromDic: v) 34 | } 35 | 36 | public func serializedValue() -> Any?{ 37 | return self.toDictionary() 38 | } 39 | 40 | fileprivate mutating func mapFrom(dic: [String : Any]){ 41 | 42 | let structInfo = MetadataInfoFor(type: Self.self) 43 | 44 | if structInfo.kind == .class { 45 | 46 | let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque() 47 | self.updateValue(rawPointer: opaquePointer, withDic: dic, structInfo: structInfo) 48 | } 49 | //structInfo.kind == .struct 50 | else{ 51 | 52 | let selfPointer = withUnsafePointer(to: &self, {$0}) 53 | let p = UnsafeMutableRawPointer(mutating: selfPointer) 54 | self.updateValue(rawPointer: p, withDic: dic, structInfo: structInfo) 55 | } 56 | } 57 | 58 | private func updateValue(rawPointer p: UnsafeMutableRawPointer, withDic dic: [String : Any], structInfo: ObjectMetadata){ 59 | 60 | for i in 0.. Any? { 16 | if let exactValue = any as? NSNumber{ 17 | return exactValue.boolValue 18 | } 19 | if let str = any as? String{ 20 | 21 | let lowerCase = str.lowercased() 22 | 23 | switch lowerCase { 24 | case "true": return true 25 | case "false": return false 26 | case "0" : return false 27 | case "1" : return true 28 | default: break 29 | } 30 | 31 | return self.init(lowerCase) 32 | } 33 | return nil 34 | } 35 | } 36 | 37 | extension Int8: NumericalMapping { 38 | 39 | public static func mappingWith(any: Any?) -> Any? { 40 | if let exactValue = any as? NSNumber{ 41 | return exactValue.int8Value 42 | } 43 | if let intStr = any as? String{ 44 | return self.init(intStr) 45 | } 46 | return nil 47 | } 48 | } 49 | 50 | extension Int: NumericalMapping { 51 | 52 | public static func mappingWith(any: Any?) -> Any? { 53 | if let exactValue = any as? NSNumber{ 54 | return exactValue.intValue 55 | } 56 | if let intStr = any as? String{ 57 | return self.init(intStr) 58 | } 59 | return nil 60 | } 61 | } 62 | 63 | extension UInt8: NumericalMapping { 64 | public static func mappingWith(any: Any?) -> Any? { 65 | if let exactValue = any as? NSNumber{ 66 | return exactValue.uint8Value 67 | } 68 | if let intStr = any as? String{ 69 | return self.init(intStr) 70 | } 71 | return nil 72 | } 73 | } 74 | 75 | extension Int16: NumericalMapping { 76 | public static func mappingWith(any: Any?) -> Any? { 77 | if let exactValue = any as? NSNumber{ 78 | return exactValue.int16Value 79 | } 80 | if let intStr = any as? String{ 81 | return self.init(intStr) 82 | } 83 | return nil 84 | } 85 | } 86 | 87 | extension UInt16: NumericalMapping { 88 | public static func mappingWith(any: Any?) -> Any? { 89 | if let exactValue = any as? NSNumber{ 90 | return exactValue.uint16Value 91 | } 92 | if let intStr = any as? String{ 93 | return self.init(intStr) 94 | } 95 | return nil 96 | } 97 | } 98 | 99 | extension Int32: NumericalMapping { 100 | public static func mappingWith(any: Any?) -> Any? { 101 | if let exactValue = any as? NSNumber{ 102 | return exactValue.int32Value 103 | } 104 | if let intStr = any as? String{ 105 | return self.init(intStr) 106 | } 107 | return nil 108 | } 109 | } 110 | 111 | extension UInt32: NumericalMapping { 112 | public static func mappingWith(any: Any?) -> Any? { 113 | if let exactValue = any as? NSNumber{ 114 | return exactValue.uint32Value 115 | } 116 | if let intStr = any as? String{ 117 | return self.init(intStr) 118 | } 119 | return nil 120 | } 121 | } 122 | 123 | extension Int64: NumericalMapping { 124 | public static func mappingWith(any: Any?) -> Any? { 125 | if let exactValue = any as? NSNumber{ 126 | return exactValue.int64Value 127 | } 128 | if let intStr = any as? String{ 129 | return self.init(intStr) 130 | } 131 | return nil 132 | } 133 | } 134 | 135 | extension UInt64: NumericalMapping { 136 | public static func mappingWith(any: Any?) -> Any? { 137 | if let exactValue = any as? NSNumber{ 138 | return exactValue.uint64Value 139 | } 140 | if let intStr = any as? String{ 141 | return self.init(intStr) 142 | } 143 | return nil 144 | } 145 | } 146 | 147 | extension Float: NumericalMapping{ 148 | public static func mappingWith(any: Any?) -> Any? { 149 | if let exactValue = any as? NSNumber{ 150 | return exactValue.floatValue 151 | } 152 | if let intStr = any as? String{ 153 | return self.init(intStr) 154 | } 155 | return nil 156 | } 157 | } 158 | 159 | extension Double: NumericalMapping{ 160 | 161 | public static func mappingWith(any: Any?) -> Any? { 162 | if let exactValue = any as? NSNumber{ 163 | return exactValue.doubleValue 164 | } 165 | if let intStr = any as? String{ 166 | return self.init(intStr) 167 | } 168 | return nil 169 | } 170 | } 171 | -------------------------------------------------------------------------------- /MappingAce/KeyMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // KeyMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | public protocol KeyMapping { 13 | static func mappedKeyFor(key: String) -> String? 14 | } 15 | 16 | 17 | 18 | /// 从字段里获取对应key的值 19 | /// 20 | /// - parameter propertyName: property name write in entity 21 | /// - parameter d: dic to get property value from 22 | /// - parameter type: 23 | /// 24 | /// - returns: 25 | func valueFor(propertyName: String, fromDic d: [String : Any], type: Any.Type) -> Any?{ 26 | 27 | if let value = valueFor(keyPath: propertyName, fromDic: d){ 28 | return value 29 | } 30 | 31 | /// 如果没有key映射 或者无对应key映射的值 32 | guard let t = type as? KeyMapping.Type , let mappedKey = t.mappedKeyFor(key: propertyName) else{ 33 | return nil 34 | } 35 | 36 | /// 有key映射值 37 | return valueFor(keyPath: mappedKey, fromDic: d) 38 | } 39 | 40 | func valueFor(keyPath: String, fromDic d: [String : Any]) -> Any? { 41 | 42 | /// key 43 | let value = d[keyPath] 44 | if let value = value{ 45 | return value 46 | } 47 | 48 | /// keyPath 49 | let seperatedStr = keyPath.components(separatedBy: ".") 50 | 51 | if seperatedStr.count > 1 { 52 | 53 | var returnValue: Any? = d 54 | 55 | for key in seperatedStr{ 56 | returnValue = (returnValue as? [String : Any])?[key] 57 | } 58 | return returnValue 59 | } 60 | return nil 61 | } 62 | -------------------------------------------------------------------------------- /MappingAce/Mapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Mapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/20. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | /// Mark: - Mapping 13 | public protocol Mapping: ValueMapping, Initializable, Updatable, Serializable{ 14 | init(fromDic: [String : Any]) 15 | } 16 | 17 | public extension Mapping{ 18 | 19 | init(data: Data , options: JSONSerialization.ReadingOptions = .allowFragments) throws{ 20 | let jsonDic = try JSONSerialization.jsonObject(with: data, options: options) 21 | let dic = jsonDic as! [String : Any] 22 | self = Self.init(fromDic: dic) 23 | } 24 | } 25 | 26 | public extension Mapping{ 27 | 28 | init(fromDic dic: [String : Any]){ 29 | self = MappingAny(type: Self.self, fromDic: dic) 30 | } 31 | 32 | } 33 | 34 | extension Mapping{ 35 | public static func initialize(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?){ 36 | let mapped = self.mappingWith(any: value) 37 | pointer.storeBytes(of: mapped as! Self, toByteOffset: offset, as: Self.self) 38 | } 39 | 40 | public func serializedValue() -> Any?{ 41 | return self.toDictionary() 42 | } 43 | 44 | } 45 | 46 | 47 | extension Mapping{ 48 | 49 | public static func mappingWith(any: Any?) -> Any?{ 50 | guard let input = any as? [String : Any] else { return nil } 51 | return self.init(fromDic: input) 52 | } 53 | } 54 | 55 | 56 | /// Mark: - MappingAny 57 | 58 | 59 | public func MappingAny(type: T.Type = T.self, fromDic dic: [String : Any]) -> T{ 60 | 61 | let phone = UnsafeMutablePointer.allocate(capacity: 1) 62 | defer { 63 | phone.deallocate(capacity: 1) 64 | } 65 | let rawPhone = UnsafeMutableRawPointer(phone) 66 | 67 | let structInfo = MetadataInfoFor(type: T.self) 68 | 69 | if structInfo.kind != .struct{ 70 | fatalError("class should be implement InitMapping") 71 | } 72 | 73 | for i in 0.. 10 | 11 | //! Project version number for MappingAce. 12 | FOUNDATION_EXPORT double MappingAceVersionNumber; 13 | 14 | //! Project version string for MappingAce. 15 | FOUNDATION_EXPORT const unsigned char MappingAceVersionString[]; 16 | 17 | // In this header, you should import all the public headers of your framework using statements like #import 18 | 19 | 20 | -------------------------------------------------------------------------------- /MappingAce/MappingError.swift: -------------------------------------------------------------------------------- 1 | // 2 | // MappingError.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 2016/11/30. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | enum MappingError : Error{ 13 | case nilData 14 | case jsonInvalidate 15 | } 16 | -------------------------------------------------------------------------------- /MappingAce/Metadata.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Metadata.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/19. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | struct Metadata { 13 | var pointer: UnsafePointer 14 | } 15 | 16 | struct Struct { 17 | var kind: Int 18 | var nominalTypeDescriptorOffset: Int 19 | var parent: Metadata? 20 | } 21 | 22 | 23 | 24 | typealias FieldsTypeAccessor = @convention(c) (UnsafePointer) -> UnsafePointer> 25 | 26 | 27 | struct NominalTypeDescriptor{ 28 | 29 | var name: Int32 30 | var numberOfFields: Int32 31 | var FieldOffsetVectorOffset: Int32 32 | var fieldNames: Int32 33 | var getFieldTypes: Int32 34 | } 35 | 36 | extension NominalTypeDescriptor{ 37 | 38 | struct Class { 39 | var isa: UnsafePointer 40 | var super_: UnsafePointer 41 | var reserve1: Int 42 | var reserve2: Int 43 | 44 | var Data: Int 45 | var classFlags: Int32 46 | 47 | var instanceAdressPointer: Int32 48 | var instanceSize: Int32 49 | 50 | var instanceAlignMask: Int16 51 | var runtime_reserved: Int16 52 | 53 | var classobjectsize: Int32 54 | var classObjectAdressPointer: Int32 55 | 56 | // **offset 8** on a 64-bit platform or **offset 11** on a 32-bit platform. 57 | var Description : Int 58 | 59 | static var nominalTypeOffset: Int{ 60 | return (MemoryLayout.size == MemoryLayout.size) ? 8 : 11 61 | } 62 | } 63 | } 64 | 65 | extension NominalTypeDescriptor{ 66 | 67 | struct Struct { 68 | var name: Int32 69 | var numberOfFields: Int32 70 | var FieldOffsetVectorOffset: Int32 71 | var fieldNames: Int32 72 | var getFieldTypes: Int32 73 | static var nominalTypeOffset: Int{ 74 | return 1 75 | } 76 | } 77 | } 78 | 79 | extension NominalTypeDescriptor{ 80 | 81 | struct Enum { 82 | var name: Int32 83 | var NumPayloadCasesAndPayloadSizeOffset: Int32 84 | var NumEmptyCases: Int32 85 | var caseNames: Int32 86 | var getCaseTypes: Int32 87 | } 88 | } 89 | 90 | 91 | -------------------------------------------------------------------------------- /MappingAce/ObjectMetadata.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ObjectMetadata.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/19. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | enum MetadataKind { 13 | case `struct` 14 | case `class` 15 | case ObjCClassWrapper 16 | } 17 | 18 | struct ObjectMetadata { 19 | public var kind: MetadataKind 20 | public var propertyNames: [String] 21 | public var propertyTypes: [Any.Type] 22 | public var propertyOffsets: [Int] 23 | } 24 | 25 | 26 | func MetadataInfoFor(type: Any.Type) -> ObjectMetadata{ 27 | 28 | let typePointer = unsafeBitCast(type, to: UnsafePointer.self) 29 | let typeStruct = typePointer.pointee 30 | let kind = typeStruct.kind 31 | 32 | struct TypeInfoHashTable{ 33 | static var table: [UnsafePointer : ObjectMetadata] = [:] 34 | } 35 | 36 | if let structInfo = TypeInfoHashTable.table[typePointer]{ 37 | return structInfo 38 | } 39 | 40 | if kind == 1{ 41 | let info = nominalTypeOfStruct(typePointer: typePointer) 42 | TypeInfoHashTable.table[typePointer] = info 43 | return info 44 | } 45 | else if kind == 2{ 46 | fatalError("not implement for enum") 47 | }else if kind == 14{ 48 | return ObjectMetadata(kind: .ObjCClassWrapper, propertyNames: [], propertyTypes: [], propertyOffsets: []) 49 | } 50 | else if kind > 4096{ 51 | let info = nominalTypeOfClass(typePointer: typePointer) 52 | TypeInfoHashTable.table[typePointer] = info 53 | return info 54 | } 55 | fatalError("not implement type") 56 | } 57 | 58 | private func nominalTypeOfStruct(typePointer: UnsafePointer) -> ObjectMetadata{ 59 | 60 | let intPointer = typePointer.withMemoryRebound(to: Int.self, capacity: 1, { $0 }) 61 | 62 | let nominalTypeBase = intPointer.advanced(by: 1) 63 | 64 | let int8Type = nominalTypeBase.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }) 65 | 66 | let nominalTypePointer = int8Type.advanced(by: typePointer.pointee.nominalTypeDescriptorOffset) 67 | 68 | let nominalType = nominalTypePointer.withMemoryRebound(to: NominalTypeDescriptor.self, capacity: 1, { $0 }) 69 | let numberOfField = Int(nominalType.pointee.numberOfFields) 70 | 71 | let int32NominalType = nominalType.withMemoryRebound(to: Int32.self, capacity: 1, { $0 }) 72 | let fieldBase = int32NominalType.advanced(by: Int(nominalType.pointee.FieldOffsetVectorOffset)) 73 | 74 | let int8FieldBasePointer = fieldBase.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }) 75 | let fieldNamePointer = int8FieldBasePointer.advanced(by: Int(nominalType.pointee.fieldNames)) 76 | 77 | let fieldNames = getFieldNames(pointer: fieldNamePointer, fieldCount: numberOfField) 78 | 79 | let int32NominalFunc = nominalType.withMemoryRebound(to: Int32.self, capacity: 1, { $0 }).advanced(by: 4) 80 | 81 | let nominalFunc = int32NominalFunc.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }).advanced(by: Int(nominalType.pointee.getFieldTypes)) 82 | 83 | 84 | let fieldType = getType(pointer: nominalFunc, fieldCount: numberOfField) 85 | 86 | let offsetPointer = intPointer.advanced(by: Int(nominalType.pointee.FieldOffsetVectorOffset)) 87 | var offsetArr: [Int] = [] 88 | 89 | for i in 0.., fieldCount numberOfField: Int) -> [Any.Type]{ 101 | 102 | let funcPointer = unsafeBitCast(nominalFunc, to: FieldsTypeAccessor.self) 103 | let funcBase = funcPointer(nominalFunc.withMemoryRebound(to: Int.self, capacity: 1, { $0 })) 104 | 105 | 106 | var types: [Any.Type] = [] 107 | for i in 0.., fieldCount numberOfField: Int) -> [String]{ 118 | 119 | return Array(utf8Strings: pointer) 120 | } 121 | 122 | 123 | 124 | private func nominalTypeOfClass(typePointer t: UnsafePointer) -> ObjectMetadata{ 125 | 126 | let typePointer = t.withMemoryRebound(to: NominalTypeDescriptor.Class.self, capacity: 1, { $0 }) 127 | return nominalTypeOf(pointer: typePointer) 128 | 129 | } 130 | 131 | private func nominalTypeOf(pointer typePointer: UnsafePointer) -> ObjectMetadata{ 132 | 133 | let intPointer = typePointer.withMemoryRebound(to: Int.self, capacity: 1, { $0 }) 134 | 135 | let typePointee = typePointer.pointee 136 | let superPointee = typePointee.super_ 137 | 138 | var superObject: ObjectMetadata 139 | 140 | if Int(bitPattern: typePointer.pointee.isa) == 14 || Int(bitPattern: superPointee) == 0{ 141 | superObject = ObjectMetadata(kind: .ObjCClassWrapper, propertyNames: [], propertyTypes: [], propertyOffsets: []) 142 | return superObject 143 | }else{ 144 | superObject = nominalTypeOf(pointer: superPointee) 145 | superObject.kind = .class 146 | } 147 | 148 | let nominalTypeOffset = (MemoryLayout.size == MemoryLayout.size) ? 8 : 11 149 | let nominalTypeInt = intPointer.advanced(by: nominalTypeOffset) 150 | 151 | 152 | let nominalTypeint8 = nominalTypeInt.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }) 153 | let des = nominalTypeint8.advanced(by: typePointee.Description) 154 | 155 | let nominalType = des.withMemoryRebound(to: NominalTypeDescriptor.self, capacity: 1, { $0 }) 156 | 157 | let numberOfField = Int(nominalType.pointee.numberOfFields) 158 | 159 | let int32NominalType = nominalType.withMemoryRebound(to: Int32.self, capacity: 1, { $0 }) 160 | let fieldBase = int32NominalType.advanced(by: 3)//.advanced(by: Int(nominalType.pointee.FieldOffsetVectorOffset)) 161 | 162 | let int8FieldBasePointer = fieldBase.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }) 163 | let fieldNamePointer = int8FieldBasePointer.advanced(by: Int(nominalType.pointee.fieldNames)) 164 | 165 | let fieldNames = getFieldNames(pointer: fieldNamePointer, fieldCount: numberOfField) 166 | superObject.propertyNames.append(contentsOf: fieldNames) 167 | 168 | let int32NominalFunc = nominalType.withMemoryRebound(to: Int32.self, capacity: 1, { $0 }).advanced(by: 4) 169 | 170 | let nominalFunc = int32NominalFunc.withMemoryRebound(to: Int8.self, capacity: 1, { $0 }).advanced(by: Int(nominalType.pointee.getFieldTypes)) 171 | 172 | let fieldType = getType(pointer: nominalFunc, fieldCount: numberOfField) 173 | superObject.propertyTypes.append(contentsOf: fieldType) 174 | 175 | let offsetPointer = intPointer.advanced(by: Int(nominalType.pointee.FieldOffsetVectorOffset)) 176 | var offsetArr: [Int] = [] 177 | 178 | for i in 0..) 190 | } 191 | 192 | extension String : UTF8Initializable {} 193 | 194 | extension Array where Element : UTF8Initializable { 195 | 196 | init(utf8Strings: UnsafePointer) { 197 | var strings = [Element]() 198 | var p = utf8Strings 199 | while let string = Element(validatingUTF8: p) { 200 | strings.append(string) 201 | while p.pointee != 0 { 202 | p = p.advanced(by: 1) 203 | } 204 | p = p.advanced(by: 1) 205 | guard p.pointee != 0 else { break } 206 | } 207 | self = strings 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /MappingAce/OptionalMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // OptionalMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | extension Optional: ValueMapping{ 13 | 14 | public static func mappingWith(any: Any?) -> Any? { 15 | 16 | if let value = any{ 17 | 18 | if let type = Wrapped.self as? ValueMapping.Type{ 19 | return type.mappingWith(any: value) 20 | } 21 | } 22 | return nil 23 | } 24 | 25 | public func serializedValue() -> Any? { 26 | 27 | guard let r = self else{ 28 | return nil 29 | } 30 | 31 | if let mapping = r as? ValueMapping{ 32 | return mapping.serializedValue() 33 | } 34 | 35 | return r 36 | } 37 | } 38 | 39 | extension Optional: Initializable{ 40 | 41 | public static func initialize(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?){ 42 | 43 | let p = pointer.advanced(by: offset) 44 | let mapped = self.mappingWith(any: value) 45 | 46 | let bind = p.bindMemory(to: Optional.self, capacity: 1) 47 | bind.initialize(to: mapped as? Wrapped) 48 | } 49 | } 50 | 51 | extension Optional: Updatable{ 52 | 53 | public static func update(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?){ 54 | let p = pointer.advanced(by: offset) 55 | let mapped = self.mappingWith(any: value) 56 | 57 | let bind = p.bindMemory(to: Optional.self, capacity: 1) 58 | bind.pointee = mapped as? Wrapped 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /MappingAce/PropertyMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PropertyMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | // MARK: TODO 12 | -------------------------------------------------------------------------------- /MappingAce/Serializable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Serializable.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/25. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | public protocol Serializable{ 12 | func toDictionary() -> [String : Any] 13 | func toNullableValueDictionary() -> [String : Any?] 14 | } 15 | 16 | public extension Serializable{ 17 | 18 | func toDictionary() -> [String : Any]{ 19 | 20 | let structInfo = MetadataInfoFor(type: Self.self) 21 | 22 | var rawPointer: UnsafeRawPointer 23 | 24 | if structInfo.kind == .struct{ 25 | var toSerialize = self 26 | let selfPointer = withUnsafePointer(to: &toSerialize, {$0}) 27 | rawPointer = UnsafeRawPointer(selfPointer) 28 | }else{ 29 | let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque() 30 | rawPointer = UnsafeRawPointer(opaquePointer) 31 | } 32 | 33 | 34 | var result = [String : Any]() 35 | 36 | for i in 0.. [String : Any?]{ 56 | 57 | let structInfo = MetadataInfoFor(type: Self.self) 58 | 59 | var rawPointer: UnsafeRawPointer 60 | 61 | if structInfo.kind == .struct{ 62 | var toSerialize = self 63 | let selfPointer = withUnsafePointer(to: &toSerialize, {$0}) 64 | rawPointer = UnsafeRawPointer(selfPointer) 65 | }else{ 66 | let opaquePointer = Unmanaged.passUnretained(self as AnyObject).toOpaque() 67 | rawPointer = UnsafeRawPointer(opaquePointer) 68 | } 69 | 70 | var result = [String : Any?]() 71 | 72 | for i in 0.. Any? { 14 | if let any = any{ 15 | if any is NSNull { 16 | return nil 17 | } 18 | return String(describing: any) 19 | } 20 | return nil 21 | } 22 | } 23 | 24 | extension String: Initializable{} 25 | extension String: Updatable{} 26 | -------------------------------------------------------------------------------- /MappingAce/Updatable.swift: -------------------------------------------------------------------------------- 1 | // 2 | // Updatable.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/25. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | public protocol Updatable { 13 | static func update(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?) 14 | } 15 | 16 | public extension Updatable where Self: ValueMapping{ 17 | 18 | public static func update(pointer: UnsafeMutableRawPointer, offset: Int, value: Any?){ 19 | let mapped = self.mappingWith(any: value) 20 | let p = pointer.advanced(by: offset) 21 | let bind = p.bindMemory(to: Self.self, capacity: 1) 22 | 23 | bind.pointee = mapped as! Self 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /MappingAce/ValueMapping.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ValueMapping.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import Foundation 10 | 11 | 12 | 13 | public protocol ValueMapping{ 14 | 15 | /** 16 | do some type mapping such as When int implement this protocol 17 | this could do some work to deal some special type data 18 | 19 | eg: Int: ValueMapping{} 20 | 21 | public static func mappingWith(any: Any?) -> Any? { 22 | if let exactValue = any as? NSNumber{ 23 | return exactValue as! Self 24 | } 25 | if let intStr = any as? String{ 26 | return self.init(intStr) 27 | } 28 | return nil 29 | } 30 | */ 31 | static func mappingWith(any: Any?) -> Any? 32 | 33 | 34 | /// fetch value from pointer as Self 35 | /// 36 | /// - Parameter p: pointer 37 | /// - Returns: value of Self.type 38 | static func fetchValue(fromPointer p: UnsafeRawPointer) -> Any? 39 | 40 | /// override point if needed 41 | /// value when convert to json object 42 | /// 43 | /// - Returns: json 44 | func serializedValue() -> Any? 45 | } 46 | 47 | public extension ValueMapping{ 48 | 49 | 50 | /// fetch value from pointer 51 | /// 52 | /// - Parameter p: pointer 53 | /// - Returns: value from serializedValue of Self.Type 54 | public static func fetchValue(fromPointer p: UnsafeRawPointer) -> Any?{ 55 | let result = p.load(as: Self.self) 56 | return result.serializedValue() 57 | } 58 | 59 | 60 | /// value when convert to json object 61 | /// 62 | /// - Returns: json 63 | public func serializedValue() -> Any?{ 64 | return self 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /MappingTests/ArrayMappingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // ArrayMappingTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 2016/11/30. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | 11 | @testable import MappingAce 12 | 13 | class ArrayMappingTests: XCTestCase { 14 | 15 | override func setUp() { 16 | super.setUp() 17 | // Put setup code here. This method is called before the invocation of each test method in the class. 18 | } 19 | 20 | override func tearDown() { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | super.tearDown() 23 | } 24 | 25 | func testExample() { 26 | // This is an example of a functional test case. 27 | // Use XCTAssert and related functions to verify your tests produce the correct results. 28 | let phonesInfo: [[String : Any]] = [["tel" : "xxx1", "type": "work11"], 29 | ["tel" : "xxx2", "type": "work22"], 30 | ["tel" : "xxx3", "type": "work33"]] 31 | 32 | let result = [PhoneNumber](jsonObjArray: phonesInfo) 33 | 34 | let first = result[0] 35 | let second = result[1] 36 | let third = result[2] 37 | 38 | XCTAssertEqual(first.tel, "xxx1") 39 | XCTAssertEqual(first.type, "work11") 40 | 41 | XCTAssertEqual(second.tel, "xxx2") 42 | XCTAssertEqual(second.type, "work22") 43 | 44 | XCTAssertEqual(third.tel, "xxx3") 45 | XCTAssertEqual(third.type, "work33") 46 | } 47 | 48 | func testPerformanceExample() { 49 | // This is an example of a performance test case. 50 | self.measure { 51 | // Put the code you want to measure the time of here. 52 | } 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /MappingTests/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 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /MappingTests/JSONSerializationTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // JSONSerializationTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/25. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import MappingAce 11 | 12 | class JSONSerializationTests: XCTestCase { 13 | 14 | override func setUp() { 15 | super.setUp() 16 | // Put setup code here. This method is called before the invocation of each test method in the class. 17 | } 18 | 19 | override func tearDown() { 20 | // Put teardown code here. This method is called after the invocation of each test method in the class. 21 | super.tearDown() 22 | } 23 | 24 | func testExample() { 25 | // This is an example of a functional test case. 26 | // Use XCTAssert and related functions to verify your tests produce the correct results. 27 | 28 | 29 | struct Company: Mapping { 30 | let name:String 31 | let id:Int 32 | } 33 | 34 | let companyInfo: [String : Any] = ["name" : "MappingAce", "id" : 1] 35 | 36 | let company = Company(fromDic: companyInfo) 37 | print(company.name) 38 | print(company.id) 39 | 40 | XCTAssertEqual(company.id, 1) 41 | XCTAssertEqual(company.name, "MappingAce") 42 | 43 | } 44 | 45 | func testPerformanceExample() { 46 | // This is an example of a performance test case. 47 | self.measure { 48 | // Put the code you want to measure the time of here. 49 | } 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /MappingTests/NumericalConvertTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // NumericalConvertTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/25. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Mapping 11 | @testable import MappingAce 12 | 13 | 14 | class NumericalConvertTests: XCTestCase { 15 | 16 | override func setUp() { 17 | super.setUp() 18 | // Put setup code here. This method is called before the invocation of each test method in the class. 19 | } 20 | 21 | override func tearDown() { 22 | // Put teardown code here. This method is called after the invocation of each test method in the class. 23 | super.tearDown() 24 | } 25 | 26 | func testIntExample() { 27 | 28 | let intDic: [String : Any] = ["int" : 1] 29 | if let int = intDic["int"] as? NSNumber{ 30 | let asint = int.intValue 31 | XCTAssertEqual(asint, 1) 32 | }else{ 33 | XCTFail("此路不通") 34 | } 35 | } 36 | 37 | func testFloatExample() { 38 | 39 | let floatDic: [String : Any] = ["float" : 1] 40 | if let float = floatDic["float"] as? NSNumber{ 41 | let asfloat = float.floatValue 42 | XCTAssertEqual(asfloat, 1) 43 | }else{ 44 | XCTFail("此路不通") 45 | } 46 | } 47 | 48 | func testTimeIntervalExample() { 49 | 50 | let timeintervalDic: [String : Any] = ["timeinterval" : 1] 51 | if let timeinterval = timeintervalDic["timeinterval"] as? NSNumber{ 52 | let astimeinterval = timeinterval.doubleValue 53 | XCTAssertTrue(astimeinterval == 1) 54 | }else{ 55 | XCTFail("此路不通") 56 | } 57 | } 58 | 59 | 60 | func testBoolExample() { 61 | 62 | let boolStringTrue = Bool.mappingWith(any: "true") as! Bool 63 | XCTAssertEqual(boolStringTrue, true) 64 | 65 | let boolStringFalse = Bool.mappingWith(any: "false") as! Bool 66 | XCTAssertEqual(boolStringFalse, false) 67 | 68 | let boolStringUpcaseTrue = Bool.mappingWith(any: "True") as! Bool 69 | XCTAssertEqual(boolStringUpcaseTrue, true) 70 | 71 | 72 | let boolBoolTrue = Bool.mappingWith(any: true) as! Bool 73 | XCTAssertEqual(boolBoolTrue, true) 74 | 75 | let boolBoolFalse = Bool.mappingWith(any: false) as! Bool 76 | XCTAssertEqual(boolBoolFalse, false) 77 | 78 | let boolInt0 = Bool.mappingWith(any: 0) as! Bool 79 | XCTAssertEqual(boolInt0, false) 80 | 81 | let boolInt1 = Bool.mappingWith(any: 1) as! Bool 82 | XCTAssertEqual(boolInt1, true) 83 | 84 | let boolInt10 = Bool.mappingWith(any: 10) as! Bool 85 | XCTAssertEqual(boolInt10, true) 86 | 87 | let v = Optional.none.serializedValue() 88 | XCTAssertNil(v) 89 | 90 | 91 | let boolDic: [String : Any] = ["bool" : 0] 92 | if let bool = boolDic["bool"] as? NSNumber{ 93 | let asBool = bool.boolValue 94 | XCTAssertEqual(asBool, false) 95 | 96 | }else{ 97 | XCTFail("此路不通") 98 | } 99 | } 100 | 101 | func testSwiftBoolFunc(){ 102 | 103 | let boolfalseString = Bool.init("false") 104 | let booltrueString = Bool.init("true") 105 | 106 | let boolInt0 = Bool.init("0") 107 | let boolInt1 = Bool.init("1") 108 | 109 | XCTAssertEqual(booltrueString, true) 110 | XCTAssertEqual(boolfalseString, false) 111 | XCTAssertEqual(boolInt0, nil) 112 | XCTAssertEqual(boolInt1, nil) 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /MappingTests/PerformanceTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // PerformanceTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 2017/2/17. 6 | // Copyright © 2017年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import MappingAce 11 | @testable import Unbox 12 | @testable import ObjectMapper 13 | @testable import SwiftyJSON 14 | 15 | 16 | struct PhoneNumberInPerformance: Mapping, Mappable { 17 | var tel: String? 18 | var type: String? 19 | 20 | init?(map: Map) { 21 | self.tel <- map["tel"] 22 | self.type <- map["type"] 23 | } 24 | 25 | mutating func mapping(map: Map) { 26 | 27 | } 28 | 29 | init(tel: String?, type: String?) { 30 | self.tel = tel 31 | self.type = type 32 | } 33 | } 34 | 35 | extension PhoneNumberInPerformance: Unboxable { 36 | init(unboxer: Unboxer) throws { 37 | self.tel = unboxer.unbox(key: "tel") 38 | self.type = unboxer.unbox(key: "type") 39 | } 40 | } 41 | 42 | struct UserInPerformance: Mapping, Mappable, Unboxable{ 43 | var age: Int? 44 | var name: String? 45 | var phone: PhoneNumberInPerformance? 46 | 47 | 48 | 49 | init(age: Int?, name: String?, phone: PhoneNumberInPerformance?) { 50 | self.age = age 51 | self.name = name 52 | self.phone = phone 53 | } 54 | 55 | // MARK: - Mappable 56 | init?(map: Map) { 57 | self.age <- map["age"] 58 | self.name <- map["name"] 59 | self.phone <- map["phone"] 60 | } 61 | 62 | mutating func mapping(map: Map) { 63 | 64 | } 65 | 66 | // unbox 67 | init(unboxer: Unboxer) throws { 68 | self.age = unboxer.unbox(key: "age") 69 | self.name = unboxer.unbox(key: "name") 70 | self.phone = unboxer.unbox(key: "phone") 71 | } 72 | 73 | } 74 | 75 | 76 | class PerformanceTests: XCTestCase { 77 | 78 | 79 | let dic: [String : Any] = [ 80 | "age" : "24", 81 | "name": "Binglin", 82 | "phone": [ 83 | "tel": "186xxxxxxxx", 84 | "type": "work" 85 | ] 86 | ] 87 | 88 | 89 | func testMappingAcePerformanceExample() { 90 | 91 | self.measure { 92 | for _ in 0..<10000{ 93 | _ = UserInPerformance(fromDic: self.dic) 94 | } 95 | } 96 | } 97 | 98 | func testHardCodePerformanceExample() { 99 | 100 | self.measure { 101 | 102 | for _ in 0..<10000{ 103 | 104 | var user = UserInPerformance.init(age: nil, name: nil, phone: nil) 105 | var phone = PhoneNumberInPerformance.init(tel: nil, type: nil) 106 | 107 | if let name = self.dic["name"] as? String { 108 | user.name = name 109 | } 110 | if let age = self.dic["age"] as? Int { 111 | user.age = age 112 | } 113 | 114 | let phoneInfo = self.dic["phone"] as? [String : Any] 115 | 116 | if let phonetel = phoneInfo?["tel"] as? String { 117 | phone.tel = phonetel 118 | } 119 | 120 | if let phoneType = phoneInfo?["type"] as? String { 121 | phone.type = phoneType 122 | } 123 | user.phone = phone 124 | } 125 | } 126 | } 127 | 128 | func testSwiftyJSONPerformanceExample() { 129 | 130 | self.measure { 131 | 132 | for _ in 0..<10000{ 133 | 134 | let json = JSON.init(self.dic) 135 | 136 | var user = UserInPerformance.init(age: nil, name: nil, phone: nil) 137 | var phone = PhoneNumberInPerformance.init(tel: nil, type: nil) 138 | 139 | if let age = json["age"].int { 140 | user.age = age 141 | } 142 | 143 | if let name = json["name"].string { 144 | user.name = name 145 | } 146 | 147 | if let phoneNum = json["phone"]["tel"].string { 148 | phone.tel = phoneNum 149 | } 150 | 151 | if let type = json["phone"]["type"].string { 152 | phone.type = type 153 | } 154 | user.phone = phone 155 | 156 | } 157 | } 158 | } 159 | 160 | func testObjectMapperPerformanceExample() { 161 | 162 | self.measure { 163 | 164 | for _ in 0..<10000{ 165 | _ = UserInPerformance(map: Map.init(mappingType: MappingType.fromJSON, JSON: self.dic)) 166 | } 167 | } 168 | } 169 | 170 | func testUnboxPerformanceExample() { 171 | 172 | self.measure { 173 | 174 | do { 175 | for _ in 0..<10000{ 176 | let _: UserInPerformance = try unbox(dictionary: self.dic) 177 | } 178 | }catch { 179 | 180 | } 181 | } 182 | } 183 | } 184 | -------------------------------------------------------------------------------- /MappingTests/SwiftClassMappingTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftClassMappingTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Mapping 11 | @testable import MappingAce 12 | 13 | class SwiftClassMappingTests: XCTestCase { 14 | 15 | override func setUp() { 16 | super.setUp() 17 | // Put setup code here. This method is called before the invocation of each test method in the class. 18 | } 19 | 20 | override func tearDown() { 21 | // Put teardown code here. This method is called after the invocation of each test method in the class. 22 | super.tearDown() 23 | } 24 | 25 | func testSwiftClassInitExample() { 26 | 27 | class User: InitMapping{ 28 | var name: String = "default" 29 | var age: Int? 30 | 31 | required init() {} 32 | } 33 | 34 | let dic: [String : Any] = ["name" : "IB", "age": 14] 35 | let user = User(fromDic: dic) 36 | 37 | XCTAssertEqual(user.name, "IB") 38 | XCTAssertEqual(user.age, 14) 39 | } 40 | 41 | func testStructInitExample(){ 42 | 43 | struct User: InitMapping{ 44 | var name: String = "default" 45 | var age: Int? 46 | } 47 | 48 | let dic: [String : Any] = ["name" : "IB", "age": 14] 49 | let user = User(fromDic: dic) 50 | 51 | XCTAssertEqual(user.name, "IB") 52 | XCTAssertEqual(user.age, 14) 53 | 54 | } 55 | 56 | func testOCClassInitExample(){ 57 | 58 | class User: NSObject, InitMapping{ 59 | var name: String = "default" 60 | var age: Int? 61 | required override init() {} 62 | } 63 | 64 | let dic: [String : Any] = ["name" : "IB", "age": 14] 65 | let user = User(fromDic: dic) 66 | 67 | XCTAssertEqual(user.name, "IB") 68 | XCTAssertEqual(user.age, 14) 69 | } 70 | 71 | func testSwiftClassInitOptionalPropertyExample() { 72 | 73 | class User: InitMapping{ 74 | var name: String = "default" 75 | var age: Int? 76 | 77 | required init() {} 78 | } 79 | 80 | let dic: [String : Any] = ["name" : "IB"] 81 | let user = User(fromDic: dic) 82 | 83 | XCTAssertEqual(user.name, "IB") 84 | XCTAssertEqual(user.age, nil) 85 | } 86 | 87 | func testStructInitOptionalPropertyExample(){ 88 | 89 | struct User: InitMapping{ 90 | var name: String = "default" 91 | var age: Int? 92 | } 93 | 94 | let dic: [String : Any] = ["age": 14] 95 | let user = User(fromDic: dic) 96 | 97 | XCTAssertEqual(user.name, "default") 98 | XCTAssertEqual(user.age, 14) 99 | 100 | } 101 | 102 | func testOCClassInitOptionalPropertyExample(){ 103 | 104 | class User: NSObject, InitMapping{ 105 | var name: String = "default" 106 | var age: Int? 107 | required override init() {} 108 | } 109 | 110 | let dic: [String : Any] = ["name" : "IB"] 111 | let user = User(fromDic: dic) 112 | 113 | XCTAssertEqual(user.name, "IB") 114 | XCTAssertEqual(user.age, nil) 115 | } 116 | 117 | /// 类继承 118 | /// TO CHECK: NSObject 119 | /// SwiftClass 的super是否为空 120 | func testSubclassExample(){ 121 | 122 | class People: InitMapping, Serializable{ 123 | var name: String = "" 124 | var age: Int = 0 125 | required init(){} 126 | } 127 | 128 | class Student: People{ 129 | var grade: Int = 0 130 | } 131 | 132 | 133 | let studentInfo: [String : Any] = [ 134 | "name" : "Binglin", 135 | "age" : 18, 136 | "grade" : 9 137 | ] 138 | 139 | let student = Student(fromDic: studentInfo) 140 | let serializeStudent = student.toDictionary() 141 | 142 | 143 | 144 | XCTAssertEqual(student.name, "Binglin") 145 | XCTAssertEqual(student.age, 18) 146 | XCTAssertEqual(student.grade, 9) 147 | 148 | XCTAssertEqual(studentInfo as NSDictionary, serializeStudent as NSDictionary) 149 | } 150 | 151 | } 152 | -------------------------------------------------------------------------------- /MappingTests/SwiftStructNonilTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftStructNonilTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Mapping 11 | @testable import MappingAce 12 | 13 | private struct User: Mapping{ 14 | var age: Int 15 | var name: String 16 | var phone: PhoneNumber 17 | } 18 | 19 | class SwiftStructNonilTests: XCTestCase { 20 | 21 | override func setUp() { 22 | super.setUp() 23 | // Put setup code here. This method is called before the invocation of each test method in the class. 24 | } 25 | 26 | override func tearDown() { 27 | // Put teardown code here. This method is called after the invocation of each test method in the class. 28 | super.tearDown() 29 | } 30 | 31 | func testMappingAny_struct(){ 32 | 33 | 34 | struct PhoneEntity { 35 | var tel: String 36 | var type: String 37 | } 38 | 39 | let phoneInfo: [String : Any] = [ 40 | "tel": "186xxxxxxxx", 41 | "type": "work" 42 | ] 43 | 44 | let phone = MappingAny(type: PhoneEntity.self, fromDic: phoneInfo) 45 | 46 | XCTAssertEqual(phone.tel, "186xxxxxxxx") 47 | XCTAssertEqual(phone.type, "work") 48 | 49 | } 50 | 51 | func testStructMapping(){ 52 | 53 | let phoneInfo: [String : Any] = [ 54 | "tel": "186xxxxxxxx", 55 | "type": "work" 56 | ] 57 | 58 | let phone = PhoneNumber(fromDic: phoneInfo) 59 | let dic = phone.toDictionary() 60 | 61 | print(dic) 62 | XCTAssertEqual(dic as NSDictionary, phoneInfo as NSDictionary) 63 | 64 | XCTAssertEqual(phone.tel, "186xxxxxxxx") 65 | XCTAssertEqual(phone.type, "work") 66 | } 67 | 68 | func testEmbedMappingExample() { 69 | 70 | let phone: [String : Any] = [ 71 | "tel": "186xxxxxxxx", 72 | "type": "work" 73 | ] 74 | 75 | let dic: [String : Any] = [ 76 | "age" : 24, 77 | "name": "Binglin", 78 | "phone": phone 79 | ] 80 | 81 | let user = MappingAny(type: User.self, fromDic: dic) 82 | let userDic = user.toDictionary() 83 | 84 | XCTAssertEqual(dic as NSDictionary, userDic as NSDictionary) 85 | 86 | XCTAssertEqual(user.age, 24) 87 | XCTAssertEqual(user.name, "Binglin") 88 | XCTAssertEqual(user.phone.tel, "186xxxxxxxx") 89 | XCTAssertEqual(user.phone.type, "work") 90 | } 91 | 92 | func testStringToIntExample() { 93 | 94 | let phone: [String : Any] = [ 95 | "tel": "186xxxxxxxx", 96 | "type": "work" 97 | ] 98 | 99 | let dic: [String : Any] = [ 100 | "age" : "24", 101 | "name": "Binglin", 102 | "phone": phone 103 | ] 104 | 105 | let user = MappingAny(type: User.self, fromDic: dic) 106 | 107 | XCTAssertEqual(user.age, 24) 108 | XCTAssertEqual(user.name, "Binglin") 109 | XCTAssertEqual(user.phone.tel, "186xxxxxxxx") 110 | XCTAssertEqual(user.phone.type, "work") 111 | } 112 | 113 | func testEnumIntExample(){ 114 | 115 | enum Gender: Int, EnumInt{ 116 | case male = 1 117 | case female = 2 118 | } 119 | 120 | struct User: Mapping, Serializable{ 121 | var name: String 122 | var gender: Gender 123 | } 124 | 125 | 126 | let dicGender1: [String : Any] = [ 127 | "name": "Binglin", 128 | "gender": 1 129 | ] 130 | 131 | let dicGender2: [String : Any] = [ 132 | "name": "Binglin", 133 | "gender": 2 134 | ] 135 | 136 | let userMale = User(fromDic: dicGender1) 137 | let userFemale = User(fromDic: dicGender2) 138 | 139 | XCTAssertEqual(userMale.name, "Binglin") 140 | XCTAssertEqual(userFemale.name, "Binglin") 141 | XCTAssertEqual(userMale.gender, Gender.male) 142 | XCTAssertEqual(userFemale.gender, Gender.female) 143 | 144 | XCTAssertEqual(userMale.toDictionary() as NSDictionary, dicGender1 as NSDictionary) 145 | XCTAssertEqual(userFemale.toDictionary() as NSDictionary, dicGender2 as NSDictionary) 146 | 147 | } 148 | 149 | 150 | func testEnumStringExample(){ 151 | 152 | enum Gender: String, EnumString{ 153 | case male = "m" 154 | case female = "f" 155 | } 156 | 157 | struct User: Mapping{ 158 | var name: String 159 | var gender: Gender 160 | } 161 | 162 | 163 | let dicGender1: [String : Any] = [ 164 | "name": "Binglin", 165 | "gender": "m" 166 | ] 167 | 168 | let dicGender2: [String : Any] = [ 169 | "name": "Binglin", 170 | "gender": "f" 171 | ] 172 | 173 | let userMale = User(fromDic: dicGender1) 174 | let userFemale = User(fromDic: dicGender2) 175 | 176 | XCTAssertEqual(userMale.name, "Binglin") 177 | XCTAssertEqual(userFemale.name, "Binglin") 178 | XCTAssertEqual(userMale.gender, Gender.male) 179 | XCTAssertEqual(userFemale.gender, Gender.female) 180 | 181 | } 182 | 183 | func testInitMappintExample(){ 184 | 185 | struct User: InitMapping{ 186 | var name = "default" 187 | var age = 24 188 | } 189 | 190 | 191 | let dic: [String : Any] = ["name" : "Binglin"] 192 | let user = User(fromDic: dic) 193 | 194 | 195 | 196 | XCTAssertEqual(user.name, "Binglin") 197 | XCTAssertEqual(user.age, 24) 198 | 199 | } 200 | 201 | func testKeyMappingExample(){ 202 | 203 | struct User: Mapping, KeyMapping{ 204 | var name: String 205 | var avator: String 206 | 207 | static func mappedKeyFor(key: String) -> String?{ 208 | switch key { 209 | case "avator": return "headURL" 210 | default: return nil 211 | } 212 | } 213 | } 214 | 215 | let dic: [String : Any] = ["name" : "Binglin", "headURL" : "www.xxx.com"] 216 | 217 | let user = User(fromDic: dic) 218 | 219 | XCTAssertEqual(user.name, "Binglin") 220 | XCTAssertEqual(user.avator, "www.xxx.com") 221 | } 222 | 223 | func testArrayMappingExample(){ 224 | 225 | struct UserArrayPhoneEntity: Mapping{ 226 | var age: Int 227 | var name: String 228 | var phones: [PhoneNumber] 229 | var phonesArr : [[PhoneNumber]] 230 | var phonesArrS : [[[PhoneNumber]]] 231 | } 232 | 233 | 234 | let phone: [String : Any] = [ 235 | "tel": "186xxxxxxxx", 236 | "type": "work" 237 | ] 238 | 239 | let phones = Array(repeating: phone, count: 10) 240 | let dic: [String : Any] = [ 241 | "age" : 24, 242 | "name": "Binglin", 243 | "phones": phones, 244 | "phonesArr" : [phones, phones], 245 | "phonesArrS" : [[phones, phones]] 246 | ] 247 | 248 | let user = UserArrayPhoneEntity.init(fromDic: dic) 249 | let serializedUser = user.toDictionary() 250 | 251 | XCTAssertEqual(dic as NSDictionary, serializedUser as NSDictionary) 252 | 253 | XCTAssertEqual(user.phones.count, 10) 254 | XCTAssertEqual(user.phones[0].type, "work") 255 | } 256 | 257 | func testArrayInitMappingExample(){ 258 | 259 | struct UserArrayPhoneEntity: InitMapping{ 260 | var age: Int = 0 261 | var name: String = "" 262 | var phones: [PhoneNumber] = [] 263 | } 264 | 265 | 266 | let phone: [String : Any] = [ 267 | "tel": "186xxxxxxxx", 268 | "type": "work" 269 | ] 270 | 271 | let phones = Array(repeating: phone, count: 10) 272 | let dic: [String : Any] = [ 273 | "age" : 24, 274 | "name": "Binglin", 275 | "phones": phones 276 | ] 277 | 278 | let user = UserArrayPhoneEntity.init(fromDic: dic) 279 | let dicArr = user.toDictionary() 280 | 281 | XCTAssertEqual(dic as NSDictionary, dicArr as NSDictionary) 282 | 283 | XCTAssertEqual(user.phones.count, 10) 284 | XCTAssertEqual(user.phones[0].type, "work") 285 | } 286 | 287 | 288 | func testEntityInitMappingExample(){ 289 | 290 | 291 | struct PhoneNumber: Mapping { 292 | var tel: String 293 | var type: String 294 | } 295 | 296 | struct UserArrayPhoneEntity: InitMapping{ 297 | var age: Int = 0 298 | var name: String = "" 299 | var phone: PhoneNumber = PhoneNumber(tel: "", type: "") 300 | } 301 | 302 | 303 | let phone: [String : Any] = [ 304 | "tel": "186xxxxxxxx", 305 | "type": "work" 306 | ] 307 | 308 | let dic: [String : Any] = [ 309 | "age" : "24", 310 | "name": "Binglin", 311 | "phone": phone 312 | ] 313 | 314 | let user = UserArrayPhoneEntity.init(fromDic: dic) 315 | 316 | XCTAssertEqual(user.phone.tel, "186xxxxxxxx") 317 | XCTAssertEqual(user.phone.type, "work") 318 | } 319 | 320 | 321 | func testNumericalExample(){ 322 | 323 | struct Numerical: Mapping{ 324 | 325 | var bool : Bool 326 | var int: Int 327 | var int8 : Int8 328 | 329 | var float: Float 330 | var double: Double 331 | 332 | var timeInterval: TimeInterval 333 | } 334 | 335 | 336 | let numericalSet: [String : Any] = [ 337 | "bool": "true", 338 | "int": "5", 339 | "int8": "1", 340 | "float": 1.99, 341 | "double": 3.14, 342 | "timeInterval": 12345 343 | ] 344 | 345 | let num = Numerical.init(fromDic: numericalSet) 346 | XCTAssertEqual(num.bool, true) 347 | XCTAssertEqual(num.int, 5) 348 | XCTAssertEqual(num.int8, 1) 349 | XCTAssertEqual(num.float, 1.99) 350 | XCTAssertEqual(num.double, 3.14) 351 | XCTAssertEqual(num.timeInterval, 12345) 352 | 353 | } 354 | 355 | func testKeyPathMapping(){ 356 | 357 | struct A: KeyMapping{ 358 | var int: Int 359 | 360 | fileprivate static func mappedKeyFor(key: String) -> String? { 361 | if key == "int" { 362 | return "a.b.c" 363 | } 364 | return nil 365 | } 366 | } 367 | 368 | let dic : [String : Any] = ["a" : ["b": ["c": 1]]] 369 | let keyPathA = MappingAny(type: A.self, fromDic: dic) 370 | 371 | XCTAssertEqual(keyPathA.int, 1) 372 | } 373 | 374 | 375 | } 376 | 377 | 378 | 379 | -------------------------------------------------------------------------------- /MappingTests/SwiftStructNullableTests.swift: -------------------------------------------------------------------------------- 1 | // 2 | // SwiftStructNullableTests.swift 3 | // Mapping 4 | // 5 | // Created by ET|冰琳 on 16/10/24. 6 | // Copyright © 2016年 Ice Butterfly. All rights reserved. 7 | // 8 | 9 | import XCTest 10 | @testable import Mapping 11 | @testable import MappingAce 12 | 13 | private struct User: Serializable{ 14 | var age: Int? 15 | var name: String? 16 | var phone: PhoneNumber? 17 | } 18 | 19 | struct PhoneNumber: Mapping { 20 | var tel: String 21 | var type: String 22 | } 23 | 24 | class SwiftStructNullableTests: XCTestCase { 25 | 26 | override func setUp() { 27 | super.setUp() 28 | // Put setup code here. This method is called before the invocation of each test method in the class. 29 | } 30 | 31 | override func tearDown() { 32 | // Put teardown code here. This method is called after the invocation of each test method in the class. 33 | super.tearDown() 34 | } 35 | 36 | func testAllNilExample() { 37 | 38 | let user = MappingAny(type: User.self, fromDic: [:]) 39 | let dic = user.toDictionary() 40 | print(dic) 41 | 42 | let dicNull = user.toNullableValueDictionary() 43 | print(dicNull) 44 | 45 | XCTAssertEqual(user.age, nil) 46 | XCTAssertEqual(user.name, nil) 47 | XCTAssertEqual(user.phone?.tel, nil) 48 | XCTAssertEqual(user.phone?.type, nil) 49 | } 50 | 51 | 52 | func testSomeNilExample(){ 53 | 54 | let dic: [String : Any] = [ 55 | "name": "Binglin", 56 | ] 57 | 58 | let user = MappingAny(type: User.self, fromDic: dic) 59 | 60 | XCTAssertEqual(user.age, nil) 61 | XCTAssertEqual(user.name, "Binglin") 62 | XCTAssertEqual(user.phone?.tel, nil) 63 | XCTAssertEqual(user.phone?.type, nil) 64 | 65 | } 66 | 67 | func testPhoneNotNilExample(){ 68 | 69 | let dic: [String : Any] = [ 70 | "name": "Binglin", 71 | "phone": ["tel" : "xxx", "type": "work"] 72 | ] 73 | 74 | let user = MappingAny(type: User.self, fromDic: dic) 75 | 76 | let serialized = user.toDictionary() 77 | XCTAssertEqual(dic as NSDictionary, serialized as NSDictionary) 78 | 79 | XCTAssertEqual(user.age, nil) 80 | XCTAssertEqual(user.name, "Binglin") 81 | XCTAssertEqual(user.phone?.tel, "xxx") 82 | XCTAssertEqual(user.phone?.type, "work") 83 | 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | target 'Mapping' do 5 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | # Pods for Mapping 9 | 10 | target 'MappingTests' do 11 | inherit! :search_paths 12 | # Pods for testing 13 | 14 | 15 | pod 'Unbox', '~> 2.3.1' 16 | pod 'ObjectMapper', '~> 2.2.2' 17 | pod 'SwiftyJSON', '~> 3.1.4' 18 | end 19 | 20 | end 21 | 22 | target 'MappingAce' do 23 | # Comment the next line if you're not using Swift and don't want to use dynamic frameworks 24 | use_frameworks! 25 | 26 | # Pods for MappingAce 27 | 28 | end 29 | -------------------------------------------------------------------------------- /Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - ObjectMapper (2.2.2) 3 | - SwiftyJSON (3.1.4) 4 | - Unbox (2.3.1) 5 | 6 | DEPENDENCIES: 7 | - ObjectMapper (~> 2.2.2) 8 | - SwiftyJSON (~> 3.1.4) 9 | - Unbox (~> 2.3.1) 10 | 11 | SPEC CHECKSUMS: 12 | ObjectMapper: 9e385c2295bcc4e16eabbcfc85db801442bba545 13 | SwiftyJSON: c2842d878f95482ffceec5709abc3d05680c0220 14 | Unbox: 96e54c15284b97244a1daf8ea560f648dd08f0db 15 | 16 | PODFILE CHECKSUM: 6f6f24457828426e2b7726c79f90c61cec0dcb3e 17 | 18 | COCOAPODS: 1.2.1 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 |

3 | MappingAce 4 |

5 | 6 | 7 | [![Swift](https://img.shields.io/badge/Swift-3.0+-orange.svg?style=flat)](https://swift.org) 8 | [![Swift](https://img.shields.io/badge/Swift-4.0-orange.svg?style=flat)](https://swift.org) 9 | 10 | [![CocoaPods Compatible](https://img.shields.io/cocoapods/v/MappingAce.svg)](https://img.shields.io/cocoapods/v/MappingAce.svg) 11 | [![Carthage Compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage) 12 | [![License](https://img.shields.io/badge/License-MIT-blue.svg?style=flat)](https://tldrlegal.com/license/mit-license) 13 | 14 | *Swift JSON to Struct, class* 15 | 16 | MappingAce allows rapid creation of struct , Swift class, OC class . Automatic transform dictionary to model(model could be struct), forget to manually write property mapping code 17 | 18 | 19 | - [Usage](#usage) 20 | - [JSON -> Model](#json-model) 21 | - [Raw struct ](#raw-struct) 22 | - [Nested struct mapping](#nested-struct-mapping) 23 | - [Optional property](#optional-property) 24 | - [Enum](#enum) 25 | - [Struct or class has default property value](#struct-or-class-has-default-property-value) 26 | - [Model -> JSON](#model-json) 27 | - just implement protocol `Serializable` 28 | - [Installation](#installation) 29 | 30 | 31 | 32 | ## Usage 33 | 34 | ### JSON -> Model 35 | 36 | ##### Raw struct 37 | 38 | ``` 39 | 40 | // It is recommend to implement protocol `Mapping`, and just implement `Mapping`, no more works 41 | struct PhoneNumber: Mapping{ 42 | var tel: String 43 | var type: String 44 | } 45 | 46 | let phoneInfo: [String : Any] = [ 47 | "tel": "186xxxxxxxx", 48 | "type": "work" 49 | ] 50 | let phone = PhoneNumber(fromDic: phoneInfo) 51 | 52 | print(phone.tel) //"186xxxxxxxx" 53 | print(phone.type) //"work" 54 | 55 | 56 | 57 | // Struct did not implement the `Mapping` protocol 58 | struct PhoneNumber { 59 | var tel: String 60 | var type: String 61 | } 62 | 63 | let phone = MappingAny(type: PhoneEntity.self, fromDic: phoneInfo) 64 | 65 | ``` 66 | ##### Nested struct mapping 67 | 68 | ``` 69 | struct User{ 70 | var age: Int 71 | var name: String 72 | var phone: PhoneNumber 73 | } 74 | 75 | // if you want your serilized nested struct, just implement the `Mapping` protocol 76 | struct PhoneNumber: Mapping { 77 | var tel: String 78 | var type: String 79 | } 80 | 81 | let dic: [String : Any] = [ 82 | "age" : 24, 83 | "name": "Binglin", 84 | "phone": phoneInfo 85 | ] 86 | 87 | let user = MappingAny(type: User.self, fromDic: dic) 88 | ``` 89 | 90 | ###### Optional property 91 | ``` 92 | struct User{ 93 | var age: Int? 94 | var name: String? 95 | var phone: PhoneNumber? 96 | } 97 | 98 | private struct PhoneNumber: Mapping { 99 | var tel: String 100 | var type: String 101 | } 102 | 103 | let dic: [String : Any] = [ 104 | "name": "Binglin", 105 | ] 106 | 107 | let user = MappingAny(type: User.self, fromDic: dic) 108 | 109 | XCTAssertEqual(user.age, nil) 110 | XCTAssertEqual(user.name, "Binglin") 111 | XCTAssertEqual(user.phone?.tel, nil) 112 | XCTAssertEqual(user.phone?.type, nil) 113 | ``` 114 | 115 | ##### Enum 116 | enum type of Int & String is support 117 | ``` 118 | // eg: EnumInt 119 | enum Gender: Int, EnumInt{ 120 | case male = 1 121 | case female = 2 122 | } 123 | 124 | struct User: Mapping{ 125 | var gender: Gender 126 | } 127 | 128 | let dicGender: [String : Any] = ["gender": 1] 129 | let userMale = User(fromDic: dicGender) 130 | 131 | XCTAssertEqual(userMale.gender, Gender.male) 132 | ``` 133 | 134 | ``` 135 | // when enum is string type 136 | enum Gender: String, EnumString{ 137 | case male = "m" 138 | case female = "f" 139 | } 140 | ``` 141 | 142 | 143 | ### Struct or class has default property value 144 | protocol: InitMapping (Struct or Class) 145 | 146 | ``` 147 | // struct 148 | struct User: InitMapping{ 149 | var name: String = "default" 150 | var age: Int? 151 | } 152 | 153 | let dic: [String : Any] = ["age": 14] 154 | let user = User(fromDic: dic) 155 | 156 | print(user.name) //"default" 157 | print(user.age) //14 158 | 159 | 160 | // class 161 | // need to implement an empty initializer. 162 | class User: NSObject, InitMapping{ 163 | var name: String = "default" 164 | var age: Int? 165 | 166 | required override init() {}/*required*/ 167 | } 168 | 169 | let dic: [String : Any] = ["name" : "IB"] 170 | let user = User(fromDic: dic) 171 | ``` 172 | 173 | 174 | 175 | 176 | ### Model -> JSON 177 | 178 | 179 | ``` 180 | // for object implement Mapping or InitMapping 181 | struct PhoneNumber: Mapping { 182 | var tel: String 183 | var type: String 184 | } 185 | 186 | let phone = PhoneNumber(tel: "186xxxxxxxx", type: "work") 187 | let toDic = phone.toDictionary() 188 | print(toDic) // ["type": "work", "tel": "186xxxxxxxx"] 189 | 190 | 191 | // for object do not implement Mapping or InitMapping 192 | // just implement protocol Serializable 193 | struct PhoneNumber: `Serializable` { 194 | var tel: String 195 | var type: String 196 | } 197 | 198 | let phone = PhoneNumber(tel: "186xxxxxxxx", type: "work") 199 | let toDic = phone.toDictionary() 200 | print(toDic) // ["type": "work", "tel": "186xxxxxxxx"] 201 | ``` 202 | 203 | 204 | 205 | 206 | ## Installation 207 | 208 | | swift version | framework version | 209 | | - | - | 210 | | 3.0 | 1.0.2 | 211 | | 3.1 | 1.0.3 | 212 | | 4.0 | 1.0.4 | 213 | 214 | 215 | ### Installation with CocoaPods 216 | 217 | #### Podfile 218 | 219 | To integrate MappingAce into your Xcode project using CocoaPods, specify it in your `Podfile`: 220 | 221 | 222 | ```ruby 223 | platform :ios, '8.0' 224 | 225 | target 'TargetName' do 226 | pod 'MappingAce', '~> 1.0.3' 227 | end 228 | ``` 229 | 230 | 231 | Then, run the following command: 232 | 233 | ```bash 234 | $ pod install 235 | ``` 236 | 237 | ### Installation with [Carthage](https://github.com/Carthage/Carthage) 238 | To integrate MappingAce into your Xcode project using Carthage, specify it in your `Cartfile`: 239 | 240 | ```ogdl 241 | github "IcyButterfly/MappingAce" ~> 1.0.3 242 | ``` 243 | 244 | Run `carthage` to build the framework and drag the built `MappingAce.framework` into your Xcode project. 245 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Binglin/MappingAce/a02b3cf8e65ddc1294522a336f1a825b838b0ab2/logo.png --------------------------------------------------------------------------------