Swift 4添加了新Codable协议.当我使用JSONDecoder它似乎要求我的Codable类的所有非可选属性在JSON中有键或它会引发错误.
使我的类的每个属性都是可选的似乎是一个不必要的麻烦,因为我真正想要的是使用json中的值或默认值.(我不希望这个属性为零.)
有没有办法做到这一点?
class MyCodable: Codable {
var name: String = "Default Appleseed"
}
func load(input: String) {
do {
if let data = input.data(using: .utf8) {
let result = try JSONDecoder().decode(MyCodable.self, from: data)
print("name: \(result.name)")
}
} catch {
print("error: \(error)")
// `Error message: "Key not found when expecting non-optional type
// String for coding key \"name\""`
}
}
let goodInput = "{\"name\": \"Jonny Appleseed\" }"
let badInput = "{}"
load(input: goodInput) …Run Code Online (Sandbox Code Playgroud) 尽管已经为所有元素设置了约束,包括单元格计算其高度所需的垂直元素,但自动布局似乎被忽略:所有单元格都被挤压.
在包含tableView的VC中,这是viewDidLoad中的代码:
tableView.estimatedRowHeight = 120.0
tableView.rowHeight = UITableViewAutomaticDimension
Run Code Online (Sandbox Code Playgroud)
注释掉第二行会使单元格的高度为120.0,但也会忽略Autolayout.
谢谢
为了简化界面,我留下了一个标签,作为约束:
通过这个简化的界面,仍然没有考虑自动布局,这暗示我的问题并非来自严重设置的约束.
在"大小"检查器中,行高设置为120,并选中"自定义".单元格具有正确的自定义类,单元格重用标识符是正确的.
这是一个简单的错误,请参阅下面的答案.
我似乎遇到了一堵砖墙,但基本上我在我的应用程序中的是用户的登录页面和创建帐户页面.当用户打开我的应用并创建新帐户时,他们的信息将存储在Firebase服务器(BaSS)上.
现在我的问题是我将如何制作它以便对于通过我的应用程序创建帐户的每个用户,他们可以选择订阅我的应用程序,并且此订阅仅对他们的帐户有效(不是苹果ID).目前,如果用户与我创建了一个帐户并继续说订阅服务,那么一切都可以访问应用程序的全部功能.
但是,当他们注销并创建另一个帐户时,因为现在它的订阅与用户的苹果ID相关联,另一个帐户或任何帐户可以完全访问该应用程序.不只是购买的那个.
所以我想我的问题是如何制作它以便每次订阅/购买都与我的内部用户相关联,而不是设备上登录的苹果ID.(基本上像pandora或spotify,您对应用的访问权限取决于您的帐户,而不是您的苹果ID)
根据苹果文档:
持续使用您自己的服务器将收据的副本连同某种凭据或标识符一起发送到您的服务器,以便您可以跟踪哪些收据属于特定用户.例如,让用户使用电子邮件或用户名以及密码向服务器标识自己.不要使用UIDevice的identifierForVendor属性 - 您不能使用它来识别和恢复同一用户在其他设备上进行的购买,因为不同的设备对此属性具有不同的值.
我如何使用Firebase做类似的事情?
我正在处理在 Xcode 9 之前创建的项目,并且文件夹结构与组结构不匹配。
有些组与文件夹无关,而其他组则是。有些文件在文件夹之外,而它们在组中。
当我的 UILabel 的字体大小被调整以适应标签的宽度时,文本的底部被切断。这是调试视图的屏幕截图:
UILabel 具有以下特点:
附加元素:
不起作用的事情:
(在我输入这个问题时,我再次尝试更改基线调整设置以确认它不起作用,这次它起作用了。请参阅答案。)
我正在尝试显示包含参数的本地化字符串。结果不是在一行中显示嵌入参数的字符串,而是一个断开的 3 行字符串:
预期结果:
The price is $9.99/year.
Run Code Online (Sandbox Code Playgroud)
结果:
The price is (
"$9.99"
)/year.
Run Code Online (Sandbox Code Playgroud)
Localizable.strings:
"price_string" = "The price is %@/year.";
Run Code Online (Sandbox Code Playgroud)
称呼:
"price_string".localized(priceString)
Run Code Online (Sandbox Code Playgroud)
其中priceString是一个字符串变量。
并.localized()定义如下:
extension String {
var localized: String {
return NSLocalizedString(self, comment: "\(self)_comment")
}
func localized(_ args: CVarArg...) -> String {
return String(format: localized, args)
}
}
Run Code Online (Sandbox Code Playgroud) 如果我们编码了符合Codable并希望使用具有新属性的新类代码解码这些对象的类的对象,那么需要什么代码才能使该新属性成为非可选的,并为其属性赋予默认值?
老班:
class Item: Codable {
let id: String
}
Run Code Online (Sandbox Code Playgroud)
新班级:
class Item: Codable {
let id: String
let title: String
}
Run Code Online (Sandbox Code Playgroud)
当使用新格式的代码解码以旧格式保存的对象时,title将找不到任何属性,并且解码将不起作用。
我们可以通过创建title一个可选的String?.
但是我们如何实现title作为非可选的保持String,并在解码每个对象时给它一个默认值?
PS:这是完整的代码。没有指定编码密钥,也没有编写来自解码器的自定义初始化。
(令我惊讶的是,我找不到任何地方都可以问这个问题,听起来很基本。我可能会遗漏一些东西...)
有没有一种方法可以创建与Date / NSDate对象(日期,时间,日历,timeZone)完全匹配的DateComponents()对象,而不必指定我们要包括的所有组件?
具体用例示例:UNCalendarNotificationTrigger的init方法将DateComponents作为参数,并且我们希望将该通知设置为作为Date / NSDate对象保留的特定日期和时间,因此需要提取其dateComponents。
ios ×6
swift ×6
autolayout ×1
codable ×1
firebase ×1
json ×1
nsdate ×1
objective-c ×1
storekit ×1
swift3 ×1
swift4 ×1
uitableview ×1
xcode ×1