-
Notifications
You must be signed in to change notification settings - Fork 4
Added json example to the example application #11
base: master
Are you sure you want to change the base?
Changes from 6 commits
3984098
6ad88c9
fad8890
ecf6a2b
1f81a59
48cff56
dbfc34d
06e62df
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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" | ||
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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) | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or |
||
|
||
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" | ||
} | ||
} |
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" | ||
} | ||
} |
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 { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We shouldn't duplicate this file here, will add There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
} | ||
} |
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) | ||
) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not returning this component when declaring the There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Or just |
||
} | ||
|
||
init(text: String?, color: UIColor) { | ||
|
There was a problem hiding this comment.
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?