I'm trying to add data to array inside for loop and again to array in another for loop.
Its working on first for loo, but in second data is empty. How to fix that
This is how it currently looks inside firestore and you can see scores missing.
this is code:
func updateCourseData() {
var data = ["endTime": Timestamp(date: Date()),
"players": []] as [String : Any]
for i in 0..<players.count {
var playerData = ["playerId": games[i].id,
"scores": []] as [String : Any]
var existingItems = data["players"] as? [[String: Any]] ?? [[String: Any]]()
existingItems.append(playerData)
data["players"] = existingItems
for score in 0..<selectedPage + 1 {
let scoreData = ["hole": games[i].scores[score].hole,
"score": games[i].scores[score].score] as [String : Any]
var existingScores = playerData["scores"] as? [[String: Any]] ?? [[String: Any]]()
existingScores.append(scoreData)
playerData["scores"] = existingScores
}
}
Constants.FirebaseCollection.gamesCollection.document(documentId).updateData(data) { error in
if let error = error {
print(error.localizedDescription)
}
print("Game updated")
}
}
My code below is trying to take core data from a NSManagedObject append it to an array. The core data element is saved as a string. My code is not compelling. Ideally the code should be able to append code into the array then the array is filled, find the sum of the numbers added together and print them into the viewDidLoad() func.
var itemName : [NSManagedObject] = []
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? Double {
retrievedData.append(value)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}
I reviewed your code when you will need to change small thing over there. Replace performAction function as per my updated answer.
func performAction() {
let appD = UIApplication.shared.delegate as! AppDelegate
let context = appD.persistentContainer.viewContext
let request = NSFetchRequest<NSFetchRequestResult>(entityName: "Data")
request.returnsObjectsAsFaults = false
do {
let result = try context.fetch(request)
var retrievedData = [Double]()
for data in result as! [NSManagedObject] {
if let value = data.value(forKey: "ee") as? String {
retrievedData.append(Double(value) ?? 0)
}
}
let arraySum = retrievedData.reduce(0, +)
print(arraySum)
} catch {
print("Failed")
}
}
Someone can explain me that piece of code because I can't understand well. I find this code and I can't understand notably this line : Room(dict: $0)
var rooms: [Room] = [] // The globale variable
func refresh() {
let request = URLRequest(url: URL(string: "\(Config.serverUrl)/rooms")!)
NSURLConnection.sendAsynchronousRequest(request, queue: OperationQueue.main, completionHandler: { resp, data, err in
guard err == nil else {
return
}
let rooms = try! JSONSerialization.jsonObject(with: data!, options: JSONSerialization.ReadingOptions()) as! [[String: AnyObject]]
self.rooms = rooms.map {
Room(dict: $0) // I can't understand this line
}
self.tableView.reloadData()
})
}
My Room struct:
struct Room {
var key: String
var title: String
var cat: String!
init(dict: [String: AnyObject]) {
title = dict["title"] as! String
key = dict["key"] as! String
cat = dict["cat"] as! String
}
init(key: String, title: String, cat: String) {
self.key = key
self.title = title
self.cat = cat
}
func toDict() -> [String: AnyObject] {
return [
"title": title as AnyObject,
"key": key as AnyObject,
"cat": cat as AnyObject
]
}
}
If someone can help me to understand and explain it, thank you
The map function loops over every item in a collection, and applies an operation to each element in the collection.
This piece of code
self.rooms = rooms.map {
Room(dict: $0)
}
is a short form of this.
// `dict` paramater is `$0` in shorter form
self.rooms = rooms.map { (dict : [String: AnyObject]) -> Room in
return Room(dict: dict)
}
Ok, so I have an app that is designed for roleplaying. I have a guide that guides the user to creating the character. So the first thing the user has to do is put the character number. So I want it to search all the records for the attribute I have called characternumber and see what the largest number is.
Example: Lets say I have 5 characters. with character numbers 1,2,3,4,5. I want to cycle through all the records and see that 5 is the biggest number than automatically place a 6 in the character number text field.
This is what I have so far:
#IBOutlet var societyNumberTxt: UITextField!
#IBOutlet var characterNumberTxt: UITextField!
let managedObjectContext = (UIApplication.shared.delegate as! AppDelegate).persistentContainer.viewContext
var characters: [NSManagedObject] = []
var societyNum: [NSManagedObject] = []
var charNum: [String] = []
override func viewDidLoad()
{
super.viewDidLoad()
//1
guard let appDelegate = UIApplication.shared.delegate as? AppDelegate else {
return
}
let managedContext = appDelegate.persistentContainer.viewContext
//2
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
//3
do {
societyNum = try managedContext.fetch(fetchRequest)
let entityDescription = NSEntityDescription.entity(forEntityName: "Characters", in: managedObjectContext)
let request: NSFetchRequest<Characters> = Characters.fetchRequest()
request.entity = entityDescription
var results = try managedObjectContext.fetch(request as! NSFetchRequest<NSFetchRequestResult>)
if societyNum.count > 0
{
let match = results[0] as! NSManagedObject
societyNumberTxt.text = (match.value(forKey: "societynumber") as? String)!
print(match)
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
else
{
print("empty array")
characterNumberTxt.text = "1"
}
}
else
{
societyNumberTxt.placeholder = "Society # not set"
}
} catch let error as NSError {
print("Could not fetch. \(error), \(error.userInfo)")
}
}
I am not sure how to cycle through every record and check the attribute and place in the array. I have tried something like this:
var i = 0
for i in results
{
var match = results[i] as? NSManagedObject
charNum[i] = match
}
I get the error:
cannot subscript a value of type '[Any]' with an index of type 'Any'
Now to test my code for the if statement:
if (match.value(forKey: "characternumber") != nil)
{
self.charNum = match.value(forKey: "characternumber") as! [String]
print(self.charNum)
}
It returned and error:
Could not cast value of type 'NSTaggedPointerString' (0x108578d10) to 'NSArray' (0x108578dd8).
Am I even on the right past?
Adjust your fetch request with a SortDescriptor instead of finding the highest characterNumber manually:
...
//2
// get all characters ...
let fetchRequest = NSFetchRequest<NSManagedObject>(entityName: "Characters")
// ... sorted by characternumber in acending order
let sortDescriptor = NSSortDescriptor(key: "characternumber", ascending: true)
let sortDescriptors = [sortDescriptor]
fetchRequest.sortDescriptors = sortDescriptors
//3
do {
let characters = try managedContext.fetch(fetchRequest) as! [Characters]
if let highestCharacterNumber = characters.last?.characternumber {
characterNumberTxt.text = String(highestCharacterNumber + 1) // assuming characternumber is of type Int
} else {
characterNumberTxt.text = "1"
}
} ...
I have problem with JSON Array that I want to be display on textfield. JSON is taken from URL. This is JSON structure:
{
description = „This is short decripton”;
);
more-description = (
„this is first line”,
„this is second line”,
„third line”,
„etc”,
„etc”
);
one-more-description = (
„this is first line”,
„this is second line”,
„third line”,
„etc”,
„etc”
);
And this is my code:
import UIKit
class RecipeViewController: UIViewController {
#IBOutlet weak var descriptionTextField: UITextView!
#IBOutlet weak var more-descriptionTextField: UITextView!
#IBOutlet weak var one-more-descriptionTextField: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
let urlAsString = "http://JSON-Address.com"
let url = NSURL(string: urlAsString)!
let urlSession = NSURLSession.sharedSession()
let jsonQuery = urlSession.dataTaskWithURL(url, completionHandler: { data, response, error -> Void in
do {
if let jsonDate = data, let jsonResult = try NSJSONSerialization.JSONObjectWithData(jsonDate, options: []) as? NSDictionary {
print(jsonResult)
let jsonDescription = jsonResult["description"] as? String
print("result: \(jsonDescription)")
let jsonMoreDescrp: AnyObject? = jsonResult["more-description"] as? Array<AnyObject>
print("result: \(jsonMoreDescrp)")
let jsonOneMoreDescrp: AnyObject? = jsonResult["one-more-description"] as? Array<AnyObject>
print("result: \(jsonOneMoreDescrp)")
dispatch_async(dispatch_get_main_queue(),{
self.descriptionTextField.text = jsonDescription
self.more-descriptionTextField.text = jsonMoreDescrp as? String
self.one-more-descriptionTextField.text = jsonOneMoreDescrp as? String
});
}
} catch let error as NSError {
print(error)
}
})
jsonQuery.resume()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
The problem is with jsonMoreDescrp & jsonOneMoreDescrp. Althought I've changed it to String, after running Xcode the result is empty. jsonDescription of course works, but this is just simple string.
I know I'm doing something wrong with Array, but - can you tell me what?
jsonMoreDescrp & jsonOneMoreDescrp are array. so, you can call like this
self.more-descriptionTextField.text = jsonMoreDescrp[indexValue] as? String
self.one-more-descriptionTextField.text = jsonOneMoreDescrp[indexValue] as? String
Hope this will help you.
Try this way, if it not works comment me the error you come across.
self.more-descriptionTextField.text = jsonMoreDescrp[indexValue].stringValue
self.one-more-descriptionTextField.text = jsonOneMoreDescrp[indexValue].stringValue
indexValue is the key of the value you want in the json.
[Updated] As Sudhir noticed there is also error in code, try this to show comma separated strings:
dispatch_async(dispatch_get_main_queue(),{
self.descriptionTextField.text = jsonDescription
self.more-descriptionTextField.text = (jsonMoreDescrp as? [String])?.joinWithSeparator(",") ?? ""
self.one-more-descriptionTextField.text = (jsonOneMoreDescrp as? [String])?.joinWithSeparator(",") ?? ""
});
Validate JSON structure online before using http://jsonlint.com/
Valid JSON:
{
"description": "This is short decription",
"more-description": [
"this is first line",
"this is second line",
"third line",
"etc",
"etc"
],
"one-more-description": [
"this is first line",
"this is second line",
"third line",
"etc",
"etc"
]
}
try this code, it is much easy to use.
First of all parse all elements of map to the variables and than do what you want with knowing structure of just created variables.
let task = session.dataTask(with: url!) {
(data, response, error) in
do {
let json = try JSONSerialization.jsonObject(with: data!, options: .mutableContainers) as! [String : AnyObject]
if let desc = json["description"] as? String,
let moreDesc = json["more-description"] as? [String],
let oneMoreDesc = json["one-more-description"] as? [String] {
dispatch_async(dispatch_get_main_queue(),{
self.descriptionTextField.text = moreDesc
self.more-descriptionTextField.text = moreDesc.joinWithSeparator("/n")
self.one-more-descriptionTextField.text = oneMoreDesc.joinWithSeparator("/n")
});
}
} catch let error {
print (error)
}
}
task.resume()
I have not tested it, but it should work. Feel free to ask.