├── .gitignore
├── .swiftpm
└── xcode
│ └── package.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── Example
├── JSONViewExample.xcodeproj
│ ├── project.pbxproj
│ └── project.xcworkspace
│ │ ├── contents.xcworkspacedata
│ │ └── xcshareddata
│ │ └── IDEWorkspaceChecks.plist
└── JSONViewExample
│ ├── AppDelegate.swift
│ ├── Assets.xcassets
│ ├── AppIcon.appiconset
│ │ └── Contents.json
│ └── Contents.json
│ ├── Base.lproj
│ └── LaunchScreen.storyboard
│ ├── ContentView.swift
│ ├── Info.plist
│ ├── Preview Content
│ └── Preview Assets.xcassets
│ │ └── Contents.json
│ ├── SceneDelegate.swift
│ └── appStore-receipt.json
├── JSONView.podspec
├── JSONView.xcodeproj
├── JSONView_Info.plist
├── project.pbxproj
├── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ │ ├── IDEWorkspaceChecks.plist
│ │ └── WorkspaceSettings.xcsettings
└── xcshareddata
│ └── xcschemes
│ └── JSONView.xcscheme
├── JSONView
├── Info.plist
└── JSONView.h
├── LICENSE
├── Package.swift
├── README.md
├── Sources
└── JSONView
│ ├── JSONCell.swift
│ ├── JSONTreeView.swift
│ └── JSONView.swift
├── Tests
└── JSONViewTests
│ └── .gitkeep
└── resources
└── example-of-usage.gif
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | # Created by https://www.gitignore.io/api/xcode,swiftpm,carthage,cocoapods
3 | # Edit at https://www.gitignore.io/?templates=xcode,swiftpm,carthage,cocoapods
4 |
5 | ### Carthage ###
6 | # Carthage
7 | #
8 | # Add this line if you want to avoid checking in source code from Carthage dependencies.
9 | # Carthage/Checkouts
10 |
11 | Carthage/Build
12 |
13 | ### CocoaPods ###
14 | ## CocoaPods GitIgnore Template
15 |
16 | # CocoaPods - Only use to conserve bandwidth / Save time on Pushing
17 | # - Also handy if you have a large number of dependant pods
18 | # - AS PER https://guides.cocoapods.org/using/using-cocoapods.html NEVER IGNORE THE LOCK FILE
19 | Pods/
20 |
21 | ### SwiftPM ###
22 | Packages
23 | .build/
24 | xcuserdata
25 | DerivedData/
26 | #*.xcodeproj
27 |
28 |
29 | ### Xcode ###
30 | # Xcode
31 | # gitignore contributors: remember to update Global/Xcode.gitignore, Objective-C.gitignore & Swift.gitignore
32 |
33 | ## User settings
34 | xcuserdata/
35 |
36 | ## compatibility with Xcode 8 and earlier (ignoring not required starting Xcode 9)
37 | *.xcscmblueprint
38 | *.xccheckout
39 |
40 | ## compatibility with Xcode 3 and earlier (ignoring not required starting Xcode 4)
41 | build/
42 | *.moved-aside
43 | *.pbxuser
44 | !default.pbxuser
45 | *.mode1v3
46 | !default.mode1v3
47 | *.mode2v3
48 | !default.mode2v3
49 | *.perspectivev3
50 | !default.perspectivev3
51 |
52 | ## Xcode Patch
53 | *.xcodeproj/*
54 | !*.xcodeproj/project.pbxproj
55 | !*.xcodeproj/xcshareddata/
56 | !*.xcworkspace/contents.xcworkspacedata
57 | /*.gcno
58 |
59 | ### Xcode Patch ###
60 | **/xcshareddata/WorkspaceSettings.xcsettings
61 |
62 | # End of https://www.gitignore.io/api/xcode,swiftpm,carthage,cocoapods
63 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.swiftpm/xcode/package.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/JSONViewExample.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 50;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 66D4490D244970E8008A4CCB /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4490C244970E8008A4CCB /* AppDelegate.swift */; };
11 | 66D4490F244970E8008A4CCB /* SceneDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4490E244970E8008A4CCB /* SceneDelegate.swift */; };
12 | 66D44911244970E8008A4CCB /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D44910244970E8008A4CCB /* ContentView.swift */; };
13 | 66D44913244970EA008A4CCB /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 66D44912244970EA008A4CCB /* Assets.xcassets */; };
14 | 66D44916244970EA008A4CCB /* Preview Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 66D44915244970EA008A4CCB /* Preview Assets.xcassets */; };
15 | 66D44919244970EA008A4CCB /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 66D44917244970EA008A4CCB /* LaunchScreen.storyboard */; };
16 | 66D44924244974A0008A4CCB /* appStore-receipt.json in Resources */ = {isa = PBXBuildFile; fileRef = 66D449202449733C008A4CCB /* appStore-receipt.json */; };
17 | 66D44950244980FC008A4CCB /* JSONTreeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494D244980FC008A4CCB /* JSONTreeView.swift */; };
18 | 66D44951244980FC008A4CCB /* JSONCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494E244980FC008A4CCB /* JSONCell.swift */; };
19 | 66D44952244980FC008A4CCB /* JSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494F244980FC008A4CCB /* JSONView.swift */; };
20 | /* End PBXBuildFile section */
21 |
22 | /* Begin PBXFileReference section */
23 | 66D44909244970E8008A4CCB /* JSONViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = JSONViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
24 | 66D4490C244970E8008A4CCB /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; };
25 | 66D4490E244970E8008A4CCB /* SceneDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SceneDelegate.swift; sourceTree = ""; };
26 | 66D44910244970E8008A4CCB /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; };
27 | 66D44912244970EA008A4CCB /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
28 | 66D44915244970EA008A4CCB /* Preview Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "Preview Assets.xcassets"; sourceTree = ""; };
29 | 66D44918244970EA008A4CCB /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
30 | 66D4491A244970EA008A4CCB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
31 | 66D449202449733C008A4CCB /* appStore-receipt.json */ = {isa = PBXFileReference; lastKnownFileType = text.json; path = "appStore-receipt.json"; sourceTree = ""; };
32 | 66D4494D244980FC008A4CCB /* JSONTreeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONTreeView.swift; path = ../../Sources/JSONView/JSONTreeView.swift; sourceTree = ""; };
33 | 66D4494E244980FC008A4CCB /* JSONCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONCell.swift; path = ../../Sources/JSONView/JSONCell.swift; sourceTree = ""; };
34 | 66D4494F244980FC008A4CCB /* JSONView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONView.swift; path = ../../Sources/JSONView/JSONView.swift; sourceTree = ""; };
35 | /* End PBXFileReference section */
36 |
37 | /* Begin PBXFrameworksBuildPhase section */
38 | 66D44906244970E8008A4CCB /* Frameworks */ = {
39 | isa = PBXFrameworksBuildPhase;
40 | buildActionMask = 2147483647;
41 | files = (
42 | );
43 | runOnlyForDeploymentPostprocessing = 0;
44 | };
45 | /* End PBXFrameworksBuildPhase section */
46 |
47 | /* Begin PBXGroup section */
48 | 66D44900244970E8008A4CCB = {
49 | isa = PBXGroup;
50 | children = (
51 | 66D4490B244970E8008A4CCB /* JSONViewExample */,
52 | 66D4490A244970E8008A4CCB /* Products */,
53 | 66D4492124497364008A4CCB /* Frameworks */,
54 | );
55 | sourceTree = "";
56 | };
57 | 66D4490A244970E8008A4CCB /* Products */ = {
58 | isa = PBXGroup;
59 | children = (
60 | 66D44909244970E8008A4CCB /* JSONViewExample.app */,
61 | );
62 | name = Products;
63 | sourceTree = "";
64 | };
65 | 66D4490B244970E8008A4CCB /* JSONViewExample */ = {
66 | isa = PBXGroup;
67 | children = (
68 | 66D4494C244980ED008A4CCB /* JSONView */,
69 | 66D4490C244970E8008A4CCB /* AppDelegate.swift */,
70 | 66D4490E244970E8008A4CCB /* SceneDelegate.swift */,
71 | 66D44910244970E8008A4CCB /* ContentView.swift */,
72 | 66D449202449733C008A4CCB /* appStore-receipt.json */,
73 | 66D44912244970EA008A4CCB /* Assets.xcassets */,
74 | 66D44917244970EA008A4CCB /* LaunchScreen.storyboard */,
75 | 66D4491A244970EA008A4CCB /* Info.plist */,
76 | 66D44914244970EA008A4CCB /* Preview Content */,
77 | );
78 | path = JSONViewExample;
79 | sourceTree = "";
80 | };
81 | 66D44914244970EA008A4CCB /* Preview Content */ = {
82 | isa = PBXGroup;
83 | children = (
84 | 66D44915244970EA008A4CCB /* Preview Assets.xcassets */,
85 | );
86 | path = "Preview Content";
87 | sourceTree = "";
88 | };
89 | 66D4492124497364008A4CCB /* Frameworks */ = {
90 | isa = PBXGroup;
91 | children = (
92 | );
93 | name = Frameworks;
94 | sourceTree = "";
95 | };
96 | 66D4494C244980ED008A4CCB /* JSONView */ = {
97 | isa = PBXGroup;
98 | children = (
99 | 66D4494E244980FC008A4CCB /* JSONCell.swift */,
100 | 66D4494D244980FC008A4CCB /* JSONTreeView.swift */,
101 | 66D4494F244980FC008A4CCB /* JSONView.swift */,
102 | );
103 | name = JSONView;
104 | sourceTree = "";
105 | };
106 | /* End PBXGroup section */
107 |
108 | /* Begin PBXNativeTarget section */
109 | 66D44908244970E8008A4CCB /* JSONViewExample */ = {
110 | isa = PBXNativeTarget;
111 | buildConfigurationList = 66D4491D244970EA008A4CCB /* Build configuration list for PBXNativeTarget "JSONViewExample" */;
112 | buildPhases = (
113 | 66D44905244970E8008A4CCB /* Sources */,
114 | 66D44906244970E8008A4CCB /* Frameworks */,
115 | 66D44907244970E8008A4CCB /* Resources */,
116 | );
117 | buildRules = (
118 | );
119 | dependencies = (
120 | );
121 | name = JSONViewExample;
122 | packageProductDependencies = (
123 | );
124 | productName = Example;
125 | productReference = 66D44909244970E8008A4CCB /* JSONViewExample.app */;
126 | productType = "com.apple.product-type.application";
127 | };
128 | /* End PBXNativeTarget section */
129 |
130 | /* Begin PBXProject section */
131 | 66D44901244970E8008A4CCB /* Project object */ = {
132 | isa = PBXProject;
133 | attributes = {
134 | LastSwiftUpdateCheck = 1140;
135 | LastUpgradeCheck = 1140;
136 | ORGANIZATIONNAME = "QF Codes";
137 | TargetAttributes = {
138 | 66D44908244970E8008A4CCB = {
139 | CreatedOnToolsVersion = 11.4;
140 | };
141 | };
142 | };
143 | buildConfigurationList = 66D44904244970E8008A4CCB /* Build configuration list for PBXProject "JSONViewExample" */;
144 | compatibilityVersion = "Xcode 9.3";
145 | developmentRegion = en;
146 | hasScannedForEncodings = 0;
147 | knownRegions = (
148 | en,
149 | Base,
150 | );
151 | mainGroup = 66D44900244970E8008A4CCB;
152 | productRefGroup = 66D4490A244970E8008A4CCB /* Products */;
153 | projectDirPath = "";
154 | projectRoot = "";
155 | targets = (
156 | 66D44908244970E8008A4CCB /* JSONViewExample */,
157 | );
158 | };
159 | /* End PBXProject section */
160 |
161 | /* Begin PBXResourcesBuildPhase section */
162 | 66D44907244970E8008A4CCB /* Resources */ = {
163 | isa = PBXResourcesBuildPhase;
164 | buildActionMask = 2147483647;
165 | files = (
166 | 66D44924244974A0008A4CCB /* appStore-receipt.json in Resources */,
167 | 66D44919244970EA008A4CCB /* LaunchScreen.storyboard in Resources */,
168 | 66D44916244970EA008A4CCB /* Preview Assets.xcassets in Resources */,
169 | 66D44913244970EA008A4CCB /* Assets.xcassets in Resources */,
170 | );
171 | runOnlyForDeploymentPostprocessing = 0;
172 | };
173 | /* End PBXResourcesBuildPhase section */
174 |
175 | /* Begin PBXSourcesBuildPhase section */
176 | 66D44905244970E8008A4CCB /* Sources */ = {
177 | isa = PBXSourcesBuildPhase;
178 | buildActionMask = 2147483647;
179 | files = (
180 | 66D44952244980FC008A4CCB /* JSONView.swift in Sources */,
181 | 66D4490D244970E8008A4CCB /* AppDelegate.swift in Sources */,
182 | 66D4490F244970E8008A4CCB /* SceneDelegate.swift in Sources */,
183 | 66D44951244980FC008A4CCB /* JSONCell.swift in Sources */,
184 | 66D44950244980FC008A4CCB /* JSONTreeView.swift in Sources */,
185 | 66D44911244970E8008A4CCB /* ContentView.swift in Sources */,
186 | );
187 | runOnlyForDeploymentPostprocessing = 0;
188 | };
189 | /* End PBXSourcesBuildPhase section */
190 |
191 | /* Begin PBXVariantGroup section */
192 | 66D44917244970EA008A4CCB /* LaunchScreen.storyboard */ = {
193 | isa = PBXVariantGroup;
194 | children = (
195 | 66D44918244970EA008A4CCB /* Base */,
196 | );
197 | name = LaunchScreen.storyboard;
198 | sourceTree = "";
199 | };
200 | /* End PBXVariantGroup section */
201 |
202 | /* Begin XCBuildConfiguration section */
203 | 66D4491B244970EA008A4CCB /* Debug */ = {
204 | isa = XCBuildConfiguration;
205 | buildSettings = {
206 | ALWAYS_SEARCH_USER_PATHS = NO;
207 | CLANG_ANALYZER_NONNULL = YES;
208 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
209 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
210 | CLANG_CXX_LIBRARY = "libc++";
211 | CLANG_ENABLE_MODULES = YES;
212 | CLANG_ENABLE_OBJC_ARC = YES;
213 | CLANG_ENABLE_OBJC_WEAK = YES;
214 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
215 | CLANG_WARN_BOOL_CONVERSION = YES;
216 | CLANG_WARN_COMMA = YES;
217 | CLANG_WARN_CONSTANT_CONVERSION = YES;
218 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
219 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
220 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
221 | CLANG_WARN_EMPTY_BODY = YES;
222 | CLANG_WARN_ENUM_CONVERSION = YES;
223 | CLANG_WARN_INFINITE_RECURSION = YES;
224 | CLANG_WARN_INT_CONVERSION = YES;
225 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
226 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
227 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
228 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
229 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
230 | CLANG_WARN_STRICT_PROTOTYPES = YES;
231 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
232 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
233 | CLANG_WARN_UNREACHABLE_CODE = YES;
234 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
235 | COPY_PHASE_STRIP = NO;
236 | DEBUG_INFORMATION_FORMAT = dwarf;
237 | ENABLE_STRICT_OBJC_MSGSEND = YES;
238 | ENABLE_TESTABILITY = YES;
239 | GCC_C_LANGUAGE_STANDARD = gnu11;
240 | GCC_DYNAMIC_NO_PIC = NO;
241 | GCC_NO_COMMON_BLOCKS = YES;
242 | GCC_OPTIMIZATION_LEVEL = 0;
243 | GCC_PREPROCESSOR_DEFINITIONS = (
244 | "DEBUG=1",
245 | "$(inherited)",
246 | );
247 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
248 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
249 | GCC_WARN_UNDECLARED_SELECTOR = YES;
250 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
251 | GCC_WARN_UNUSED_FUNCTION = YES;
252 | GCC_WARN_UNUSED_VARIABLE = YES;
253 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
254 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
255 | MTL_FAST_MATH = YES;
256 | ONLY_ACTIVE_ARCH = YES;
257 | SDKROOT = iphoneos;
258 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
259 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
260 | };
261 | name = Debug;
262 | };
263 | 66D4491C244970EA008A4CCB /* Release */ = {
264 | isa = XCBuildConfiguration;
265 | buildSettings = {
266 | ALWAYS_SEARCH_USER_PATHS = NO;
267 | CLANG_ANALYZER_NONNULL = YES;
268 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
269 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
270 | CLANG_CXX_LIBRARY = "libc++";
271 | CLANG_ENABLE_MODULES = YES;
272 | CLANG_ENABLE_OBJC_ARC = YES;
273 | CLANG_ENABLE_OBJC_WEAK = YES;
274 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
275 | CLANG_WARN_BOOL_CONVERSION = YES;
276 | CLANG_WARN_COMMA = YES;
277 | CLANG_WARN_CONSTANT_CONVERSION = YES;
278 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
279 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
280 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
281 | CLANG_WARN_EMPTY_BODY = YES;
282 | CLANG_WARN_ENUM_CONVERSION = YES;
283 | CLANG_WARN_INFINITE_RECURSION = YES;
284 | CLANG_WARN_INT_CONVERSION = YES;
285 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
286 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
287 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
288 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
289 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
290 | CLANG_WARN_STRICT_PROTOTYPES = YES;
291 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
292 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
293 | CLANG_WARN_UNREACHABLE_CODE = YES;
294 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
295 | COPY_PHASE_STRIP = NO;
296 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
297 | ENABLE_NS_ASSERTIONS = NO;
298 | ENABLE_STRICT_OBJC_MSGSEND = YES;
299 | GCC_C_LANGUAGE_STANDARD = gnu11;
300 | GCC_NO_COMMON_BLOCKS = YES;
301 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
302 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
303 | GCC_WARN_UNDECLARED_SELECTOR = YES;
304 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
305 | GCC_WARN_UNUSED_FUNCTION = YES;
306 | GCC_WARN_UNUSED_VARIABLE = YES;
307 | IPHONEOS_DEPLOYMENT_TARGET = 13.4;
308 | MTL_ENABLE_DEBUG_INFO = NO;
309 | MTL_FAST_MATH = YES;
310 | SDKROOT = iphoneos;
311 | SWIFT_COMPILATION_MODE = wholemodule;
312 | SWIFT_OPTIMIZATION_LEVEL = "-O";
313 | VALIDATE_PRODUCT = YES;
314 | };
315 | name = Release;
316 | };
317 | 66D4491E244970EA008A4CCB /* Debug */ = {
318 | isa = XCBuildConfiguration;
319 | buildSettings = {
320 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
321 | CODE_SIGN_STYLE = Automatic;
322 | DEVELOPMENT_ASSET_PATHS = "\"JSONViewExample/Preview Content\"";
323 | DEVELOPMENT_TEAM = "";
324 | ENABLE_PREVIEWS = YES;
325 | INFOPLIST_FILE = JSONViewExample/Info.plist;
326 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
327 | LD_RUNPATH_SEARCH_PATHS = (
328 | "$(inherited)",
329 | "@executable_path/Frameworks",
330 | );
331 | PRODUCT_BUNDLE_IDENTIFIER = "com.quentin-fasquel.jsonViewExample";
332 | PRODUCT_NAME = "$(TARGET_NAME)";
333 | SWIFT_VERSION = 5.0;
334 | TARGETED_DEVICE_FAMILY = "1,2";
335 | };
336 | name = Debug;
337 | };
338 | 66D4491F244970EA008A4CCB /* Release */ = {
339 | isa = XCBuildConfiguration;
340 | buildSettings = {
341 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
342 | CODE_SIGN_STYLE = Automatic;
343 | DEVELOPMENT_ASSET_PATHS = "\"JSONViewExample/Preview Content\"";
344 | DEVELOPMENT_TEAM = "";
345 | ENABLE_PREVIEWS = YES;
346 | INFOPLIST_FILE = JSONViewExample/Info.plist;
347 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
348 | LD_RUNPATH_SEARCH_PATHS = (
349 | "$(inherited)",
350 | "@executable_path/Frameworks",
351 | );
352 | PRODUCT_BUNDLE_IDENTIFIER = "com.quentin-fasquel.jsonViewExample";
353 | PRODUCT_NAME = "$(TARGET_NAME)";
354 | SWIFT_VERSION = 5.0;
355 | TARGETED_DEVICE_FAMILY = "1,2";
356 | };
357 | name = Release;
358 | };
359 | /* End XCBuildConfiguration section */
360 |
361 | /* Begin XCConfigurationList section */
362 | 66D44904244970E8008A4CCB /* Build configuration list for PBXProject "JSONViewExample" */ = {
363 | isa = XCConfigurationList;
364 | buildConfigurations = (
365 | 66D4491B244970EA008A4CCB /* Debug */,
366 | 66D4491C244970EA008A4CCB /* Release */,
367 | );
368 | defaultConfigurationIsVisible = 0;
369 | defaultConfigurationName = Release;
370 | };
371 | 66D4491D244970EA008A4CCB /* Build configuration list for PBXNativeTarget "JSONViewExample" */ = {
372 | isa = XCConfigurationList;
373 | buildConfigurations = (
374 | 66D4491E244970EA008A4CCB /* Debug */,
375 | 66D4491F244970EA008A4CCB /* Release */,
376 | );
377 | defaultConfigurationIsVisible = 0;
378 | defaultConfigurationName = Release;
379 | };
380 | /* End XCConfigurationList section */
381 | };
382 | rootObject = 66D44901244970E8008A4CCB /* Project object */;
383 | }
384 |
--------------------------------------------------------------------------------
/Example/JSONViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/Example/JSONViewExample.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/AppDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.swift
3 | // JSONViewExample
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | // Copyright © 2020 QF CODES. All rights reserved.
7 | //
8 |
9 | import UIKit
10 |
11 | @UIApplicationMain
12 | class AppDelegate: UIResponder, UIApplicationDelegate {
13 |
14 | func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
15 | return true
16 | }
17 |
18 | // MARK: UISceneSession Lifecycle
19 |
20 | func application(_ application: UIApplication, configurationForConnecting connectingSceneSession: UISceneSession, options: UIScene.ConnectionOptions) -> UISceneConfiguration {
21 | return UISceneConfiguration(name: "Default Configuration", sessionRole: connectingSceneSession.role)
22 | }
23 |
24 | func application(_ application: UIApplication, didDiscardSceneSessions sceneSessions: Set) {
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/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 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/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 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/ContentView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // ContentView.swift
3 | // JSONViewExample
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | // Copyright © 2020 QF CODES. All rights reserved.
7 | //
8 |
9 | import SwiftUI
10 |
11 | struct ContentView: View {
12 | let url: URL = Bundle.main.url(forResource: "appStore-receipt", withExtension: "json")!
13 |
14 | @State var isPresented: Bool = false
15 |
16 | var body: some View {
17 | Button(action: toggleSheet) {
18 | Text("Open \(url.lastPathComponent)")
19 | }.sheet(isPresented: $isPresented) {
20 | JSONView(url: self.url)
21 | }
22 | }
23 |
24 | func toggleSheet() {
25 | isPresented.toggle()
26 | }
27 | }
28 |
29 | struct ContentView_Previews: PreviewProvider {
30 | static var previews: some View {
31 | ContentView()
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/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 | LSRequiresIPhoneOS
22 |
23 | UIApplicationSceneManifest
24 |
25 | UIApplicationSupportsMultipleScenes
26 |
27 | UISceneConfigurations
28 |
29 | UIWindowSceneSessionRoleApplication
30 |
31 |
32 | UISceneConfigurationName
33 | Default Configuration
34 | UISceneDelegateClassName
35 | $(PRODUCT_MODULE_NAME).SceneDelegate
36 |
37 |
38 |
39 |
40 | UILaunchStoryboardName
41 | LaunchScreen
42 | UIRequiredDeviceCapabilities
43 |
44 | armv7
45 |
46 | UISupportedInterfaceOrientations
47 |
48 | UIInterfaceOrientationPortrait
49 | UIInterfaceOrientationLandscapeLeft
50 | UIInterfaceOrientationLandscapeRight
51 |
52 | UISupportedInterfaceOrientations~ipad
53 |
54 | UIInterfaceOrientationPortrait
55 | UIInterfaceOrientationPortraitUpsideDown
56 | UIInterfaceOrientationLandscapeLeft
57 | UIInterfaceOrientationLandscapeRight
58 |
59 |
60 |
61 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/Preview Content/Preview Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/SceneDelegate.swift:
--------------------------------------------------------------------------------
1 | //
2 | // SceneDelegate.swift
3 | // JSONViewExample
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | // Copyright © 2020 QF CODES. All rights reserved.
7 | //
8 |
9 | import UIKit
10 | import SwiftUI
11 |
12 | class SceneDelegate: UIResponder, UIWindowSceneDelegate {
13 | var window: UIWindow?
14 |
15 | func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
16 | let contentView = ContentView()
17 |
18 | if let windowScene = scene as? UIWindowScene {
19 | let window = UIWindow(windowScene: windowScene)
20 | window.rootViewController = UIHostingController(rootView: contentView)
21 | self.window = window
22 | window.makeKeyAndVisible()
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/Example/JSONViewExample/appStore-receipt.json:
--------------------------------------------------------------------------------
1 | {"status":0, "environment":"Sandbox",
2 | "receipt":{"receipt_type":"ProductionSandbox", "adam_id":0, "app_item_id":0, "bundle_id":"com.quentin-fasquel.jsonViewExample", "application_version":"1", "download_id":0, "version_external_identifier":0, "receipt_creation_date":"2020-04-16 20:51:42 Etc/GMT", "receipt_creation_date_ms":"1587070302000", "receipt_creation_date_pst":"2020-04-16 13:51:42 America/Los_Angeles", "request_date":"2020-04-16 20:51:52 Etc/GMT", "request_date_ms":"1587070312042", "request_date_pst":"2020-04-16 13:51:52 America/Los_Angeles", "original_purchase_date":"2013-08-01 07:00:00 Etc/GMT", "original_purchase_date_ms":"1375340400000", "original_purchase_date_pst":"2013-08-01 00:00:00 America/Los_Angeles", "original_application_version":"1.0",
3 | "in_app":[
4 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651861677", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:20:42 Etc/GMT", "purchase_date_ms":"1586902842000", "purchase_date_pst":"2020-04-14 15:20:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:25:42 Etc/GMT", "expires_date_ms":"1586903142000", "expires_date_pst":"2020-04-14 15:25:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740703", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
5 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651862276", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:25:42 Etc/GMT", "purchase_date_ms":"1586903142000", "purchase_date_pst":"2020-04-14 15:25:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:30:42 Etc/GMT", "expires_date_ms":"1586903442000", "expires_date_pst":"2020-04-14 15:30:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740770", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
6 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651863381", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:30:45 Etc/GMT", "purchase_date_ms":"1586903445000", "purchase_date_pst":"2020-04-14 15:30:45 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:35:45 Etc/GMT", "expires_date_ms":"1586903745000", "expires_date_pst":"2020-04-14 15:35:45 America/Los_Angeles", "web_order_line_item_id":"1000000051740829", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
7 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651866765", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:49:21 Etc/GMT", "purchase_date_ms":"1586904561000", "purchase_date_pst":"2020-04-14 15:49:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:54:21 Etc/GMT", "expires_date_ms":"1586904861000", "expires_date_pst":"2020-04-14 15:54:21 America/Los_Angeles", "web_order_line_item_id":"1000000051740919", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
8 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651867022", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:54:21 Etc/GMT", "purchase_date_ms":"1586904861000", "purchase_date_pst":"2020-04-14 15:54:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:59:21 Etc/GMT", "expires_date_ms":"1586905161000", "expires_date_pst":"2020-04-14 15:59:21 America/Los_Angeles", "web_order_line_item_id":"1000000051741174", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
9 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652308513", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:46:51 Etc/GMT", "purchase_date_ms":"1586972811000", "purchase_date_pst":"2020-04-15 10:46:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 17:51:51 Etc/GMT", "expires_date_ms":"1586973111000", "expires_date_pst":"2020-04-15 10:51:51 America/Los_Angeles", "web_order_line_item_id":"1000000051741222", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
10 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652310057", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:51:51 Etc/GMT", "purchase_date_ms":"1586973111000", "purchase_date_pst":"2020-04-15 10:51:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 17:56:51 Etc/GMT", "expires_date_ms":"1586973411000", "expires_date_pst":"2020-04-15 10:56:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767574", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
11 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652312346", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:56:51 Etc/GMT", "purchase_date_ms":"1586973411000", "purchase_date_pst":"2020-04-15 10:56:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:01:51 Etc/GMT", "expires_date_ms":"1586973711000", "expires_date_pst":"2020-04-15 11:01:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767645", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
12 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652314332", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:01:51 Etc/GMT", "purchase_date_ms":"1586973711000", "purchase_date_pst":"2020-04-15 11:01:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:06:51 Etc/GMT", "expires_date_ms":"1586974011000", "expires_date_pst":"2020-04-15 11:06:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767737", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
13 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652317467", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:09:21 Etc/GMT", "purchase_date_ms":"1586974161000", "purchase_date_pst":"2020-04-15 11:09:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:14:21 Etc/GMT", "expires_date_ms":"1586974461000", "expires_date_pst":"2020-04-15 11:14:21 America/Los_Angeles", "web_order_line_item_id":"1000000051767837", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
14 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652320073", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:15:05 Etc/GMT", "purchase_date_ms":"1586974505000", "purchase_date_pst":"2020-04-15 11:15:05 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:20:05 Etc/GMT", "expires_date_ms":"1586974805000", "expires_date_pst":"2020-04-15 11:20:05 America/Los_Angeles", "web_order_line_item_id":"1000000051768010", "is_trial_period":"false", "is_in_intro_offer_period":"false"},
15 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651861166", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:15:42 Etc/GMT", "purchase_date_ms":"1586902542000", "purchase_date_pst":"2020-04-14 15:15:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:20:42 Etc/GMT", "expires_date_ms":"1586902842000", "expires_date_pst":"2020-04-14 15:20:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740702", "is_trial_period":"true", "is_in_intro_offer_period":"false"}]},
16 | "latest_receipt_info":[
17 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651861166", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:15:42 Etc/GMT", "purchase_date_ms":"1586902542000", "purchase_date_pst":"2020-04-14 15:15:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:20:42 Etc/GMT", "expires_date_ms":"1586902842000", "expires_date_pst":"2020-04-14 15:20:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740702", "is_trial_period":"true", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
18 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651861677", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:20:42 Etc/GMT", "purchase_date_ms":"1586902842000", "purchase_date_pst":"2020-04-14 15:20:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:25:42 Etc/GMT", "expires_date_ms":"1586903142000", "expires_date_pst":"2020-04-14 15:25:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740703", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
19 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651862276", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:25:42 Etc/GMT", "purchase_date_ms":"1586903142000", "purchase_date_pst":"2020-04-14 15:25:42 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:30:42 Etc/GMT", "expires_date_ms":"1586903442000", "expires_date_pst":"2020-04-14 15:30:42 America/Los_Angeles", "web_order_line_item_id":"1000000051740770", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
20 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651863381", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:30:45 Etc/GMT", "purchase_date_ms":"1586903445000", "purchase_date_pst":"2020-04-14 15:30:45 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:35:45 Etc/GMT", "expires_date_ms":"1586903745000", "expires_date_pst":"2020-04-14 15:35:45 America/Los_Angeles", "web_order_line_item_id":"1000000051740829", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
21 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651866765", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:49:21 Etc/GMT", "purchase_date_ms":"1586904561000", "purchase_date_pst":"2020-04-14 15:49:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:54:21 Etc/GMT", "expires_date_ms":"1586904861000", "expires_date_pst":"2020-04-14 15:54:21 America/Los_Angeles", "web_order_line_item_id":"1000000051740919", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
22 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000651867022", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-14 22:54:21 Etc/GMT", "purchase_date_ms":"1586904861000", "purchase_date_pst":"2020-04-14 15:54:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-14 22:59:21 Etc/GMT", "expires_date_ms":"1586905161000", "expires_date_pst":"2020-04-14 15:59:21 America/Los_Angeles", "web_order_line_item_id":"1000000051741174", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
23 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652308513", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:46:51 Etc/GMT", "purchase_date_ms":"1586972811000", "purchase_date_pst":"2020-04-15 10:46:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 17:51:51 Etc/GMT", "expires_date_ms":"1586973111000", "expires_date_pst":"2020-04-15 10:51:51 America/Los_Angeles", "web_order_line_item_id":"1000000051741222", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
24 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652310057", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:51:51 Etc/GMT", "purchase_date_ms":"1586973111000", "purchase_date_pst":"2020-04-15 10:51:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 17:56:51 Etc/GMT", "expires_date_ms":"1586973411000", "expires_date_pst":"2020-04-15 10:56:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767574", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
25 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652312346", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 17:56:51 Etc/GMT", "purchase_date_ms":"1586973411000", "purchase_date_pst":"2020-04-15 10:56:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:01:51 Etc/GMT", "expires_date_ms":"1586973711000", "expires_date_pst":"2020-04-15 11:01:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767645", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
26 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652314332", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:01:51 Etc/GMT", "purchase_date_ms":"1586973711000", "purchase_date_pst":"2020-04-15 11:01:51 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:06:51 Etc/GMT", "expires_date_ms":"1586974011000", "expires_date_pst":"2020-04-15 11:06:51 America/Los_Angeles", "web_order_line_item_id":"1000000051767737", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
27 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652317467", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:09:21 Etc/GMT", "purchase_date_ms":"1586974161000", "purchase_date_pst":"2020-04-15 11:09:21 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:14:21 Etc/GMT", "expires_date_ms":"1586974461000", "expires_date_pst":"2020-04-15 11:14:21 America/Los_Angeles", "web_order_line_item_id":"1000000051767837", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"},
28 | {"quantity":"1", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "transaction_id":"1000000652320073", "original_transaction_id":"1000000651861166", "purchase_date":"2020-04-15 18:15:05 Etc/GMT", "purchase_date_ms":"1586974505000", "purchase_date_pst":"2020-04-15 11:15:05 America/Los_Angeles", "original_purchase_date":"2020-04-14 22:15:44 Etc/GMT", "original_purchase_date_ms":"1586902544000", "original_purchase_date_pst":"2020-04-14 15:15:44 America/Los_Angeles", "expires_date":"2020-04-15 18:20:05 Etc/GMT", "expires_date_ms":"1586974805000", "expires_date_pst":"2020-04-15 11:20:05 America/Los_Angeles", "web_order_line_item_id":"1000000051768010", "is_trial_period":"false", "is_in_intro_offer_period":"false", "subscription_group_identifier":"20447762"}],
29 | "latest_receipt":"MIIkwwYJKoZIhvcNAQcCoIIktDCCJLACAQExCzAJBgUrDgMCGgUAMIIUZAYJKoZIhvcNAQcBoIIUVQSCFFExghRNMAoCAQgCAQEEAhYAMAoCARQCAQEEAgwAMAsCAQECAQEEAwIBADALAgEDAgEBBAMMATEwCwIBCwIBAQQDAgEAMAsCAQ8CAQEEAwIBADALAgEQAgEBBAMCAQAwCwIBGQIBAQQDAgEDMAwCAQoCAQEEBBYCNCswDAIBDgIBAQQEAgIAiTANAgENAgEBBAUCAwH8NDANAgETAgEBBAUMAzEuMDAOAgEJAgEBBAYCBFAyNTMwGAIBBAIBAgQQNmhCFiqmg+k3BtQ9/U47SDAbAgEAAgEBBBMMEVByb2R1Y3Rpb25TYW5kYm94MBwCAQUCAQEEFDEIdLWp0eYOLdWriHJ98BfjL0kMMB4CAQwCAQEEFhYUMjAyMC0wNC0xNlQyMDo1MTo1MlowHgIBEgIBAQQWFhQyMDEzLTA4LTAxVDA3OjAwOjAwWjAkAgECAgEBBBwMGmNvbS5tb25jb3lvdGUuaWNveW90ZUZSMzAyMEMCAQcCAQEEO5ldQKz5izc9nrt/6qi/+X9qv5jLsrcA8rW1Z7uvzFNHE0zhgJtUzxJV3Be0t+Bln34Err8YcqL38r1uMFMCAQYCAQEES360uUpeSEOGTgOgbJohTrV4EyKMOOqP4uUmgZRGF5Vxy32stkQKKmBKniq5TXCy/rYJAU+RURzJWpQPWmw3278JrtgsZVhLhGOeGjCCAYICARECAQEEggF4MYIBdDALAgIGrQIBAQQCDAAwCwICBrACAQEEAhYAMAsCAgayAgEBBAIMADALAgIGswIBAQQCDAAwCwICBrQCAQEEAgwAMAsCAga1AgEBBAIMADALAgIGtgIBAQQCDAAwDAICBqUCAQEEAwIBATAMAgIGqwIBAQQDAgEDMAwCAgauAgEBBAMCAQAwDAICBrECAQEEAwIBADAMAgIGtwIBAQQDAgEAMBICAgavAgEBBAkCBwONfqfcAB8wGwICBqcCAQEEEgwQMTAwMDAwMDY1MTg2MTY3NzAbAgIGqQIBAQQSDBAxMDAwMDAwNjUxODYxMTY2MB8CAgaoAgEBBBYWFDIwMjAtMDQtMTRUMjI6MjA6NDJaMB8CAgaqAgEBBBYWFDIwMjAtMDQtMTRUMjI6MTU6NDRaMB8CAgasAgEBBBYWFDIwMjAtMDQtMTRUMjI6MjU6NDJaMCACAgamAgEBBBcMFUFCT19NRV8xTU9JU18zMEpQUk9NTzCCAYICARECAQEEggF4MYIBdDALAgIGrQIBAQQCDAAwCwICBrACAQEEAhYAMAsCAgayAgEBBAIMADALAgIGswIBAQQCDAAwCwICBrQCAQEEAgwAMAsCAga1AgEBBAIMADALAgIGtgIBAQQCDAAwDAICBqUCAQEEAwIBATAMAgIGqwIBAQQDAgEDMAwCAgauAgEBBAMCAQAwDAICBrECAQEEAwIBADAMAgIGtwIBAQQDAgEAMBICAgavAgEBBAkCBwONfqfcAGIwGwICBqcCAQEEEgwQMTAwMDAwMDY1MTg2MjI3NjAbAgIGqQIBAQQSDBAxMDAwMDAwNjUxODYxMTY2MB8CAgaoAgEBBBYWFDIwMjAtMDQtMTRUMjI6MjU6NDJaMB8CAgaqAgEBBBYWFDIwMjAtMDQtMTRUMjI6MTU6NDRaMB8CAgasAgEBBBYWFDIwMjAtMDQtMTRUMjI6MzA6NDJaMCACAgamAgEBBBcMFUFCT19NRV8xTU9JU18zMEpQUk9NTzCCAYICARECAQEEggF4MYIBdDALAgIGrQIBAQQCDAAwCwICBrACAQEEAhYAMAsCAgayAgEBBAIMADALAgIGswIBAQQCDAAwCwICBrQCAQEEAgwAMAsCAga1AgEBBAIMADALAgIGtgIBAQQCDAAwDAICBqUCAQEEAwIBATAMAgIGqwIBAQQDAgEDMAwCAgauAgEBBAMCAQAwDAICBrECAQEEAwIBADAMAgIGtwIBAQQDAgEAMBICAgavAgEBBAkCBwONfqfcAJ0wGwICBqcCAQEEEgwQMTAwMDAwMDY1MTg2MzM4MTAbAgIGqQIBAQQSDBAxMDAwMDAwNjUxODYxMTY2MB8CAgaoAgEBBBYWFDIwMjAtMDQtMTRUMjI6MzA6NDVaMB8CAgaqAgEBBBYWFDIwMjAtMDQtMTRUMjI6MTU6NDRaMB8CAgasAgEBBBYWFDIwMjAtMDQtMTRUMjI6MzU6NDVaMCACAgamAgEBBBcMFUFCT19NRV8xTU9JU18zMEpQUk9NTzCCAYICARECAQEEggF4M7NWZkTHajsSHe6k4GZjBR+u22A==",
30 | "pending_renewal_info":[
31 | {"expiration_intent":"1", "auto_renew_product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "original_transaction_id":"1000000651861166", "is_in_billing_retry_period":"0", "product_id":"com.quentin-fasquel.subscriptions.sample-monthly", "auto_renew_status":"0"}]}
32 |
--------------------------------------------------------------------------------
/JSONView.podspec:
--------------------------------------------------------------------------------
1 | Pod::Spec.new do |spec|
2 | spec.name = "JSONView"
3 | spec.version = "0.0.3"
4 | spec.summary = "A light-weight SwiftUI visualizer of JSON content"
5 | spec.homepage = "https://github.com/quentinfasquel/JSONView"
6 | spec.license = { :type => "MIT", :file => "LICENSE" }
7 | spec.author = { "author" => "quentin.fasquel@gmail.com" }
8 | spec.documentation_url = "https://github.com/quentinfasquel/JSONView"
9 | spec.platforms = { :ios => "13.0" }
10 | spec.swift_version = "5.2"
11 | spec.source = { :git => "https://github.com/quentinfasquel/JSONView.git", :tag => "#{spec.version}" }
12 | spec.source_files = "Sources/JSONView/**/*.swift"
13 | spec.xcconfig = { "SWIFT_VERSION" => "5.2" }
14 | end
15 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/JSONView_Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | FMWK
17 | CFBundleShortVersionString
18 | $(MARKETING_VERSION)
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | $(CURRENT_PROJECT_VERSION)
23 | NSPrincipalClass
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 46;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | 66D4493B24497E56008A4CCB /* JSONView.h in Headers */ = {isa = PBXBuildFile; fileRef = 66D4492D24497E56008A4CCB /* JSONView.h */; settings = {ATTRIBUTES = (Public, ); }; };
11 | 66D4494924497F29008A4CCB /* JSONTreeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494624497F29008A4CCB /* JSONTreeView.swift */; };
12 | 66D4494A24497F29008A4CCB /* JSONView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494724497F29008A4CCB /* JSONView.swift */; };
13 | 66D4494B24497F29008A4CCB /* JSONCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 66D4494824497F29008A4CCB /* JSONCell.swift */; };
14 | /* End PBXBuildFile section */
15 |
16 | /* Begin PBXFileReference section */
17 | 66D4492B24497E56008A4CCB /* JSONView.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = JSONView.framework; sourceTree = BUILT_PRODUCTS_DIR; };
18 | 66D4492D24497E56008A4CCB /* JSONView.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = JSONView.h; path = JSONView/JSONView.h; sourceTree = ""; };
19 | 66D4492E24497E56008A4CCB /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Info.plist; path = JSONView/Info.plist; sourceTree = ""; };
20 | 66D4494624497F29008A4CCB /* JSONTreeView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONTreeView.swift; path = Sources/JSONView/JSONTreeView.swift; sourceTree = ""; };
21 | 66D4494724497F29008A4CCB /* JSONView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONView.swift; path = Sources/JSONView/JSONView.swift; sourceTree = ""; };
22 | 66D4494824497F29008A4CCB /* JSONCell.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = JSONCell.swift; path = Sources/JSONView/JSONCell.swift; sourceTree = ""; };
23 | OBJ_18 /* README.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; };
24 | /* End PBXFileReference section */
25 |
26 | /* Begin PBXFrameworksBuildPhase section */
27 | 66D4492824497E56008A4CCB /* Frameworks */ = {
28 | isa = PBXFrameworksBuildPhase;
29 | buildActionMask = 2147483647;
30 | files = (
31 | );
32 | runOnlyForDeploymentPostprocessing = 0;
33 | };
34 | /* End PBXFrameworksBuildPhase section */
35 |
36 | /* Begin PBXGroup section */
37 | 66D4492C24497E56008A4CCB /* JSONView */ = {
38 | isa = PBXGroup;
39 | children = (
40 | 66D4492D24497E56008A4CCB /* JSONView.h */,
41 | 66D4494624497F29008A4CCB /* JSONTreeView.swift */,
42 | 66D4494724497F29008A4CCB /* JSONView.swift */,
43 | 66D4494824497F29008A4CCB /* JSONCell.swift */,
44 | 66D4492E24497E56008A4CCB /* Info.plist */,
45 | );
46 | name = JSONView;
47 | sourceTree = SOURCE_ROOT;
48 | };
49 | OBJ_13 /* Products */ = {
50 | isa = PBXGroup;
51 | children = (
52 | 66D4492B24497E56008A4CCB /* JSONView.framework */,
53 | );
54 | name = Products;
55 | sourceTree = BUILT_PRODUCTS_DIR;
56 | };
57 | OBJ_5 = {
58 | isa = PBXGroup;
59 | children = (
60 | OBJ_18 /* README.md */,
61 | 66D4492C24497E56008A4CCB /* JSONView */,
62 | OBJ_13 /* Products */,
63 | );
64 | sourceTree = "";
65 | };
66 | /* End PBXGroup section */
67 |
68 | /* Begin PBXHeadersBuildPhase section */
69 | 66D4492624497E56008A4CCB /* Headers */ = {
70 | isa = PBXHeadersBuildPhase;
71 | buildActionMask = 2147483647;
72 | files = (
73 | 66D4493B24497E56008A4CCB /* JSONView.h in Headers */,
74 | );
75 | runOnlyForDeploymentPostprocessing = 0;
76 | };
77 | /* End PBXHeadersBuildPhase section */
78 |
79 | /* Begin PBXNativeTarget section */
80 | 66D4492A24497E56008A4CCB /* JSONView */ = {
81 | isa = PBXNativeTarget;
82 | buildConfigurationList = 66D4493C24497E56008A4CCB /* Build configuration list for PBXNativeTarget "JSONView" */;
83 | buildPhases = (
84 | 66D4492624497E56008A4CCB /* Headers */,
85 | 66D4492724497E56008A4CCB /* Sources */,
86 | 66D4492824497E56008A4CCB /* Frameworks */,
87 | 66D4492924497E56008A4CCB /* Resources */,
88 | );
89 | buildRules = (
90 | );
91 | dependencies = (
92 | );
93 | name = JSONView;
94 | productName = JSONView;
95 | productReference = 66D4492B24497E56008A4CCB /* JSONView.framework */;
96 | productType = "com.apple.product-type.framework";
97 | };
98 | /* End PBXNativeTarget section */
99 |
100 | /* Begin PBXProject section */
101 | OBJ_1 /* Project object */ = {
102 | isa = PBXProject;
103 | attributes = {
104 | LastSwiftMigration = 9999;
105 | LastSwiftUpdateCheck = 1140;
106 | LastUpgradeCheck = 9999;
107 | ORGANIZATIONNAME = "QF CODES";
108 | TargetAttributes = {
109 | 66D4492A24497E56008A4CCB = {
110 | CreatedOnToolsVersion = 11.4;
111 | DevelopmentTeam = H9EZHJZX4M;
112 | ProvisioningStyle = Automatic;
113 | };
114 | };
115 | };
116 | buildConfigurationList = OBJ_2 /* Build configuration list for PBXProject "JSONView" */;
117 | compatibilityVersion = "Xcode 3.2";
118 | developmentRegion = en;
119 | hasScannedForEncodings = 0;
120 | knownRegions = (
121 | en,
122 | );
123 | mainGroup = OBJ_5;
124 | productRefGroup = OBJ_13 /* Products */;
125 | projectDirPath = "";
126 | projectRoot = "";
127 | targets = (
128 | 66D4492A24497E56008A4CCB /* JSONView */,
129 | );
130 | };
131 | /* End PBXProject section */
132 |
133 | /* Begin PBXResourcesBuildPhase section */
134 | 66D4492924497E56008A4CCB /* Resources */ = {
135 | isa = PBXResourcesBuildPhase;
136 | buildActionMask = 2147483647;
137 | files = (
138 | );
139 | runOnlyForDeploymentPostprocessing = 0;
140 | };
141 | /* End PBXResourcesBuildPhase section */
142 |
143 | /* Begin PBXSourcesBuildPhase section */
144 | 66D4492724497E56008A4CCB /* Sources */ = {
145 | isa = PBXSourcesBuildPhase;
146 | buildActionMask = 2147483647;
147 | files = (
148 | 66D4494B24497F29008A4CCB /* JSONCell.swift in Sources */,
149 | 66D4494A24497F29008A4CCB /* JSONView.swift in Sources */,
150 | 66D4494924497F29008A4CCB /* JSONTreeView.swift in Sources */,
151 | );
152 | runOnlyForDeploymentPostprocessing = 0;
153 | };
154 | /* End PBXSourcesBuildPhase section */
155 |
156 | /* Begin XCBuildConfiguration section */
157 | 66D4493D24497E56008A4CCB /* Debug */ = {
158 | isa = XCBuildConfiguration;
159 | buildSettings = {
160 | ALWAYS_SEARCH_USER_PATHS = NO;
161 | CLANG_ANALYZER_NONNULL = YES;
162 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
163 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
164 | CLANG_CXX_LIBRARY = "libc++";
165 | CLANG_ENABLE_MODULES = YES;
166 | CLANG_ENABLE_OBJC_WEAK = YES;
167 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
168 | CLANG_WARN_BOOL_CONVERSION = YES;
169 | CLANG_WARN_COMMA = YES;
170 | CLANG_WARN_CONSTANT_CONVERSION = YES;
171 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
172 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
173 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
174 | CLANG_WARN_EMPTY_BODY = YES;
175 | CLANG_WARN_ENUM_CONVERSION = YES;
176 | CLANG_WARN_INFINITE_RECURSION = YES;
177 | CLANG_WARN_INT_CONVERSION = YES;
178 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
179 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
180 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
181 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
182 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
183 | CLANG_WARN_STRICT_PROTOTYPES = YES;
184 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
185 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
186 | CLANG_WARN_UNREACHABLE_CODE = YES;
187 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
188 | CODE_SIGN_STYLE = Automatic;
189 | CURRENT_PROJECT_VERSION = 1;
190 | DEFINES_MODULE = YES;
191 | DEVELOPMENT_TEAM = H9EZHJZX4M;
192 | DYLIB_COMPATIBILITY_VERSION = 1;
193 | DYLIB_CURRENT_VERSION = 1;
194 | DYLIB_INSTALL_NAME_BASE = "@rpath";
195 | ENABLE_STRICT_OBJC_MSGSEND = YES;
196 | ENABLE_TESTABILITY = YES;
197 | GCC_C_LANGUAGE_STANDARD = gnu11;
198 | GCC_DYNAMIC_NO_PIC = NO;
199 | GCC_NO_COMMON_BLOCKS = YES;
200 | GCC_PREPROCESSOR_DEFINITIONS = (
201 | "DEBUG=1",
202 | "$(inherited)",
203 | );
204 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
205 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
206 | GCC_WARN_UNDECLARED_SELECTOR = YES;
207 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
208 | GCC_WARN_UNUSED_FUNCTION = YES;
209 | GCC_WARN_UNUSED_VARIABLE = YES;
210 | INFOPLIST_FILE = JSONView/Info.plist;
211 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
212 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
213 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
214 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
215 | MTL_FAST_MATH = YES;
216 | PRODUCT_BUNDLE_IDENTIFIER = "com.quentin-fasquel.JSONView";
217 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
218 | SDKROOT = iphoneos;
219 | SKIP_INSTALL = YES;
220 | SUPPORTS_MACCATALYST = NO;
221 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
222 | SWIFT_VERSION = 5.0;
223 | TARGETED_DEVICE_FAMILY = "1,2";
224 | VERSIONING_SYSTEM = "apple-generic";
225 | VERSION_INFO_PREFIX = "";
226 | };
227 | name = Debug;
228 | };
229 | 66D4493E24497E56008A4CCB /* Release */ = {
230 | isa = XCBuildConfiguration;
231 | buildSettings = {
232 | ALWAYS_SEARCH_USER_PATHS = NO;
233 | CLANG_ANALYZER_NONNULL = YES;
234 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
235 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++14";
236 | CLANG_CXX_LIBRARY = "libc++";
237 | CLANG_ENABLE_MODULES = YES;
238 | CLANG_ENABLE_OBJC_WEAK = YES;
239 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
240 | CLANG_WARN_BOOL_CONVERSION = YES;
241 | CLANG_WARN_COMMA = YES;
242 | CLANG_WARN_CONSTANT_CONVERSION = YES;
243 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
244 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
245 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
246 | CLANG_WARN_EMPTY_BODY = YES;
247 | CLANG_WARN_ENUM_CONVERSION = YES;
248 | CLANG_WARN_INFINITE_RECURSION = YES;
249 | CLANG_WARN_INT_CONVERSION = YES;
250 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
251 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
252 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
253 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
254 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
255 | CLANG_WARN_STRICT_PROTOTYPES = YES;
256 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
257 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
258 | CLANG_WARN_UNREACHABLE_CODE = YES;
259 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
260 | CODE_SIGN_STYLE = Automatic;
261 | COPY_PHASE_STRIP = NO;
262 | CURRENT_PROJECT_VERSION = 1;
263 | DEFINES_MODULE = YES;
264 | DEVELOPMENT_TEAM = H9EZHJZX4M;
265 | DYLIB_COMPATIBILITY_VERSION = 1;
266 | DYLIB_CURRENT_VERSION = 1;
267 | DYLIB_INSTALL_NAME_BASE = "@rpath";
268 | ENABLE_NS_ASSERTIONS = NO;
269 | ENABLE_STRICT_OBJC_MSGSEND = YES;
270 | GCC_C_LANGUAGE_STANDARD = gnu11;
271 | GCC_NO_COMMON_BLOCKS = YES;
272 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
273 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
274 | GCC_WARN_UNDECLARED_SELECTOR = YES;
275 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
276 | GCC_WARN_UNUSED_FUNCTION = YES;
277 | GCC_WARN_UNUSED_VARIABLE = YES;
278 | INFOPLIST_FILE = JSONView/Info.plist;
279 | INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
280 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
281 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
282 | MTL_ENABLE_DEBUG_INFO = NO;
283 | MTL_FAST_MATH = YES;
284 | PRODUCT_BUNDLE_IDENTIFIER = "com.quentin-fasquel.JSONView";
285 | PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
286 | SDKROOT = iphoneos;
287 | SKIP_INSTALL = YES;
288 | SUPPORTS_MACCATALYST = NO;
289 | SWIFT_VERSION = 5.0;
290 | TARGETED_DEVICE_FAMILY = "1,2";
291 | VALIDATE_PRODUCT = YES;
292 | VERSIONING_SYSTEM = "apple-generic";
293 | VERSION_INFO_PREFIX = "";
294 | };
295 | name = Release;
296 | };
297 | OBJ_3 /* Debug */ = {
298 | isa = XCBuildConfiguration;
299 | buildSettings = {
300 | CLANG_ENABLE_OBJC_ARC = YES;
301 | COMBINE_HIDPI_IMAGES = YES;
302 | COPY_PHASE_STRIP = NO;
303 | DEBUG_INFORMATION_FORMAT = dwarf;
304 | DYLIB_INSTALL_NAME_BASE = "@rpath";
305 | ENABLE_NS_ASSERTIONS = YES;
306 | GCC_OPTIMIZATION_LEVEL = 0;
307 | GCC_PREPROCESSOR_DEFINITIONS = (
308 | "$(inherited)",
309 | "SWIFT_PACKAGE=1",
310 | "DEBUG=1",
311 | );
312 | MACOSX_DEPLOYMENT_TARGET = 10.10;
313 | ONLY_ACTIVE_ARCH = YES;
314 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
315 | PRODUCT_NAME = "$(TARGET_NAME)";
316 | SDKROOT = iphoneos;
317 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
318 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE DEBUG";
319 | SWIFT_OPTIMIZATION_LEVEL = "-Onone";
320 | USE_HEADERMAP = NO;
321 | };
322 | name = Debug;
323 | };
324 | OBJ_4 /* Release */ = {
325 | isa = XCBuildConfiguration;
326 | buildSettings = {
327 | CLANG_ENABLE_OBJC_ARC = YES;
328 | COMBINE_HIDPI_IMAGES = YES;
329 | COPY_PHASE_STRIP = YES;
330 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
331 | DYLIB_INSTALL_NAME_BASE = "@rpath";
332 | GCC_OPTIMIZATION_LEVEL = s;
333 | GCC_PREPROCESSOR_DEFINITIONS = (
334 | "$(inherited)",
335 | "SWIFT_PACKAGE=1",
336 | );
337 | MACOSX_DEPLOYMENT_TARGET = 10.10;
338 | OTHER_SWIFT_FLAGS = "$(inherited) -DXcode";
339 | PRODUCT_NAME = "$(TARGET_NAME)";
340 | SDKROOT = iphoneos;
341 | SUPPORTED_PLATFORMS = "iphonesimulator iphoneos";
342 | SWIFT_ACTIVE_COMPILATION_CONDITIONS = "$(inherited) SWIFT_PACKAGE";
343 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
344 | USE_HEADERMAP = NO;
345 | };
346 | name = Release;
347 | };
348 | /* End XCBuildConfiguration section */
349 |
350 | /* Begin XCConfigurationList section */
351 | 66D4493C24497E56008A4CCB /* Build configuration list for PBXNativeTarget "JSONView" */ = {
352 | isa = XCConfigurationList;
353 | buildConfigurations = (
354 | 66D4493D24497E56008A4CCB /* Debug */,
355 | 66D4493E24497E56008A4CCB /* Release */,
356 | );
357 | defaultConfigurationIsVisible = 0;
358 | defaultConfigurationName = Release;
359 | };
360 | OBJ_2 /* Build configuration list for PBXProject "JSONView" */ = {
361 | isa = XCConfigurationList;
362 | buildConfigurations = (
363 | OBJ_3 /* Debug */,
364 | OBJ_4 /* Release */,
365 | );
366 | defaultConfigurationIsVisible = 0;
367 | defaultConfigurationName = Release;
368 | };
369 | /* End XCConfigurationList section */
370 | };
371 | rootObject = OBJ_1 /* Project object */;
372 | }
373 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEWorkspaceSharedSettings_AutocreateContextsIfNeeded
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/JSONView.xcodeproj/xcshareddata/xcschemes/JSONView.xcscheme:
--------------------------------------------------------------------------------
1 |
2 |
5 |
8 |
9 |
15 |
21 |
22 |
23 |
24 |
25 |
30 |
31 |
32 |
33 |
43 |
44 |
50 |
51 |
57 |
58 |
59 |
60 |
62 |
63 |
66 |
67 |
68 |
--------------------------------------------------------------------------------
/JSONView/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 | $(CURRENT_PROJECT_VERSION)
21 |
22 |
23 |
--------------------------------------------------------------------------------
/JSONView/JSONView.h:
--------------------------------------------------------------------------------
1 | //
2 | // JSONView.h
3 | // JSONView
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | //
7 |
8 | #import
9 |
10 | //! Project version number for JSONView.
11 | FOUNDATION_EXPORT double JSONViewVersionNumber;
12 |
13 | //! Project version string for JSONView.
14 | FOUNDATION_EXPORT const unsigned char JSONViewVersionString[];
15 |
16 | // In this header, you should import all the public headers of your framework using statements like #import
17 |
18 |
19 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 QF CODES
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
--------------------------------------------------------------------------------
/Package.swift:
--------------------------------------------------------------------------------
1 | // swift-tools-version:5.2
2 | // The swift-tools-version declares the minimum version of Swift required to build this package.
3 |
4 | import PackageDescription
5 |
6 | let package = Package(
7 | name: "JSONView",
8 | platforms: [
9 | .iOS(.v13),
10 | ],
11 | products: [
12 | .library(name: "JSONView", targets: ["JSONView"]),
13 | ],
14 | targets: [
15 | .target(name: "JSONView", dependencies: []),
16 | .testTarget( name: "JSONViewTests", dependencies: ["JSONView"]),
17 | ]
18 | )
19 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSONView
2 |
3 | [](https://github.com/Carthage/Carthage)
4 | [](https://cocoapods.org/pods/JSONView)
5 | 
6 | [](https://github.com/apple/swift-package-manager)
7 | [](https://opensource.org/licenses/MIT)
8 |
9 | A light-weight __SwiftUI__ visualizer of JSON content.
10 |
11 | 
12 |
13 | ## Requirements
14 | * iOS 13.0+
15 | * Swift 5.2+
16 |
17 | ## Installation
18 |
19 | ### CocoaPods
20 | ```
21 | pod 'JSONView'
22 | ```
23 | ### Swift Package Manager
24 |
25 | Go to XCode:
26 |
27 | * File -> Swift Packages -> Add Package Dependency...
28 | * Use the URL https://github.com/quentinfasquel/JSONView.git
29 |
30 | ### Carthage
31 |
32 | ```
33 | github "quentinfasquel/JSONView"
34 | ```
35 |
36 | ## License
37 |
38 | `JSONView` is available under the MIT license. See the [LICENSE](/LICENSE) file for more info.
--------------------------------------------------------------------------------
/Sources/JSONView/JSONCell.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONCell.swift
3 | // JSONView
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | //
7 |
8 | import SwiftUI
9 |
10 | public struct JSONCell: View {
11 | private let key: String
12 |
13 | /// * note: According to [JSONSerialization](https://developer.apple.com/documentation/foundation/jsonserialization),
14 | /// acceptable values may be NSArray, NSDictionary, NSNumber, NSString or NSNull...
15 | private let rawValue: AnyHashable
16 |
17 | @State private var isOpen: Bool = false
18 | @State private var isRotate: Bool = false
19 |
20 | internal init(_ keyValue: (key: String, value: AnyHashable)) {
21 | self.init(key: keyValue.key, value: keyValue.value)
22 | }
23 |
24 | public init(key: String, value: AnyHashable) {
25 | self.key = key
26 | self.rawValue = value
27 | }
28 |
29 | private func specificView() -> some View {
30 | switch rawValue {
31 | case let array as [JSON]: // NSArray
32 | return AnyView(keyValueView(treeView: JSONTreeView(array, prefix: key)))
33 | case let dictionary as JSON: // NSDictionary
34 | return AnyView(keyValueView(treeView: JSONTreeView(dictionary, prefix: key)))
35 | case let number as NSNumber: // NSNumber
36 | return AnyView(leafView(number.stringValue))
37 | case let string as String: // NSString
38 | return AnyView(leafView(string))
39 | case is NSNull: // NSNull
40 | return AnyView(leafView("null"))
41 | default:
42 | fatalError()
43 | }
44 | }
45 |
46 | public func copyValue() {
47 | switch rawValue {
48 | case let array as [JSON]:
49 | UIPasteboard.general.string = (array as JSONRepresentable).stringValue
50 | case let dictionary as JSON:
51 | UIPasteboard.general.string = (dictionary as JSONRepresentable).stringValue
52 | case let number as NSNumber:
53 | UIPasteboard.general.string = number.stringValue
54 | case let string as String:
55 | UIPasteboard.general.string = string
56 | default:
57 | UIPasteboard.general.string = nil
58 | }
59 | }
60 |
61 | public var body: some View {
62 | specificView().padding(.leading, 10).contextMenu {
63 | Button(action: copyValue) {
64 | Text("Copy Value")
65 | }
66 | }
67 | }
68 |
69 | private func leafView(_ stringValue: String) -> some View {
70 | VStack(alignment: .leading, spacing: 4) {
71 | HStack(alignment: .center) {
72 | Text(key)
73 | Spacer()
74 | }
75 |
76 | Text(stringValue.prefix(60))
77 | .lineSpacing(0)
78 | .foregroundColor(Color.gray)
79 | }
80 | .padding(.vertical, 5)
81 | .padding(.trailing, 10)
82 | }
83 |
84 | private func toggle() {
85 | self.isOpen.toggle()
86 | withAnimation(.linear(duration: 0.1)) {
87 | self.isRotate.toggle()
88 | }
89 | }
90 |
91 | private func keyValueView(treeView valueView: JSONTreeView) -> some View {
92 | VStack(alignment: .leading) {
93 | Button(action: toggle) {
94 | HStack(alignment: .center) {
95 | Image(systemName: "arrowtriangle.right.fill")
96 | .resizable()
97 | .frame(width: 10, height: 10, alignment: .center)
98 | .foregroundColor(Color.gray)
99 | .rotationEffect(Angle(degrees: isRotate ? 90 : 0))
100 |
101 | Text(key)
102 | Spacer()
103 | }
104 | }
105 |
106 | if isOpen {
107 | Divider()
108 | valueView
109 | }
110 | }
111 | }
112 | }
113 |
--------------------------------------------------------------------------------
/Sources/JSONView/JSONTreeView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONTreeView.swift
3 | // Example
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | //
7 |
8 | import SwiftUI
9 |
10 | public struct JSONTreeView: View {
11 | private let keyValues: [(key: String, value: AnyHashable)]
12 |
13 | public init(_ dictionary: JSON) {
14 | self.keyValues = dictionary.sorted { $0.key < $1.key }
15 | }
16 |
17 | public init(_ array: [JSON], prefix key: String = "") {
18 | self.keyValues = array.enumerated().map {
19 | (key: "\(key)[\($0.offset)]", value: $0.element)
20 | }
21 | }
22 |
23 | public init(_ source: [(key: String, value: AnyHashable)]) {
24 | self.keyValues = source
25 | }
26 |
27 | public var body: some View {
28 | ForEach(keyValues.indices, id: \.self) { index in
29 | VStack(alignment: .leading) {
30 | if index > 0 {
31 | Divider()
32 | }
33 |
34 | JSONCell(self.keyValues[index])
35 | }
36 | }.frame(minWidth: 0, maxWidth: .infinity)
37 | }
38 | }
39 |
40 | // MARK: -
41 |
42 | internal protocol JSONRepresentable {
43 | var stringValue: String? { get }
44 | }
45 |
46 | extension JSONRepresentable {
47 | var stringValue: String? {
48 | do {
49 | let data = try JSONSerialization.data(withJSONObject: self, options: .prettyPrinted)
50 | return String(data: data, encoding: .utf8)
51 | } catch {
52 | return nil
53 | }
54 | }
55 | }
56 |
57 | extension Array: JSONRepresentable where Element: JSONRepresentable {
58 | }
59 |
60 | extension JSON: JSONRepresentable {
61 | }
62 |
63 | extension JSONTreeView {
64 | internal init(_ json: JSONRepresentable, prefix key: String = "") {
65 | switch json {
66 | case let array as [JSON]:
67 | self.init(array, prefix: key)
68 | case let dictionary as JSON:
69 | self.init(dictionary)
70 | default:
71 | self.init(JSON())
72 | }
73 | }
74 | }
75 |
--------------------------------------------------------------------------------
/Sources/JSONView/JSONView.swift:
--------------------------------------------------------------------------------
1 | //
2 | // JSONView.swift
3 | // JSONView
4 | //
5 | // Created by Quentin Fasquel on 16/04/2020.
6 | //
7 |
8 | import SwiftUI
9 |
10 | public typealias JSON = [String: AnyHashable]
11 |
12 | // MARK: -
13 |
14 | public struct JSONView: View {
15 | private let rootArray: [JSON]?
16 | private let rootDictionary: JSON
17 |
18 | public init(_ array: [JSON]) {
19 | self.rootArray = array
20 | self.rootDictionary = JSON()
21 | }
22 |
23 | public init(_ dictionary: JSON) {
24 | self.rootArray = nil
25 | self.rootDictionary = dictionary
26 | }
27 |
28 | public init(url: URL) {
29 | do {
30 | let data = try Data(contentsOf: url)
31 | let jsonData = try JSONSerialization.jsonObject(with: data, options: [])
32 | self.rootArray = jsonData as? [JSON]
33 | self.rootDictionary = jsonData as? JSON ?? JSON()
34 | } catch {
35 | self.rootArray = nil
36 | self.rootDictionary = JSON()
37 | print("JSONView error: \(error.localizedDescription)")
38 | }
39 | }
40 |
41 | public var body: some View {
42 | ScrollView(.vertical, showsIndicators: true) {
43 | JSONTreeView(rootArray ?? rootDictionary)
44 | .padding([.top, .bottom], 10)
45 | .padding(.trailing, 10)
46 | }
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/Tests/JSONViewTests/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinfasquel/JSONView/12be2902651993ebc77a3a2f162ea6b2d32538e0/Tests/JSONViewTests/.gitkeep
--------------------------------------------------------------------------------
/resources/example-of-usage.gif:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/quentinfasquel/JSONView/12be2902651993ebc77a3a2f162ea6b2d32538e0/resources/example-of-usage.gif
--------------------------------------------------------------------------------