似乎Swift 4正在为struct User {
let name: String?
let email: String?
}
实现不同的方法,在Swift 4中该函数的替换是什么?
我有
的结构dictionaryOfUsers
let dictionaryOfUsers = [{key1: "name1", key2 : "name1@xyz.com"}, {key1 : "name2", key2 : "name2@gmail.com"} ]
let users = [User]
来自数据结构,该值根据数据库中的用户数动态显示:
for dictionary in dictionaryOfUsers {
let user = User()
user.setValuesForKeysWithDictionary(dictionary)
现在我想使用此函数创建我的用户数组以在Swift 4中创建字典:
users.append(user)
}
并附加给用户
CREATE VIEW ShipItemsBrand AS
SELECT sh.ShipmentID, sh.ShipmentOrderDate, sh.TaxAmount, sh.ShipDate,
si.ShipItemPrice, si.ShipItemDiscountAmount, SUM(si.ShipItemPrice - si.ShipItemDiscountAmount) As FinalPrice, si.Quantity, SUM((si.ShipItemPrice - si.ShipItemDiscountAmount) * si.Quantity) AS ItemTotal,
b.BrandName
FROM Brands AS b
JOIN ShipItems AS si
ON b.BrandID = si.BrandID
JOIN Shipments AS sh
ON si.ShipmentID = sh.ShipmentID
GROUP BY sh.ShipmentID,sh.ShipmentOrderDate
答案 0 :(得分:3)
请尝试使用此方法:
func setValuesForKeys(_ keyedValues: [String : Any])
使用给定字典中的值来设置接收器的属性,使用其键来标识属性。默认实现为每个键值对...
调用setValue(_:forKey:)
您的代码有许多小问题 - 以及一些主要问题(有关详细信息,请参阅 matt 答案)。无论如何,我认为这应该完成你的目标:
import Foundation
class User: NSObject {
@objc var name: String!
@objc var email: String!
}
let dictionaryOfUsers = [
["name": "name1", "email": "name1@xyz.com"],
["name": "name2", "email": "name2@gmail.com"]
]
var users = [User]()
for dictionary in dictionaryOfUsers {
let user = User()
user.setValuesForKeys(dictionary)
users.append(user)
}
答案 1 :(得分:2)
问题是你正试图在 struct 上使用Cocoa键值编码 - 这是setValuesForKeys(_:)
的来源。你不能这样做。可可是Objective-C; Objective-C不知道Cocoa结构是什么。您需要User
成为从NSObject派生的@objc
类,并且其所有属性也需要公开为@objc
。
或者,使用新的Swift 4密钥路径功能,该功能可以通过密钥访问struct属性。例如:
struct User {
var name: String?
var email: String?
}
let arrayOfDicts = [
[\User.name: "name1", \User.email : "name1@xyz.com"],
[\User.name : "name2", \User.email : "name2@gmail.com"]
]
for d in arrayOfDicts {
var user = User()
for key in d.keys {
user[keyPath:key] = d[key]!
}
print(user)
}
/*
User(name: Optional("name1"), email: Optional("name1@xyz.com"))
User(name: Optional("name2"), email: Optional("name2@gmail.com"))
*/
答案 2 :(得分:1)
不必说Swift 4没有setValuesForKeysWithDictionary方法。而且,当前的setValuesForKeys方法在最新版本的Xcode中,在Swift 4中经常失败。
我的用户对象如下。
import UIKit
class User: NSObject {
var name: String?
var email: String?
}
我自己针对此问题的解决方案是如下手动将密钥添加为NSDictionary。
let user = User()
user.email = (snapshot.value as? NSDictionary)?["email"] as? String ?? ""
user.name = (snapshot.value as? NSDictionary)?["name"] as? String ?? ""
print(user.email as Any)
print(user.name as Any)
它可以正常工作。试试吧。
答案 3 :(得分:0)
我正在做某事。万一有帮助... 附言:请使用泛型对其进行优化。
import Foundation
import CoreData
enum ModelInitializationResult {
case none
case completedWithoutErrors
case completedWithNullDataErrors
case completedWithNoSuchKeyErrors
}
extension NSManagedObject {
//Note: For this to work, the keys in the dictionary should be same as attibute name of this class
func initializeModelFromDictionary(dictionary: [String:Any] ) -> ModelInitializationResult{
var completionResult = ModelInitializationResult.none
let modelAttributes = self.entity.attributesByName
let modelAttributeKeys = modelAttributes.keys
for case let (keyToSet, valueToSet) in dictionary {
//check for invalid key
guard modelAttributeKeys.contains(keyToSet) else{
completionResult = .completedWithNoSuchKeyErrors
continue;
}
//check valueToSetType for Null
let valueToSetType = type(of: valueToSet)
guard valueToSetType != NSNull.self else{
print("ERROR: Found NSNUll for value to set")
completionResult = .completedWithNullDataErrors
continue;
}
//Check desiredType ; set value for defined types
let modelAttributeValue = modelAttributes[keyToSet]
let modelAttributeType = modelAttributeValue?.attributeType
switch (modelAttributeType!) {
case .undefinedAttributeType :
print("Error : undefinedAttributeType")
case .integer16AttributeType, .integer32AttributeType, .integer64AttributeType :
if let anInt = valueToSet as? Int{
self.setValue(anInt, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .stringAttributeType :
if let anString = valueToSet as? String{
self.setValue(anString, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .booleanAttributeType :
if let aBool = valueToSet as? Bool{
self.setValue(aBool, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .dateAttributeType :
if let aDate = valueToSet as? Date{
self.setValue(aDate, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .binaryDataAttributeType :
if let aData = valueToSet as? Data{
self.setValue(aData, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .transformableAttributeType :// If your attribute is of NSTransformableAttributeType,
//print(Pretty//printedFunction(), "desiredType : transformableAttributeType")
if let anObject = valueToSet as? NSObject {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .doubleAttributeType :
//print(Pretty//printedFunction(), "desiredType : doubleAttributeType")
if let anObject = valueToSet as? Double {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .floatAttributeType :
//print(Pretty//printedFunction(), "desiredType : floatAttributeType")
if let anObject = valueToSet as? Float {
self.setValue(anObject, forKey: keyToSet)
}
else{
//print(Pretty//printedFunction(),"Error in setting value for key:\(keyToSet) Incompatible type")
}
case .decimalAttributeType :
print("Error: Data type decimalAttributeType Not handled\(String(describing: modelAttributeType))")
case .objectIDAttributeType:
print("Error: Data type transformableAttributeType Not handled\(String(describing: modelAttributeType))")
default :
print("ERROR : \(String(describing: modelAttributeType))")
}
}
return completionResult
}
func toDictionary() -> [String:Any] {
let keys = Array(self.entity.attributesByName.keys)
let dict = self.dictionaryWithValues(forKeys: keys)
return dict
}
func printAllValues (){
for key in self.entity.attributesByName.keys{
let value: Any? = self.value(forKey: key)
print("\(key) = \(String(describing: value))")
}
}
}