I am new to swift but learning as I go. I have a function to get data from AWS DynamoDB table, using a for..loop. I am capturing field values of table items in struct variables within the loop, but when I call the struct variables in a tableview, it is showing blank array like [] in the log screen in Xcode. Here is the code:
import Foundation
import SQLite3
import UIKit
import AWSDynamoDB
struct MyVariables {
static var empDict: [String: String] = [:]
static var arrayEmployees = Array<Dictionary<String, String>>()
}
// This is a class defined to hold various methods to be used throughout the app.
class DatabaseClass: UIViewController, UITextFieldDelegate
{
// other methods within DatabaseClass
// ........
//
//
// Scan DynamoDB table for employees
func scanEmployees () {
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
let scanExpression = AWSDynamoDBScanExpression()
scanExpression.limit = 20
dynamoDBObjectMapper.scan(Employees.self, expression: scanExpression).continueWith(block: { (task:AWSTask<AWSDynamoDBPaginatedOutput>!) -> Any? in
if let error = task.error as NSError? {
print("The request failed. Error: \(error)")
}
let paginatedOutput = task.result!
for emp in paginatedOutput.items as! [Employees] {
if emp._empid != nil {
MyVariables.empDict["Empid"] = emp._empid
} else {
MyVariables.empDict["Empid"] = nil
}
if emp._email != nil {
MyVariables.empDict["email"] = emp._email
} else {
MyVariables.empDict["email"] = nil
}
if emp._firstname != nil {
MyVariables.empDict["firstname"] = emp._firstname
} else {
MyVariables.empDict["firstname"] = nil
}
if emp._lastname != nil {
MyVariables.empDict["lastname"] = emp._lastname
} else {
MyVariables.empDict["lastname"] = nil
}
if emp._location != nil {
MyVariables.empDict["location"] = emp._location
} else {
MyVariables.empDict["location"] = nil
}
if emp._mobile != nil {
MyVariables.empDict["mobile"] = emp._mobile
} else {
MyVariables.empDict["mobile"] = nil
}
if emp._work != nil {
MyVariables.empDict["work"] = emp._work
} else {
MyVariables.empDict["work"] = nil
}
if emp._site != nil {
MyVariables.empDict["site"] = emp._site
} else {
MyVariables.empDict["site"] = nil
}
MyVariables.arrayEmployees.append(MyVariables.empDict)
//print(MyVariables.arrayEmployees)
} // for loop
print ("printing array employees just after for loop")
print(MyVariables.arrayEmployees)
// The above print works
return nil
})
// print(MyVariables.arrayEmployees)
// Above doesn’t print
}
}
Later, I call this DatabaseClass in a tableview as follows:
class JsonParseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let createEmp = DatabaseClass()
createEmp.scanEmployees()
print("in JsonParseViewController, calling scan function")
print(MyVariables.arrayEmployees)
When running in simulator, the log file shows the following:
in JsonParseViewController, calling scan function
[]
printing array employees just after for loop
[["location": "XXXXXX", "email": "johnSmith1@email.com", "firstname": "John1", "lastname": "Smith1", "mobile": "123-456-7890", "work": "123-456-7890", "Empid": "12345", "site": "KKKKKK"], ["location": "YYYYY", "email": "johnSmith8@email.com", "firstname": "John8", "lastname": "Smith8", "mobile": "123-456-7890", "work": "123-456-7890", "Empid": "12415", "site": "ZZZZZ"], ......etc]]
While executing the function scanEmployees, it seems to skip the DynamoDB scan command and returns [] in tableview, but goes to the function somehow and executes the data. It fails to capture the data in struct variables. I have bee trying to fix this for many days.
You miss asynchronous call
func scanEmployees (completion:@escaping ()-> Void) {
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
let scanExpression = AWSDynamoDBScanExpression()
scanExpression.limit = 20
dynamoDBObjectMapper.scan(Employees.self, expression: scanExpression).continueWith(block: { (task:AWSTask<AWSDynamoDBPaginatedOutput>!) -> Any? in
if let error = task.error as NSError? {
print("The request failed. Error: \(error)")
}
let paginatedOutput = task.result!
for emp in paginatedOutput.items as! [Employees] {
myVariables.empDict["Empid"] = emp._empid
myVariables.empDict["email"] = emp._email
myVariables.empDict["firstname"] = emp._firstname
myVariables.empDict["lastname"] = emp._lastname
myVariables.empDict["location"] = emp._location
myVariables.empDict["mobile"] = emp._mobile
myVariables.empDict["work"] = emp._work
myVariables.empDict["site"] = emp._site
MyVariables.arrayEmployees.append(MyVariables.empDict)
//print(MyVariables.arrayEmployees)
} // for loop
print ("printing array employees just after for loop")
print(MyVariables.arrayEmployees)
// The above print works
completion()
return nil
}
)
// print(MyVariables.arrayEmployees)
// Above doesn’t print
}
//
when calling
createEmp.scanEmployees {
print(MyVariables.arrayEmployees)
}
Note : I recommend using SwiftyJson or JSONDecoder intstead of manually parsing the keys
You have a problem with static memory. I would suggest not to use static values, its a very bad practice. The solution could be to create a structure inside The class DatabaseClass. For example var myVariables = MyVariables() and fill it in the same way. Now You have the option for return it or use it from the DatabaseClass object. I will show the example now how it should look.
struct MyVariables {
var empDict: [String: String] = [:]
var arrayEmployees = Array<Dictionary<String, String>>()
}
// This is a class defined to hold various methods to be used throughout the app.
class DatabaseClass: UIViewController, UITextFieldDelegate
{
// other methods within DatabaseClass
// ........
//
//
// Scan DynamoDB table for employees
public var myVariables = MyVariables()
func scanEmployees () {
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
let scanExpression = AWSDynamoDBScanExpression()
scanExpression.limit = 20
dynamoDBObjectMapper.scan(Employees.self, expression: scanExpression).continueWith(block: { (task:AWSTask<AWSDynamoDBPaginatedOutput>!) -> Any? in
if let error = task.error as NSError? {
print("The request failed. Error: \(error)")
}
let paginatedOutput = task.result!
for emp in paginatedOutput.items as! [Employees] {
myVariables.empDict["Empid"] = emp._empid
myVariables.empDict["email"] = emp._email
myVariables.empDict["firstname"] = emp._firstname
myVariables.empDict["lastname"] = emp._lastname
myVariables.empDict["location"] = emp._location
myVariables.empDict["mobile"] = emp._mobile
myVariables.empDict["work"] = emp._work
myVariables.empDict["site"] = emp._site
myVariables.arrayEmployees.append(myVariables.empDict)
//print(myVariables.arrayEmployees)
} // for loop
print ("printing array employees just after for loop")
print(myVariables.arrayEmployees)
// The above print works
return nil
})
// print(myVariables.arrayEmployees)
// Above doesn’t print
}
}
//then use it in this way
class JsonParseViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let createEmp = DatabaseClass()
createEmp.scanEmployees()
print("in JsonParseViewController, calling scan function")
print(createEmp.myVariables.arrayEmployees)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.