Skip to content

Commit

Permalink
Merge pull request #53 from crane-hiromu/feature/license
Browse files Browse the repository at this point in the history
ライセンス画面の追加
  • Loading branch information
crane-hiromu authored Sep 7, 2022
2 parents ebf2d4a + f5ac81b commit 95a1b38
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 99 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ playground.xcworkspace
#
# Swift Playground 4.1 でアプリをクローンした際に、クラッシュするため、一旦リポジトリにも含めておく
# Package.resolved
CachedManifest.plist

#
# Xcode automatically generates this directory with a .xcworkspacedata file and xcuserdata
Expand Down
86 changes: 0 additions & 86 deletions .swiftpm/playgrounds/CachedManifest.plist

This file was deleted.

11 changes: 10 additions & 1 deletion App/Helpers/Router.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ protocol RouterProtocol {
static func routeToSessionDetail(with model: SessionModel) -> SessionDetailView
static func routeToUserList(with models: [User]) -> UserListView
static func routeToLicense() -> LicenseView
static func routeToLicenseDetail(with model: LicenseModel) -> LicenseDetailView
// Web
static func routeToWeb(with url: URL)
}
Expand Down Expand Up @@ -78,7 +79,15 @@ enum Router: RouterProtocol {
}

static func routeToLicense() -> LicenseView {
.init()
.init(viewModel: .init(), environment: .init())
}

static func routeToLicenseDetail(with model: LicenseModel) -> LicenseDetailView {
.init(
viewModel: .init(
output: .init(model: model)
)
)
}

// MARK: Web
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import Foundation
{% if document.metadata.type == "Array" %}
{{accessModifier}} static let items: {{rootType}} = arrayFromPlist(at: "{% call transformPath file.path %}")
{% elif document.metadata.type == "Dictionary" %}
static let name = "{% call transformPath file.path %}"
private static let _document = PlistDocument(path: "{% call transformPath file.path %}")
{% for key,value in document.metadata.properties %}
{{accessModifier}} {%+ call propertyBlock key value %}
Expand Down
8 changes: 4 additions & 4 deletions App/Screens/Info/InfoView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -83,10 +83,10 @@ private extension InfoView {
type: .privacyPolicy,
action: { viewModel.input.didTapButton.send(.privacyPolicy) }
)
// InfoNavigationRow(
// type: .license,
// destination: licenseView
// )
InfoNavigationRow(
type: .license,
destination: licenseView
)
}
}

Expand Down
6 changes: 6 additions & 0 deletions App/Screens/License/LicenseEnvironment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import SwiftUI

// MARK: - Environment
struct LicenseEnvironment: DynamicProperty {
@Environment(\.router) var router
}
11 changes: 9 additions & 2 deletions App/Screens/License/LicenseView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,16 @@ import SwiftUI

// MARK: - View
struct LicenseView: View {
@ObservedObject var viewModel: LicenseViewModel
let environment: LicenseEnvironment

var body: some View {
Text("LicenseView")
List(viewModel.output.models, id: \.id) {
LicenseRow(
name: $0.name,
destination: environment.router.routeToLicenseDetail(with: $0)
)
}
.navigationBarTitle(L10n.infoTypeLicense, displayMode: .inline)
}
}

59 changes: 59 additions & 0 deletions App/Screens/License/LicenseViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import SwiftUI
import Foundation
import Combine
import CombineStorable

// MARK: - ViewModel
final class LicenseViewModel: NSObject, ObservableObject, Storable {
let input: Input
let output: Output
@ObservedObject var binding: Binding

init(
input: Input = .init(),
output: Output = .init(),
binding: Binding = .init()
) {
self.input = input
self.output = output
self.binding = binding
super.init()
bind(input: input, output: output, binding: binding)
}
}

// MARK: - Property
extension LicenseViewModel {

final class Input {
// NOP
}

final class Output: ObservableObject {
// fixme: update stencil
let models: [LicenseModel] = [
LicenseModel(name: PlistFiles.CombineStorable.name, plist: PlistFiles.CombineStorable.preferenceSpecifiers),
LicenseModel(name: PlistFiles.PlaygroundTester.name, plist: PlistFiles.PlaygroundTester.preferenceSpecifiers),
LicenseModel(name: PlistFiles.SwiftUIWorkaround.name, plist: PlistFiles.SwiftUIWorkaround.preferenceSpecifiers)
]
}

final class Binding: ObservableObject {
// NOP
}
}


// MARK: - Private
private extension LicenseViewModel {

func bind(input: Input, output: Output, binding: Binding) {
// 親孫でのbindを可能にする
binding.objectWillChange
.sink { [weak self] _ in
self?.objectWillChange.send()
}
.store(in: &cancellables)
}
}

30 changes: 30 additions & 0 deletions App/Screens/License/Models/LicenseModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import SwiftUI

// MARK: - Model
final class LicenseModel {
let name: String
let description: String

init(
name: String,
plist: [[String: Any]]
) {
self.name = name.replaceExtension
self.description = plist.compactMap {
$0["FooterText"] as? String
}.first ?? ""
}
}

// MARK: - Identifiable
extension LicenseModel: Identifiable {
var id: UUID { UUID() }
}

/* fixme: いずれ stenceil ファイル側で制御する */
private extension String {

var replaceExtension: String {
replacingOccurrences(of: ".plist", with: "")
}
}
23 changes: 23 additions & 0 deletions App/Screens/License/Views/LicenseRow.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import SwiftUI

// MARK: - Row
struct LicenseRow<Destination: View>: View {
let name: String
let destination: Destination

var body: some View {
NavigationLink(
destination: destination,
label: { label }
)
}
}

// MARK: - Private
private extension LicenseRow {

var label: some View {
Text(name)
.foregroundColor(.primary)
}
}
14 changes: 14 additions & 0 deletions App/Screens/LicenseDetail/LicenseDetailView.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import SwiftUI

// MARK: - View
struct LicenseDetailView: View {
@ObservedObject var viewModel: LicenseDetailViewModel

var body: some View {
ScrollView {
Text(viewModel.output.model.description)
.padding()
}
.navigationBarTitle(viewModel.output.model.name, displayMode: .inline)
}
}
43 changes: 43 additions & 0 deletions App/Screens/LicenseDetail/LicenseDetailViewModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import SwiftUI
import Foundation
import Combine
import CombineStorable


// MARK: - ViewModel
final class LicenseDetailViewModel: NSObject, ObservableObject, Storable {
let input: Input
let output: Output
@ObservedObject var binding: Binding

init(
input: Input = .init(),
output: Output = .init(),
binding: Binding = .init()
) {
self.input = input
self.output = output
self.binding = binding
super.init()
}
}

// MARK: - Property
extension LicenseDetailViewModel {

final class Input {
// NOP
}

final class Output: ObservableObject {
let model: LicenseModel

init(model: LicenseModel = .init(name: "", plist: [])) {
self.model = model
}
}

final class Binding: ObservableObject {
// NOP
}
}
14 changes: 8 additions & 6 deletions Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ let package = Package(
.product(name: "PlaygroundTester", package: "playgroundtester")
],
path: ".",
exclude: [
"swiftgen.yml",
"README.md",
"Makefile",
"App/Resources/SwiftGen/Stencil"
],
resources: [
.copy("swiftgen.yml"),
.copy("README.md"),
.copy("Makefile"),
.copy("App.plist"),
.copy("App/Resources/License"),
.copy("App/Resources/SwiftGen/Stencil")
.process("App/Resources/License"),
.copy("App.plist")
],
swiftSettings: [
.unsafeFlags(["-Xfrontend", "-warn-long-function-bodies=100"], .when(configuration: .debug)),
Expand Down

0 comments on commit 95a1b38

Please sign in to comment.