Skip to content
This repository has been archived by the owner on Aug 16, 2019. It is now read-only.

Added json example to the example application #11

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions Example/.swiftlint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
disabled_rules:
- trailing_whitespace # seems like Xcode does this by default

opt_in_rules:
- empty_count
- force_unwrapping
- private_outlet
- vertical_whitespace
# - missing_docs # broken
- closure_spacing
- conditional_returns_on_newline
- overridden_super_call
- redundant_nil_coalesing
# - switch_case_on_newline # broken

included:
- MatrioskaExample

excluded:
- Pods
- Example

reporter: "xcode"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we use the main .swiftlint file?

27 changes: 27 additions & 0 deletions Example/MatrioskaExample.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
objects = {

/* Begin PBXBuildFile section */
21F6211E1E3147AF006C0DBE /* JSONReader.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F6211D1E3147AF006C0DBE /* JSONReader.swift */; };
21F621201E3147D5006C0DBE /* app_structure.json in Resources */ = {isa = PBXBuildFile; fileRef = 21F6211F1E3147D5006C0DBE /* app_structure.json */; };
21F621221E3155D1006C0DBE /* MatrioskaCodeViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 21F621211E3155D1006C0DBE /* MatrioskaCodeViewController.swift */; };
3E97AAB4FE1D9B124FD14CAB /* Pods_MatrioskaExample.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0188753F69D4AFD24551958B /* Pods_MatrioskaExample.framework */; };
DE7C386A1E005E3C00A399A3 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C38691E005E3C00A399A3 /* AppDelegate.swift */; };
DE7C386C1E005E3C00A399A3 /* TileViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = DE7C386B1E005E3C00A399A3 /* TileViewController.swift */; };
Expand All @@ -17,6 +20,9 @@
/* Begin PBXFileReference section */
0188753F69D4AFD24551958B /* Pods_MatrioskaExample.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MatrioskaExample.framework; sourceTree = BUILT_PRODUCTS_DIR; };
10AE7CFAC2D2657BBA53BF57 /* Pods-MatrioskaExample.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MatrioskaExample.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MatrioskaExample/Pods-MatrioskaExample.debug.xcconfig"; sourceTree = "<group>"; };
21F6211D1E3147AF006C0DBE /* JSONReader.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = JSONReader.swift; sourceTree = "<group>"; };
21F6211F1E3147D5006C0DBE /* app_structure.json */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json; path = app_structure.json; sourceTree = "<group>"; };
21F621211E3155D1006C0DBE /* MatrioskaCodeViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MatrioskaCodeViewController.swift; sourceTree = "<group>"; };
DE7C38661E005E3C00A399A3 /* MatrioskaExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MatrioskaExample.app; sourceTree = BUILT_PRODUCTS_DIR; };
DE7C38691E005E3C00A399A3 /* AppDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
DE7C386B1E005E3C00A399A3 /* TileViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TileViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -68,11 +74,14 @@
DE7C38681E005E3C00A399A3 /* MatrioskaExample */ = {
isa = PBXGroup;
children = (
21F6211F1E3147D5006C0DBE /* app_structure.json */,
21F6211D1E3147AF006C0DBE /* JSONReader.swift */,
DE7C38691E005E3C00A399A3 /* AppDelegate.swift */,
DE7C386B1E005E3C00A399A3 /* TileViewController.swift */,
DE7C38701E005E3C00A399A3 /* Assets.xcassets */,
DE7C38721E005E3C00A399A3 /* LaunchScreen.storyboard */,
DE7C38751E005E3C00A399A3 /* Info.plist */,
21F621211E3155D1006C0DBE /* MatrioskaCodeViewController.swift */,
);
path = MatrioskaExample;
sourceTree = "<group>";
Expand All @@ -98,6 +107,7 @@
DE7C38641E005E3C00A399A3 /* Resources */,
4AE147B018A9543A80727648 /* [CP] Embed Pods Frameworks */,
AC908C2BE3E29B7037E5E673 /* [CP] Copy Pods Resources */,
21F621231E315F15006C0DBE /* swiftlint */,
);
buildRules = (
);
Expand Down Expand Up @@ -148,13 +158,28 @@
buildActionMask = 2147483647;
files = (
DE7C38741E005E3C00A399A3 /* LaunchScreen.storyboard in Resources */,
21F621201E3147D5006C0DBE /* app_structure.json in Resources */,
DE7C38711E005E3C00A399A3 /* Assets.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */

/* Begin PBXShellScriptBuildPhase section */
21F621231E315F15006C0DBE /* swiftlint */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = swiftlint;
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "if which swiftlint >/dev/null; then\nswiftlint\nelse\necho \"warning: SwiftLint not installed, download from https://github.com/realm/SwiftLint\"\nfi";
};
4AE147B018A9543A80727648 /* [CP] Embed Pods Frameworks */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
Expand Down Expand Up @@ -208,7 +233,9 @@
buildActionMask = 2147483647;
files = (
DE7C386C1E005E3C00A399A3 /* TileViewController.swift in Sources */,
21F6211E1E3147AF006C0DBE /* JSONReader.swift in Sources */,
DE7C386A1E005E3C00A399A3 /* AppDelegate.swift in Sources */,
21F621221E3155D1006C0DBE /* MatrioskaCodeViewController.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
110 changes: 49 additions & 61 deletions Example/MatrioskaExample/AppDelegate.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,72 +14,60 @@ class AppDelegate: UIResponder, UIApplicationDelegate {

var window: UIWindow?

let rootComponent = ClusterLayout.tabBar(
children: [
blankComponent(
meta: ClusterLayout.TabConfig(title: "First", iconName: "tabIcon")
),
blankComponent(
meta: ClusterLayout.TabConfig(title: "Second", iconName: "tabIcon")
),
navComponent(child:
ClusterLayout.stack(
children: [
tileComponent(meta: TileConfig(text: "One", color: .red)),
tileComponent(meta: TileConfig(text: "Two", color: .green)),
ClusterLayout.stack(
children: [
tileComponent(meta: TileConfig(text: "A", color: .red)),
tileComponent(meta: TileConfig(text: "B", color: .green)),
tileComponent(meta: TileConfig(text: "C", color: .orange)),
tileComponent(meta: TileConfig(text: "D", color: .yellow))
],
meta: ClusterLayout.StackConfig(axis: .horizontal)
),
tileComponent(meta: TileConfig(text: "Three", color: .orange)),
tileComponent(meta: TileConfig(text: "Four", color: .yellow))
],
meta: ZipMeta(ClusterLayout.TabConfig(title: "Third", iconName: "tabIcon"))
)
),
blankComponent(
meta: ClusterLayout.TabConfig(title: "Fourth", iconName: "tabIcon")
),
blankComponent(
meta: ClusterLayout.TabConfig(title: "Fifth", iconName: "tabIcon")
)
],
meta: ClusterLayout.TabBarConfig(selectedIndex: 2)
)

func application(_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {

window = UIWindow(frame: UIScreen.main.bounds)
window?.rootViewController = rootComponent.viewController()
window?.makeKeyAndVisible()

let factory = JSONFactory()

let tabBarBuilder: JSONFactory.ClusterBuilder = { (children, meta) in
ClusterLayout.tabBar(children: children, meta: meta)
}

let stackBuilder: JSONFactory.ClusterBuilder = { (children, meta) in
ClusterLayout.stack(children: children, meta: meta)
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or let stackBuilder: JSONFactory.ClusterFactoryBuilder = ClusterLayout.stack


let navigationBuilder: JSONFactory.WrapperBuilder = { (child, meta) in
Component.wrapper(viewBuilder: { (child, meta) in
guard let vc = child.viewController() else {
return nil
}
return UINavigationController(rootViewController: vc)
}, child: child, meta: meta)
}

let tileBuilder: JSONFactory.SingleBuilder = { (meta) in
Component.single(viewBuilder: { (meta) -> UIViewController? in
TileViewController.init(meta: TileConfig.materialize(meta))
}, meta: meta)
}

let matrioskaCodeBuilder: JSONFactory.SingleBuilder = { (meta) in
Component.single(viewBuilder: {_ in
return MatrioskaCodeViewController()
}, meta: meta)
}

factory.register(builder: tabBarBuilder, forType: "tabbar")
factory.register(builder: stackBuilder, forType: "stack")
factory.register(builder: navigationBuilder, forType: "navigation")
factory.register(builder: tileBuilder, forType: "tile")
factory.register(builder: matrioskaCodeBuilder, forType: "matrioska")

do {
if let json = try JSONReader.jsonObject(from: "app_structure") {

let rootComponent = try factory.makeComponent(json: json)
window?.rootViewController = rootComponent?.viewController()
window?.makeKeyAndVisible()
}

} catch {
assert(false, "JSON could not be parsed")
}

return true
}
}

private func navComponent(child: Component) -> Component {
let viewBuilder: Component.WrapperViewBuilder = { (child, meta) -> UIViewController? in
return child.viewController().map { UINavigationController(rootViewController: $0) }
}

return Component.wrapper(viewBuilder: viewBuilder, child: child, meta: child.meta)
}

private func blankComponent(meta: ComponentMeta?) -> Component {
let viewBuilder: Component.SingleViewBuilder = { (meta) in
let vc = UIViewController()
vc.view.backgroundColor = .white
return vc
}
return Component.single(viewBuilder: viewBuilder, meta: meta)
}

private func tileComponent(meta: TileConfig) -> Component {
return Component.single(viewBuilder: TileViewController.init(meta:), meta: meta)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "home.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"images" : [
{
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "list.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions Example/MatrioskaExample/JSONReader.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
//
// JSONReader.swift
// Matrioska
//
// Created by Andreas Thenn on 12/01/2017.
// Copyright © 2017 runtastic. All rights reserved.
//

import Foundation
@testable import Matrioska

/// A JSONReader used to convert to JSONObject
final class JSONReader {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We shouldn't duplicate this file here, will add structure to the JSONFactory.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah too bad we cannot use the one from the project.


/// Serializes from a given JSON Data into JSONObject
///
/// - Parameter data: the Data object used in serialization
/// - Returns: an optional serialized JSONObject
/// - Throws: throws an error in case of failure or invalid JSON data
class func jsonObject(from data: Data) throws -> JSONObject? {
let json = try JSONSerialization.jsonObject(with: data) as? JSONObject

return json
}

/// Serializes from a given JSON file into JSONObject
///
/// - Parameters:
/// - jsonFilename: the file name
/// - bundle: the bundle where the file is located
/// - Returns: an optional serialized JSONObject
/// - Throws: throws an error in case of failure or invalid JSON data
class func jsonObject(from jsonFilename: String, bundle: Bundle = .main) throws -> JSONObject? {
guard let filePath = bundle.path(forResource: jsonFilename, ofType: "json") else {
return nil
}

let url = URL(fileURLWithPath: filePath)

return try jsonObject(from: Data(contentsOf: url, options: .uncached))
}
}
57 changes: 57 additions & 0 deletions Example/MatrioskaExample/MatrioskaCodeViewController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
//
// MatrioskaCodeViewController.swift
// MatrioskaExample
//
// Created by Mathias Aichinger on 19/01/2017.
// Copyright © 2017 runtastic. All rights reserved.
//

import UIKit
import Matrioska
import SnapKit

class MatrioskaCodeViewController: UIViewController {

let rootComponent = ClusterLayout.stack(
children: [
tileComponent(meta: TileConfig(text: "One", color: .red)),
tileComponent(meta: TileConfig(text: "Two", color: .green)),
ClusterLayout.stack(
children: [
tileComponent(meta: TileConfig(text: "A", color: .red)),
tileComponent(meta: TileConfig(text: "B", color: .green)),
tileComponent(meta: TileConfig(text: "C", color: .orange)),
tileComponent(meta: TileConfig(text: "D", color: .yellow))
],
meta: ClusterLayout.StackConfig(axis: .horizontal)
),
tileComponent(meta: TileConfig(text: "Three", color: .orange)),
tileComponent(meta: TileConfig(text: "Four", color: .yellow))
],
meta: ClusterLayout.StackConfig(title: "Test",
spacing: CGFloat(10.0),
axis: .vertical,
preserveParentWidth: true,
backgroundColor: .blue)
)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not returning this component when declaring the matrioskaCodeBuilder on AppDelegate?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wanted to separate it from the AppDelegate to show that you can always use Matrioska in own ViewControllers


override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = .red

guard let rootViewController = rootComponent.viewController(), let rootView = rootViewController.view else {
return
}

addChildViewController(rootViewController)
view.addSubview(rootView)
rootViewController.didMove(toParentViewController: self)
rootView.snp.makeConstraints { (make) in
make.edges.equalTo(self.view).inset(0)
}
}
}

private func tileComponent(meta: TileConfig) -> Component {
return Component.single(viewBuilder: TileViewController.init(meta:), meta: meta)
}
5 changes: 4 additions & 1 deletion Example/MatrioskaExample/TileViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ struct TileConfig: ExpressibleByComponentMeta {

init?(meta: ComponentMeta) {
text = meta["text"] as? String
color = meta["color"] as? UIColor

let hexColor = meta["color"] as? String
let color = UIColor(hexString: hexColor ?? "")
self.color = color
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or just color = UIColor(hexString: hexColor ?? "")

}

init(text: String?, color: UIColor) {
Expand Down
Loading