├── .gitignore ├── .travis.yml ├── Demo ├── Podfile ├── Podfile.lock ├── Pods │ ├── Manifest.lock │ ├── Pods.xcodeproj │ │ └── xcuserdata │ │ │ └── qianlongxu.xcuserdatad │ │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ └── Target Support Files │ │ ├── Pods-SCJSONUtilDemo │ │ ├── Pods-SCJSONUtilDemo-Info.plist │ │ ├── Pods-SCJSONUtilDemo-acknowledgements.markdown │ │ ├── Pods-SCJSONUtilDemo-acknowledgements.plist │ │ ├── Pods-SCJSONUtilDemo-dummy.m │ │ ├── Pods-SCJSONUtilDemo-umbrella.h │ │ └── Pods-SCJSONUtilDemo.modulemap │ │ └── SCJSONUtil │ │ ├── SCJSONUtil-Info.plist │ │ ├── SCJSONUtil-dummy.m │ │ ├── SCJSONUtil-prefix.pch │ │ ├── SCJSONUtil-umbrella.h │ │ ├── SCJSONUtil.modulemap │ │ └── SCJSONUtil.xcconfig ├── SCJSONUtilDemo.xcodeproj │ ├── project.pbxproj │ ├── project.xcworkspace │ │ ├── contents.xcworkspacedata │ │ ├── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcuserdata │ │ │ ├── crown.xcuserdatad │ │ │ └── UserInterfaceState.xcuserstate │ │ │ └── qianlongxu.xcuserdatad │ │ │ ├── UserInterfaceState.xcuserstate │ │ │ └── WorkspaceSettings.xcsettings │ └── xcuserdata │ │ ├── crown.xcuserdatad │ │ └── xcschemes │ │ │ ├── SCJSONUtilDemo.xcscheme │ │ │ └── xcschememanagement.plist │ │ ├── matt.xcuserdatad │ │ └── xcschemes │ │ │ └── xcschememanagement.plist │ │ └── qianlongxu.xcuserdatad │ │ ├── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist │ │ └── xcschemes │ │ └── xcschememanagement.plist ├── SCJSONUtilDemo.xcworkspace │ ├── contents.xcworkspacedata │ ├── xcshareddata │ │ └── IDEWorkspaceChecks.plist │ └── xcuserdata │ │ └── qianlongxu.xcuserdatad │ │ └── xcdebugger │ │ └── Breakpoints_v2.xcbkptlist ├── SCJSONUtilDemo │ ├── AppDelegate.h │ ├── AppDelegate.m │ ├── Assets.xcassets │ │ └── AppIcon.appiconset │ │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Info.plist │ ├── Test.h │ ├── Test.m │ ├── ViewController.h │ ├── ViewController.m │ ├── jsonfiles │ │ ├── Car.json │ │ ├── DynamicVideos.json │ │ ├── FavConcern.json │ │ ├── GalleryList.json │ │ ├── NewRecProduct.json │ │ ├── OCTypes.json │ │ ├── Store.json │ │ ├── Userinfo.json │ │ ├── VideoInfo.json │ │ └── newMainPageSecond.json │ ├── main.m │ ├── models │ │ ├── Car.h │ │ ├── Car.m │ │ ├── DynamicVideos.h │ │ ├── DynamicVideos.m │ │ ├── FavModel.h │ │ ├── FavModel.m │ │ ├── GalleryModel.h │ │ ├── GalleryModel.m │ │ ├── OCTypes.h │ │ ├── OCTypes.m │ │ ├── StoreModel.h │ │ ├── StoreModel.m │ │ ├── UserInfoModel.h │ │ ├── UserInfoModel.m │ │ ├── VideoInfo.h │ │ └── VideoInfo.m │ └── util │ │ ├── Util.h │ │ └── Util.m └── SCJSONUtilTests │ ├── Info.plist │ └── SCJSONUtilTests.m ├── LICENSE ├── README.md ├── SCJSONUtil.podspec └── SCJSONUtil ├── SCJSONUtil.h ├── SCJSONUtil.m ├── SCModelUtil.h ├── SCModelUtil.m └── internal ├── scutil.c └── scutil.h /.gitignore: -------------------------------------------------------------------------------- 1 | SCJSONUtilDemo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata 2 | Demo/SCJSONUtilDemo.xcworkspace/xcuserdata 3 | Demo/Pods 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | # references: 2 | # * https://www.objc.io/issues/6-build-tools/travis-ci/ 3 | # * https://github.com/supermarin/xcpretty#usage 4 | 5 | osx_image: xcode11.3 6 | language: objective-c 7 | # cache: cocoapods 8 | podfile: Demo/Podfile 9 | before_install: 10 | - gem install cocoapods # Since Travis is not always on latest version 11 | - pod install --project-directory=Demo 12 | script: 13 | - set -o pipefail && xcodebuild test -enableCodeCoverage YES -workspace Demo/SCJSONUtilDemo.xcworkspace -scheme SCJSONUtilTests -destination 'platform=iOS Simulator,OS=13.3,name=iPhone 8' ONLY_ACTIVE_ARCH=NO | xcpretty 14 | - pod lib lint --allow-warnings 15 | -------------------------------------------------------------------------------- /Demo/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment the next line to define a global platform for your project 2 | platform :ios, '12.0' 3 | 4 | target 'SCJSONUtilDemo' do 5 | # Comment the next line if you don't want to use dynamic frameworks 6 | use_frameworks! 7 | 8 | pod 'SCJSONUtil',:path => '../' 9 | 10 | end 11 | 12 | target 'SCJSONUtilTests' do 13 | # Comment the next line if you don't want to use dynamic frameworks 14 | use_frameworks! 15 | 16 | pod 'SCJSONUtil',:path => '../' 17 | 18 | end -------------------------------------------------------------------------------- /Demo/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SCJSONUtil (2.5.6) 3 | 4 | DEPENDENCIES: 5 | - SCJSONUtil (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SCJSONUtil: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SCJSONUtil: 0e8be7fd76b0aadcedd974f77e86981ec71a0ece 13 | 14 | PODFILE CHECKSUM: 3b4591dd2be1e6d0a179416cc51e1c04038e2832 15 | 16 | COCOAPODS: 1.16.1 17 | -------------------------------------------------------------------------------- /Demo/Pods/Manifest.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - SCJSONUtil (2.5.6) 3 | 4 | DEPENDENCIES: 5 | - SCJSONUtil (from `../`) 6 | 7 | EXTERNAL SOURCES: 8 | SCJSONUtil: 9 | :path: "../" 10 | 11 | SPEC CHECKSUMS: 12 | SCJSONUtil: 0e8be7fd76b0aadcedd974f77e86981ec71a0ece 13 | 14 | PODFILE CHECKSUM: 3b4591dd2be1e6d0a179416cc51e1c04038e2832 15 | 16 | COCOAPODS: 1.16.1 17 | -------------------------------------------------------------------------------- /Demo/Pods/Pods.xcodeproj/xcuserdata/qianlongxu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | Pods-SCJSONUtilDemo.xcscheme 8 | 9 | isShown 10 | 11 | 12 | Pods-SCJSONUtilTests.xcscheme 13 | 14 | isShown 15 | 16 | 17 | SCJSONUtil.xcscheme 18 | 19 | isShown 20 | 21 | 22 | 23 | SuppressBuildableAutocreation 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 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.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo-acknowledgements.markdown: -------------------------------------------------------------------------------- 1 | # Acknowledgements 2 | This application makes use of the following third party libraries: 3 | 4 | ## SCJSONUtil 5 | 6 | Apache License 7 | Version 2.0, January 2004 8 | http://www.apache.org/licenses/ 9 | 10 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 11 | 12 | 1. Definitions. 13 | 14 | "License" shall mean the terms and conditions for use, reproduction, 15 | and distribution as defined by Sections 1 through 9 of this document. 16 | 17 | "Licensor" shall mean the copyright owner or entity authorized by 18 | the copyright owner that is granting the License. 19 | 20 | "Legal Entity" shall mean the union of the acting entity and all 21 | other entities that control, are controlled by, or are under common 22 | control with that entity. For the purposes of this definition, 23 | "control" means (i) the power, direct or indirect, to cause the 24 | direction or management of such entity, whether by contract or 25 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 26 | outstanding shares, or (iii) beneficial ownership of such entity. 27 | 28 | "You" (or "Your") shall mean an individual or Legal Entity 29 | exercising permissions granted by this License. 30 | 31 | "Source" form shall mean the preferred form for making modifications, 32 | including but not limited to software source code, documentation 33 | source, and configuration files. 34 | 35 | "Object" form shall mean any form resulting from mechanical 36 | transformation or translation of a Source form, including but 37 | not limited to compiled object code, generated documentation, 38 | and conversions to other media types. 39 | 40 | "Work" shall mean the work of authorship, whether in Source or 41 | Object form, made available under the License, as indicated by a 42 | copyright notice that is included in or attached to the work 43 | (an example is provided in the Appendix below). 44 | 45 | "Derivative Works" shall mean any work, whether in Source or Object 46 | form, that is based on (or derived from) the Work and for which the 47 | editorial revisions, annotations, elaborations, or other modifications 48 | represent, as a whole, an original work of authorship. For the purposes 49 | of this License, Derivative Works shall not include works that remain 50 | separable from, or merely link (or bind by name) to the interfaces of, 51 | the Work and Derivative Works thereof. 52 | 53 | "Contribution" shall mean any work of authorship, including 54 | the original version of the Work and any modifications or additions 55 | to that Work or Derivative Works thereof, that is intentionally 56 | submitted to Licensor for inclusion in the Work by the copyright owner 57 | or by an individual or Legal Entity authorized to submit on behalf of 58 | the copyright owner. For the purposes of this definition, "submitted" 59 | means any form of electronic, verbal, or written communication sent 60 | to the Licensor or its representatives, including but not limited to 61 | communication on electronic mailing lists, source code control systems, 62 | and issue tracking systems that are managed by, or on behalf of, the 63 | Licensor for the purpose of discussing and improving the Work, but 64 | excluding communication that is conspicuously marked or otherwise 65 | designated in writing by the copyright owner as "Not a Contribution." 66 | 67 | "Contributor" shall mean Licensor and any individual or Legal Entity 68 | on behalf of whom a Contribution has been received by Licensor and 69 | subsequently incorporated within the Work. 70 | 71 | 2. Grant of Copyright License. Subject to the terms and conditions of 72 | this License, each Contributor hereby grants to You a perpetual, 73 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 74 | copyright license to reproduce, prepare Derivative Works of, 75 | publicly display, publicly perform, sublicense, and distribute the 76 | Work and such Derivative Works in Source or Object form. 77 | 78 | 3. Grant of Patent License. Subject to the terms and conditions of 79 | this License, each Contributor hereby grants to You a perpetual, 80 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 81 | (except as stated in this section) patent license to make, have made, 82 | use, offer to sell, sell, import, and otherwise transfer the Work, 83 | where such license applies only to those patent claims licensable 84 | by such Contributor that are necessarily infringed by their 85 | Contribution(s) alone or by combination of their Contribution(s) 86 | with the Work to which such Contribution(s) was submitted. If You 87 | institute patent litigation against any entity (including a 88 | cross-claim or counterclaim in a lawsuit) alleging that the Work 89 | or a Contribution incorporated within the Work constitutes direct 90 | or contributory patent infringement, then any patent licenses 91 | granted to You under this License for that Work shall terminate 92 | as of the date such litigation is filed. 93 | 94 | 4. Redistribution. You may reproduce and distribute copies of the 95 | Work or Derivative Works thereof in any medium, with or without 96 | modifications, and in Source or Object form, provided that You 97 | meet the following conditions: 98 | 99 | (a) You must give any other recipients of the Work or 100 | Derivative Works a copy of this License; and 101 | 102 | (b) You must cause any modified files to carry prominent notices 103 | stating that You changed the files; and 104 | 105 | (c) You must retain, in the Source form of any Derivative Works 106 | that You distribute, all copyright, patent, trademark, and 107 | attribution notices from the Source form of the Work, 108 | excluding those notices that do not pertain to any part of 109 | the Derivative Works; and 110 | 111 | (d) If the Work includes a "NOTICE" text file as part of its 112 | distribution, then any Derivative Works that You distribute must 113 | include a readable copy of the attribution notices contained 114 | within such NOTICE file, excluding those notices that do not 115 | pertain to any part of the Derivative Works, in at least one 116 | of the following places: within a NOTICE text file distributed 117 | as part of the Derivative Works; within the Source form or 118 | documentation, if provided along with the Derivative Works; or, 119 | within a display generated by the Derivative Works, if and 120 | wherever such third-party notices normally appear. The contents 121 | of the NOTICE file are for informational purposes only and 122 | do not modify the License. You may add Your own attribution 123 | notices within Derivative Works that You distribute, alongside 124 | or as an addendum to the NOTICE text from the Work, provided 125 | that such additional attribution notices cannot be construed 126 | as modifying the License. 127 | 128 | You may add Your own copyright statement to Your modifications and 129 | may provide additional or different license terms and conditions 130 | for use, reproduction, or distribution of Your modifications, or 131 | for any such Derivative Works as a whole, provided Your use, 132 | reproduction, and distribution of the Work otherwise complies with 133 | the conditions stated in this License. 134 | 135 | 5. Submission of Contributions. Unless You explicitly state otherwise, 136 | any Contribution intentionally submitted for inclusion in the Work 137 | by You to the Licensor shall be under the terms and conditions of 138 | this License, without any additional terms or conditions. 139 | Notwithstanding the above, nothing herein shall supersede or modify 140 | the terms of any separate license agreement you may have executed 141 | with Licensor regarding such Contributions. 142 | 143 | 6. Trademarks. This License does not grant permission to use the trade 144 | names, trademarks, service marks, or product names of the Licensor, 145 | except as required for reasonable and customary use in describing the 146 | origin of the Work and reproducing the content of the NOTICE file. 147 | 148 | 7. Disclaimer of Warranty. Unless required by applicable law or 149 | agreed to in writing, Licensor provides the Work (and each 150 | Contributor provides its Contributions) on an "AS IS" BASIS, 151 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 152 | implied, including, without limitation, any warranties or conditions 153 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 154 | PARTICULAR PURPOSE. You are solely responsible for determining the 155 | appropriateness of using or redistributing the Work and assume any 156 | risks associated with Your exercise of permissions under this License. 157 | 158 | 8. Limitation of Liability. In no event and under no legal theory, 159 | whether in tort (including negligence), contract, or otherwise, 160 | unless required by applicable law (such as deliberate and grossly 161 | negligent acts) or agreed to in writing, shall any Contributor be 162 | liable to You for damages, including any direct, indirect, special, 163 | incidental, or consequential damages of any character arising as a 164 | result of this License or out of the use or inability to use the 165 | Work (including but not limited to damages for loss of goodwill, 166 | work stoppage, computer failure or malfunction, or any and all 167 | other commercial damages or losses), even if such Contributor 168 | has been advised of the possibility of such damages. 169 | 170 | 9. Accepting Warranty or Additional Liability. While redistributing 171 | the Work or Derivative Works thereof, You may choose to offer, 172 | and charge a fee for, acceptance of support, warranty, indemnity, 173 | or other liability obligations and/or rights consistent with this 174 | License. However, in accepting such obligations, You may act only 175 | on Your own behalf and on Your sole responsibility, not on behalf 176 | of any other Contributor, and only if You agree to indemnify, 177 | defend, and hold each Contributor harmless for any liability 178 | incurred by, or claims asserted against, such Contributor by reason 179 | of your accepting any such warranty or additional liability. 180 | 181 | END OF TERMS AND CONDITIONS 182 | 183 | APPENDIX: How to apply the Apache License to your work. 184 | 185 | To apply the Apache License to your work, attach the following 186 | boilerplate notice, with the fields enclosed by brackets "{}" 187 | replaced with your own identifying information. (Don't include 188 | the brackets!) The text should be enclosed in the appropriate 189 | comment syntax for the file format. We also recommend that a 190 | file or class name and description of purpose be included on the 191 | same "printed page" as the copyright notice for easier 192 | identification within third-party archives. 193 | 194 | Copyright {yyyy} {name of copyright owner} 195 | 196 | Licensed under the Apache License, Version 2.0 (the "License"); 197 | you may not use this file except in compliance with the License. 198 | You may obtain a copy of the License at 199 | 200 | http://www.apache.org/licenses/LICENSE-2.0 201 | 202 | Unless required by applicable law or agreed to in writing, software 203 | distributed under the License is distributed on an "AS IS" BASIS, 204 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 205 | See the License for the specific language governing permissions and 206 | limitations under the License. 207 | 208 | 209 | Generated by CocoaPods - https://cocoapods.org 210 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo-acknowledgements.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreferenceSpecifiers 6 | 7 | 8 | FooterText 9 | This application makes use of the following third party libraries: 10 | Title 11 | Acknowledgements 12 | Type 13 | PSGroupSpecifier 14 | 15 | 16 | FooterText 17 | Apache License 18 | Version 2.0, January 2004 19 | http://www.apache.org/licenses/ 20 | 21 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 22 | 23 | 1. Definitions. 24 | 25 | "License" shall mean the terms and conditions for use, reproduction, 26 | and distribution as defined by Sections 1 through 9 of this document. 27 | 28 | "Licensor" shall mean the copyright owner or entity authorized by 29 | the copyright owner that is granting the License. 30 | 31 | "Legal Entity" shall mean the union of the acting entity and all 32 | other entities that control, are controlled by, or are under common 33 | control with that entity. For the purposes of this definition, 34 | "control" means (i) the power, direct or indirect, to cause the 35 | direction or management of such entity, whether by contract or 36 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 37 | outstanding shares, or (iii) beneficial ownership of such entity. 38 | 39 | "You" (or "Your") shall mean an individual or Legal Entity 40 | exercising permissions granted by this License. 41 | 42 | "Source" form shall mean the preferred form for making modifications, 43 | including but not limited to software source code, documentation 44 | source, and configuration files. 45 | 46 | "Object" form shall mean any form resulting from mechanical 47 | transformation or translation of a Source form, including but 48 | not limited to compiled object code, generated documentation, 49 | and conversions to other media types. 50 | 51 | "Work" shall mean the work of authorship, whether in Source or 52 | Object form, made available under the License, as indicated by a 53 | copyright notice that is included in or attached to the work 54 | (an example is provided in the Appendix below). 55 | 56 | "Derivative Works" shall mean any work, whether in Source or Object 57 | form, that is based on (or derived from) the Work and for which the 58 | editorial revisions, annotations, elaborations, or other modifications 59 | represent, as a whole, an original work of authorship. For the purposes 60 | of this License, Derivative Works shall not include works that remain 61 | separable from, or merely link (or bind by name) to the interfaces of, 62 | the Work and Derivative Works thereof. 63 | 64 | "Contribution" shall mean any work of authorship, including 65 | the original version of the Work and any modifications or additions 66 | to that Work or Derivative Works thereof, that is intentionally 67 | submitted to Licensor for inclusion in the Work by the copyright owner 68 | or by an individual or Legal Entity authorized to submit on behalf of 69 | the copyright owner. For the purposes of this definition, "submitted" 70 | means any form of electronic, verbal, or written communication sent 71 | to the Licensor or its representatives, including but not limited to 72 | communication on electronic mailing lists, source code control systems, 73 | and issue tracking systems that are managed by, or on behalf of, the 74 | Licensor for the purpose of discussing and improving the Work, but 75 | excluding communication that is conspicuously marked or otherwise 76 | designated in writing by the copyright owner as "Not a Contribution." 77 | 78 | "Contributor" shall mean Licensor and any individual or Legal Entity 79 | on behalf of whom a Contribution has been received by Licensor and 80 | subsequently incorporated within the Work. 81 | 82 | 2. Grant of Copyright License. Subject to the terms and conditions of 83 | this License, each Contributor hereby grants to You a perpetual, 84 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 85 | copyright license to reproduce, prepare Derivative Works of, 86 | publicly display, publicly perform, sublicense, and distribute the 87 | Work and such Derivative Works in Source or Object form. 88 | 89 | 3. Grant of Patent License. Subject to the terms and conditions of 90 | this License, each Contributor hereby grants to You a perpetual, 91 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 92 | (except as stated in this section) patent license to make, have made, 93 | use, offer to sell, sell, import, and otherwise transfer the Work, 94 | where such license applies only to those patent claims licensable 95 | by such Contributor that are necessarily infringed by their 96 | Contribution(s) alone or by combination of their Contribution(s) 97 | with the Work to which such Contribution(s) was submitted. If You 98 | institute patent litigation against any entity (including a 99 | cross-claim or counterclaim in a lawsuit) alleging that the Work 100 | or a Contribution incorporated within the Work constitutes direct 101 | or contributory patent infringement, then any patent licenses 102 | granted to You under this License for that Work shall terminate 103 | as of the date such litigation is filed. 104 | 105 | 4. Redistribution. You may reproduce and distribute copies of the 106 | Work or Derivative Works thereof in any medium, with or without 107 | modifications, and in Source or Object form, provided that You 108 | meet the following conditions: 109 | 110 | (a) You must give any other recipients of the Work or 111 | Derivative Works a copy of this License; and 112 | 113 | (b) You must cause any modified files to carry prominent notices 114 | stating that You changed the files; and 115 | 116 | (c) You must retain, in the Source form of any Derivative Works 117 | that You distribute, all copyright, patent, trademark, and 118 | attribution notices from the Source form of the Work, 119 | excluding those notices that do not pertain to any part of 120 | the Derivative Works; and 121 | 122 | (d) If the Work includes a "NOTICE" text file as part of its 123 | distribution, then any Derivative Works that You distribute must 124 | include a readable copy of the attribution notices contained 125 | within such NOTICE file, excluding those notices that do not 126 | pertain to any part of the Derivative Works, in at least one 127 | of the following places: within a NOTICE text file distributed 128 | as part of the Derivative Works; within the Source form or 129 | documentation, if provided along with the Derivative Works; or, 130 | within a display generated by the Derivative Works, if and 131 | wherever such third-party notices normally appear. The contents 132 | of the NOTICE file are for informational purposes only and 133 | do not modify the License. You may add Your own attribution 134 | notices within Derivative Works that You distribute, alongside 135 | or as an addendum to the NOTICE text from the Work, provided 136 | that such additional attribution notices cannot be construed 137 | as modifying the License. 138 | 139 | You may add Your own copyright statement to Your modifications and 140 | may provide additional or different license terms and conditions 141 | for use, reproduction, or distribution of Your modifications, or 142 | for any such Derivative Works as a whole, provided Your use, 143 | reproduction, and distribution of the Work otherwise complies with 144 | the conditions stated in this License. 145 | 146 | 5. Submission of Contributions. Unless You explicitly state otherwise, 147 | any Contribution intentionally submitted for inclusion in the Work 148 | by You to the Licensor shall be under the terms and conditions of 149 | this License, without any additional terms or conditions. 150 | Notwithstanding the above, nothing herein shall supersede or modify 151 | the terms of any separate license agreement you may have executed 152 | with Licensor regarding such Contributions. 153 | 154 | 6. Trademarks. This License does not grant permission to use the trade 155 | names, trademarks, service marks, or product names of the Licensor, 156 | except as required for reasonable and customary use in describing the 157 | origin of the Work and reproducing the content of the NOTICE file. 158 | 159 | 7. Disclaimer of Warranty. Unless required by applicable law or 160 | agreed to in writing, Licensor provides the Work (and each 161 | Contributor provides its Contributions) on an "AS IS" BASIS, 162 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 163 | implied, including, without limitation, any warranties or conditions 164 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 165 | PARTICULAR PURPOSE. You are solely responsible for determining the 166 | appropriateness of using or redistributing the Work and assume any 167 | risks associated with Your exercise of permissions under this License. 168 | 169 | 8. Limitation of Liability. In no event and under no legal theory, 170 | whether in tort (including negligence), contract, or otherwise, 171 | unless required by applicable law (such as deliberate and grossly 172 | negligent acts) or agreed to in writing, shall any Contributor be 173 | liable to You for damages, including any direct, indirect, special, 174 | incidental, or consequential damages of any character arising as a 175 | result of this License or out of the use or inability to use the 176 | Work (including but not limited to damages for loss of goodwill, 177 | work stoppage, computer failure or malfunction, or any and all 178 | other commercial damages or losses), even if such Contributor 179 | has been advised of the possibility of such damages. 180 | 181 | 9. Accepting Warranty or Additional Liability. While redistributing 182 | the Work or Derivative Works thereof, You may choose to offer, 183 | and charge a fee for, acceptance of support, warranty, indemnity, 184 | or other liability obligations and/or rights consistent with this 185 | License. However, in accepting such obligations, You may act only 186 | on Your own behalf and on Your sole responsibility, not on behalf 187 | of any other Contributor, and only if You agree to indemnify, 188 | defend, and hold each Contributor harmless for any liability 189 | incurred by, or claims asserted against, such Contributor by reason 190 | of your accepting any such warranty or additional liability. 191 | 192 | END OF TERMS AND CONDITIONS 193 | 194 | APPENDIX: How to apply the Apache License to your work. 195 | 196 | To apply the Apache License to your work, attach the following 197 | boilerplate notice, with the fields enclosed by brackets "{}" 198 | replaced with your own identifying information. (Don't include 199 | the brackets!) The text should be enclosed in the appropriate 200 | comment syntax for the file format. We also recommend that a 201 | file or class name and description of purpose be included on the 202 | same "printed page" as the copyright notice for easier 203 | identification within third-party archives. 204 | 205 | Copyright {yyyy} {name of copyright owner} 206 | 207 | Licensed under the Apache License, Version 2.0 (the "License"); 208 | you may not use this file except in compliance with the License. 209 | You may obtain a copy of the License at 210 | 211 | http://www.apache.org/licenses/LICENSE-2.0 212 | 213 | Unless required by applicable law or agreed to in writing, software 214 | distributed under the License is distributed on an "AS IS" BASIS, 215 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 216 | See the License for the specific language governing permissions and 217 | limitations under the License. 218 | 219 | 220 | License 221 | Apache License 222 | Title 223 | SCJSONUtil 224 | Type 225 | PSGroupSpecifier 226 | 227 | 228 | FooterText 229 | Generated by CocoaPods - https://cocoapods.org 230 | Title 231 | 232 | Type 233 | PSGroupSpecifier 234 | 235 | 236 | StringsTable 237 | Acknowledgements 238 | Title 239 | Acknowledgements 240 | 241 | 242 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_Pods_SCJSONUtilDemo : NSObject 3 | @end 4 | @implementation PodsDummy_Pods_SCJSONUtilDemo 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | 14 | FOUNDATION_EXPORT double Pods_SCJSONUtilDemoVersionNumber; 15 | FOUNDATION_EXPORT const unsigned char Pods_SCJSONUtilDemoVersionString[]; 16 | 17 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/Pods-SCJSONUtilDemo/Pods-SCJSONUtilDemo.modulemap: -------------------------------------------------------------------------------- 1 | framework module Pods_SCJSONUtilDemo { 2 | umbrella header "Pods-SCJSONUtilDemo-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil-Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | ${PODS_DEVELOPMENT_LANGUAGE} 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 | 2.5.6 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | ${CURRENT_PROJECT_VERSION} 23 | NSPrincipalClass 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil-dummy.m: -------------------------------------------------------------------------------- 1 | #import 2 | @interface PodsDummy_SCJSONUtil : NSObject 3 | @end 4 | @implementation PodsDummy_SCJSONUtil 5 | @end 6 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil-prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil-umbrella.h: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #else 4 | #ifndef FOUNDATION_EXPORT 5 | #if defined(__cplusplus) 6 | #define FOUNDATION_EXPORT extern "C" 7 | #else 8 | #define FOUNDATION_EXPORT extern 9 | #endif 10 | #endif 11 | #endif 12 | 13 | #import "SCJSONUtil.h" 14 | #import "SCModelUtil.h" 15 | 16 | FOUNDATION_EXPORT double SCJSONUtilVersionNumber; 17 | FOUNDATION_EXPORT const unsigned char SCJSONUtilVersionString[]; 18 | 19 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil.modulemap: -------------------------------------------------------------------------------- 1 | framework module SCJSONUtil { 2 | umbrella header "SCJSONUtil-umbrella.h" 3 | 4 | export * 5 | module * { export * } 6 | } 7 | -------------------------------------------------------------------------------- /Demo/Pods/Target Support Files/SCJSONUtil/SCJSONUtil.xcconfig: -------------------------------------------------------------------------------- 1 | CONFIGURATION_BUILD_DIR = ${PODS_CONFIGURATION_BUILD_DIR}/SCJSONUtil 2 | GCC_PREPROCESSOR_DEFINITIONS = $(inherited) COCOAPODS=1 3 | OTHER_LDFLAGS = $(inherited) -framework "Foundation" 4 | PODS_BUILD_DIR = ${BUILD_DIR} 5 | PODS_CONFIGURATION_BUILD_DIR = ${PODS_BUILD_DIR}/$(CONFIGURATION)$(EFFECTIVE_PLATFORM_NAME) 6 | PODS_ROOT = ${SRCROOT} 7 | PODS_TARGET_SRCROOT = ${PODS_ROOT}/../.. 8 | PRODUCT_BUNDLE_IDENTIFIER = org.cocoapods.${PRODUCT_NAME:rfc1034identifier} 9 | SKIP_INSTALL = YES 10 | USE_RECURSIVE_SCRIPT_INPUTS_IN_SCRIPT_PHASES = YES 11 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildSystemType 6 | Original 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata/crown.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debugly/SCJSONUtil/c1041eaf8c2924e9c3dd53a46b00d167b2fdab08/Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata/crown.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata/qianlongxu.xcuserdatad/UserInterfaceState.xcuserstate: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/debugly/SCJSONUtil/c1041eaf8c2924e9c3dd53a46b00d167b2fdab08/Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata/qianlongxu.xcuserdatad/UserInterfaceState.xcuserstate -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/project.xcworkspace/xcuserdata/qianlongxu.xcuserdatad/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | BuildLocationStyle 6 | UseAppPreferences 7 | CustomBuildLocationType 8 | RelativeToDerivedData 9 | DerivedDataLocationStyle 10 | Default 11 | EnabledFullIndexStoreVisibility 12 | 13 | IssueFilterStyle 14 | ShowActiveSchemeOnly 15 | LiveSourceIssuesEnabled 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/xcuserdata/crown.xcuserdatad/xcschemes/SCJSONUtilDemo.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/xcuserdata/crown.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SCJSONUtilDemo.xcscheme 8 | 9 | orderHint 10 | 0 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | C342B29A1F218554007F04FC 16 | 17 | primary 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/xcuserdata/matt.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SCJSONUtilDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 3 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/xcuserdata/qianlongxu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcodeproj/xcuserdata/qianlongxu.xcuserdatad/xcschemes/xcschememanagement.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | SchemeUserState 6 | 7 | SCJSONUtilDemo.xcscheme_^#shared#^_ 8 | 9 | orderHint 10 | 1 11 | 12 | 13 | SuppressBuildableAutocreation 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo.xcworkspace/xcuserdata/qianlongxu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 9 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/AppDelegate.h: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by xuqianlong on 2017/7/21. 6 | // Copyright © 2017年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AppDelegate : UIResponder 12 | 13 | @property (strong, nonatomic) UIWindow *window; 14 | 15 | 16 | @end 17 | 18 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/AppDelegate.m: -------------------------------------------------------------------------------- 1 | // 2 | // AppDelegate.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by xuqianlong on 2017/7/21. 6 | // Copyright © 2017年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "AppDelegate.h" 10 | 11 | @interface AppDelegate () 12 | 13 | @end 14 | 15 | @implementation AppDelegate 16 | 17 | 18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 19 | // Override point for customization after application launch. 20 | return YES; 21 | } 22 | 23 | 24 | - (void)applicationWillResignActive:(UIApplication *)application { 25 | // 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. 26 | // Use this method to pause ongoing tasks, disable timers, and invalidate graphics rendering callbacks. Games should use this method to pause the game. 27 | } 28 | 29 | 30 | - (void)applicationDidEnterBackground:(UIApplication *)application { 31 | // 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. 32 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits. 33 | } 34 | 35 | 36 | - (void)applicationWillEnterForeground:(UIApplication *)application { 37 | // 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. 38 | } 39 | 40 | 41 | - (void)applicationDidBecomeActive:(UIApplication *)application { 42 | // 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. 43 | } 44 | 45 | 46 | - (void)applicationWillTerminate:(UIApplication *)application { 47 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:. 48 | } 49 | 50 | 51 | @end 52 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "scale" : "2x", 6 | "size" : "20x20" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "scale" : "3x", 11 | "size" : "20x20" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "scale" : "2x", 16 | "size" : "29x29" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "scale" : "3x", 21 | "size" : "29x29" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "scale" : "2x", 26 | "size" : "40x40" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "scale" : "3x", 31 | "size" : "40x40" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "scale" : "2x", 36 | "size" : "60x60" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "scale" : "3x", 41 | "size" : "60x60" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "scale" : "1x", 46 | "size" : "20x20" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "scale" : "2x", 51 | "size" : "20x20" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "scale" : "1x", 56 | "size" : "29x29" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "scale" : "2x", 61 | "size" : "29x29" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "scale" : "1x", 66 | "size" : "40x40" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "scale" : "2x", 71 | "size" : "40x40" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "scale" : "1x", 76 | "size" : "76x76" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "scale" : "2x", 81 | "size" : "76x76" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "scale" : "2x", 86 | "size" : "83.5x83.5" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "scale" : "1x", 91 | "size" : "1024x1024" 92 | } 93 | ], 94 | "info" : { 95 | "author" : "xcode", 96 | "version" : 1 97 | } 98 | } 99 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/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 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/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 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/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 | UIRequiresFullScreen 32 | 33 | UIStatusBarHidden~ipad 34 | 35 | UISupportedInterfaceOrientations 36 | 37 | UIInterfaceOrientationLandscapeLeft 38 | UIInterfaceOrientationLandscapeRight 39 | 40 | UISupportedInterfaceOrientations~ipad 41 | 42 | UIInterfaceOrientationLandscapeRight 43 | UIInterfaceOrientationLandscapeLeft 44 | UIInterfaceOrientationPortrait 45 | UIInterfaceOrientationPortraitUpsideDown 46 | 47 | 48 | 49 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/Test.h: -------------------------------------------------------------------------------- 1 | // 2 | // Test.h 3 | // JSONUtilDemo 4 | // 5 | // Created by Reach Matt on 2025/4/1. 6 | // 7 | 8 | #import 9 | 10 | @interface Test : NSObject 11 | 12 | + (NSString *)testAll; 13 | + (void)printTypeEncodings; 14 | + (NSString *)testOCTypes; 15 | + (NSString *)testKeyPathFromDictionary; 16 | + (NSString *)testModelFromDictionary; 17 | + (NSString *)testModelsFromJSONArr; 18 | + (NSString *)testKeyPath; 19 | + (NSString *)testDynamicConvertFromDictionary; 20 | + (NSString *)testCustomConvertFromDictionary; 21 | + (void)testPerformance; 22 | 23 | @end 24 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/Test.m: -------------------------------------------------------------------------------- 1 | // 2 | // Test.h 3 | // JSONUtilDemo 4 | // 5 | // Created by Reach Matt on 2025/4/1. 6 | // 7 | 8 | #import "Test.h" 9 | #import "Util.h" 10 | #import "UserInfoModel.h" 11 | #import "FavModel.h" 12 | #import "OCTypes.h" 13 | #import "Car.h" 14 | #import "DynamicVideos.h" 15 | #import "VideoInfo.h" 16 | #import "StoreModel.h" 17 | #import 18 | #import 19 | 20 | @implementation NSObject (print) 21 | 22 | - (NSString *)sc_calssName 23 | { 24 | NSString *clazz = NSStringFromClass([self class]); 25 | if ([clazz hasPrefix:@"__"]) { 26 | clazz = NSStringFromClass([self superclass]); 27 | } 28 | if ([clazz isEqualToString:@"NSTaggedPointerString"]) { 29 | clazz = NSStringFromClass([[self superclass]superclass]); 30 | } 31 | return clazz; 32 | } 33 | 34 | - (NSString *)sc_toJSONString:(BOOL)prettyPrinted 35 | { 36 | return [self sc_toJSONString:prettyPrinted printProperyType:NO]; 37 | } 38 | 39 | - (NSString *)sc_toJSONString:(BOOL)prettyPrinted printProperyType:(BOOL)printProperyType 40 | { 41 | NSDictionary *dic = [self sc_toJSONWithProperyType:printProperyType]; 42 | NSString *jsonStr = JSON2String(dic, prettyPrinted); 43 | return [NSString stringWithFormat:@"%@* %p:\n%@",[self sc_calssName],self,jsonStr]; 44 | } 45 | 46 | @end 47 | 48 | @implementation Test 49 | 50 | + (NSString *)testAll 51 | { 52 | SCJSONUtilLog(YES); 53 | 54 | NSString *result = [NSString stringWithFormat:@"\n=======日志开关=======\n%d\n\n",isSCJSONUtilLogOn()]; 55 | 56 | result = [result stringByAppendingString:@"\n=======Objc 基础数据类型解析=======\n\n"]; 57 | 58 | result = [result stringByAppendingString:[self testOCTypes]]; 59 | 60 | result = [result stringByAppendingString:@"\n\n=======通过keypath查找简化解析=======\n\n"]; 61 | 62 | result = [result stringByAppendingString:[self testKeyPathFromDictionary]]; 63 | 64 | result = [result stringByAppendingString:@"\n\n=======json数组转model数组============\n\n"]; 65 | 66 | result = [result stringByAppendingString:[self testModelsFromJSONArr]]; 67 | 68 | result = [result stringByAppendingString:@"\n\n=========指定解析的路径,找到指定 json;==========\n\n"]; 69 | 70 | result = [result stringByAppendingString:[self testKeyPath]]; 71 | 72 | result = [result stringByAppendingString:@"\n\n=========多层嵌套字典转嵌套model==========\n\n"]; 73 | 74 | result = [result stringByAppendingString:[self testModelFromDictionary]]; 75 | 76 | result = [result stringByAppendingString:@"\n\n=========动态参照解析==========\n\n"]; 77 | 78 | result = [result stringByAppendingString:[self testDynamicConvertFromDictionary]]; 79 | 80 | result = [result stringByAppendingString:@"\n\n=========自定义解析==========\n\n"]; 81 | 82 | result = [result stringByAppendingString:[self testCustomConvertFromDictionary]]; 83 | 84 | result = [result stringByAppendingString:@"\n\n===================\n"]; 85 | 86 | return result; 87 | } 88 | 89 | + (NSString *)testOCTypes 90 | { 91 | SCJSONUtilLog(YES); 92 | 93 | NSDictionary *typesDic = [Util readOCTypes]; 94 | OCTypes *model = [OCTypes sc_instanceFormDic:typesDic]; 95 | //美化打印 96 | return [model sc_toJSONString:YES]; 97 | } 98 | 99 | + (NSString *)testKeyPathFromDictionary 100 | { 101 | SCJSONUtilLog(YES); 102 | 103 | NSDictionary *json = [Util readStore]; 104 | StoreModel *store = SCJSON2Model(json, @"StoreModel"); 105 | //美化打印,并且json的key值里包含定义属性的类型 106 | return [store sc_toJSONString:YES printProperyType:YES]; 107 | } 108 | 109 | + (void)testCount:(long)count work:(dispatch_block_t)block 110 | { 111 | if (!block) { 112 | return; 113 | } 114 | CFAbsoluteTime begin = CFAbsoluteTimeGetCurrent(); 115 | for (int i = 0; i 10 | 11 | @interface ViewController : UIViewController 12 | 13 | 14 | @end 15 | 16 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/ViewController.m: -------------------------------------------------------------------------------- 1 | // 2 | // ViewController.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by xuqianlong on 2017/7/21. 6 | // Copyright © 2017年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "ViewController.h" 10 | #import "Test.h" 11 | 12 | @interface ViewController () 13 | 14 | @property (weak, nonatomic) IBOutlet UITextView *txv; 15 | 16 | @end 17 | 18 | @implementation ViewController 19 | 20 | - (void)viewDidLoad { 21 | [super viewDidLoad]; 22 | 23 | [Test testPerformance]; 24 | [Test printTypeEncodings]; 25 | 26 | self.txv.text = [Test testAll]; 27 | // self.txv.text = [Test testOCTypes]; 28 | // self.txv.text = [Test testKeyPathFromDictionary]; 29 | // self.txv.text = [Test testModelFromDictionary]; 30 | // self.txv.text = [Test testModelsFromJSONArr]; 31 | // self.txv.text = [Test testKeyPath]; 32 | // self.txv.text = [Test testDynamicConvertFromDictionary]; 33 | // self.txv.text = [Test testCustomConvertFromDictionary]; 34 | } 35 | 36 | @end 37 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/Car.json: -------------------------------------------------------------------------------- 1 | { 2 | "b":true, 3 | "b1":-1, 4 | "b2":"1", 5 | "pStorng": 6 | { 7 | "refContent":3333333, 8 | "nameEN":"TopShop", 9 | "nameCN":"TopShop", 10 | "desc":"描述摘要", 11 | "pic": "http://pic14.shangpin.com/e/s/15/04/01/20150401185027193594-10-10.jpg" 12 | }, 13 | "pWeak" :123 14 | } 15 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/DynamicVideos.json: -------------------------------------------------------------------------------- 1 | { 2 | "playlistid": 5828854, 3 | "area": "内地", 4 | "activity": { 5 | "on": 1 6 | }, 7 | "array": ["abc"], 8 | "wp": [ 9 | { 10 | "v": "上错车暧昧偶遇,为美人抛弃兄弟", 11 | "k": "102" 12 | }, 13 | { 14 | "v": "试镜失败再失恋,祸不单行患血癌", 15 | "k": "591" 16 | }, 17 | { 18 | "v": "想方设法欲接近,撒娇求助屡碰壁", 19 | "k": "1288" 20 | }, 21 | { 22 | "v": "泳池装死险亲吻,突然求婚做交换", 23 | "k": "1791" 24 | } 25 | ], 26 | "qq": { 27 | "size": 48, 28 | "videos": [ 29 | { 30 | "no": 1, 31 | "uid": 454463456, 32 | "showName": "第1集", 33 | "swfurl": 454463456, 34 | "domain": "qq.com", 35 | "rUrl": "http://v.qq.com/x/page/b0029rfy05v.html?ptag=hu.tv", 36 | "rSwfurl": "http://imgcache.qq.com/tencentvideo_v1/player/TencentPlayer.swf?vid=b0029rfy05v&autoplay=0&list=2&showcfg=1&tpid=1&cid=3p2fnoopmegcajh", 37 | "rid": 5828854, 38 | "title": "大江大河[TV版]_01", 39 | "type": 0, 40 | "url": "http://v.qq.com/x/page/b0029rfy05v.html?ptag=hu.tv" 41 | }, 42 | { 43 | "no": 2, 44 | "uid": 454463457, 45 | "showName": "第2集", 46 | "swfurl": 454463457, 47 | "domain": "qq.com", 48 | "rUrl": "http://v.qq.com/x/page/q0029dl5gs3.html?ptag=hu.tv", 49 | "rSwfurl": "http://imgcache.qq.com/tencentvideo_v1/player/TencentPlayer.swf?vid=q0029dl5gs3&autoplay=0&list=2&showcfg=1&tpid=1&cid=3p2fnoopmegcajh", 50 | "rid": 5828854, 51 | "title": "大江大河[TV版]_02", 52 | "type": 0, 53 | "url": "http://v.qq.com/x/page/q0029dl5gs3.html?ptag=hu.tv" 54 | } 55 | ] 56 | }, 57 | "albumName": "大江大河", 58 | "types": [ 59 | "剧情片" 60 | ], 61 | "author": "", 62 | "smallVerPicUrl": "http://img.tv.itc.cn/soimg/test/default.png", 63 | "directors": [ 64 | "孔笙", 65 | "黄伟" 66 | ], 67 | "updateTime": 1547618953594, 68 | "iqiyi": { 69 | "size": 2, 70 | "videos": [ 71 | { 72 | "no": 1, 73 | "uid": 454463474, 74 | "showName": "第1集", 75 | "swfurl": 454463474, 76 | "domain": "iqiyi.com", 77 | "rUrl": "http://www.iqiyi.com/v_19rqs0we9s.html?vfm=m_312_shsp", 78 | "rid": 5828854, 79 | "title": "大江大河第1集", 80 | "type": 2, 81 | "url": "http://www.iqiyi.com/v_19rqs0we9s.html?vfm=m_312_shsp" 82 | }, 83 | { 84 | "no": 2, 85 | "uid": 454463473, 86 | "showName": "第2集", 87 | "swfurl": 454463473, 88 | "domain": "iqiyi.com", 89 | "rUrl": "http://www.iqiyi.com/v_19rqs0wim0.html?vfm=m_312_shsp", 90 | "rid": 5828854, 91 | "title": "大江大河第2集", 92 | "type": 2, 93 | "url": "http://www.iqiyi.com/v_19rqs0wim0.html?vfm=m_312_shsp" 94 | } 95 | ] 96 | }, 97 | "albumDesc": "宋运辉(王凯饰)天资聪颖,却出身不好,一直倍受歧视,但是他把握住了1978年恢复高考的机会,抓住机遇,勤学苦干,当上了国企的技术人员,一步步晋升,奠定了成功人生的基础,但也在新时代的变革中逐渐迷失。与宋运辉不同的是他的姐夫雷东宝(杨烁 饰)。他出身贫寒、属于苗正根红的“大老粗”,行动力十足。在乡村改革的浪潮中带领村民紧跟政策,一直走在时代的前沿。但由于自身文化水平不高,眼界不够开阔,最终绊倒在新事物脚下。如果说宋运辉和雷东宝的经历是国营经济和集体经济的缩影。那么个体户杨巡(董子健 饰)无疑就是个体经济的典型代表,在翻滚向前的时代中,他手忙脚乱抓住过商机,也踩踏过陷阱,生意场上几经波折,最终拥有了自己的产业,成为了那个时代个体经济的典型代表。", 98 | "categories": [ 99 | "电视剧" 100 | ], 101 | "showAlbumName": "大江大河(48集全)" 102 | } 103 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/FavConcern.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "refContent": "111111111", 4 | "nameEN": "TopShopEN1", 5 | "nameCN": "TopShopCN1", 6 | "desc": "描述摘要1", 7 | "pic": "http://pic.shangpin.com/1.jpg" 8 | },{ 9 | "refContent": "222222222", 10 | "nameEN": "TopShopEN2", 11 | "nameCN": "TopShopCN2", 12 | "desc": "描述摘要2", 13 | "pic": "http://pic.shangpin.com/2.jpg" 14 | },{ 15 | "refContent": "333333333", 16 | "nameEN": "TopShopEN3", 17 | "nameCN": "TopShopCN3", 18 | "desc": "描述摘要3", 19 | "pic": "http://pic.shangpin.com/3.jpg" 20 | },{ 21 | "refContent": "444444444", 22 | "nameEN": "TopShopEN4", 23 | "nameCN": "TopShopCN4", 24 | "desc": "描述摘要4", 25 | "pic": "http://pic.shangpin.com/4.jpg" 26 | },{ 27 | "refContent": "555555555", 28 | "nameEN": "TopShopEN5", 29 | "nameCN": "TopShopCN5", 30 | "desc": "描述摘要5", 31 | "pic": "http://pic.shangpin.com/5.jpg" 32 | },{ 33 | "refContent": "666666666", 34 | "nameEN": "TopShopEN6", 35 | "nameCN": "TopShopCN6", 36 | "desc": "描述摘要6", 37 | "pic": "http://pic.shangpin.com/6.jpg" 38 | } 39 | ] 40 | 41 | 42 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/GalleryList.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": "0", 3 | "content": { 4 | "gallery": [ 5 | { 6 | "isFlagship": "0", 7 | "name": "白色情人节 与浪漫牵手", 8 | "pic": "http://pic16.shangpin.com/e/s/15/03/06/20150306174649601525-10-10.jpg", 9 | "refContent": "http://m.shangpin.com/meet/189", 10 | "type": "1" 11 | }, 12 | { 13 | "isFlagship": "1", 14 | "name": "【早春新品预售】", 15 | "pic": "http://pic11.shangpin.com/e/s/15/03/13/20150313101837452024-10-10.jpg", 16 | "refContent": "50310992", 17 | "type": "2" 18 | }, 19 | { 20 | "isFlagship": "0", 21 | "name": "【男装春季促销】", 22 | "pic": "http://pic12.shangpin.com/e/s/15/03/12/20150312092557150616-10-10.jpg", 23 | "refContent": "50310978", 24 | "type": "3" 25 | }, 26 | { 27 | "isFlagship": "1", 28 | "name": "【男装春季促销】", 29 | "pic": "http://pic12.shangpin.com/e/s/15/03/12/20150312092557150616-10-10.jpg", 30 | "refContent": "50310978", 31 | "type": "4" 32 | }, 33 | { 34 | "isFlagship": "0", 35 | "name": "【男装春季促销】", 36 | "pic": "http://pic12.shangpin.com/e/s/15/03/12/20150312092557150616-10-10.jpg", 37 | "refContent": "50310978", 38 | "type": "5" 39 | }, 40 | { 41 | "isFlagship": "1", 42 | "name": "【男装春季促销】", 43 | "pic": "http://pic12.shangpin.com/e/s/15/03/12/20150312092557150616-10-10.jpg", 44 | "refContent": "50310978", 45 | "type": "6" 46 | } 47 | ], 48 | "entrance": [ 49 | { 50 | "isFlagship": "0", 51 | "name": "时尚潮时尚", 52 | "pic": "http://pic12.shangpin.com/e/s/15/03/03/20150303151320537363-10-10.jpg", 53 | "refContent": "http://m.shangpin.com/meet/185", 54 | "type": "5" 55 | }, 56 | { 57 | "isFlagship": "0", 58 | "name": "优惠券留", 59 | "pic": "http://pic14.shangpin.com/e/s/15/03/05/20150305164615551722-10-10.jpg", 60 | "refContent": "50305792", 61 | "type": "1" 62 | }, 63 | { 64 | "isFlagship": "0", 65 | "name": "物流查", 66 | "pic": "http://pic15.shangpin.com/e/s/15/03/03/20150303155535618638-10-10.jpg", 67 | "refContent": "http://m.shangpin.com/meet/188", 68 | "type": "5" 69 | }, 70 | { 71 | "isFlagship": "0", 72 | "name": "入口", 73 | "pic": "http://pic14.shangpin.com/e/s/15/03/05/20150305164615551722-10-10.jpg", 74 | "refContent": "50305792", 75 | "type": "1" 76 | }, 77 | { 78 | "isFlagship": "0", 79 | "name": "礼品卡", 80 | "pic": "http://pic15.shangpin.com/e/s/15/03/03/20150303155535618638-10-10.jpg", 81 | "refContent": "http://m.shangpin.com/meet/188", 82 | "type": "5" 83 | }, 84 | { 85 | "name": "不错哦", 86 | "pic": "http://pic14.shangpin.com/e/s/15/03/05/20150305142326260964-10-10.jpg", 87 | "refContent": "50302515", 88 | "type": "1" 89 | }, 90 | { 91 | "name": "购物车", 92 | "pic": "http://pic12.shangpin.com/e/s/15/03/05/20150305143006228421-10-10.jpg", 93 | "refContent": "50215339", 94 | "type": "1" 95 | }, 96 | { 97 | "name": "列表页", 98 | "pic": "http://pic14.shangpin.com/e/s/15/03/05/20150305142326260964-10-10.jpg", 99 | "refContent": "50302515", 100 | "type": "1" 101 | } 102 | ], 103 | "releases": [ 104 | { 105 | "desc": "", 106 | "endTime": "1426554000000", 107 | "height": "720", 108 | "name": "【TOPSHOP 2000条牛仔裤补货到】", 109 | "pic": "http://pic12.shangpin.com/e/s/15/03/12/20150312132707142163-10-10.jpg", 110 | "refContent": "50311019", 111 | "startTag": "03.13", 112 | "startTime": "1426212600000", 113 | "type": "1", 114 | "width": "720" 115 | }, 116 | { 117 | "desc": "MO&CO.新品特惠", 118 | "endTime": "1426467600000", 119 | "height": "490", 120 | "name": "MO&CO.新品特惠", 121 | "pic": "http://pic14.shangpin.com/e/s/15/03/13/20150313095913400551-10-10.jpg", 122 | "refContent": "50306843", 123 | "startTag": "03.13", 124 | "startTime": "1426209300000", 125 | "type": "1", 126 | "width": "720" 127 | }, 128 | { 129 | "desc": "美式轻奢风", 130 | "endTime": "1426467600000", 131 | "height": "580", 132 | "name": "【新品预售 3月18日发货】", 133 | "pic": "http://pic11.shangpin.com/e/s/15/03/09/20150309145151259290-10-10.jpg", 134 | "refContent": "50309891", 135 | "startTag": "03.13", 136 | "startTime": "1426208400000", 137 | "type": "1", 138 | "width": "720" 139 | } 140 | ], 141 | "sale": [ 142 | { 143 | "list": [ 144 | { 145 | "desc": "新品网络独家首发", 146 | "endTime": "1426467600000", 147 | "height": "670", 148 | "name": "【STELLA LUNA新品网络首发】", 149 | "pic": "http://pic16.shangpin.com/e/s/15/03/06/20150306170847472468-10-10.jpg", 150 | "refContent": "50306871", 151 | "startTag": "09:00", 152 | "startTime": "1426208400000", 153 | "type": "1", 154 | "width": "720" 155 | }, 156 | { 157 | "desc": "意大利新品睡衣", 158 | "endTime": "1426813200000", 159 | "height": "550", 160 | "name": "意大利进口 新品睡衣", 161 | "pic": "http://pic16.shangpin.com/e/s/15/03/09/20150309105605840242-10-10.jpg", 162 | "refContent": "50302526", 163 | "startTag": "09:00", 164 | "startTime": "1426208400000", 165 | "type": "1", 166 | "width": "720" 167 | }, 168 | { 169 | "desc": "打底裤集合", 170 | "endTime": "1426467600000", 171 | "height": "350", 172 | "name": "打底裤集合", 173 | "pic": "http://pic14.shangpin.com/e/s/15/03/09/20150309153725584647-10-10.jpg", 174 | "refContent": "50303576", 175 | "startTag": "09:00", 176 | "startTime": "1426208400000", 177 | "type": "1", 178 | "width": "720" 179 | }, 180 | { 181 | "desc": "早春美饰上新", 182 | "endTime": "1426467600000", 183 | "height": "1050", 184 | "name": "炫彩水晶 低调华丽", 185 | "pic": "http://pic14.shangpin.com/e/s/15/03/10/20150310161702642930-10-10.jpg", 186 | "refContent": "50304615", 187 | "startTag": "09:00", 188 | "startTime": "1426208400000", 189 | "type": "1", 190 | "width": "720" 191 | }, 192 | { 193 | "desc": "阿玛尼新年特惠", 194 | "endTime": "1426467600000", 195 | "height": "50", 196 | "name": "【阿玛尼新年特惠】 ", 197 | "pic": "http://pic15.shangpin.com/e/s/15/03/12/20150312142428193691-10-10.jpg", 198 | "refContent": "50304727", 199 | "startTag": "09:00", 200 | "startTime": "1426208400000", 201 | "type": "1", 202 | "width": "720" 203 | }, 204 | { 205 | "desc": "", 206 | "endTime": "1428135660000", 207 | "height": "150", 208 | "name": "kate spade", 209 | "pic": "http://pic15.shangpin.com/e/s/15/03/12/20150312162128286598-10-10.jpg", 210 | "refContent": "50312101", 211 | "startTag": "09:00", 212 | "startTime": "1426208400000", 213 | "type": "1", 214 | "width": "720" 215 | } 216 | ], 217 | "title": "今日特卖 DAILY EVENTS", 218 | "type": "1" 219 | }, 220 | { 221 | "list": [ 222 | { 223 | "desc": "波西米亚风女装", 224 | "endTime": "1426485600000", 225 | "height": "250", 226 | "name": "波西米亚风女装", 227 | "pic": "http://pic14.shangpin.com/e/s/15/03/09/20150309153809514337-10-10.jpg", 228 | "refContent": "50304587", 229 | "startTag": "14:00", 230 | "startTime": "1426226400000", 231 | "type": "1", 232 | "width": "720" 233 | }, 234 | { 235 | "desc": "高级彩宝专场", 236 | "endTime": "1426485600000", 237 | "height": "850", 238 | "name": "时尚彩宝 高贵专属", 239 | "pic": "http://pic11.shangpin.com/e/s/15/03/10/20150310162008391046-10-10.jpg", 240 | "refContent": "50304625", 241 | "startTag": "14:00", 242 | "startTime": "1426226400000", 243 | "type": "1", 244 | "width": "720" 245 | }, 246 | { 247 | "desc": "", 248 | "endTime": "1428135780000", 249 | "height": "650", 250 | "name": "saint laurent", 251 | "pic": "http://pic11.shangpin.com/e/s/15/03/12/20150312162313055123-10-10.jpg", 252 | "refContent": "50312103", 253 | "startTag": "14:00", 254 | "startTime": "1426226400000", 255 | "type": "1", 256 | "width": "720" 257 | } 258 | ], 259 | "title": "即将开始 (每日14:00开启)", 260 | "type": "2" 261 | } 262 | ], 263 | "sysTime": "1426226372902", 264 | "themes": [ 265 | { 266 | "height": "550", 267 | "name": "Salvatore Ferragamo", 268 | "pic": "http://pic14.shangpin.com/e/s/15/03/09/20150309113148373426-10-10.jpg", 269 | "refContent": "50305771", 270 | "type": "1", 271 | "width": "720" 272 | }, 273 | { 274 | "height": "450", 275 | "name": "【早春新品预售】", 276 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 277 | "refContent": "50310992", 278 | "type": "1", 279 | "width": "720" 280 | }, 281 | { 282 | "height": "800", 283 | "name": "【TOPSHOP 上班女郎穿衣术】", 284 | "pic": "http://pic11.shangpin.com/e/s/15/03/12/20150312170612069350-10-10.jpg", 285 | "refContent": "50303556", 286 | "type": "1", 287 | "width": "720" 288 | } 289 | ], 290 | "brand": [ 291 | { 292 | "refContent": "111111111", 293 | "nameEN": "TopShop", 294 | "nameCN": "TopShop", 295 | "desc": "描述摘要", 296 | "pic": "http://pic16.shangpin.com/e/s/15/02/15/20150215155540295340-10-10.jpg", 297 | "type": "3", 298 | "refContent": "" 299 | },{ 300 | "refContent": "2222222", 301 | "nameEN": "TopShop", 302 | "nameCN": "TopShop", 303 | "desc": "描述摘要", 304 | "pic": "http://pic12.shangpin.com/e/s/15/02/15/20150215154810871864-10-10.jpg", 305 | "type": "3", 306 | "refContent": "" 307 | },{ 308 | "refContent": "3333333", 309 | "nameEN": "TopShop", 310 | "nameCN": "TopShop", 311 | "desc": "描述摘要", 312 | "pic": "http://pic14.shangpin.com/e/s/15/04/01/20150401185027193594-10-10.jpg", 313 | "type": "3", 314 | "refContent": "" 315 | },{ 316 | "refContent": "4444444", 317 | "nameEN": "TopShop", 318 | "nameCN": "TopShop", 319 | "desc": "描述摘要", 320 | "pic": "http://pic11.shangpin.com/e/s/15/02/15/20150215150055287171-10-10.jpg", 321 | "type": "3", 322 | "refContent": "" 323 | },{ 324 | "refContent": "5555555", 325 | "nameEN": "TopShop", 326 | "nameCN": "TopShop", 327 | "desc": "描述摘要", 328 | "pic": "http://pic14.shangpin.com/e/s/15/02/15/20150215155043347252-10-10.jpg", 329 | "type": "3", 330 | "refContent": "" 331 | },{ 332 | "refContent": "6666666", 333 | "nameEN": "TopShop", 334 | "nameCN": "TopShop", 335 | "desc": "描述摘要", 336 | "pic": "http://pic12.shangpin.com/e/s/15/02/15/20150215150258387585-10-10.jpg", 337 | "type": "3", 338 | "refContent": "" 339 | },{ 340 | "refContent": "7777777", 341 | "nameEN": "TopShop", 342 | "nameCN": "TopShop", 343 | "desc": "描述摘要", 344 | "pic": "http://pic13.shangpin.com/e/s/15/02/15/20150215155140474254-10-10.jpg", 345 | "type": "3", 346 | "refContent": "" 347 | },{ 348 | "refContent": "8888888", 349 | "nameEN": "TopShop", 350 | "nameCN": "TopShop", 351 | "desc": "描述摘要", 352 | "pic": "http://pic14.shangpin.com/e/s/15/02/15/20150215154845410359-10-10.jpg", 353 | "type": "3", 354 | "refContent": "" 355 | },{ 356 | "refContent": "9999999", 357 | "nameEN": "TopShop", 358 | "nameCN": "TopShop", 359 | "desc": "描述摘要", 360 | "pic": "http://pic16.shangpin.com/e/s/15/02/15/20150215151504769908-10-10.jpg", 361 | "type": "3", 362 | "refContent": "" 363 | },{ 364 | "refContent": "1000000", 365 | "nameEN": "TopShop", 366 | "nameCN": "TopShop", 367 | "desc": "描述摘要", 368 | "pic": "http://pic15.shangpin.com/e/s/15/04/13/20150413174239555535-10-10.jpg", 369 | "type": "3", 370 | "refContent": "" 371 | },{ 372 | "refContent": "1100000", 373 | "nameEN": "TopShop", 374 | "nameCN": "TopShop", 375 | "desc": "描述摘要", 376 | "pic": "http://pic15.shangpin.com/e/s/15/03/27/20150327170622288008-10-10.jpg", 377 | "type": "3", 378 | "refContent": "" 379 | },{ 380 | "refContent": "1200000", 381 | "nameEN": "TopShop", 382 | "nameCN": "TopShop", 383 | "desc": "描述摘要", 384 | "pic": "http://pic12.shangpin.com/e/s/15/02/15/20150215164135101731-10-10.jpg", 385 | "type": "3", 386 | "refContent": "" 387 | },{ 388 | "refContent": "1300000", 389 | "nameEN": "TopShop", 390 | "nameCN": "TopShop", 391 | "desc": "描述摘要", 392 | "pic": "http://pic15.shangpin.com/e/s/15/02/15/20150215154213693963-10-10.jpg", 393 | "type": "3", 394 | "refContent": "" 395 | },{ 396 | "refContent": "1400000", 397 | "nameEN": "TopShop", 398 | "nameCN": "TopShop", 399 | "desc": "描述摘要", 400 | "pic": "http://pic15.shangpin.com/e/s/15/02/15/20150215154009066205-10-10.jpg", 401 | "type": "3", 402 | "refContent": "" 403 | },{ 404 | "refContent": "1500000", 405 | "nameEN": "TopShop", 406 | "nameCN": "TopShop", 407 | "desc": "描述摘要", 408 | "pic": "http://pic15.shangpin.com/e/s/15/04/01/20150401153506809822-10-10.jpg", 409 | "type": "3", 410 | "refContent": "" 411 | },{ 412 | "refContent": "1600000", 413 | "nameEN": "TopShop", 414 | "nameCN": "TopShop", 415 | "desc": "描述摘要", 416 | "pic": "http://pic15.shangpin.com/e/s/15/02/15/20150215154757876484-10-10.jpg", 417 | "type": "3", 418 | "refContent": "" 419 | },{ 420 | "refContent": "1600000", 421 | "nameEN": "TopShop", 422 | "nameCN": "TopShop", 423 | "desc": "描述摘要", 424 | "pic": "http://pic16.shangpin.com/e/s/15/02/15/20150215155121052546-10-10.jpg", 425 | "type": "3", 426 | "refContent": "" 427 | },{ 428 | "refContent": "1600000", 429 | "nameEN": "TopShop", 430 | "nameCN": "TopShop", 431 | "desc": "描述摘要", 432 | "pic": "http://pic14.shangpin.com/e/s/15/02/15/20150215155558703893-10-10.jpg", 433 | "type": "3", 434 | "refContent": "" 435 | },{ 436 | "refContent": "1600000", 437 | "nameEN": "TopShop", 438 | "nameCN": "TopShop", 439 | "desc": "描述摘要", 440 | "pic": "http://pic11.shangpin.com/e/s/15/03/27/20150327170606111386-10-10.jpg", 441 | "type": "3", 442 | "refContent": "" 443 | 444 | } 445 | ], 446 | "fashion": [ 447 | { 448 | "name": "尚潮流标题", 449 | "type": "5", 450 | "pubTime": "83838928291", 451 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 452 | "summary": "文章摘要", 453 | "source": "文章来源", 454 | "refContent": "http://m.shangpin.com/meet/185" 455 | },{ 456 | "name": "尚潮流标题", 457 | "type": "5", 458 | "pubTime": "83838928291", 459 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 460 | "summary": "文章摘要", 461 | "source": "文章来源", 462 | "refContent": "http://m.shangpin.com/meet/185" 463 | },{ 464 | "name": "尚潮流标题", 465 | "type": "5", 466 | "pubTime": "83838928291", 467 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 468 | "summary": "文章摘要", 469 | "source": "文章来源", 470 | "refContent": "http://m.shangpin.com/meet/185" 471 | },{ 472 | "name": "尚潮流标题", 473 | "type": "5", 474 | "pubTime": "83838928291", 475 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 476 | "summary": "文章摘要", 477 | "source": "文章来源", 478 | "refContent": "http://m.shangpin.com/meet/185" 479 | },{ 480 | "name": "尚潮流标题", 481 | "type": "5", 482 | "pubTime": "83838928291", 483 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 484 | "summary": "文章摘要", 485 | "source": "文章来源", 486 | "refContent": "http://m.shangpin.com/meet/185" 487 | },{ 488 | "name": "尚潮流标题", 489 | "type": "5", 490 | "pubTime": "83838928291", 491 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 492 | "summary": "文章摘要", 493 | "source": "文章来源", 494 | "refContent": "http://m.shangpin.com/meet/185" 495 | },{ 496 | "name": "尚潮流标题", 497 | "type": "5", 498 | "pubTime": "83838928291", 499 | "pic": "http://pic13.shangpin.com/e/s/15/03/13/20150313101818280750-10-10.jpg", 500 | "summary": "文章摘要", 501 | "source": "文章来源", 502 | "refContent": "http://m.shangpin.com/meet/185" 503 | } 504 | ] 505 | }, 506 | "msg": "" 507 | } 508 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/NewRecProduct.json: -------------------------------------------------------------------------------- 1 | { 2 | "code": "0", 3 | "msg": "成功", 4 | "content": { 5 | "systime": "12312134212", 6 | "recommendNum": "为该用户推荐的单品量", 7 | "list": [ 8 | { 9 | "productId": "1001", 10 | "productName": "碎花连衣裙", 11 | "advertWord": "有广告语的时候优先选择使用广告语,", 12 | "brandNameCN": "菲拉格慕", 13 | "brandNameEN": "SALVATORE FERRAGAMO", 14 | "brandNo": "B0084", 15 | "marketPrice": "1899", 16 | "limitedPrice": "1899", 17 | "goldPrice": "1899", 18 | "platinumPrice": "1899", 19 | "diamondPrice": "1899", 20 | "limitedVipPrice": "899", 21 | "promotionPrice": "699", 22 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 23 | "promotionDesc": "促销描述", 24 | "count": "2", 25 | "collections": "2222", 26 | "comments": "1111", 27 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 28 | "status": "0" 29 | },{ 30 | "productId": "1001", 31 | "productName": "碎花连衣裙", 32 | "advertWord": "臣本布衣,躬耕于南阳,苟全性出师于乱世,不求闻达于诸侯。先帝不以臣卑鄙,猥自枉屈,三顾臣于草庐之中,咨臣以当世之事,由是感激,遂许先帝以驱驰。后值倾覆,受任于败军之际,奉命于危难之间:尔来二十有一年矣。", 33 | "brandNameCN": "菲拉格慕", 34 | "brandNameEN": "SALVATORE FERRAGAMO", 35 | "brandNo": "B0084", 36 | "marketPrice": "1899", 37 | "limitedPrice": "1899", 38 | "goldPrice": "1899", 39 | "platinumPrice": "1899", 40 | "diamondPrice": "1899", 41 | "limitedVipPrice": "899", 42 | "promotionPrice": "699", 43 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 44 | "promotionDesc": "促销描述", 45 | "count": "2", 46 | "collections": "1111", 47 | "comments": "1111", 48 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 49 | "status": "0" 50 | },{ 51 | "productId": "1001", 52 | "productName": "碎花连衣裙", 53 | "advertWord": "", 54 | "brandNameCN": "菲拉格慕", 55 | "brandNameEN": "SALVATORE FERRAGAMO", 56 | "brandNo": "B0084", 57 | "marketPrice": "1899", 58 | "limitedPrice": "1899", 59 | "goldPrice": "1899", 60 | "platinumPrice": "1899", 61 | "diamondPrice": "1899", 62 | "limitedVipPrice": "899", 63 | "promotionPrice": "699", 64 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 65 | "promotionDesc": "促销描述", 66 | "count": "2", 67 | "collections": "2222", 68 | "comments": "1111", 69 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 70 | "status": "0" 71 | },{ 72 | "productId": "1001", 73 | "productName": "碎花连衣裙", 74 | "advertWord": "", 75 | "brandNameCN": "菲拉格慕", 76 | "brandNameEN": "SALVATORE FERRAGAMO", 77 | "brandNo": "B0084", 78 | "marketPrice": "1899", 79 | "limitedPrice": "1899", 80 | "goldPrice": "1899", 81 | "platinumPrice": "1899", 82 | "diamondPrice": "1899", 83 | "limitedVipPrice": "899", 84 | "promotionPrice": "699", 85 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 86 | "promotionDesc": "促销描述", 87 | "count": "2", 88 | "collections": "1111", 89 | "comments": "1111", 90 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 91 | "status": "0" 92 | },{ 93 | "productId": "1001", 94 | "productName": "碎花连衣裙", 95 | "advertWord": "", 96 | "brandNameCN": "菲拉格慕", 97 | "brandNameEN": "SALVATORE FERRAGAMO", 98 | "brandNo": "B0084", 99 | "marketPrice": "1899", 100 | "limitedPrice": "1899", 101 | "goldPrice": "1899", 102 | "platinumPrice": "1899", 103 | "diamondPrice": "1899", 104 | "limitedVipPrice": "899", 105 | "promotionPrice": "699", 106 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 107 | "promotionDesc": "促销描述", 108 | "count": "2", 109 | "collections": "2222", 110 | "comments": "1111", 111 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 112 | "status": "0" 113 | },{ 114 | "productId": "1001", 115 | "productName": "碎花连衣裙", 116 | "advertWord": "", 117 | "brandNameCN": "菲拉格慕", 118 | "brandNameEN": "SALVATORE FERRAGAMO", 119 | "brandNo": "B0084", 120 | "marketPrice": "1899", 121 | "limitedPrice": "1899", 122 | "goldPrice": "1899", 123 | "platinumPrice": "1899", 124 | "diamondPrice": "1899", 125 | "limitedVipPrice": "899", 126 | "promotionPrice": "699", 127 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 128 | "promotionDesc": "促销描述", 129 | "count": "2", 130 | "collections": "1111", 131 | "comments": "1111", 132 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 133 | "status": "0" 134 | },{ 135 | "productId": "1001", 136 | "productName": "碎花连衣裙", 137 | "advertWord": "", 138 | "brandNameCN": "菲拉格慕", 139 | "brandNameEN": "SALVATORE FERRAGAMO", 140 | "brandNo": "B0084", 141 | "marketPrice": "1899", 142 | "limitedPrice": "1899", 143 | "goldPrice": "1899", 144 | "platinumPrice": "1899", 145 | "diamondPrice": "1899", 146 | "limitedVipPrice": "899", 147 | "promotionPrice": "699", 148 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 149 | "promotionDesc": "促销描述", 150 | "count": "2", 151 | "collections": "2222", 152 | "comments": "1111", 153 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 154 | "status": "0" 155 | },{ 156 | "productId": "1001", 157 | "productName": "碎花连衣裙", 158 | "advertWord": "", 159 | "brandNameCN": "菲拉格慕", 160 | "brandNameEN": "SALVATORE FERRAGAMO", 161 | "brandNo": "B0084", 162 | "marketPrice": "1899", 163 | "limitedPrice": "1899", 164 | "goldPrice": "1899", 165 | "platinumPrice": "1899", 166 | "diamondPrice": "1899", 167 | "limitedVipPrice": "899", 168 | "promotionPrice": "699", 169 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 170 | "promotionDesc": "促销描述", 171 | "count": "2", 172 | "collections": "1111", 173 | "comments": "1111", 174 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 175 | "status": "0" 176 | },{ 177 | "productId": "1001", 178 | "productName": "碎花连衣裙", 179 | "advertWord": "", 180 | "brandNameCN": "菲拉格慕", 181 | "brandNameEN": "SALVATORE FERRAGAMO", 182 | "brandNo": "B0084", 183 | "marketPrice": "1899", 184 | "limitedPrice": "1899", 185 | "goldPrice": "1899", 186 | "platinumPrice": "1899", 187 | "diamondPrice": "1899", 188 | "limitedVipPrice": "899", 189 | "promotionPrice": "699", 190 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 191 | "promotionDesc": "促销描述", 192 | "count": "2", 193 | "collections": "2222", 194 | "comments": "1111", 195 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 196 | "status": "0" 197 | },{ 198 | "productId": "1001", 199 | "productName": "碎花连衣裙", 200 | "advertWord": "", 201 | "brandNameCN": "菲拉格慕", 202 | "brandNameEN": "SALVATORE FERRAGAMO", 203 | "brandNo": "B0084", 204 | "marketPrice": "1899", 205 | "limitedPrice": "1899", 206 | "goldPrice": "1899", 207 | "platinumPrice": "1899", 208 | "diamondPrice": "1899", 209 | "limitedVipPrice": "899", 210 | "promotionPrice": "699", 211 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 212 | "promotionDesc": "促销描述", 213 | "count": "2", 214 | "collections": "1111", 215 | "comments": "1111", 216 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 217 | "status": "0" 218 | },{ 219 | "productId": "1001", 220 | "productName": "碎花连衣裙", 221 | "advertWord": "", 222 | "brandNameCN": "菲拉格慕", 223 | "brandNameEN": "SALVATORE FERRAGAMO", 224 | "brandNo": "B0084", 225 | "marketPrice": "1899", 226 | "limitedPrice": "1899", 227 | "goldPrice": "1899", 228 | "platinumPrice": "1899", 229 | "diamondPrice": "1899", 230 | "limitedVipPrice": "899", 231 | "promotionPrice": "699", 232 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 233 | "promotionDesc": "促销描述", 234 | "count": "2", 235 | "collections": "2222", 236 | "comments": "1111", 237 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 238 | "status": "0" 239 | },{ 240 | "productId": "1001", 241 | "productName": "碎花连衣裙", 242 | "advertWord": "", 243 | "brandNameCN": "菲拉格慕", 244 | "brandNameEN": "SALVATORE FERRAGAMO", 245 | "brandNo": "B0084", 246 | "marketPrice": "1899", 247 | "limitedPrice": "1899", 248 | "goldPrice": "1899", 249 | "platinumPrice": "1899", 250 | "diamondPrice": "1899", 251 | "limitedVipPrice": "899", 252 | "promotionPrice": "699", 253 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 254 | "promotionDesc": "促销描述", 255 | "count": "2", 256 | "collections": "1111", 257 | "comments": "1111", 258 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 259 | "status": "0" 260 | },{ 261 | "productId": "1001", 262 | "productName": "碎花连衣裙", 263 | "advertWord": "", 264 | "brandNameCN": "菲拉格慕", 265 | "brandNameEN": "SALVATORE FERRAGAMO", 266 | "brandNo": "B0084", 267 | "marketPrice": "1899", 268 | "limitedPrice": "1899", 269 | "goldPrice": "1899", 270 | "platinumPrice": "1899", 271 | "diamondPrice": "1899", 272 | "limitedVipPrice": "899", 273 | "promotionPrice": "699", 274 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 275 | "promotionDesc": "促销描述", 276 | "count": "2", 277 | "collections": "2222", 278 | "comments": "1111", 279 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 280 | "status": "0" 281 | },{ 282 | "productId": "1001", 283 | "productName": "碎花连衣裙", 284 | "advertWord": "", 285 | "brandNameCN": "菲拉格慕", 286 | "brandNameEN": "SALVATORE FERRAGAMO", 287 | "brandNo": "B0084", 288 | "marketPrice": "1899", 289 | "limitedPrice": "1899", 290 | "goldPrice": "1899", 291 | "platinumPrice": "1899", 292 | "diamondPrice": "1899", 293 | "limitedVipPrice": "899", 294 | "promotionPrice": "699", 295 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 296 | "promotionDesc": "促销描述", 297 | "count": "2", 298 | "collections": "1111", 299 | "comments": "1111", 300 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 301 | "status": "0" 302 | },{ 303 | "productId": "1001", 304 | "productName": "碎花连衣裙", 305 | "advertWord": "", 306 | "brandNameCN": "菲拉格慕", 307 | "brandNameEN": "SALVATORE FERRAGAMO", 308 | "brandNo": "B0084", 309 | "marketPrice": "1899", 310 | "limitedPrice": "1899", 311 | "goldPrice": "1899", 312 | "platinumPrice": "1899", 313 | "diamondPrice": "1899", 314 | "limitedVipPrice": "899", 315 | "promotionPrice": "699", 316 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 317 | "promotionDesc": "促销描述", 318 | "count": "2", 319 | "collections": "2222", 320 | "comments": "1111", 321 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 322 | "status": "0" 323 | },{ 324 | "productId": "1001", 325 | "productName": "碎花连衣裙", 326 | "advertWord": "", 327 | "brandNameCN": "菲拉格慕", 328 | "brandNameEN": "SALVATORE FERRAGAMO", 329 | "brandNo": "B0084", 330 | "marketPrice": "1899", 331 | "limitedPrice": "1899", 332 | "goldPrice": "1899", 333 | "platinumPrice": "1899", 334 | "diamondPrice": "1899", 335 | "limitedVipPrice": "899", 336 | "promotionPrice": "699", 337 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 338 | "promotionDesc": "促销描述", 339 | "count": "2", 340 | "collections": "1111", 341 | "comments": "1111", 342 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 343 | "status": "0" 344 | },{ 345 | "productId": "1001", 346 | "productName": "碎花连衣裙", 347 | "advertWord": "", 348 | "brandNameCN": "菲拉格慕", 349 | "brandNameEN": "SALVATORE FERRAGAMO", 350 | "brandNo": "B0084", 351 | "marketPrice": "1899", 352 | "limitedPrice": "1899", 353 | "goldPrice": "1899", 354 | "platinumPrice": "1899", 355 | "diamondPrice": "1899", 356 | "limitedVipPrice": "899", 357 | "promotionPrice": "699", 358 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 359 | "promotionDesc": "促销描述", 360 | "count": "2", 361 | "collections": "2222", 362 | "comments": "1111", 363 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 364 | "status": "0" 365 | },{ 366 | "productId": "1001", 367 | "productName": "碎花连衣裙", 368 | "advertWord": "", 369 | "brandNameCN": "菲拉格慕", 370 | "brandNameEN": "SALVATORE FERRAGAMO", 371 | "brandNo": "B0084", 372 | "marketPrice": "1899", 373 | "limitedPrice": "1899", 374 | "goldPrice": "1899", 375 | "platinumPrice": "1899", 376 | "diamondPrice": "1899", 377 | "limitedVipPrice": "899", 378 | "promotionPrice": "699", 379 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 380 | "promotionDesc": "促销描述", 381 | "count": "2", 382 | "collections": "1111", 383 | "comments": "1111", 384 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 385 | "status": "0" 386 | },{ 387 | "productId": "1001", 388 | "productName": "碎花连衣裙", 389 | "advertWord": "", 390 | "brandNameCN": "菲拉格慕", 391 | "brandNameEN": "SALVATORE FERRAGAMO", 392 | "brandNo": "B0084", 393 | "marketPrice": "1899", 394 | "limitedPrice": "1899", 395 | "goldPrice": "1899", 396 | "platinumPrice": "1899", 397 | "diamondPrice": "1899", 398 | "limitedVipPrice": "899", 399 | "promotionPrice": "699", 400 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 401 | "promotionDesc": "促销描述", 402 | "count": "2", 403 | "collections": "2222", 404 | "comments": "1111", 405 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 406 | "status": "0" 407 | },{ 408 | "productId": "1001", 409 | "productName": "碎花连衣裙", 410 | "advertWord": "", 411 | "brandNameCN": "菲拉格慕", 412 | "brandNameEN": "SALVATORE FERRAGAMO", 413 | "brandNo": "B0084", 414 | "marketPrice": "1899", 415 | "limitedPrice": "1899", 416 | "goldPrice": "1899", 417 | "platinumPrice": "1899", 418 | "diamondPrice": "1899", 419 | "limitedVipPrice": "899", 420 | "promotionPrice": "699", 421 | "isSupportDiscount": "是否支持会员权益0,否;1,是", 422 | "promotionDesc": "促销描述", 423 | "count": "2", 424 | "collections": "1111", 425 | "comments": "1111", 426 | "pic": "http://pic14.shangpin.com/e/s/14/08/20/20140820191723534713-10-10.jpg", 427 | "status": "0" 428 | } 429 | ] 430 | } 431 | } -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/OCTypes.json: -------------------------------------------------------------------------------- 1 | { 2 | "boolType": true, 3 | "BOOLType": true, 4 | "charType": 32, 5 | "uCharType": 97, 6 | "shortType": 123, 7 | "uShortType": 234, 8 | "intType": 345, 9 | "uIntType": 456, 10 | "longType": 567, 11 | "uLongType": 789, 12 | "longlongType": 5677, 13 | "uLongLongType": 7899, 14 | "floatType": 345.123, 15 | "doubleType": 456.12345, 16 | "stringType": "I'm a string.", 17 | "mutableStringType": "I'm a mutable string.", 18 | "numberType": "7982", 19 | "urlType": "https://debugly.cn", 20 | "fileURLType": "file:///Users/qianlongxu/Desktop/Caption.zip", 21 | "classAType": { 22 | "name": "I'm a classA instance." 23 | }, 24 | "idType": "I'm id type.", 25 | "hash": 979798, 26 | "superclass": "NSObject", 27 | "description": "I'm a description", 28 | "debugDescription": "I'm a debug description" 29 | } 30 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/Store.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "测试下KeyPath", 3 | "data" : { 4 | "order": [1,2,3], 5 | "category": ["蔬菜","水果","肉食"], 6 | "weight": ["15","16","17"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/Userinfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "code" : "10000", 3 | "test" : "testValue", 4 | "data" :{ 5 | "basic":{ 6 | "gender":"男", 7 | "uid":209849, 8 | "name":"芒果", 9 | "phone_number":"999198838229", 10 | "avatar_img":{ 11 | "original_url":"http://original/e/s/15/04/01/20150401185027193594-10-10.jpg", 12 | "thumbnail_url":"http://thumbnail/e/s/15/04/01/20150401185027193594-10-10.jpg", 13 | "raw_url":"http://raw/e/s/15/04/01/20150401185027193594-10-10.jpg" 14 | } 15 | }, 16 | "cars":[ 17 | { 18 | "bought_time":"2002", 19 | "brand":"werty", 20 | "brand_img_url":{ 21 | "original_url":"http://original/e/s/15/04/01/20150401185027193594-10-10.jpg", 22 | "thumbnail_url":"http://thumbnail/e/s/15/04/01/20150401185027193594-10-10.jpg", 23 | "raw_url":"http://raw/e/s/15/04/01/20150401185027193594-10-10.jpg" 24 | } 25 | }, 26 | { 27 | "bought_time":"2002", 28 | "brand":"werty", 29 | "brand_img_url":{ 30 | "original_url":"http://original/e/s/15/04/01/20150401185027193594-10-10.jpg", 31 | "thumbnail_url":"http://thumbnail/e/s/15/04/01/20150401185027193594-10-10.jpg", 32 | "raw_url":"http://raw/e/s/15/04/01/20150401185027193594-10-10.jpg" 33 | } 34 | }, 35 | { 36 | "bought_time":"2002", 37 | "brand":"werty", 38 | "brand_img_url":{ 39 | "original_url":"http://original/e/s/15/04/01/20150401185027193594-10-10.jpg", 40 | "thumbnail_url":"http://thumbnail/e/s/15/04/01/20150401185027193594-10-10.jpg", 41 | "raw_url":"http://raw/e/s/15/04/01/20150401185027193594-10-10.jpg" 42 | } 43 | } 44 | ] 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/jsonfiles/VideoInfo.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "欢乐颂", 3 | "data" : { 4 | "cks": [1,2,3], 5 | "hcs": ["a","b","c"], 6 | "dus": ["15","16","17"] 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/main.m: -------------------------------------------------------------------------------- 1 | // 2 | // main.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by xuqianlong on 2017/7/21. 6 | // Copyright © 2017年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "AppDelegate.h" 11 | 12 | int main(int argc, char * argv[]) { 13 | @autoreleasepool { 14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/Car.h: -------------------------------------------------------------------------------- 1 | // 2 | // Car.h 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 2016/12/18. 6 | // Copyright © 2016年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "FavModel.h" 11 | #import "objc/runtime.h" 12 | @interface Car : NSObject 13 | 14 | @property (nonatomic, strong) FavModel *pStorng; 15 | @property (nonatomic, weak) NSNumber *pWeak; 16 | @property (nonatomic, retain) NSMutableArray *pRetain; 17 | @property (nonatomic, copy) NSString *pCopy; 18 | @property (nonatomic, assign) NSArray *pAssign; 19 | @property (nonatomic, readonly) NSArray *pReadonly; 20 | @property (nonatomic, readonly,getter=isReadonly) NSArray *pReadonlyGetter; 21 | @property (atomic, assign) NSDictionary *pAutomicAssign; 22 | @property (atomic, retain) NSDictionary *pAutomicRetain; 23 | @property (nonatomic, retain) NSMutableArray * pFanXing; 24 | 25 | @property (nonatomic, strong) id pID; 26 | @property (nonatomic, strong) dispatch_block_t pBlock; 27 | @property (nonatomic, strong) Class pClass; 28 | @property (nonatomic, assign) SEL pSEL; 29 | @property (nonatomic, assign) Method pMethod; 30 | 31 | @property (nonatomic, assign) float pFloat; 32 | @property (nonatomic, assign) double pDouble; 33 | 34 | @property (nonatomic, assign) Byte pByte; 35 | @property (nonatomic, assign) char pChar; 36 | @property (nonatomic, assign) short pShort; 37 | @property (nonatomic, assign) int pInt; 38 | @property (nonatomic, assign) long pLong; 39 | @property (nonatomic, assign) long long pLongLong; 40 | @property (nonatomic, assign) BOOL pBool; 41 | @property (nonatomic, assign) bool pbool; 42 | 43 | @property (nonatomic, assign) bool b; 44 | @property (nonatomic, assign) bool b1; 45 | @property (nonatomic, assign) bool b2; 46 | 47 | @end 48 | /* 49 | T@"FavModel",&,N,V_pStorng 50 | T@"NSNumber",W,N,V_pWeak 51 | T@"NSMutableArray",&,N,V_pRetain 52 | T@"NSString",C,N,V_pCopy 53 | T@"NSArray",N,V_pAssign 54 | T@"NSArray",R,N,V_pReadonly 55 | T@"NSArray",R,N,GisReadonly,V_pReadonlyGetter 56 | T@"NSDictionary",V_pAutomicAssign 57 | T@"NSDictionary",&,V_pAutomicRetain 58 | T@,&,N,V_pID 59 | T@?,C,N,V_pBlock 60 | T#,&,N,V_pClass 61 | T:,N,V_pSEL 62 | T^{objc_method=},N,V_pMethod 63 | Tf,N,V_pFloat 64 | Td,N,V_pDouble 65 | TC,N,V_pByte 66 | Tc,N,V_pChar 67 | Ts,N,V_pShort 68 | Ti,N,V_pInt 69 | Tq,N,V_pLong 70 | Tq,N,V_pLongLong 71 | TB,N,V_pBool 72 | TB,N,V_pbool 73 | */ 74 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/Car.m: -------------------------------------------------------------------------------- 1 | // 2 | // Car.m 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 2016/12/18. 6 | // Copyright © 2016年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "Car.h" 10 | 11 | @implementation Car 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/DynamicVideos.h: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicVideos.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2019/1/16. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface VideoItem : NSObject 14 | 15 | @property (nonatomic,assign) long no; 16 | @property (nonatomic,copy) NSString *showName; 17 | @property (nonatomic,copy) NSString *title; 18 | @property (nonatomic,copy) NSString *domain; 19 | @property (nonatomic,strong) NSNumber *type; 20 | @property (nonatomic,strong) NSNumber *rid; 21 | @property (nonatomic,strong) NSNumber *uid; 22 | @property (nonatomic,copy) NSMutableString *rSwfurl; 23 | @property (nonatomic,copy) NSURL *url; 24 | 25 | @end 26 | 27 | @interface DynamicVideos : NSObject 28 | 29 | @property (nonatomic,copy) NSString *area; 30 | @property (nonatomic,assign) long playlistid; 31 | @property (nonatomic,strong) NSArray *videos; 32 | ///没有指定model,原值输出! 33 | @property (nonatomic,strong) NSArray *wps; 34 | ///与服务器返回类型不同,也不能自动转换,因此不能解析! 35 | @property (nonatomic,assign) int array; 36 | @property (nonatomic,assign) BOOL activity; 37 | @property (nonatomic,copy) NSURL * smallVerPicUrl; 38 | @property (nonatomic,copy) NSMutableString * showAlbumName; 39 | 40 | @end 41 | 42 | NS_ASSUME_NONNULL_END 43 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/DynamicVideos.m: -------------------------------------------------------------------------------- 1 | // 2 | // DynamicVideos.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2019/1/16. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "DynamicVideos.h" 10 | 11 | @implementation VideoItem 12 | 13 | @end 14 | 15 | @implementation DynamicVideos 16 | 17 | - (NSDictionary *)sc_collideKeysMap 18 | { 19 | return @{@"wp" : @"wps",@"activity.on" : @"activity"}; 20 | } 21 | 22 | - (NSDictionary *)sc_collideKeyModelMap 23 | { 24 | return @{@"videos":@"VideoItem"}; 25 | } 26 | 27 | - (BOOL)sc_unDefinedKey:(NSString **)keyPtr forValue:(id *)valuePtr refObj:(id)refObj 28 | { 29 | NSDictionary *refDic = refObj; 30 | NSString *key = *keyPtr; 31 | NSString *mapedKey = [refDic objectForKey:key]; 32 | if (mapedKey) { 33 | *keyPtr = mapedKey; 34 | NSDictionary *value = *valuePtr; 35 | if ([value isKindOfClass:[NSDictionary class]]) { 36 | NSArray *videos = value[@"videos"]; 37 | *valuePtr = videos; 38 | } 39 | return YES; 40 | } 41 | return NO; 42 | } 43 | @end 44 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/FavModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // FavModel.h 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 15/7/16. 6 | // Copyright (c) 2015年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface FavModel : NSObject 12 | 13 | @property (nonatomic, assign) long refContent; 14 | @property (nonatomic, copy) NSString *nameEN; 15 | @property (nonatomic, copy) NSString *nameCN; 16 | @property (nonatomic, copy) NSURL *pic; //这个需要手动transfer 17 | @property (nonatomic, copy) NSString *desc; 18 | 19 | @end 20 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/FavModel.m: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // FavModel.m 4 | // QLJSON2Model 5 | // 6 | // Created by xuqianlong on 15/7/16. 7 | // Copyright (c) 2015年 xuqianlong. All rights reserved. 8 | // 9 | 10 | #import "FavModel.h" 11 | 12 | @implementation FavModel 13 | 14 | @end 15 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/GalleryModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // GalleryModel.h 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 15/9/8. 6 | // Copyright © 2015年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface GalleryModel : NSObject 12 | 13 | @property (nonatomic, assign) BOOL isFlagship; 14 | @property (nonatomic, copy) NSString *name; 15 | @property (nonatomic, copy) NSURL *pic; 16 | @property (nonatomic, copy) NSString *refContent; 17 | @property (nonatomic, copy) NSString *type; 18 | 19 | @end 20 | 21 | /* 22 | "isFlagship": "0", 23 | "name": "白色情人节 与浪漫牵手", 24 | "pic": "http://pic16.shangpin.com/e/s/15/03/06/20150306174649601525-10-10.jpg", 25 | "refContent": "http://m.shangpin.com/meet/189", 26 | "type": "5" 27 | 28 | */ 29 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/GalleryModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // GalleryModel.m 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 15/9/8. 6 | // Copyright © 2015年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "GalleryModel.h" 10 | 11 | @implementation GalleryModel 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/OCTypes.h: -------------------------------------------------------------------------------- 1 | // 2 | // OCTypes.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by qianlongxu on 2019/11/26. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface OCClassA : NSObject 12 | 13 | @property (nonatomic, copy) NSString * name; 14 | 15 | @end 16 | 17 | @interface OCTypes : NSObject 18 | 19 | @property (nonatomic, assign) bool boolType; 20 | @property (nonatomic, assign) BOOL BOOLType; 21 | @property (nonatomic, assign) char charType; 22 | @property (nonatomic, assign) unsigned char uCharType; 23 | @property (nonatomic, assign) short shortType; 24 | @property (nonatomic, assign) unsigned short uShortType; 25 | @property (nonatomic, assign) int intType; 26 | @property (nonatomic, assign) unsigned int uIntType; 27 | @property (nonatomic, assign) long longType; 28 | @property (nonatomic, assign) unsigned long uLongType; 29 | @property (nonatomic, assign) long long longlongType; 30 | @property (nonatomic, assign) unsigned long long uLongLongType; 31 | @property (nonatomic, assign) float floatType; 32 | @property (nonatomic, assign) double doubleType; 33 | 34 | @property (nonatomic, copy) NSString * stringType; 35 | @property (nonatomic, copy) NSMutableString * mutableStringType; 36 | @property (nonatomic, strong) NSNumber * numberType; 37 | @property (nonatomic, strong) NSURL * urlType; 38 | @property (nonatomic, strong) NSURL * fileURLType; 39 | @property (nonatomic, strong) OCClassA * classAType; 40 | @property (nonatomic, strong) id idType; 41 | //只读属性不解析 42 | @property (readonly, strong) NSString *skipMe; 43 | 44 | @end 45 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/OCTypes.m: -------------------------------------------------------------------------------- 1 | // 2 | // OCTypes.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by qianlongxu on 2019/11/26. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "OCTypes.h" 10 | 11 | @implementation OCClassA 12 | 13 | @end 14 | 15 | @implementation OCTypes 16 | 17 | - (instancetype)init 18 | { 19 | self = [super init]; 20 | if (self) { 21 | _skipMe = @"我没有被解析"; 22 | } 23 | return self; 24 | } 25 | 26 | @end 27 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/StoreModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // StoreModel.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2020/11/13. 6 | // Copyright © 2020 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SCJSONUtil.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface StoreModel : NSObject 15 | 16 | @property (nonatomic, copy) NSString *name; 17 | @property (nonatomic, strong) NSArray *order; 18 | @property (nonatomic, strong) NSArray *category; 19 | @property (nonatomic, strong) NSArray *weight; 20 | 21 | @end 22 | 23 | NS_ASSUME_NONNULL_END 24 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/StoreModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // StoreModel.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2020/11/13. 6 | // Copyright © 2020 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "StoreModel.h" 10 | 11 | @implementation StoreModel 12 | 13 | - (NSDictionary *)sc_collideKeysMap 14 | { 15 | return @{ 16 | @"data.order":@"order", 17 | @"data.category":@"category", 18 | @"data.weight":@"weight", 19 | }; 20 | } 21 | 22 | @end 23 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/UserInfoModel.h: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoModel.h 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 15/7/14. 6 | // Copyright (c) 2015年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | @interface AvatarInfoModel : NSObject 12 | 13 | @property (nonatomic,copy) NSString *original_url; 14 | @property (nonatomic,copy) NSString *thumbnail_url; 15 | @property (nonatomic,copy) NSURL *raw_url; 16 | 17 | @end 18 | 19 | @interface CarInfoModel : NSObject 20 | 21 | @property (nonatomic,copy) NSString *bought_time; 22 | @property (nonatomic,copy) NSString *brand; 23 | @property (nonatomic,retain) AvatarInfoModel *brandImg; 24 | 25 | @end 26 | 27 | @interface BasicInfoModel : NSObject 28 | 29 | @property (nonatomic,retain) AvatarInfoModel *avatarInfo; 30 | @property (nonatomic,copy) NSString *gender; 31 | @property (nonatomic,assign) long uid; 32 | @property (nonatomic,copy) NSString *name; 33 | @property (nonatomic,copy) NSString *phone_number; 34 | 35 | @end 36 | 37 | @interface DataInfoModel : NSObject 38 | 39 | @property (nonatomic,retain) BasicInfoModel *basicInfo; 40 | @property (nonatomic,retain) NSMutableArray *carInfoArr; 41 | 42 | @end 43 | 44 | @interface UserInfoModel : NSObject 45 | 46 | @property (nonatomic,copy) NSString *code; 47 | @property (nonatomic,retain) DataInfoModel *data; 48 | @property (nonatomic,copy) NSString *test; 49 | 50 | @end 51 | 52 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/UserInfoModel.m: -------------------------------------------------------------------------------- 1 | // 2 | // UserInfoModel.m 3 | // QLJSON2Model 4 | // 5 | // Created by xuqianlong on 15/7/14. 6 | // Copyright (c) 2015年 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "UserInfoModel.h" 10 | #import "SCJSONUtil.h" 11 | 12 | @implementation CarInfoModel 13 | 14 | - (NSDictionary *)sc_collideKeysMap 15 | { 16 | return @{@"brand_img_url":@"brandImg"}; 17 | } 18 | 19 | @end 20 | 21 | @implementation AvatarInfoModel 22 | 23 | @end 24 | 25 | @implementation BasicInfoModel 26 | 27 | - (NSDictionary *)sc_collideKeysMap 28 | { 29 | return @{@"avatar_img":@"avatarInfo"}; 30 | } 31 | 32 | //给name加个前缀; 33 | 34 | - (id)sc_key:(NSString *)key beforeAssignedValue:(NSString *)value 35 | { 36 | if ([key isEqualToString:@"name"]) { 37 | if ([value isKindOfClass:[NSString class]]) { 38 | return [@"xql." stringByAppendingString:value]; 39 | } 40 | return nil; 41 | } 42 | return value; 43 | } 44 | 45 | @end 46 | 47 | @implementation DataInfoModel 48 | 49 | - (NSDictionary *)sc_collideKeyModelMap 50 | { 51 | return @{@"cars":@"CarInfoModel"}; 52 | } 53 | 54 | - (NSDictionary *)sc_collideKeysMap 55 | { 56 | return @{@"basic":@"basicInfo",@"cars":@"carInfoArr"}; 57 | } 58 | 59 | @end 60 | 61 | @implementation UserInfoModel 62 | 63 | @end 64 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/VideoInfo.h: -------------------------------------------------------------------------------- 1 | // 2 | // VideoInfo.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2019/2/28. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import "SCJSONUtil.h" 11 | 12 | NS_ASSUME_NONNULL_BEGIN 13 | 14 | @interface VideoSection : NSObject 15 | 16 | @property (nonatomic, assign) int ck; 17 | @property (nonatomic, copy) NSString *hc; 18 | @property (nonatomic, copy) NSString *du; 19 | 20 | @end 21 | 22 | @interface VideoInfo : NSObject 23 | 24 | @property (nonatomic, copy) NSString *name; 25 | @property (nonatomic, strong) NSArray *sections; 26 | 27 | @end 28 | 29 | NS_ASSUME_NONNULL_END 30 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/models/VideoInfo.m: -------------------------------------------------------------------------------- 1 | // 2 | // VideoInfo.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2019/2/28. 6 | // Copyright © 2019 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "VideoInfo.h" 10 | 11 | @implementation VideoSection 12 | 13 | @end 14 | 15 | @implementation VideoInfo 16 | 17 | - (void)sc_willFinishConvert:(id)data refObj:(id)refObj 18 | { 19 | if([data isKindOfClass:[NSDictionary class]]){ 20 | NSDictionary *dic = (NSDictionary *)data; 21 | NSDictionary *sectionData = dic[@"data"]; 22 | if (sectionData) { 23 | NSArray *cks = sectionData[@"cks"]; 24 | NSArray *hcs = sectionData[@"hcs"]; 25 | NSArray *dus = sectionData[@"dus"]; 26 | if ([cks isKindOfClass:[NSArray class]] && [hcs isKindOfClass:[NSArray class]] && [dus isKindOfClass:[NSArray class]]) { 27 | 28 | if ([cks count] == [hcs count] && [hcs count] == [dus count]) { 29 | NSMutableArray *secArr = [NSMutableArray arrayWithCapacity:3]; 30 | for (int i = 0 ; i < [cks count]; i++) { 31 | id ck = cks[i]; 32 | id hc = hcs[i]; 33 | id du = dus[i]; 34 | [secArr addObject:@{ 35 | @"ck":ck, 36 | @"hc":hc, 37 | @"du":du 38 | }]; 39 | } 40 | 41 | NSArray * videoSecs = [VideoSection sc_instanceArrFormArray:secArr]; 42 | self.sections = videoSecs; 43 | } 44 | } 45 | } 46 | } 47 | } 48 | 49 | @end 50 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/util/Util.h: -------------------------------------------------------------------------------- 1 | // 2 | // Util.h 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2020/11/13. 6 | // Copyright © 2020 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | 11 | NS_ASSUME_NONNULL_BEGIN 12 | 13 | @interface Util : NSObject 14 | 15 | + (NSDictionary *)readOCTypes; 16 | 17 | + (NSDictionary *)readCarInfo; 18 | 19 | + (NSDictionary *)readUserInfo; 20 | 21 | + (NSArray *)readFavConcern; 22 | 23 | + (NSDictionary *)readGalleryList; 24 | 25 | + (NSDictionary *)readVideoList; 26 | 27 | + (NSDictionary *)readVideoInfo; 28 | 29 | + (NSDictionary *)readStore; 30 | 31 | @end 32 | 33 | NS_ASSUME_NONNULL_END 34 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilDemo/util/Util.m: -------------------------------------------------------------------------------- 1 | // 2 | // Util.m 3 | // SCJSONUtilDemo 4 | // 5 | // Created by Matt Reach on 2020/11/13. 6 | // Copyright © 2020 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import "Util.h" 10 | 11 | @implementation Util 12 | 13 | + (NSString *)jsonFilePath:(NSString *)fName 14 | { 15 | return [[NSBundle mainBundle]pathForResource:fName ofType:@"json"]; 16 | } 17 | 18 | + (id)readBundleJSONFile:(NSString *)fName 19 | { 20 | NSData *data = [NSData dataWithContentsOfFile:[self jsonFilePath:fName]]; 21 | NSError *err = nil; 22 | id json = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&err]; 23 | if (err) { 24 | return nil; 25 | } 26 | return json; 27 | } 28 | 29 | + (NSDictionary *)readOCTypes 30 | { 31 | return [self readBundleJSONFile:@"OCTypes"]; 32 | } 33 | 34 | + (NSDictionary *)readCarInfo 35 | { 36 | return [self readBundleJSONFile:@"Car"]; 37 | } 38 | 39 | + (NSDictionary *)readUserInfo 40 | { 41 | return [self readBundleJSONFile:@"Userinfo"]; 42 | } 43 | 44 | + (NSArray *)readFavConcern 45 | { 46 | return [self readBundleJSONFile:@"FavConcern"]; 47 | } 48 | 49 | + (NSDictionary *)readGalleryList 50 | { 51 | return [self readBundleJSONFile:@"GalleryList"]; 52 | } 53 | 54 | + (NSDictionary *)readVideoList 55 | { 56 | return [self readBundleJSONFile:@"DynamicVideos"]; 57 | } 58 | 59 | + (NSDictionary *)readVideoInfo 60 | { 61 | return [self readBundleJSONFile:@"VideoInfo"]; 62 | } 63 | 64 | + (NSDictionary *)readStore 65 | { 66 | return [self readBundleJSONFile:@"Store"]; 67 | } 68 | 69 | @end 70 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilTests/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | 22 | 23 | -------------------------------------------------------------------------------- /Demo/SCJSONUtilTests/SCJSONUtilTests.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCJSONUtilTests.m 3 | // SCJSONUtilTests 4 | // 5 | // Created by Matt Reach on 2020/4/22. 6 | // Copyright © 2020 xuqianlong. All rights reserved. 7 | // 8 | 9 | #import 10 | #import 11 | #import 12 | #import "UserInfoModel.h" 13 | #import "FavModel.h" 14 | #import "OCTypes.h" 15 | #import "Car.h" 16 | #import "DynamicVideos.h" 17 | #import "VideoInfo.h" 18 | #import "GalleryModel.h" 19 | #import "StoreModel.h" 20 | #import "Util.h" 21 | 22 | @interface SCJSONUtilTests : XCTestCase 23 | 24 | @end 25 | 26 | @implementation SCJSONUtilTests 27 | 28 | - (void)setUp { 29 | // Put setup code here. This method is called before the invocation of each test method in the class. 30 | } 31 | 32 | - (void)tearDown { 33 | // Put teardown code here. This method is called after the invocation of each test method in the class. 34 | } 35 | 36 | - (void)testLogSwitch 37 | { 38 | SCJSONUtilLog(YES); 39 | XCTAssert(isSCJSONUtilLogOn() == YES); 40 | SCJSONUtilLog(NO); 41 | XCTAssert(isSCJSONUtilLogOn() == NO); 42 | } 43 | 44 | - (void)rawJson:(id)json model:(id)model 45 | { 46 | //测试下json转成的model,再转回json跟原json是否相等; 47 | NSDictionary *json2 = [model sc_toJSON]; 48 | //以model转成的josn为主,因为可能有的model没有解析json的所有字段 49 | [json2 enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { 50 | id obj2 = json[key]; 51 | NSLog(@"test equal[%@:%@:%@]",key,obj,obj2); 52 | //由于浮点数字不能直接比较,因此这里统一转为字符串再比 53 | XCTAssert([[obj2 description] isEqual:[obj description]]); 54 | }]; 55 | } 56 | 57 | - (void)testOCTypes 58 | { 59 | NSDictionary *typesDic = [Util readOCTypes]; 60 | OCTypes *model = [OCTypes sc_instanceFormDic:typesDic]; 61 | [self rawJson:typesDic model:model]; 62 | 63 | XCTAssert(model.boolType == YES); 64 | XCTAssert(model.BOOLType == YES); 65 | XCTAssert(model.charType == 32); 66 | XCTAssert(model.uCharType == 97); 67 | XCTAssert(model.shortType == 123); 68 | XCTAssert(model.uShortType == 234); 69 | XCTAssert(model.intType == 345); 70 | XCTAssert(model.uIntType == 456); 71 | XCTAssert(model.longType == 567); 72 | XCTAssert(model.uLongType == 789); 73 | XCTAssert(model.longlongType == 5677); 74 | XCTAssert(model.uLongLongType == 7899); 75 | XCTAssert((int)(model.floatType * 1000) == (int)(345.123 * 1000)); 76 | XCTAssert((long)(model.doubleType * 100000) == (long)(456.12345 * 100000)); 77 | XCTAssert([model.stringType isEqualToString:@"I'm a string."]); 78 | XCTAssert([model.mutableStringType isEqualToString:@"I'm a mutable string."]); 79 | XCTAssert([model.mutableStringType isKindOfClass:[NSMutableString class]]); 80 | XCTAssert([[model.numberType description] isEqualToString:@"7982"]); 81 | XCTAssert([model.numberType isKindOfClass:[NSNumber class]]); 82 | XCTAssert([[model.urlType absoluteString] isEqualToString:@"https://debugly.cn"]); 83 | XCTAssert([model.urlType isKindOfClass:[NSURL class]]); 84 | XCTAssert([[model.fileURLType absoluteString] isEqualToString:@"file:///Users/qianlongxu/Desktop/Caption.zip"]); 85 | XCTAssert([model.fileURLType isFileURL]); 86 | XCTAssert([model.fileURLType isKindOfClass:[NSURL class]]); 87 | XCTAssert([model.classAType isKindOfClass:[OCClassA class]]); 88 | XCTAssert([model.classAType.name isEqualToString:@"I'm a classA instance."]); 89 | XCTAssert([model.idType isEqualToString:@"I'm id type."]); 90 | XCTAssert(model.skipMe == nil); 91 | 92 | } 93 | 94 | - (void)performance:(long)count work:(dispatch_block_t)block 95 | { 96 | [self measureBlock:^{ 97 | for (int i = 0; i "qianlongxu@gmail.com" } 22 | 23 | s.ios.deployment_target = "10.0" 24 | s.tvos.deployment_target = "10.0" 25 | s.osx.deployment_target = "10.11" 26 | 27 | s.source = { :git => "https://github.com/debugly/SCJSONUtil.git", :tag => "#{s.version}" } 28 | s.source_files = "SCJSONUtil/**/*.{h,m,c}" 29 | s.private_header_files = "SCJSONUtil/internal/*.h" 30 | s.framework = "Foundation" 31 | s.requires_arc = true 32 | 33 | end 34 | -------------------------------------------------------------------------------- /SCJSONUtil/SCJSONUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCJSONUtil.h 3 | // 4 | // Created by xuqianlong on 15/9/3. 5 | // Copyright (c) 2015年 Mac. All rights reserved. 6 | // 7 | //https://github.com/debugly/SCJSONUtil 8 | 9 | #import 10 | 11 | ///日志开关,默认关闭 12 | void SCJSONUtilLog(BOOL on); 13 | BOOL isSCJSONUtilLogOn(void); 14 | 15 | @protocol SCJSON2ModelProtocol 16 | 17 | @optional; 18 | /** 19 | * @brief:存放冲突key映射的字典 @{@"server's key":@"model‘s property name"} 20 | * 遍历服务端返回数据,通过key去查找客户端model里定义的属性名 21 | */ 22 | - (NSDictionary *)sc_collideKeysMap; 23 | 24 | /** 25 | * @brief:存放服务端key和映射Model的字典,@{@"server's key":@"your Model Name"} 26 | */ 27 | - (NSDictionary *)sc_collideKeyModelMap; 28 | 29 | /** 30 | 用于解决映射关系不能确定,需要动态修改的情况 31 | 32 | @param keyPtr 服务器key(如果做了映射sc_collideKeysMap,则是映射之后的key);二级指针,可修改内容 33 | @param valuePtr 服务器value;二级指针,可修改内容 34 | @param refObj 客户端解析时传过来的额外信息 35 | @return 36 | YES:动态解决了映射关系,可根据 *keyPtr 查找到属性信息!继续走解析流程; 37 | NO:没有解决,放弃该key-value;中断解析流程,开始解析下一个key; 38 | */ 39 | - (BOOL)sc_unDefinedKey:(NSString **)keyPtr forValue:(id *)valuePtr refObj:(id)refObj; 40 | 41 | /** 42 | * @brief:在给 key 赋值之前,将从字典里找到的 value 返回来,你可以修改这个值,然后返回新的值,从而达到处理业务逻辑的目的; 43 | @parameter key :该model的属性名 44 | @parameter value :从字典里取出来的原始值,还未做自动映射 45 | 框架会将返回值进行自动映射! 46 | */ 47 | - (id)sc_key:(NSString *)key beforeAssignedValue:(id)value refObj:(id)refObj; 48 | 49 | /** 50 | * @brief:JOSN 转 Model即将完成,你可以在这里做最后的自定义解析,以完成复杂的转换! 51 | @parameter data :服务器返回的原始JSON数据; 52 | @parameter refObj :客户端解析时传过来的额外信息; 53 | */ 54 | - (void)sc_willFinishConvert:(id)data refObj:(id)refObj; 55 | 56 | @end 57 | 58 | 59 | @interface NSObject (SCJSON2Model) 60 | 61 | /** 62 | * @brief:创建好对象后调用此方法,将json赋值给该modle对象; 63 | * 64 | * @param jsonDic 与model对应的json 65 | */ 66 | - (void)sc_assembleDataFormDic:(NSDictionary *)jsonDic; 67 | 68 | /** 69 | * @brief:创建一个已经赋过值的model对像; 70 | * if jsonDic is nil or empty return nil; 71 | * 72 | * @param jsonDic 与 modle 属性对应的字典 73 | */ 74 | + (instancetype)sc_instanceFormDic:(NSDictionary *)jsonDic; 75 | 76 | /** 77 | * @brief:jsonArr数组--》model数组,if jsonArr is nil or empty return nil; 78 | */ 79 | + (NSArray *)sc_instanceArrFormArray:(NSArray *)jsonArr; 80 | 81 | /** 82 | * @brief:自动判断Value类型进行解析 83 | * a、if value is array --> a model instances array,if JSON is nil or empty return nil; 84 | * b、if value is dictionary --> a model instance,if JSON is nil or empty return nil; 85 | * c、if caller's Class is NSNumber、NSString、NSURL or NSDecimalNumber ; auto convert value to (the caller's Class) instance. 86 | */ 87 | + (id)sc_instanceFromValue:(id)value; 88 | 89 | @end 90 | 91 | 92 | #pragma mark - JOSNUtil c functions 93 | 94 | /** 95 | @brief 很方便的一个c方法,将 JSON 转为 Model,可用将 JSON 数据解析成 Model 对象! 96 | 97 | @param json 服务器返回的JSON 98 | @param modelName 客户端定义的Model类类名, 或者系统的 NSNumber、NSString、NSURL、NSDecimalNumber 99 | @return Model类的实例对象 100 | */ 101 | FOUNDATION_EXPORT id SCJSON2Model(id json, NSString *modelName); 102 | 103 | /** 104 | @brief 同 SCJSON2Model 105 | @param refObj 客户端传递的额外参数,辅助解析;具体参考 Video.json 解析成 DynamicVideos 的例子! 106 | */ 107 | FOUNDATION_EXPORT id SCJSON2ModelV2(id json, NSString *modelName, id refObj); 108 | 109 | /** 110 | * @brief 根据 pathArr 找到目标 JSON,可辅助 JSON2Model 函数使用,先找到目标 JOSN 再解析; 111 | * @param pathArr 查找目标 JSON 的路径数组;@[@"data"], @[@"data",@"list"] 112 | */ 113 | 114 | FOUNDATION_EXPORT id SCFindJSONwithKeyPathArr(NSArray *pathArr, NSDictionary *json); 115 | 116 | /** 117 | * @brief 根据 keyPath 找到目标 JSON,可辅助 JSON2Model 函数使用,先找到目标 JOSN 再解析; 118 | * @param keyPath 查找目标 JSON 的路径;以 / 为分割的字符;例如:@"data", @"data/list",@"data/detail/price"; 119 | */ 120 | FOUNDATION_EXPORT id SCFindJSONwithKeyPath(NSString *keyPath, NSDictionary *json); 121 | 122 | /** 123 | * @brief see SCFindJSONwithKeyPath 124 | * @param keyPath JSON 数据里的一个路径 125 | * @param separator 指定分割字符; 126 | */ 127 | FOUNDATION_EXPORT id SCFindJSONwithKeyPathV2(NSString *keyPath, NSDictionary *JSON, NSString *separator); 128 | 129 | /** 130 | * @brief 将 JSON 对象转成字符串(url类型不会将 / 转义为 \\/) 131 | * @param json JSON 对像 132 | * @param prettyPrinted 是否需要打印的更漂亮,自动换行、缩进 133 | */ 134 | FOUNDATION_EXPORT NSString *JSON2String(id json, BOOL prettyPrinted); 135 | -------------------------------------------------------------------------------- /SCJSONUtil/SCJSONUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCJSONUtil.m 3 | // 4 | // Created by xuqianlong on 15/9/3. 5 | // Copyright (c) 2015年 Mac. All rights reserved. 6 | // 7 | 8 | #import "SCJSONUtil.h" 9 | #import "objc/runtime.h" 10 | #import "scutil.h" 11 | 12 | static BOOL s_SCJSONUtilLogOn = NO; 13 | 14 | void SCJSONUtilLog(BOOL on) { 15 | s_SCJSONUtilLogOn = on; 16 | } 17 | 18 | BOOL isSCJSONUtilLogOn(void) { 19 | return s_SCJSONUtilLogOn; 20 | } 21 | 22 | #define SCJSONLog(...) do{ \ 23 | if (s_SCJSONUtilLogOn) { \ 24 | NSLog(__VA_ARGS__); \ 25 | } \ 26 | }while(0) 27 | 28 | #define SCJSONError(...) do{ \ 29 | NSLog(__VA_ARGS__); \ 30 | }while(0) 31 | 32 | typedef NS_ENUM(NSUInteger, QLPropertyType) { 33 | QLPropertyTypeUnknow, 34 | QLPropertyTypeId = '*', 35 | QLPropertyTypeObj = '@', 36 | QLPropertyTypeFloat = 'f', 37 | QLPropertyTypeDouble = 'd', 38 | QLPropertyTypeBOOL = 'B', 39 | QLPropertyTypeBool = QLPropertyTypeBOOL, 40 | QLPropertyTypeInt8 = 'c', 41 | QLPropertyTypeUInt8 = 'C', 42 | QLPropertyTypeInt16 = 's', 43 | QLPropertyTypeUInt16 = 'S', 44 | QLPropertyTypeInt32 = 'i', 45 | QLPropertyTypeUInt32 = 'I', 46 | QLPropertyTypeLong32 = 'l', //32位机器 long 型 47 | QLPropertyTypeULong32 = 'L', //32位机器 unsigned long 型 48 | QLPropertyTypeInt64 = 'q', //32位机器 long long 类型;64位机器 long long 和 long 类型 49 | QLPropertyTypeUInt64 = 'Q' //32位机器 unsigned long long 类型;64位机器 unsigned long long 和 unsigned long 类型 50 | }; 51 | 52 | typedef struct QLPropertyDescS { 53 | QLPropertyType type; 54 | char * clazz; 55 | } QLPropertyDesc; 56 | 57 | #pragma mark - C Functions -Begin- 58 | 59 | #pragma mark 【Utils】 60 | 61 | static void *QLMallocInit(size_t __size) { 62 | void *p = malloc(__size); 63 | memset(p, 0, __size); 64 | return p; 65 | } 66 | 67 | static QLPropertyDesc * QLPropertyDescForClassProperty(Class clazz, const char *key) { 68 | objc_property_t property = class_getProperty(clazz, key); 69 | if (NULL == property) { 70 | return NULL; 71 | } 72 | // 2.成员类型 73 | const char *encodedType = property_getAttributes(property); 74 | //TB,N,V_boolType 75 | //T@"NSString",C,N,V_stringType 76 | //T@,&,N,V_idType 77 | //T@"NSString",R,C description debugDescription 78 | //T#,R superclass 79 | //TQ,R hash 80 | NSString *encodedStr = [[NSString alloc] initWithCString:encodedType encoding:NSUTF8StringEncoding]; 81 | NSArray *items = [encodedStr componentsSeparatedByString:@","]; 82 | //skip the readonly property. fix [ setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key description.' 83 | if ([items containsObject:@"R"]) { 84 | return NULL; 85 | } 86 | 87 | NSString *varFullType = [items firstObject]; 88 | 89 | if (varFullType.length >= 2) { 90 | const char iType = [varFullType characterAtIndex:1]; 91 | switch (iType) { 92 | case QLPropertyTypeObj: 93 | { 94 | //属性是对象类型,这里取出对象的类型,id取不出来; 95 | bool isID = [@"T@" isEqualToString:varFullType]; 96 | if (isID) { 97 | QLPropertyDesc *desc = (QLPropertyDesc *)QLMallocInit(sizeof(QLPropertyDesc)); 98 | desc->type = QLPropertyTypeId; 99 | return desc; 100 | } else { 101 | NSString *varType = [varFullType substringFromIndex:2]; 102 | varType = [varType stringByReplacingOccurrencesOfString:@"\"" withString:@""]; 103 | QLPropertyDesc *desc = (QLPropertyDesc *)QLMallocInit(sizeof(QLPropertyDesc)); 104 | char *pclazz = (char *)QLMallocInit(varType.length + 1); 105 | strcpy(pclazz, varType.UTF8String); 106 | desc->clazz = pclazz; 107 | desc->type = iType; 108 | return desc; 109 | } 110 | } 111 | break; 112 | case QLPropertyTypeFloat: 113 | case QLPropertyTypeDouble: 114 | case QLPropertyTypeBOOL: 115 | case QLPropertyTypeInt8: 116 | case QLPropertyTypeUInt8: 117 | case QLPropertyTypeInt16: 118 | case QLPropertyTypeUInt16: 119 | case QLPropertyTypeInt32: 120 | case QLPropertyTypeUInt32: 121 | case QLPropertyTypeLong32: 122 | case QLPropertyTypeULong32: 123 | case QLPropertyTypeInt64: 124 | case QLPropertyTypeUInt64: 125 | { 126 | QLPropertyDesc *desc = QLMallocInit(sizeof(QLPropertyDesc));//must init!!! iphone 5 crash,clazz is empty string : '' ; 127 | desc->type = iType; 128 | return desc; 129 | } 130 | break; 131 | 132 | default: // #:^ igonre:Class,SEL,Method... 133 | { 134 | SCJSONLog(@"unrecognized type:%c",iType); 135 | } 136 | break; 137 | } 138 | } 139 | return NULL; 140 | } 141 | 142 | #pragma mark 【ValueTransfer】 143 | 144 | static NSString * QLValueTransfer2NSString(id value) { 145 | return [value description]; 146 | } 147 | 148 | static NSNumber * QLValueTransfer2NSNumber(id value) { 149 | if ([value isKindOfClass:[NSString class]]) { 150 | NSNumberFormatter *numberFormatter = [[NSNumberFormatter alloc] init]; 151 | return [numberFormatter numberFromString:value]; 152 | } else if ([value isKindOfClass:[NSNumber class]]) { 153 | return value; 154 | } 155 | return nil; 156 | } 157 | 158 | static NSDecimalNumber * QLValueTransfer2NSDecimalNumber(id value) { 159 | if ([value isKindOfClass:[NSString class]]) { 160 | return [NSDecimalNumber decimalNumberWithString:value]; 161 | } 162 | return nil; 163 | } 164 | 165 | static NSURL * QLValueTransfer2NSURL(id value) { 166 | if ([value isKindOfClass:[NSString class]]) { 167 | NSString *str = (NSString *)value; 168 | if ([str hasPrefix:@"file://"]) { 169 | str = [str stringByReplacingOccurrencesOfString:@"file://" withString:@""]; 170 | return [NSURL fileURLWithPath:str]; 171 | } 172 | return [NSURL URLWithString:str]; 173 | } 174 | return nil; 175 | } 176 | 177 | #pragma mark C Functions -End- 178 | #pragma mark - 179 | 180 | @implementation NSObject (SCJSON2Model) 181 | 182 | - (void)sc_findPropertyFromCollideKeyMap:(NSString *)serverKey 183 | forValue:(id)serverValue 184 | completion:(void(^)(NSString *, NSString *,id))comp 185 | { 186 | id_self = (id)self; 187 | if ([_self respondsToSelector:@selector(sc_collideKeysMap)]) { 188 | NSDictionary *map = [_self sc_collideKeysMap]; 189 | NSString * mappedName = map[serverKey]; 190 | //严格匹配上了,意味着很明确要映射 191 | if (mappedName) { 192 | if (comp) { 193 | //此时仍然使用 serverKey 作为后续的查询 Model 类名的 key 194 | comp(mappedName,serverKey,serverValue); 195 | } 196 | return; 197 | } 198 | //下面是支持 keypath 查找的逻辑 199 | __block BOOL matched = NO; 200 | [map enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull customServerKey, NSString * _Nonnull mappedPropertyName, BOOL * _Nonnull stop) { 201 | //自定义了属性名,将服务器返回的值根据keypath进一步查找,然后对应到自定义的属性名上 202 | if ([customServerKey hasPrefix:serverKey]) { 203 | NSRange range = [customServerKey rangeOfString:@"."]; 204 | if (range.location != NSNotFound) { 205 | if([serverValue isKindOfClass:[NSDictionary class]]) { 206 | NSString *targetKey = [customServerKey substringFromIndex:range.location + range.length]; 207 | id mappedValue = [serverValue valueForKeyPath:targetKey]; 208 | //确定一个keypath查找就invoke下;但仍旧继续遍历,以处理通过多个 keypath 查找同一个字段下的多个子字段情况 @{@"data.a":"a",@"data.b":"b"} 209 | if (comp) { 210 | comp(mappedPropertyName,customServerKey,mappedValue); 211 | } 212 | matched = YES; 213 | } 214 | } 215 | } 216 | }]; 217 | //遍历完了还没匹配上,说明没有配置映射 218 | if (!matched) { 219 | if (comp) { 220 | comp(nil,serverKey,serverValue); 221 | } 222 | } 223 | } else { 224 | //默认情况下,把服务器返回的字段名,当做model的属性名 225 | if (comp) { 226 | comp(nil,serverKey,serverValue); 227 | } 228 | } 229 | } 230 | 231 | - (void)sc_resolveunDefinedKey:(NSString *)propertyName 232 | forValue:(id)propertyValue 233 | refObj:(id)refObj 234 | completion:(void(^)(NSString *, NSString *,id))comp 235 | { 236 | NSString *outName = propertyName; 237 | id outValue = propertyValue; 238 | 239 | id_self = (id)self; 240 | if ([_self respondsToSelector:@selector(sc_unDefinedKey:forValue:refObj:)] && [_self sc_unDefinedKey:&outName forValue:&outValue refObj:refObj]) { 241 | SCJSONLog(@"mapped server key:%@->%@.%@",propertyName,NSStringFromClass([self class]),outName); 242 | if (outName.length > 0) { 243 | if (comp) { 244 | //此时使用自定义映射属性名 outName 作为后续的查询 Model 类名的 key 245 | comp(outName,outName,outValue); 246 | } 247 | return; 248 | } 249 | } else { 250 | NSString *propertyClass = NSStringFromClass([propertyValue class]); 251 | if ([propertyClass hasPrefix:@"__"]) { 252 | propertyClass = NSStringFromClass([propertyValue superclass]); 253 | } 254 | SCJSONLog(@"igonred %@.%@,add property use %@ * %@",NSStringFromClass([self class]),propertyName,propertyClass,propertyName); 255 | } 256 | } 257 | 258 | - (void)sc_resolveProperty:(NSString *)propertyName 259 | forValue:(id)propertyValue 260 | refObj:(id)refObj 261 | completion:(void(^)(QLPropertyDesc *, NSString *, NSString *,id))comp 262 | { 263 | /* 264 | 为了支持 keypath 查找,只能优先查找 sc_collideKeysMap,否则会出现类型不匹配,出现没解析的情况! 265 | 比如:{@"activity.on" : @"activity"} 266 | */ 267 | [self sc_findPropertyFromCollideKeyMap:propertyName 268 | forValue:propertyValue 269 | completion:^(NSString *pName, NSString *mKey, id mValue) { 270 | QLPropertyDesc * pdesc = NULL; 271 | if (pName) { 272 | //通过sc_collideKeysMap提供了 273 | pdesc = QLPropertyDescForClassProperty([self class], [pName UTF8String]); 274 | } else { 275 | //当sc_collideKeysMap没提供时,就把服务区返回字段当做 Model 属性名进行试探 276 | pdesc = QLPropertyDescForClassProperty([self class], [propertyName UTF8String]); 277 | } 278 | 279 | if (pdesc) { 280 | if (pName) { 281 | comp(pdesc,pName,mKey,mValue); 282 | } else { 283 | comp(pdesc,propertyName,propertyName,propertyValue); 284 | } 285 | } else { 286 | //获取属性类型,获取不到时走 sc_unDefinedKey 来补救 287 | [self sc_resolveunDefinedKey:propertyName 288 | forValue:propertyValue 289 | refObj:refObj 290 | completion:^(NSString *aName,NSString *aKey,id aValue) { 291 | if (aName) { 292 | QLPropertyDesc * pdesc = QLPropertyDescForClassProperty([self class], [aName UTF8String]); 293 | //补救的属性存在? 294 | if (pdesc) { 295 | comp(pdesc,aName,aKey,aValue); 296 | } 297 | } 298 | }]; 299 | } 300 | }]; 301 | } 302 | 303 | - (void)sc_autoMatchValue:(id)serverValue 304 | forKey:(NSString *)serverKey 305 | refObj:(id)refObj 306 | { 307 | //1、处理属性名(顺序:根据sc_collideKeysMap获取;服务器返回的字段名;通过sc_unDefinedKey方法) 308 | [self sc_resolveProperty:serverKey 309 | forValue:serverValue 310 | refObj:refObj 311 | completion:^(QLPropertyDesc *pdesc,NSString *propertyName,NSString *modelKey,id mappedValue) { 312 | if (pdesc) { 313 | //属性描述不空,则表示有这个属性 314 | id instance = (id)self; 315 | 316 | //2、进行自动匹配赋值之前,再给客户端一次机会,可根据业务逻辑自行处理 317 | if ([instance respondsToSelector:@selector(sc_key:beforeAssignedValue:refObj:)]) { 318 | mappedValue = [instance sc_key:propertyName beforeAssignedValue:mappedValue refObj:refObj]; 319 | } 320 | 321 | //3、进入类型自动匹配流程 322 | do { 323 | //属性是 id 类型时,无法进行值的类型匹配 324 | if (pdesc->type == QLPropertyTypeId) { 325 | if (mappedValue) { 326 | [self setValue:mappedValue forKey:propertyName]; 327 | } 328 | break; 329 | } 330 | 331 | //3.1、匹配数组类型 332 | if ([mappedValue isKindOfClass:[NSArray class]]) { 333 | 334 | if (pdesc->type == QLPropertyTypeObj && (QLCStrEqual((char *)pdesc->clazz, "NSMutableArray") || QLCStrEqual((char *)pdesc->clazz, "NSArray") )) { 335 | //优先从 collideKeyModelMap 获取 Model 类名 336 | NSString *modleName = nil; 337 | if ([instance respondsToSelector:@selector(sc_collideKeyModelMap)]) { 338 | modleName = [[instance sc_collideKeyModelMap]objectForKey:modelKey]; 339 | } 340 | 341 | NSArray *objs = nil; 342 | if (modleName) { 343 | Class clazz = NSClassFromString(modleName); 344 | if (clazz) { 345 | objs = [clazz sc_instanceArrFormArray:mappedValue]; 346 | } else { 347 | SCJSONLog(@"⚠️⚠️⚠️[%@ Class] is undefined!",modleName); 348 | break; 349 | } 350 | } else { 351 | //当获取不到 Model 类名时不解析 352 | objs = [NSArray arrayWithArray:mappedValue]; 353 | } 354 | 355 | char * pclazz = pdesc->clazz; 356 | //如果属性是可变的,那么做个可变处理 357 | if (QLCStrEqual(pclazz, "NSMutableArray")) { 358 | objs = [NSMutableArray arrayWithArray:objs]; 359 | } 360 | if (objs) { 361 | [self setValue:objs forKey:propertyName]; 362 | } 363 | } else { 364 | //忽略掉 Model 属性不是 NSMutableArray/NSArray 的情况 365 | SCJSONLog(@"⚠️⚠️ %@.%@ may be: (%@*)%@",NSStringFromClass([self class]),propertyName,NSStringFromClass([mappedValue class]),propertyName); 366 | } 367 | } 368 | //3.2、匹配字典类型 369 | else if ([mappedValue isKindOfClass:[NSDictionary class]]) { 370 | //如果 property 是字典类型则直接赋值,否则执行 model 解析 371 | if (pdesc->type == QLPropertyTypeObj) { 372 | if (QLCStrEqual((char *)pdesc->clazz, "NSMutableDictionary")) { 373 | [self setValue:[mappedValue mutableCopy] forKey:propertyName]; 374 | } else if (QLCStrEqual((char *)pdesc->clazz, "NSDictionary")) { 375 | [self setValue:mappedValue forKey:propertyName]; 376 | } else { 377 | Class clazz = objc_getClass(pdesc->clazz); 378 | if (clazz) { 379 | id value = [clazz sc_instanceFormDic:mappedValue]; 380 | if (value) { 381 | [self setValue:value forKey:propertyName]; 382 | } 383 | } 384 | } 385 | } else { 386 | //忽略掉 Model 属性不是 NSMutableDictionary/NSDictionary 的情况 387 | SCJSONLog(@"⚠️⚠️ %@.%@ may be: (%@*)%@",NSStringFromClass([self class]),propertyName,NSStringFromClass([mappedValue class]),propertyName); 388 | } 389 | } 390 | //3.3、匹配非 NULL 类型 391 | else if (![mappedValue isKindOfClass:[NSNull class]]) { 392 | //简单非空类型 id,NSStirng,NSNumber,int,bool,float... 393 | switch (pdesc->type) { 394 | case QLPropertyTypeObj: 395 | { 396 | id r = nil; 397 | const char *pClazz = pdesc->clazz; 398 | //目标类型可能是id类型,直接赋值 399 | if (!pClazz) { 400 | r = mappedValue; 401 | } else if (QLCStrEqual((char *)pClazz, (char *)object_getClassName(mappedValue))) { 402 | //目标类型和值类型相同,则直接赋值 403 | r = mappedValue; 404 | } else if (QLCStrEqual((char *)pClazz, "NSString")) { 405 | //目标类型是NSString 406 | r = QLValueTransfer2NSString(mappedValue); 407 | } else if (QLCStrEqual((char *)pClazz, "NSMutableString")) { 408 | //目标类型是NSMutableString 409 | NSString *value = QLValueTransfer2NSString(mappedValue); 410 | r = [NSMutableString stringWithString:value]; 411 | } else if (QLCStrEqual((char *)pClazz, "NSNumber")) { 412 | //目标类型是NSNumber 413 | r = QLValueTransfer2NSNumber(mappedValue); 414 | } else if (QLCStrEqual((char *)pClazz, "NSDecimalNumber")) { 415 | //目标类型是NSDecimalNumber 416 | r = QLValueTransfer2NSDecimalNumber(mappedValue); 417 | } else if (QLCStrEqual((char *)pClazz, "NSURL")) { 418 | //目标类型是NSURL 419 | r = QLValueTransfer2NSURL(mappedValue); 420 | } else { 421 | SCJSONError(@"unrecognized type (%s)%@ for (%@)",pClazz,propertyName,NSStringFromClass([mappedValue class])); 422 | } 423 | 424 | if (r) { 425 | [self setValue:r forKey:propertyName]; 426 | } 427 | } 428 | break; 429 | //因为kvc本身需要的value是id类型,所以对于基本数据类型不处理,而是交给系统 KVC 处理; 430 | case QLPropertyTypeFloat: 431 | case QLPropertyTypeDouble: 432 | case QLPropertyTypeBOOL: 433 | case QLPropertyTypeInt8: 434 | case QLPropertyTypeUInt8: 435 | case QLPropertyTypeInt16: 436 | case QLPropertyTypeUInt16: 437 | case QLPropertyTypeInt32: 438 | case QLPropertyTypeUInt32: 439 | case QLPropertyTypeLong32: 440 | case QLPropertyTypeULong32: 441 | case QLPropertyTypeInt64: 442 | case QLPropertyTypeUInt64: 443 | { 444 | NSNumber *numberValue = mappedValue; 445 | //ios 8, -[__NSCFString longValue]: unrecognized selector 446 | if ([numberValue isKindOfClass:[NSString class]]) { 447 | numberValue = QLValueTransfer2NSNumber(mappedValue); 448 | } 449 | //could not set nil as the value for the scalar key(int,float,...) 450 | if (numberValue) { 451 | [self setValue:numberValue forKey:propertyName]; 452 | } 453 | } 454 | break; 455 | default: 456 | break; 457 | } 458 | } 459 | } while (0); 460 | 461 | //4、释放内存 462 | if (NULL != pdesc) { 463 | if (NULL != pdesc->clazz) { 464 | free((void *)pdesc->clazz); 465 | pdesc->clazz = NULL; 466 | } 467 | free(pdesc); 468 | pdesc = NULL; 469 | } 470 | } 471 | }]; 472 | } 473 | 474 | - (void)sc_assembleDataFormDic:(NSDictionary *)dic 475 | { 476 | [self sc_assembleDataFormDic:dic refObj:nil]; 477 | } 478 | 479 | - (void)sc_assembleDataFormDic:(NSDictionary *)dic refObj:(id)refObj 480 | { 481 | [dic enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) { 482 | [self sc_autoMatchValue:obj forKey:key refObj:refObj]; 483 | }]; 484 | 485 | id instance = (id)self; 486 | if ([instance respondsToSelector:@selector(sc_willFinishConvert:refObj:)]) { 487 | [instance sc_willFinishConvert:dic refObj:refObj]; 488 | } 489 | } 490 | 491 | + (id)sc_instanceFromValue:(id)json refObj:(id)refObj 492 | { 493 | if ([json isKindOfClass:[NSDictionary class]]) { 494 | NSObject *obj = [[self alloc]init]; 495 | [obj sc_assembleDataFormDic:json refObj:refObj]; 496 | return obj; 497 | } 498 | if ([json isKindOfClass:[NSArray class]]) { 499 | NSArray *jsonArr = json; 500 | 501 | if (!jsonArr || jsonArr.count == 0) { 502 | return nil; 503 | } 504 | 505 | NSMutableArray *modelArr = [[NSMutableArray alloc]initWithCapacity:3]; 506 | [jsonArr enumerateObjectsUsingBlock:^(id json, NSUInteger idx, BOOL *stop) { 507 | id instance = [self sc_instanceFromValue:json refObj:refObj]; 508 | if (instance) { 509 | [modelArr addObject:instance]; 510 | } else { 511 | SCJSONError(@"WTF?can't convert json [%@] to [%@]",json,NSStringFromClass([self class])); 512 | } 513 | }]; 514 | return [NSArray arrayWithArray:modelArr]; 515 | } 516 | if ([self class] == [NSNumber class]) { 517 | return QLValueTransfer2NSNumber(json); 518 | } 519 | if ([self class] == [NSString class]) { 520 | return QLValueTransfer2NSString(json); 521 | } 522 | if ([self class] == [NSURL class]) { 523 | return QLValueTransfer2NSURL(json); 524 | } 525 | if ([self class] == [NSDecimalNumber class]) { 526 | return QLValueTransfer2NSDecimalNumber(json); 527 | } 528 | SCJSONError(@"can't convert json [%@] to [%@]",json,NSStringFromClass([self class])); 529 | return nil; 530 | } 531 | 532 | + (id)sc_instanceFromValue:(id)json 533 | { 534 | return [self sc_instanceFromValue:json refObj:nil]; 535 | } 536 | 537 | + (instancetype)sc_instanceFormDic:(NSDictionary *)jsonDic 538 | { 539 | return [self sc_instanceFromValue:jsonDic]; 540 | } 541 | 542 | + (NSArray *)sc_instanceArrFormArray:(NSArray *)jsonArr 543 | { 544 | return [self sc_instanceFromValue:jsonArr]; 545 | } 546 | 547 | @end 548 | 549 | #pragma mark - JOSNUtil public c functions 550 | 551 | id SCFindJSONwithKeyPathArr(NSArray *pathArr, NSDictionary *json){ 552 | if (!json) { 553 | return nil; 554 | } 555 | if (!pathArr || pathArr.count == 0) { 556 | return json; 557 | } 558 | NSMutableArray *pathArr2 = [NSMutableArray arrayWithArray:pathArr]; 559 | 560 | while ([pathArr2 firstObject] && [[pathArr2 firstObject] description].length == 0) { 561 | [pathArr2 removeObjectAtIndex:0]; 562 | } 563 | if ([pathArr2 firstObject]) { 564 | json = [json objectForKey:[pathArr2 firstObject]]; 565 | [pathArr2 removeObjectAtIndex:0]; 566 | return SCFindJSONwithKeyPathArr(pathArr2, json); 567 | } else { 568 | return json; 569 | } 570 | } 571 | 572 | id SCFindJSONwithKeyPathV2(NSString *keyPath, NSDictionary *JSON, NSString *separator){ 573 | if (!keyPath || keyPath.length == 0) { 574 | return JSON; 575 | } 576 | if (!separator) { 577 | separator = @""; 578 | } 579 | NSArray *pathArr = [keyPath componentsSeparatedByString:separator]; 580 | return SCFindJSONwithKeyPathArr(pathArr, JSON); 581 | } 582 | 583 | id SCFindJSONwithKeyPath(NSString *keyPath, NSDictionary *json){ 584 | return SCFindJSONwithKeyPathV2(keyPath, json, @"/"); 585 | } 586 | 587 | id SCJSON2ModelV2(id json, NSString *modelName, id refObj){ 588 | Class clazz = NSClassFromString(modelName); 589 | return [clazz sc_instanceFromValue:json refObj:refObj]; 590 | } 591 | 592 | id SCJSON2Model(id json, NSString *modelName){ 593 | return SCJSON2ModelV2(json, modelName, nil); 594 | } 595 | 596 | NSString *JSON2String(id json, BOOL prettyPrinted) { 597 | if (@available(iOS 13.0,macos 10.15, watchos 6.0, tvos 13.0, *)) { 598 | NSJSONWritingOptions opts = NSJSONWritingWithoutEscapingSlashes; 599 | if (prettyPrinted) { 600 | opts |= NSJSONWritingPrettyPrinted; 601 | } 602 | NSData *data = [NSJSONSerialization dataWithJSONObject:json options:opts error:nil]; 603 | if (data) { 604 | return [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 605 | } 606 | } else { 607 | NSData *data = [NSJSONSerialization dataWithJSONObject:json options:prettyPrinted ? NSJSONWritingPrettyPrinted:0 error:nil]; 608 | if (data) { 609 | NSString *jsonStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; 610 | return [jsonStr stringByReplacingOccurrencesOfString:@"\\/" withString:@"/"]; 611 | } 612 | } 613 | return nil; 614 | } 615 | -------------------------------------------------------------------------------- /SCJSONUtil/SCModelUtil.h: -------------------------------------------------------------------------------- 1 | // 2 | // SCModelUtil.h 3 | // SCJSONUtil 4 | // 5 | // Created by qianlongxu on 2020/11/15. 6 | // 7 | 8 | #import 9 | 10 | NS_ASSUME_NONNULL_BEGIN 11 | 12 | @interface NSObject(SCModel2JSON) 13 | 14 | /** 15 | * @brief:将 model 对象转成 json 对象 16 | */ 17 | - (id)sc_toJSON; 18 | 19 | /** 20 | * @brief:将 model 对象转成 json 对象,字典key值有所不同 21 | * 22 | * @param printProperyType 23 | * YES:字典key值会带上Modle里定义的类型,用于debug时查看,不适合发送给服务器等场景! 24 | * NO:等同于 sc_toJSON; 25 | */ 26 | - (id)sc_toJSONWithProperyType:(BOOL)printProperyType; 27 | 28 | @end 29 | 30 | NS_ASSUME_NONNULL_END 31 | -------------------------------------------------------------------------------- /SCJSONUtil/SCModelUtil.m: -------------------------------------------------------------------------------- 1 | // 2 | // SCModelUtil.m 3 | // SCJSONUtil 4 | // 5 | // Created by qianlongxu on 2020/11/15. 6 | // 7 | 8 | #import "SCModelUtil.h" 9 | #import "objc/runtime.h" 10 | #import "scutil.h" 11 | 12 | @implementation NSObject (SCModel2JSON) 13 | 14 | - (NSArray *)sc_propertyNames 15 | { 16 | NSArray *ignoreArr = @[@"superclass", @"description", @"debugDescription", @"hash"]; 17 | 18 | NSArray *(^propertiesForClass)(Class clazz) = ^ NSArray * (Class clazz) { 19 | unsigned int count = 0; 20 | objc_property_t *properties = class_copyPropertyList(clazz, &count); 21 | NSMutableArray *propertyNames = [NSMutableArray array]; 22 | for (int i = 0; i < count; i++) { 23 | NSString *key = [NSString stringWithUTF8String:property_getName(properties[i])]; 24 | if (key) { 25 | if ([ignoreArr containsObject:key]) { 26 | continue; 27 | } 28 | [propertyNames addObject:key]; 29 | } 30 | } 31 | free(properties); 32 | return propertyNames; 33 | }; 34 | 35 | NSMutableArray *properties = [NSMutableArray array]; 36 | Class supclass = [self class]; 37 | do { 38 | NSMutableDictionary *propertyDic = [NSMutableDictionary dictionary]; 39 | [propertyDic setObject:propertiesForClass(supclass) forKey:@"property"]; 40 | [propertyDic setObject:NSStringFromClass(supclass) forKey:@"name"]; 41 | [properties addObject:propertyDic]; 42 | supclass = [supclass superclass]; 43 | } while (supclass != [NSObject class]); 44 | 45 | return [properties copy]; 46 | } 47 | 48 | - (NSString *)sc_typeForProperty:(NSString *)name 49 | { 50 | objc_property_t property = class_getProperty([self class], [name UTF8String]); 51 | if (NULL == property) { 52 | return NULL; 53 | } 54 | // 2.成员类型 55 | const char *encodedType = property_getAttributes(property); 56 | //TB,N,V_boolType 57 | //T@"NSString",C,N,V_stringType 58 | //T@,&,N,V_idType 59 | char *comma = strchr(encodedType, ','); 60 | int bufferLen = (int)(comma - encodedType + 1); 61 | char fullType[bufferLen]; 62 | bzero(fullType, bufferLen); 63 | sscanf(encodedType,"%[^,]",fullType); 64 | 65 | if (strlen(fullType)>=2) { 66 | const char iType = fullType[1]; 67 | switch (iType) { 68 | case '@': 69 | { 70 | //属性是对象类型,这里取出对象的类型,id取不出来; 71 | bool isID = QLCStrEqual("T@", fullType); 72 | if (isID) { 73 | return @"id"; 74 | } else { 75 | char buffer [bufferLen + 1]; 76 | bzero(buffer, bufferLen + 1); 77 | sscanf(fullType, "%*[^\"]\"%[^\"]",buffer); 78 | buffer[strlen(buffer)] = '*'; 79 | return [[NSString alloc]initWithCString:buffer encoding:NSUTF8StringEncoding]; 80 | } 81 | } 82 | break; 83 | case 'f': 84 | { 85 | return @"float"; 86 | } 87 | case 'd': 88 | { 89 | return @"double"; 90 | } 91 | case 'B': 92 | { 93 | return @"BOOL"; 94 | } 95 | case 'c': 96 | { 97 | return @"char"; 98 | } 99 | case 'C': 100 | { 101 | return @"unsigned char"; 102 | } 103 | case 's': 104 | { 105 | return @"short"; 106 | } 107 | case 'S': 108 | { 109 | return @"unsigned short"; 110 | } 111 | case 'i': 112 | { 113 | return @"int"; 114 | } 115 | case 'I': 116 | { 117 | return @"unsigned int"; 118 | } 119 | case 'l': 120 | { 121 | return @"long"; 122 | } 123 | case 'L': 124 | { 125 | return @"unsigned long"; 126 | } 127 | case 'q': 128 | { 129 | return @"long long"; 130 | } 131 | case 'Q': 132 | { 133 | return @"unsigned long long"; 134 | } 135 | default: // #:^ igonre:Class,SEL,Method... 136 | { 137 | return @"unknown"; 138 | } 139 | break; 140 | } 141 | } 142 | return @"unknown"; 143 | } 144 | 145 | - (id)sc_toJSON 146 | { 147 | return [self sc_toJSONWithProperyType:NO]; 148 | } 149 | 150 | - (id)sc_toJSONWithProperyType:(BOOL)printProperyType 151 | { 152 | if ([self isKindOfClass:[NSArray class]]) { 153 | NSMutableArray *json = [NSMutableArray array]; 154 | NSArray *arr = (NSArray *)self; 155 | for (NSObject *obj in arr) { 156 | id o = [obj sc_toJSONWithProperyType:printProperyType]; 157 | if (o) { 158 | [json addObject:o]; 159 | } 160 | } 161 | return [json copy]; 162 | } else if ([self isKindOfClass:[NSDictionary class]]) { 163 | NSMutableDictionary *json = [NSMutableDictionary dictionary]; 164 | NSDictionary *dic = (NSDictionary *)self; 165 | [dic enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) { 166 | id o = [obj sc_toJSONWithProperyType:printProperyType]; 167 | if (o) { 168 | [json setObject:o forKey:key]; 169 | } 170 | }]; 171 | return [json copy]; 172 | } else if ([self isKindOfClass:[NSNumber class]]) { 173 | return self; 174 | } else if ([self isKindOfClass:[NSNull class]]) { 175 | return [self description]; 176 | } else if ([self isKindOfClass:[NSURL class]]) { 177 | NSURL *url = (NSURL *)self; 178 | return [url absoluteString]; 179 | } else if ([self isKindOfClass:[NSString class]]) { 180 | return [self description]; 181 | } else if ([self isKindOfClass:[NSDate class]]) { 182 | return [self description]; 183 | } else { 184 | NSArray *propertiesForClass = [self sc_propertyNames]; 185 | NSMutableDictionary *json = [NSMutableDictionary dictionary]; 186 | for (NSDictionary *propertyDic in propertiesForClass) { 187 | NSArray *properties = [propertyDic objectForKey:@"property"]; 188 | for (NSString *property in properties) { 189 | id propertyValue = [self valueForKey:property]; 190 | NSString *aKey = property; 191 | if (printProperyType) { 192 | aKey = [NSString stringWithFormat:@"%@ %@",[self sc_typeForProperty:property],property]; 193 | } 194 | id obj = [propertyValue sc_toJSONWithProperyType:printProperyType]; 195 | if (obj) { 196 | [json setObject:obj forKey:aKey]; 197 | } 198 | } 199 | } 200 | return json; 201 | } 202 | } 203 | 204 | @end 205 | -------------------------------------------------------------------------------- /SCJSONUtil/internal/scutil.c: -------------------------------------------------------------------------------- 1 | // 2 | // scutil.c 3 | // SCJSONUtil 4 | // 5 | // Created by qianlongxu on 2020/11/15. 6 | // 7 | 8 | #include "scutil.h" 9 | #include 10 | 11 | bool QLCStrEqual(char *v1,char *v2) { 12 | if (NULL == v1 || NULL == v2) { 13 | return 0; 14 | } 15 | return 0 == strcmp(v1, v2); 16 | } 17 | -------------------------------------------------------------------------------- /SCJSONUtil/internal/scutil.h: -------------------------------------------------------------------------------- 1 | // 2 | // scutil.h 3 | // SCJSONUtil 4 | // 5 | // Created by qianlongxu on 2020/11/15. 6 | // 7 | 8 | #ifndef scutil_h 9 | #define scutil_h 10 | 11 | #include 12 | #include 13 | 14 | bool QLCStrEqual(char *v1,char *v2); 15 | 16 | #endif /* scutil_h */ 17 | --------------------------------------------------------------------------------