致命错误超出范围,这是日志文件
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
}
}
答案 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循环放在第一个请求中的原因。
您需要做的是使用DispatchGroup
,enter()
,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 let
,guard 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顺序)告诉你了吗?)