I am currently trying to update the code for a Udemy course I purchased a couple of months ago, which was fully working in the Swift 2.2 version. However, I am having issues with this particular function, which really just sorts and displays recent chats (with preview).
Here is the code:
func loadRecents() {
firebase.child("Recent").queryOrderedByChild("userId").queryEqualToValue(backendless.userService.currentUser.objectId).observeEventType(.Value, withBlock: {
snapshot in
self.recents.removeAll()
if snapshot.exists() {
let sorted = (snapshot.value!.allValues as NSArray).sortedArrayUsingDescriptors([NSSortDescriptor(key: "date", ascending: false)])
for recent in sorted {
self.recents.append(recent as! NSDictionary)
firebase.child("Recent").queryOrderedByChild("chatRoomID").queryEqualToValue(recent["chatRoomID"]).observeEventType(.Value, withBlock: {
snapshot in
})
}
}
self.tableView.reloadData()
})
}
I get the error here:
let sorted = (snapshot.value!.allValues as NSArray).sortedArrayUsingDescriptors([NSSortDescriptor(key: "date", ascending: false)])
I beleive the sortedArrayUsingDescriptors is deprecated, but I am still not sure. What could be a replacement of this current code?
Thanks in advance!
Update:
This is the error I am getting:
THread 1: EXC_BAD_INSTRUCTION(code=EXC_I386_INVOP, subcode=0x0)
The specific answer to the question: what is a replacement (in Swift 3):
let sorted = ((snapshot!.value! as AnyObject).allValues as NSArray)
.sortedArray(using: [NSSortDescriptor(key: "date", ascending: false)])
Also, the code posted basically works - although the code inside the for recent in sorted section is malformed for Swift 3.
recent["chatRoomID"] in that section may be an issue as the data within sorted may not be strings - they may be dictionaries. It depends on your Firebase structure.
Lastly, it's probably a good idea to reduce you're dependency on NSSortDescriptors etc and do it in a more Swifty way.
See my answer to your prior question
Swift 3 Firebase update code convertion - sorting
Related
Swift 3.x iOS 10.
Trying to understand Databases in firebase. Imported some JSON data into my app and managed to read it back. This the code.
let rootRef = Database.database().reference(withPath: "0")
print("\(rootRef.key)")
let nextRef = rootRef.child("identity")
print("\(nextRef)")
nextRef.observe(.value, with: { snapshot in
print("\(snapshot.value)")
})
Which works, my data looks like this ...
But how to do this if I want to traverse the database, looking at record 2, record 3 etc etc where I am not sure how many records I actually got.
Ok, I found it, well something that works...
let rootRef = Database.database().reference()
rootRef.observe(.value, with: { snapshot in
print("dump \(snapshot.children.allObjects)")
})
I post for posterity :)
I am having random downtimes of connection to firebase using the observeSingleEvent and observe methods in Swift for iOS.
I use multiple ways of connecting to my Firebase database using their REST API.
I use sometimes the method of going through the full URL, like for example,
https://example.firebaseio.com/problems.json.
This always returns data correctly.
When I for example use, observeSingleEvent, that sometimes no code in this gets ran, at all! And that is consistent across view controllers.
The database is still up as using the URL method 100% works, but sometimes using observeSingleEvent it does work, perfectly! But without changing any code, sometimes these events just stop working. I try rebuilding, logging in and out, combination of both, and ive even come to the conclusion that if I leave it for a while, it works again.
Does anyone have any logical reason why the sporadic downtimes occur, and what I can do to fix it? As the code works and i dont change it, but then it stops, for a while across the whole app.
Thanks for your help. Below is an example of code that sometimes runs, and sometimes doesnt.
func getComments() -> Int{
print("getting comments")
let ref = FIRDatabase.database().reference(withPath: "comments")
let query = ref.queryOrdered(byChild: "problem_id").queryEqual(toValue: self.id)
print("Starting observing");
query.observeSingleEvent(of: .value, with: { (snapshot) in
print("Got snapshot");
print(snapshot.childrenCount)
self.commentCount = Int(snapshot.childrenCount)
})
print("returning the comment count");
return commentCount
}
I am fairly new to Firebase, but from my limited experience of observing references, I've learned that observing things takes time to complete, so it is not guaranteed that the code in the closure is executed before what comes next in code. What I would suggest trying (and I'm not positive that it will work) is to modify your code so that it takes a completion handler, guaranteeing that the code in the observing block is completed before getting your result.
So your new code would be
func getComments(completion: #escaping (Int) -> Void) {
print("getting comments")
let ref = FIRDatabase.database().reference(withPath: "comments")
let query = ref.queryOrdered(byChild: "problem_id").queryEqual(toValue: self.id)
print("Starting observing");
query.observeSingleEvent(of: .value, with: { (snapshot) in
print("Got snapshot");
print(snapshot.childrenCount)
print("returning the comment count")
let commentCount = Int(snapshot.childrenCount)
self.commentCount = commentCount
completion(commentCount)
})
}
Then, when you want to use the code, you call it like
getComments(completion: { commentCount in
print(commentCount)
//Do other stuff with comment count
})
It's kinda ugly, but that's the solution that I came up with when I first had similar problems.
I am designing a litte quiz app but I'm having trouble while retrieving the game data.
As you can see in the picture I have an JSON object that contains many single games. Each single game has a unique id. My first problem is that each of the games can be available in multiple languages. I know that I could download the hole snap and then looping throw each game but that would mean really long loading times while the app is growing.
In short form:
I need to retrieve the following data from the JSON above:
A random game wich is available in a specific language (need to have the key en for example)
All games that are available in "en" but not yet in "de"
If it is easier to restructure the data in the JSON, please tell me.
Thanks for helping me.
Answer to your first part :-
let enRef = FIRDatabase.database().reference().child("singleGames").child(singleGamesUID).child("en")
enRef.observeEventType(.Value, withBlock: {(snap) in
if let enQuizQuestion = snap.value as? [String:AnyObject]{
//Question exists : Retrieve Data
}else{
//Question in english doesn't exist
}
})
For your second part
Since you are trying to save iteration time might i suggest you also save your singleGames id in a separate languagesBased nodes, there is a command in firebase that allows you to search for some keyValues in your child node's , but even that i think would be executing a search algorithm which might be a little more time consuming :--
appServerName:{
singleGames :{
uid1:{......
......
...},
uid2:{......
......
...},
uid3:{......
......
...}
},
enQuestions:{
uid3 : true
}
deQuestions:{
uid1 : true,
uid2 : true
}
}
Now all you gotta do :-
let rootRef = FIRDatabase.database().reference().child("deQuestions").observeEventType(.Value, withBlock: {(qSnap) in
if let qDict = qSnap.value as? [String:AnyObject]{
for each in qDict as [String:AnyObject]{
let deUID = each.0
}
}else{
//No question in dutch language
}
})
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 6 years ago.
Improve this question
I get the this string "85:ABC ,83:CFD" after downloading from a web service.I need to store these values to CoreData table TABLE_JOBTITLE. I have the below code
var designationDictionaryArray = results.componentsSeparatedByString(",")
var index: Int = 1
for item in designationDictionaryArray
{
let appDelegate =
UIApplication.sharedApplication().delegate as! AppDelegate
let managedContext = appDelegate.managedObjectContext
let entity = NSEntityDescription.entityForName("TABLE_JOBTITLE",
inManagedObjectContext:managedContext)
let job = NSManagedObject(entity: entity!,
insertIntoManagedObjectContext: managedContext)
job.setValue(String(index), forKey: "column_Id")
job.setValue(String(item.componentsSeparatedByString(":")[0]), forKey: "column_Server_Id")
job.setValue(String(item.componentsSeparatedByString(":")[1]), forKey: "column_Job_Name")
print("Column_Id")
print(index)
print("Column_Server_Id")
print(String(item.componentsSeparatedByString(":")[0]))
print("column_Job_Name")
print(String(item.componentsSeparatedByString(":")[1]))
do {
try managedContext.save()
print("saved job title")
} catch let error as NSError {
print("Could not save \(error), \(error.userInfo)")
}
self.desiginationArray.append(item.componentsSeparatedByString(":")[1])
index = index + 1
}
I am able to iterate through each data but the when i store it in the table..It get stored like below
coulmn_Id column_ServerId column_Job_Title
1 83 CFD
1 83 CFD
Could anyone help me with corrected code or reason for this bizarre behavior please..
I suspect one of two things:
The value in result is not as you expect.
The manner in which you are checking the output is faulty.
I lean towards the latter as I do not see any way both entities could be assigned the same column ID in a single run through.
Put breakpoints up top to check the value of results and the array returned from results.componentsSeparatedByString(",").
Show the code you used to iterate through the table to check it. My bet is that you are not showing the true output. What is the output from the print lines within the loop? If it looks something like this:
Column_Id
1
Column_Server_Id
85
column_Job_Name
ABC
Column_ID
2
Column_Server_ID
83
Column_ID
CFD
Then I'd say, for sure, you are not properly reading back your results from Core Data. Let us see where you are getting that final table.
I don't know what the problem was the same code worked as it should.
This question already has answers here:
Swift 2 ( executeFetchRequest ) : error handling
(5 answers)
Closed 7 years ago.
https://www.dropbox.com/s/vyzdrjlpvdcuill/managedContext.png?dl=0
I had this working January and when I ran it today, I was presented with this error.
I have tried to understand the new method of error handling, sadly I am not grasping it.
first time poster.
Sincerely,
rob
You have extra argument, which is the error,
Simple remove it.
Also this is a working code:
let fetchRequest = NSFetchRequest(entityName: "movieQuoteEntityName")
fetchRequest.sortDescriptors = [NSSortDescriptor(key: "lastTouchDate", ascending: false)]
var error :NSError? = nil
let appDel = UIApplication.sharedApplication().delegate as! AppDelegate
var context: NSManagedObjectContext? = nil
let movieQuotes = context!.executeFetchRequest(fetchRequest)
Well, with the Swift 2.0, they changed the whole error handling stuff so you are not able to declare that way.
Swift has try-catch now for the error handling, so you may change all of the old error handling methods.