我正在尝试附加alamofire循环并放入sqlite db,但这给了我错误

时间:2019-02-28 07:44:40

标签: arrays json swift

致命错误超出范围,这是日志文件

Alamofire URL请求在一个循环中,在系统获取到数组的第一个值之后,系统的计数器已经是第一个索引而不是第一个索引了。

我尝试在循环外打印数组,但这只是给我一个空数组,在日志上打印的只是[]

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 :(得分:0)

缩进缩进是我的意思,这是因为您不难理解不同的范围,选项卡很奇怪。

您的代码有什么问题

这是您正在做的主要逻辑:

//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请求异步的事实。这意味着,我将打印添加到// number所在的位置,控制台中的打印可能不是您期望的。 当前,应为:“ 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甚至可能没有顺序。 很明显,当您执行第三项操作(SQL的while循环)时,您没有值。

“异步”概念是您需要理解和掌握的一种导入概念,因为它确实是基础和通用的。

请参阅: Returning data from async call in Swift function
Using a value from Alamofire request outside the function

我想这就是为什么您将第二个(// 2)请求的while循环放在第一个请求中的原因。

您需要做的是使用DispatchGroupenter()leave()notify()

Swift / How to use dispatch_group with multiple called web service?
How do I use DispatchGroup / GCD to execute functions sequentially in swift?
Waiting until the task finishes
Swift closure async order of execution
Wait until swift for loop with asynchronous network requests finishes executing

有了关键词和链接,您应该能够找到可行的解决方案。

现在,在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 letguard let

最后:

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

不。只是不要。请勿为此使用多个数组。只需使用一个。为什么?如果要删除第一个数组,将删除每个数组中的第一个数组,会发生什么?如果您想重新排序(因为现在发现按ID /学生编号而不是他们的姓名对学生进行排序会更好),该怎么办?您还要对其他4个数组进行排序吗?这些信息仅具有共同的意义。

使用字典数组,自定义对象数组来保存其值,等等。

此外,由于您将了解异步问题,因此您会在其他for循环中看到(因为您执行相同操作)ArrayFirstname.first可能不适用于ArrayStudentNumber.first(请记住我的2.1、2.2顺序)告诉你了吗?)