Get data in array after web request in Swift - arrays

I am learning to program in swift. I want to load some data in JSON format (using swiftyJSON and alamoFire) in an array and then use that array in outside the function. When I print the array it is empty and printed before the output of the loop. how can I fill naamArray2 with the content of naamArray
import UIKit
import Alamofire
import SwiftyJSON
class ViewController: UIViewController {
var naamArray = [String]()
var naamArray2 = [String]()
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Alamofire.request(.GET, "http://217.149.68.51:8080/xfind.php?userId=mike", parameters: ["foo": "bar"])
.responseJSON
{ response in
if let value = response.result.value
{
print("JSON: \(value)")
let json = JSON(value)
print(json["producten"][0]["productnaam"].stringValue)
let loopCounter = json["producten"].count
for i in 0...loopCounter
{
let tempstring = json["producten"][i]["productnaam"].stringValue
self.naamArray.append(tempstring)
}
print("\(self.naamArray)")
}
}
print("koekkoek")
print("tweede \(self.naamArray)")
naamArray2 = self.naamArray
}

Call request is run async so when you put it at bottom of viewDidload it can't assign when it have value.
you can create function call assignValue and call after request success:
func assignValue() {
naamArray2 = self.naamArray
}
change to:
override func viewDidLoad()
{
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
Alamofire.request(.GET, "http://217.149.68.51:8080/xfind.php?userId=mike", parameters: ["foo": "bar"])
.responseJSON
{ response in
if let value = response.result.value
{
print("JSON: \(value)")
let json = JSON(value)
print(json["producten"][0]["productnaam"].stringValue)
let loopCounter = json["producten"].count
for i in 0...loopCounter
{
let tempstring = json["producten"][i]["productnaam"].stringValue
self.naamArray.append(tempstring)
}
print("\(self.naamArray)")
assignValue()
}
}
}

Related

Could not get JSONArray in variable Swift

So basically I want to make a TableList from my REST service. The REST service can be decoded by this code block:
func getAllParkeergarages(_ completion: #escaping ([Parkeergarage]) -> ()) {
if let url = URL(string: "http://localhost:8080/parkeergarages") {
URLSession.shared.dataTask(with: url) { data, response, error in
if let data = data {
do {
let res = try JSONDecoder().decode([Parkeergarage].self, from: data)
print(res)
completion(res)
return
} catch let error {
print(error)
}
}
}.resume()
}
}
By using this codeblock I can print the whole JSON in my terminal:
getAllParkeergarages { (array) in
print(array)
}
To get the data in a TableView I need to have the data in a variable. But here is where I get stuck. I tried some different methodes like:
private var data: [Parkeergarage] = getAllParkeergarages { (array) in
return array
}
but is gives me an error: 'Cannot convert value of type '()' to specified type '[Parkeergarage]'. Can someone help me get the result of the function in the variable?
you should do
private var data: [Parkeergarage] = []
in viewDidLoad
override func viewDidLoad() {
super.viewDidLoad()
getAllParkeergarages { (array) in
self.data = array
self.tableView.reloadData()
}
}
I cannot explain any more.

Array value shows all information of the coreData value rather than just the value

I'm hoping someone can help me understand how to get the value from an array rather than all system information about the array as shown via screen shot below.
I would instead prefer just "test" to show to prove that CoreData saved and returned the value.
Here is the code:
import UIKit
import CoreData
let context = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
let newItem = Item(context: context)
var textIn = ""
var textOut = ""
var itemArray = [] as Array
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
}
#IBOutlet weak var dataIn: UITextField!
#IBAction func save(_ sender: Any) {
newItem.title = dataIn.text
saveItems()
}
#IBOutlet weak var textLabel: UILabel!
#IBAction func showButton(_ sender: Any) {
loadItems()
}
func saveItems() {
do {
try context.save()
print("Saved!")
} catch {
print("Error saving context \(error)")
}
}
func loadItems() {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request) as [Any]
for item in itemArray {
print(item.self)
textLabel.text = ("Value: \(item.self)")
}
} catch {
print("Error fetching data from context \(error)")
}
}
}
Thanks!
Rather than the worst type [Any] use the best type [Item]
var itemArray = [Item]()
Then remove the pointless type cast in loadItems to be able to use the title attribute
func loadItems() {
let request : NSFetchRequest<Item> = Item.fetchRequest()
do {
itemArray = try context.fetch(request)
for item in itemArray {
print(item.title)
textLabel.text = ("Value:", item.title)
}
} catch {
print("Error fetching data from context \(error)")
}
}
Consider that after the loop the label will display always the title of the last item in the array.

My firebase data is geting fetched but is not appending into my array? [duplicate]

Currently I am attempting to push values into an array of note objects from firebase
The only issue is due to Firebases asynchronous nature, I am having trouble getting the main thread to wait until the fetch function is completed. I have viewed many answers on this site and I have read up on the Semaphores and Dispatch queue documentation however I cannot get this fetch to work. It appears that most of the people here are attempting to use a table view which I am not.
Here is the fetch code
func fetchUser(){
FIRDatabase.database().reference().child("notes").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = noteClass(dictionary: dictionary)
self.coordinotes.append(user)
}
}, withCancel: nil)
}
I have removed all of my semaphore and dispatch main attempts due to none of them working. This function is called in my view did load. When i check the values of my array that i push them into 'coordinotes' the value is not yet placed in and i get an out of bounds error.
Rest of code
import UIKit
import MapKit
import CoreLocation
import Firebase
import FirebaseDatabase
struct PreferencesKeys{
static let savedItems = "savedItems"
}
class ViewController: UIViewController, CLLocationManagerDelegate{
let manager = CLLocationManager()
var coordinotes:[noteClass] = Array()
var latitude = Double()
var noteTime = noteBrain()
//Map
#IBOutlet weak var map: MKMapView!
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation])
{
let location = locations[0]
let myLocation:CLLocationCoordinate2D = CLLocationCoordinate2DMake(location.coordinate.latitude, location.coordinate.longitude)
let region:MKCoordinateRegion = MKCoordinateRegionMake(myLocation, noteTime.span)
map.setRegion(region, animated: true)
self.map.showsUserLocation = true
}
override func viewDidLoad()
{
super.viewDidLoad()
navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Logout", style: .plain, target: self, action: #selector(handleLogout))
if FIRAuth.auth()?.currentUser?.uid == nil {
perform(#selector(handleLogout), with: nil, afterDelay: 0)
}
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
manager.startUpdatingLocation()
fetchUser()
loadAllCoordinotes()
}
func handleLogout() {
do {
try FIRAuth.auth()?.signOut()
} catch let logoutError {
print(logoutError)
}
let loginController = LoginController()
present(loginController, animated: true, completion: nil)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
func loadAllCoordinotes() {
let length = coordinotes.count - 1
map.addAnnotation(coordinotes[length])
}
func fetchUser(_ completion:#escaping ([noteClass] , _ success: Bool)-> Void){
let coordinotes = [noteClass]()
FIRDatabase.database().reference().child("notes").observe(.childAdded, with: { (snapshot) in
if let dictionary = snapshot.value as? [String: AnyObject] {
let user = noteClass(dictionary: dictionary)
coordinotes.append(user)
}
completion(coordinotes, true)
}, withCancel: nil)
}
and then you call it in viewDidLoad like this:
fetchUser { (coordinotes, success) in
if success {
self.coordinotes = coordinote
self.loadAllCoordinotes()
}
}

Firestore instantiate objects with data recover Swift 5.0

I get all the data from my snapshot and create an object list with the data.
My problem: I can't return a list to use my objects in other code functions.
I tried to browse my list to create using my snapshot to implement a new list of objects declared above in my code.
class ViewController: UIViewController {
lazy var usersCollection = Firestore.firestore().collection("ship")
var ships: [MyShip] = []
override func viewDidLoad() {
super.viewDidLoad()
getUsers()
print(ships.count)
}
The getData function:
func getUsers() {
usersCollection.getDocuments { (snapshot, _) in
//let documents = snapshot!.documents
// try! documents.forEach { document in
//let myUser: MyUser = try document.decoded()
//print(myUser)
//}
let myShip: [MyShip] = try! snapshot!.decoded()
// myShip.forEach({print($0)})
for elt in myShip {
print(elt)
self.ships.append(elt)
}
print(self.ships[1].nlloyds)
}
}
result console
Result in the console:
- my list is not filled return 0
- I print the objects well and I print them well
- I print the ships object[1].nloyds = 555 well in the function
Your print(ships.count) call in viewDidLoad is printing an empty array because the .getDocuments() method is asynchronous. Try writing getUsers as a closure like this:
func getUsers(completion: #escaping ([MyShip]) -> Void) {
usersCollection.getDocuments { (snapshot, _) in
let myShip: [MyShip] = try! snapshot!.decoded()
completion(myShip)
}
}
and then use it in the viewDidLoad method like this:
override func viewDidLoad() {
super.viewDidLoad()
getUsers() { shipsFound in
self.ships = shipsFound
print(self.ships.count)
}
}

Json data - white console - Xcode 9

I am trying a simple app in which I want to convert some values. It worked until I tried to convert the data in a dictionary, and when I hit run, it builds successfully, but the console does not print anything. Here is the code:
import UIKit
class ViewController: UIViewController {
override func viewDidLoad() {
super.viewDidLoad()
let url = URL(string: "http://gnb.dev.airtouchmedia.com/rates.json")
let task = URLSession.shared.dataTask(with: url!) { (data, response, error) in
if error != nil
{
print("ERROR")
}
else {
if let content = data {
do {
//Array
let myJson = try JSONSerialization.jsonObject(with:content, options: JSONSerialization.ReadingOptions.mutableContainers) as AnyObject
//print(myJson)
if let rate = myJson["rate"] as? NSDictionary {
if let currency = rate["AUD"] {
print(currency)
}
}
}
catch {
}
}
}
}
task.resume()
}
because you are parsing JSON wrongly
try this
let myJson = try JSONSerialization.jsonObject(with:content, options: JSONSerialization.ReadingOptions.mutableContainers) as? [[String: AnyObject]] else { return }
for rate in myJson
guard let cur = user["from"] as? String,
let curRate = user["rate"] as? Double else { break }
if let cur = "AUD" {
print(curRate)
}
Update:
You are receiving Array of Objects in response,
so first you have to treat it as Array of object,
Then you have to loop through this objects and then inside that loop you have to extract the data you were looking for and play with it.

Resources