Как создать вложенные элементы словаря в Swift? - PullRequest
0 голосов
/ 07 июня 2018

Я хочу создать переменную, в которой будет храниться это:

["messageCode": API_200, "data": {
    activities =     (
                {
            action = 1;
            state = 1;
        }
    );
    messages =     (
                {
            body = hi;
            // ...
        }
    );
}, "message": ]

Что я сделал, это:

var fullDict: Dictionary<String, AnyObject> = [:]
fullDict["messageCode"] = "API_200" as AnyObject

var data: Dictionary<String, AnyObject> = [:]
fullDict ["data"] = data as AnyObject

Правильно ли это и как я могу добавить действия?

Ответы [ 2 ]

0 голосов
/ 07 июня 2018

Я бы предложил перейти к созданию пользовательской модели:

struct Model {
    var messageCode: String
    var data: MyData
    var message: String
}

struct MyData {
    let activities: [Activity]
    let messages: [Message]
}

struct Activity {
    var action: Int
    var state: Int
}

struct Message {
    var body: String
    // ...
}

Таким образом, вы можете использовать ее как:

let data = MyData(activities: [Activity(action: 1, state: 1)], messages: [Message(body: "hi")])
let myModel = Model(messageCode: "API_200", data: data, message: "")

Однако, если вы по какой-то причине- нужно объявить его как словарь, это может быть что-то вроде этого:

let myDict: [String: Any] = [
                            "messageCode": "API_200",
                             "data": ["activities": [["action": 1, "state": 1]],
                                      "messages": [["body": "hi"]]
                                     ],
                             "message": ""
                            ]

, что означает, что myDict словарь содержит:

  • messageCode строка.
  • data как вложенный словарь, содержащий:
    • activities массив словарей (массив [String: Int]).
    • messages массив словарей (массив [String: String]).
  • message строка.

Одна из самых простых причин, почему вы должны пойти с моделированиемподход заключается в том, что когда дело доходит до чтения из myModel, все, что вам нужно сделать, - это использовать точку ..В отличие от работы с ним в качестве словаря, вам придется использовать его значения, которые могут быть головной болью в какой-то момент.Например, предположим, что мы хотим получить доступ к первому телу сообщения в массиве сообщений данных:

Модель:

myModel.data.messages.first?.body

Словарь:

if let data = myDict["data"] as? [String: [[String: Any]]],
   let messages = data["messages"] as? [[String: String]],
   let body = messages.first?["body"] {

    print(body)
}
0 голосов
/ 07 июня 2018

Поскольку вы явно хотите, чтобы оно было [String:AnyObject]:

var dict: [String:AnyObject] = ["messageCode":"API_200" as AnyObject,
                                "data": ["activities": [["action":1,
                                                         "state":1]],
                                         "messages": [["body":"hi"]]] as AnyObject,
                                "message": "" as AnyObject]

В основном все корневые значения должны быть типизированы as AnyObject

Или длинный путь:

//Activities is as Array of dictionary with Int values
var activities = [[String:Int]]()
activities.append(["action": 1,
                   "state": 1])

//Messages is an Array of string
var messages = [[String:String]]()
messages.append(["body" : "hi"])

//Data is dictionary containing activities and messages
var data = [String:Any]()
data["activities"] = activities
data["messages"] = messages

//Finally your base dictionary
var dict = [String:AnyObject]()
dict["messageCode"] = "API_200" as AnyObject
dict["data"] = data as AnyObject
dict["message"] = "" as AnyObject
print(dict)

Разбор этого для получения ваших данных будет адом;со всеми приведениями типов и всеми.

Пример (позволяет захватывать action):

let action = ((dict["data"] as? [String:Any])?["activities"] as? [String:Int])?.first?.value

Как вы можете видеть, вам нужно набрать тип накаждый уровень.Это проблема с использованием словарей в Swift.Слишком много ошибок.

Конечно, вы можете использовать стороннюю библиотеку, такую ​​как SwiftyJSON, чтобы уменьшить вышеупомянутое значение до:

let action = dict["data"]["activities"][0]["action"]

Но вы хотитезависимость только для чего-то такого простого?

Вместо ...

Если ваша структура определена, то вместо этого создайте модели;как подсказывает ответ Ахмада Ф. .Он будет более читабельным, обслуживаемым и гибким.

... но так как вы спросили, это то, как можно было бы сделать это с чистыми Dictionary элементами.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...