ios - 使用 init 实例化 UIViewController(来自解码器:解码器)
问题描述
我需要将用户创建的 ViewControllers 存储到一个 json 文件中,我需要稍后在同一设备或不同设备上重新创建它们。
ViewController 在情节提要中可用,但我无法在 init(来自解码器:解码器)函数中正确实例化它们。
这是要保存和恢复的 ViewController。
class SecondViewController: UIViewController, Encodable, Decodable {
@IBOutlet weak var textField: UITextField!
private var restoreText: String?
enum CodingKeys: CodingKey {
case textField
}
func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(textField.text, forKey: .textField)
}
required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
restoreText = try? container.decode(String.self, forKey: .textField)
super.init(nibName: "", bundle: nil)
}
required init?(coder: NSCoder) {
super.init(coder: coder)
}
override func viewDidLoad() {
super.viewDidLoad()
if let text = restoreText {
textField.text = text
}
}
@IBAction func save(_ sender: Any) {
do {
let jsonData = try JSONEncoder().encode(self)
let s = String(data: jsonData, encoding: .ascii)
print("Widgets \(s!)")
let filename = getDocumentsDirectory().appendingPathComponent("output.txt")
try jsonData.write(to: filename)
} catch {
print(error.localizedDescription)
}
}
}
这是我从 json 文件加载控制器并尝试重新创建它的地方。
...
do {
let filename = getDocumentsDirectory().appendingPathComponent("output.txt")
let jsonData = try Data(contentsOf: filename)
if let s = String(data: jsonData, encoding: .ascii) {
let controller = try JSONDecoder().decode(SecondViewController.self, from: jsonData)
let frame = CGRect(x: 0, y: 0, width: view.frame.width * 0.8, height: view.frame.height * 0.8)
controller.view.frame = frame
controller.view.center = view.center
view.addSubview(controller.view)
addChild(controller)
}
} catch {
print(error.localizedDescription)
}
...
运行此代码,我收到以下错误:
*** Assertion failure in -[UINib initWithNibName:directory:bundle:], /AppleInternal/BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3920.26.113/UINib.m:97
2020-04-18 09:44:03.543891+0200 ViewControllerSerialization[7764:504964] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid parameter not satisfying: (name != nil) && ([name length] > 0)'
据我了解,此错误是因为尚未从情节提要中加载控制器。
问题是如何在 init(from decoder: Decoder) 函数中从情节提要中正确初始化 ViewController?
解决方案
推荐阅读
- snowflake-cloud-data-platform - SnowFlake 中的合并语句似乎写入了太多行。有没有办法改善这一点?
- php - 尝试传递变量以在 Excel 中生成报告时出错
- c - 线程 1:EXC_BAD_ACCESS (code=1, address=0x0) 错误在运行期间不断发生
- sql - 当 R 中的 PostgreSQL 中的列号不同时如何附加两个数据框
- javascript - 不重定向到条带结帐页面 node.js
- amazon-web-services - 使用 api 调用结果作为 CloudFormation 资源的参数
- mysql - 将mysql“show grants”命令的输出保存到变量中
- vba - 改进 accdb 文件中的 INSERT-Access-VBA
- sql - PLSQL 过程迭代 SELECT 语句并提取列值
- email - Linkedin 电子邮件提取扩展概念