Swift — найти индекс массива словарей на основе значения в словарях с использованием swiftyJSON

Я очень новичок в программировании, не говоря уже о Swift. Я понимаю некоторые концепции из предыдущих попыток программирования, поэтому я продвинулся дальше, чем когда-либо прежде. Прошу прощения, если не совсем понятно, что мне нужно.

Я извлекаю данные JSON из списка предупреждений и пытаюсь проанализировать данные с помощью swiftyJSON, который, я думаю, работает нормально, но я столкнулся с проблемой при попытке получить некоторые данные из некоторых словарей в массиве, и, к сожалению, внутри словаря внутри этого массива находится адрес электронной почты, и разные словари используют одинаковые ключи друг в друге.

Я собираюсь показать вам свою структуру, функции и данные JSON. Пожалуйста, помогите мне получить адрес электронной почты, услугу - ее идентификатор и ее метку. Кроме того, может быть более одной службы, как в показанных данных, и мне нужно захватить их все.

ЗДЕСЬ ДАННЫЕ JSON:

{
"hasNext": false,
"data": [
    {
        "status": [
            1,
            "READ"
        ],
        "resolutionStatus": [
            0,
            "OPEN"
        ],
        "description": "There is some description here",
        "title": "Some Activity",
        "entities": [
            {
                "view_name": "audits",
                "type": "link",
                "parameters": {
                    "orgUnit": "/"
                },
                "label": "/"
            },
            {
                "type": "user",
                "id": "[email protected]",
                "label": "[email protected]"
            },
            {
                "type": "service",
                "id": 6666,
                "label": "someService"
            },
            {
                "type": "service",
                "id": 7777,
                "label": "anotherService"
            }
        ],
        "stories": [
            5
        ],
        "date": "2014-12-10T23:46:28.067000Z",
        "audits": [
            "ljBhqKQVOF9w",
            "pISQyT9iy9w",
            "oynGf2_CIw"
        ],
        "_id": "54fdad0dfd",
        "id": [
            14683,
            "ALERT_SOME_ACTIVITY"
        ],
        "severity": [
            5,
            "HIGH"
        ]
    }

Вот моя структура:

    struct AlertModel: Printable {
    let alertUser: String?
    let alertService: String?
    let alertTitle: String?
    let alertReadStatus: String?
    let alertResolutionStatus: String?
    let alertDescription: String?
    let alertEntities: Array <String> = []
    let alertDate: String?
    let alertAudits: Array <String> = []
    let alertId: String?
    let

     alertSeverity: String?

      // change description to print to console
         var description: String {
            return "User: \(alertUser)\nService: \(alertService)\nTitle: \(alertTitle!)\nRead Status: \(alertReadStatus!)\nResolution Status: \(alertResolutionStatus!)\nDescription: \(alertDescription!)\nDate: \(alertDate!)\nAlert ID: \(alertId!)\nSeverity: \(alertSeverity!)\n******************************************\n"
        }

        init(alertUser: String?, alertService: String?, alertTitle: String?, alertReadStat

us: String?, alertResolutionStatus: String?, alertDescription: String?/*, alertEntities: Array<String>*/, alertDate: String?/*, alertAudits: Array<String>*/, alertId: String?, alertSeverity: String?) {
        self.alertUser = alertUser
        self.alertService = alertService
        self.alertTitle = alertTitle
        self.alertReadStatus = alertReadStatus
        self.alertResolutionStatus = alertResolutionStatus
        self.alertDescription = alertDescription
        //self.alertEntities = alertEntities
        self.alertDate = alertDate
        //self.alertAudits = alertAudits
        self.alertId = alertId
        self.alertSeverity = alertSeverity
    }

А ВОТ ФУНКЦИЯ:

let jsonAlert = JSON(data: jsonAlertObject)
    if let alertArray = jsonAlert["data"].array {
        var alerts = [AlertModel]()
        for alertDict in alertArray {
            let alertTitle: String? = alertDict["title"].stringValue
            let alertReadStatus: String? = alertDict["status"][1].stringValue
            let alertResolutionStatus: String? = alertDict["resolutionStatus"][1].stringValue
            let alertDescription: String? = alertDict["description"].stringValue
            let alertDate: String? = alertDict["date"].stringValue
            let alertId: String? = alertDict["_id"].stringValue

            // Need to grab the type and label from each dictionary in the array of entities
            let alertEntitiesArray: Array? = alertDict["entities"].arrayObject
            var arrayIndex = 0
            var entitiesDict = ["" : ""]
            while arrayIndex < alertEntitiesArray?.count {
                entitiesDict[alertDict["entities"][arrayIndex]["type"].stringValue] = alertDict["entities"][arrayIndex]["label"].stringValue
                arrayIndex++
            }
            let alertService: String? = entitiesDict["service"]
            let alertUser: String? = entitiesDict["user"]
            let alertSeverity: String? = alertDict["severity"][1].stringValue

            let alert = AlertModel(alertUser: alertUser, alertService: alertService, alertTitle: alertTitle, alertReadStatus: alertReadStatus, alertResolutionStatus: alertResolutionStatus, alertDescription: alertDescription, alertDate: alertDate, alertId: alertId, alertSeverity: alertSeverity)
            alerts.append(alert)
            var alertsDictionaryByID = [alertId!: alert]

        }
        println(alerts)
    }

Как видите, данные JSON имеют несколько уровней глубины. У меня нет проблем с получением данных и их извлечением. Проблема в том, что массив «Сущности» не всегда может содержать одни и те же данные. У меня есть несколько сервисов, у него может не быть адреса электронной почты, у него может быть совершенно другой набор данных для первого значения массива.

Я пытаюсь получить адрес электронной почты. Если бы я мог найти способ поиска «пользователя», как с данными словаря, а затем, когда он был бы найден, он вернул бы значение индекса массива, чтобы иметь возможность ссылаться на него напрямую, потому что я никогда не узнаю с номером индекса значение пользователя является частью .

Я надеюсь, что я понял достаточно ясно, и кто-то может мне помочь. --- моим следующим шагом будет заполнение listView каждым отдельным предупреждением.


person Brandon Meyer    schedule 24.03.2015    source источник


Ответы (2)


Я также использовал SwiftyJSON, но использовать NSURLConnection было легко. Нравится этот метод.

//MARK: - NSURLConnection Delegate methods


    var responseData : NSMutableData = NSMutableData()

    func connection(connection: NSURLConnection!, didReceiveResponse response: NSURLResponse!)
    {
        self.responseData.length = 0
    }

    func connection(connection: NSURLConnection!, didReceiveData data: NSData!)
    {
        self.responseData.appendData(data)
    }


    func connectionDidFinishLoading(connection: NSURLConnection!)
    {
        if let responseDatas = responseData as NSData? {

            if let jsonResult : NSDictionary = NSJSONSerialization.JSONObjectWithData(responseDatas, options: NSJSONReadingOptions.MutableContainers, error: nil) as NSDictionary? {


                if let dataArray = jsonResult.valueForKeyPath("data") as? NSArray 
                 {

                  if let entitiesArray = dataArray.valueForKeyPath("entities") as? NSArray 
                 {

                 if let firstArray = dataArray[0] 
                 {
                     // access your viewName and types here
                 }                    

                     // Like this method, convert all your parameters and access it.

                }                    
                }
                else
                {
               // Do something here
                }

            }
            else
            {
                 // Do something here

            }
        }
        else
        {
             // Do something here

        }



    }

    func connection(connection: NSURLConnection!, didFailWithError error: NSError!)
    {
     // Do something here
    }
person Alvin Varghese    schedule 24.03.2015
comment
Я ценю ваш ответ. Я попытался добавить это, и я получаю две ошибки в последнем операторе if-let '1. Предполагается, что константа firstEntitiesArray имеет тип AnyObject, что может оказаться неожиданным. Этот указывает на firstArray. 2. Привязанное значение в условной привязке должно быть необязательного типа. Этот указывает на dataArray[0]. «Можете ли вы помочь мне понять, как последний оператор if-let помогает мне найти ключи\значения, которые я ищу? Это кажется достаточно простым без swiftyJSON, но, как я уже сказал, я все еще новичок, поэтому, возможно, я не смогу сделать вывод о том, о чем вы ожидаете, что я знаю. - person Brandon Meyer; 24.03.2015
comment
Можете ли вы помочь мне понять, как последний оператор if-let помогает мне найти ключи\значения, которые я ищу? Это кажется достаточно простым без swiftyJSON, но, как я уже сказал, я все еще новичок, поэтому, возможно, я не смогу сделать вывод о том, о чем вы ожидаете, что я знаю. - person Brandon Meyer; 24.03.2015

В итоге я нашел SwiftyJSON и Alamofire, которые значительно помогли с сетью и сериализацией JSON.

Что касается моей проблемы со словарями в массиве, я закончил тем, что создал функцию, которая перебирала массив сущностей, просматривая каждый словарь отдельно, а затем выполняла оператор Switch на основе key="type", чтобы определить, был ли это "пользователь " словарь или словарь "service", а затем объединил значение "type", которое говорило, был ли это пользователь или служба, со значением "label", которое является именем пользователя или именем службы, и создал новый словарь из того, на что я мог затем ссылаться, чтобы вернуть его в мою модель данных.

class func retrieveDataFromEntitiesArray (alertDict: JSON) -> (entitesDict: Dictionary<String, String>, servicesArray: [String]) {
    // Need to create an array object, instead of a JSON object, of the entities array to be able to get a count to run the while against.
    var arrayIndex = 0
    var entitiesDict: Dictionary<String, String> = [:]
    var alertEntitiesArray = alertDict.arrayObject
    var servicesArray = [String]()
    while arrayIndex < alertEntitiesArray?.count {
        var dictKey = alertDict[arrayIndex]["type"].string
        switch (dictKey!) {
        case "user":
            entitiesDict[alertDict[arrayIndex]["type"].stringValue] = alertDict[arrayIndex]["label"].stringValue
        case "service":
            servicesArray.append(alertDict[arrayIndex]["label"].stringValue)
        case "policyRule":
            entitiesDict[alertDict[arrayIndex]["type"].stringValue] = alertDict[arrayIndex]["label"].stringValue
        default:
            println("Nothing Here")
        }
        arrayIndex++
    }
    return (entitiesDict, servicesArray)
}
person Brandon Meyer    schedule 28.03.2015