Swift - 接收 json 对象作为视图控制器的输入参数?
Swift - receive json object as input parameter to view controller?
我正在为 iOS 项目做作业,业务逻辑规则之一是让视图控制器 接收 id
作为输入参数 ,我不明白这是什么意思。
id
是一个 JSON 对象字段,如下所示:
{
"id": 1213213,
"anotherKey:12322123,
"andAnotherKey: {
"keyInKey":123121
}
,
...
}
我的猜测是打开一个带有自定义初始化的视图控制器,如下所示:
init(id: String) {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
我的理解可能是作业的意图吗?如果是这样,我如何从 SceneDelegate
实例化这个视图控制器?我采用了 MVVM 模式,场景委托看起来不像是离开视图模型的好地方。任何建议将不胜感激!
Is my understanding likely what the assignment intends?
没有。如果您使用的是 MVVM,我宁愿将字符串值设置为 viewModel,并将完全配置的 viewModel 作为依赖项注入 ViewController(称为 控制反转原则 (IoC)).
如果你没有使用任何第三方依赖注入器,你总是可以使用init
这被称为通过构造函数的依赖注入
依赖注入有多种方式,不在本回答范围内讨论。
以下答案假定您没有使用任何第三方依赖注入器并使用基于 Constructor
的注入。
how do I instantiate this view controller from SceneDelegate?
第 1 步: 有一个 viewModel class
class ViewModelA {
let someParam: String
init(with param: String) {
self.someParam = param
//rest of code
}
//rest of code whatever makes sense here
//modification of string any buisness logic
//or hold other data models
}
步骤 2: 将 ViewModel 作为构造函数依赖注入到 ViewController
class ViewControllerA: UIViewController {
let viewModel: ViewModelA
init(with viewModel: ViewModelA) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//rest of code to set up, update UI and view delegates
}
第 3 步: 在 SceneDelegate
的 willConnectTo session
方法中将您的视图控制器设置为 window 的根视图控制器
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let viewModelA = ViewModelA(with: "abcd")
let viewControllerA = ViewControllerA(with: viewModelA)
window.rootViewController = viewControllerA
self.window = window
window.makeKeyAndVisible()
}
I've adopted MVVM pattern and the scene delegate doesn't look like a
great place to leave view model.
你不觉得必须在某处设置 rootView 控制器吗?早些时候我们曾经在 AppDelegate 中设置 rootView 控制器(从概念上讲,在 AppDelegate 中创建一个 ViewModel 和 ViewController 实例也有些不稳定)。即使您使用故事板并将某些视图控制器设置为初始 viewController,甚至 iOS 也会在幕后做同样的事情。这是因为你想遵循 MVVM 而不是 MVC,你必须手动拦截和实例化 ViewController 并将 viewModel 作为其依赖项。
我个人更喜欢使用带路由的 MVVM,这样创建和注入对 ViewController 的依赖可以分离出来(更好的关注点分离)并且可以重用(更好的代码重用性)
我正在为 iOS 项目做作业,业务逻辑规则之一是让视图控制器 接收 id
作为输入参数 ,我不明白这是什么意思。
id
是一个 JSON 对象字段,如下所示:
{
"id": 1213213,
"anotherKey:12322123,
"andAnotherKey: {
"keyInKey":123121
}
,
...
}
我的猜测是打开一个带有自定义初始化的视图控制器,如下所示:
init(id: String) {
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
setupUI()
}
我的理解可能是作业的意图吗?如果是这样,我如何从 SceneDelegate
实例化这个视图控制器?我采用了 MVVM 模式,场景委托看起来不像是离开视图模型的好地方。任何建议将不胜感激!
Is my understanding likely what the assignment intends?
没有。如果您使用的是 MVVM,我宁愿将字符串值设置为 viewModel,并将完全配置的 viewModel 作为依赖项注入 ViewController(称为 控制反转原则 (IoC)).
如果你没有使用任何第三方依赖注入器,你总是可以使用init
这被称为通过构造函数的依赖注入
依赖注入有多种方式,不在本回答范围内讨论。
以下答案假定您没有使用任何第三方依赖注入器并使用基于 Constructor
的注入。
how do I instantiate this view controller from SceneDelegate?
第 1 步: 有一个 viewModel class
class ViewModelA {
let someParam: String
init(with param: String) {
self.someParam = param
//rest of code
}
//rest of code whatever makes sense here
//modification of string any buisness logic
//or hold other data models
}
步骤 2: 将 ViewModel 作为构造函数依赖注入到 ViewController
class ViewControllerA: UIViewController {
let viewModel: ViewModelA
init(with viewModel: ViewModelA) {
self.viewModel = viewModel
super.init(nibName: nil, bundle: nil)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//rest of code to set up, update UI and view delegates
}
第 3 步: 在 SceneDelegate
的 willConnectTo session
方法中将您的视图控制器设置为 window 的根视图控制器
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
// Use this method to optionally configure and attach the UIWindow `window` to the provided UIWindowScene `scene`.
// If using a storyboard, the `window` property will automatically be initialized and attached to the scene.
// This delegate does not imply the connecting scene or session are new (see `application:configurationForConnectingSceneSession` instead).
guard let windowScene = (scene as? UIWindowScene) else { return }
let window = UIWindow(windowScene: windowScene)
let viewModelA = ViewModelA(with: "abcd")
let viewControllerA = ViewControllerA(with: viewModelA)
window.rootViewController = viewControllerA
self.window = window
window.makeKeyAndVisible()
}
I've adopted MVVM pattern and the scene delegate doesn't look like a great place to leave view model.
你不觉得必须在某处设置 rootView 控制器吗?早些时候我们曾经在 AppDelegate 中设置 rootView 控制器(从概念上讲,在 AppDelegate 中创建一个 ViewModel 和 ViewController 实例也有些不稳定)。即使您使用故事板并将某些视图控制器设置为初始 viewController,甚至 iOS 也会在幕后做同样的事情。这是因为你想遵循 MVVM 而不是 MVC,你必须手动拦截和实例化 ViewController 并将 viewModel 作为其依赖项。
我个人更喜欢使用带路由的 MVVM,这样创建和注入对 ViewController 的依赖可以分离出来(更好的关注点分离)并且可以重用(更好的代码重用性)