Я пытаюсь добавить цикл alamofire и положить на sqlite db, но это дает мне ошибку - PullRequest
0 голосов
/ 28 февраля 2019

Фатальная ошибка вне допустимого диапазона. Это файл журнала.

Запрос URL-адреса Alamofire находится в цикле, точка разрыва которого у системы уже составляет 44, а не первый индекс после получения первого значения массива.

Я попытался распечатать массив за пределами цикла, но он просто дал мне нулевой массив печати в журнале просто []

let url = "http://localhost:8080/iostest/selectstudents.php"
    let parameters: Parameters=[
        "StatusCodeID":"2",
        "subjectCode":"ENG 099",
        "section":"BSIT 2-2BSIT-01"
    ]
    Alamofire.request(url, method: .post, parameters: parameters).responseJSON{
        response in
        let json = response.data

        if let result = response.result.value {

            //converting it as NSDictionary
            let jsonData = result as! NSDictionary
            //displaying the message in label
            let x = jsonData.value(forKey: "Students") as! NSArray

            for dict in x {
                let dictone = dict as! NSDictionary

                ArrayStudentNumber.append(dictone["StudentNumber"]  as! String)
                ArraySection.append(dictone["Section"] as! String)
                ArraySemester.append(dictone["Semester"] as! String)
                ArraySubjectCode.append(dictone["SubjectCode"] as! String)
                ArraySchoolYear.append(dictone["SchoolYear"] as! String)
            }


        }

        let arraycount = ArrayStudentNumber.count
        var counter = 0
        while counter < arraycount{
        print(counter)
        var currentindex = counter
        print (ArrayStudentNumber[counter])
        let url2 = "http://localhost:8080/iostest/selectstudentsinfo.php"
        var parameters2: Parameters=["studentNumber" : ArrayStudentNumber[currentindex]]

        Alamofire.request(url2, method: .post, parameters: parameters2).responseJSON{
            response in
            let json = response.data
            if let result = response.result.value {
                print (response)
                //converting it as NSDictionary
                let jsonData = result as! NSDictionary
                //displaying the message in label
                let x = jsonData.value(forKey: "StudentsInfo") as! NSArray
                for dict in x {
                    let dictone = dict as! NSDictionary

                    ArrayFirstname.append(dictone["Firstname"]  as! String)
                    ArrayLastname.append(dictone["Lastname"]  as! String)
                    ArrayMiddlename.append(dictone["Middlename"]  as! String)
                    ArrayCollege.append(dictone["College"]  as! String)
                    ArrayCourse.append(dictone["Course"]  as! String)




                }

            }
        }

            counter += 1
    }

        var loopcounter = 0
        let thisarraycount = ArrayFirstname.count
        while loopcounter < thisarraycount{
            var insertstatemanet: OpaquePointer? = nil
            var insertsql = "insert into tableStudentInfo(StudentNumber,Firstname,Lastname,Middlename,College,Course,SubjectCode,Section,Semester,Schoolyear) values ('\(ArrayStudentNumber[loopcounter])','\(ArrayFirstname[loopcounter])','\(ArrayLastname[loopcounter])','\(ArrayMiddlename[loopcounter])','\(ArrayCollege[loopcounter])','\(ArrayCourse[loopcounter])','\(ArraySubjectCode[loopcounter])','\(ArraySection[loopcounter])','\(ArraySemester[loopcounter])','\(ArraySchoolYear[loopcounter])';"


            //isolate sql query and validate statements
            sqlite3_prepare_v2(db, insertsql, -1, &insertstatemanet, nil)
            //
            if sqlite3_step(insertstatemanet) == SQLITE_DONE{
                print("Inserted", "\(ArrayStudentNumber[counter])")
            }
            sqlite3_finalize(insertstatemanet)
        }
        loopcounter = loopcounter + 1


    }



}

1 Ответ

0 голосов
/ 03 марта 2019

Что я имел в виду с плохим отступом, так это то, что вам нетрудно прочитать разные области, вкладки сделаны странным образом.

Что не так с вашим кодом:

Здесьосновная логика, которую вы делаете:

//0
Alamofire.request(url, method: .post, parameters: parameters).responseJSON { response in
    if let result = response.result.value { //1
        //Populate arrays
    }

    whileLoop { //2
        Alamofire.request(url2, method: .post, parameters: parameters2).responseJSON { 
            if let result = response.result.value { //2.n
                //Populate arrays
            }
        }
    }
    whileLoop { //3
        //Populate SQL according to populated arrays
    }
}
//4

Первая большая проблема заключается в том, что вы упускаете тот факт, что ваш запрос Alamofire является асинхронным.Это означает, что если вы добавите print, где я поставлю // число, печать в консоли может быть не той, которую вы ожидаете.В настоящее время это должно быть: «0, 4, 1, 2, 3, 2.3, 2.5, 2.2, 2.1, 2.4 и т. Д.», А не «0, 1, 2, 2.1, 2.2 ..., 3, 4»,Это даже хуже, потому что 2.n может даже не быть в порядке.Ясно, что когда вы выполняете 3-е действие (цикл while для SQL), у вас нет ваших значений.

Концепция Asynchrone - это импорт, который вам необходимо понять и освоить, потому что он действительно базовыйи общие.

См .: Возврат данных из асинхронного вызова в функции Swift
Использование значения из запроса Alamofire вне функции и т. д.

Полагаю, именно поэтому вы помещаете цикл while для второго пакета (// 2) запроса в первый.

Вам нужно использовать DispatchGroup, с enter(), leave(), notify():

Swift / Как использовать dispatch_group с несколькими вызываемыми веб-службами?
Как использовать DispatchGroup / GCD для последовательного выполнения функций в swift?
Ожидание завершения задачи
Асинхронный порядок выполнения закрытия Swift
Дождаться окончания выполнения цикла swift for с асинхронными сетевыми запросами
и т. Д.

WiПо ключевым словам и ссылкам, которые нужно искать, вы должны иметь работающее решение.

Теперь, в Swift 3+, избегайте использования NSStuff, например, NSDictionary, NSArray, предпочитает версию Swift, когда она доступна.

Пример:

let jsonData = result as! NSDictionary

=>

let jsonData = result as! [String: Any]

Избегайте использования value(forKey:), его результаты могут вас удивить когда-нибудь.Для этого нужно понять KVC.Каждая вещь в свое время, но, как вы, кажется, начали, избегайте ее использования.Предпочитает object(forKey:) или прямой индекс: myDict["myKey"]

Избегайте принудительного приведения (используя !).Зачем?Это говорит компилятору: не волнуйтесь, я знаю, что делаю (что часто не так, давайте проясним).И если я ошибаюсь, просто сбой.Так что это довольно азартная игра, чтобы вывести из строя ваше приложение, потому что в одном случае вы не могли разыграть его или сделали неправильное приведение, нет?Предпочитают if let, guard let и т. Д.

Наконец:

ArrayStudentNumber.append(dictone["StudentNumber"])
ArraySection.append(dictone["Section"])
ArraySemester.append(dictone["Semester"])
ArraySubjectCode.append(dictone["SubjectCode"])
ArraySchoolYear.append(dictone["SchoolYear"])

Нет.Просто не надо.Не используйте несколько массивов для этого.Просто используйте один.Зачем?Что произойдет, если вы захотите удалить первый, вы удалите первый в каждом из этих массивов?Что если вы захотите изменить его порядок (потому что теперь вам удобнее сортировать учащихся по номеру идентификатора / номера студента, а не по имени)?Вы тоже отсортируете 4 других массива?Эта информация имеет все значение только вместе.

Используйте массив словаря, массив пользовательских объектов для хранения их значений и т. Д.

Кроме того, поскольку вы узнаете об асинхронной вещи,вы увидите, что в другом цикле for (поскольку вы делаете то же самое) ArrayFirstname.first может не быть для ArrayStudentNumber.first (помните порядок 2.1, 2.2, о котором я вам говорил?)

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