(lldb) error with Firebase - ios

I'm getting an lldb error whenever I click on a specific tab. The tab is called Account and its supposed to pull data from a child node called "requests" and display that data in a list(table view controller).
I've done this multiple times before. I'm even using my own recycled code for this task, but the error keeps showing up. I've already made sure each button/label is connected to the view controller and I've made sure none are disconnected.
The error message is saying that my request object isn't key-code compliant, but that's not the case either. What else could it be?
This is the code along with some screenshots:
Here is the method I'm using. The error only comes up when I call this function. Other than that, the screen is just blank, so I figured that the issue has to be within the function. btw, requestsArray is an array of requests declared as such: var requestsArray = [requests]()
Heres the rest of the code from that view controller:
EDIT

In Swift 4, the vars need to be marked as #objc like this
class requests: NSObject {
#objc var from: String?
#objc var location: String?
...
}

Related

Changing one NSManaged object changes other objects

I have an app called Hapistats on the app store. It uses cloudkit. I am in the process of converting all data from cloudkit to Coredata.
I have an entity called log, it has a one to many relationship with activity.
The problem is when I try and update a log's activities. Lets lay log1 is a log that has an activity called activity1. When I try to add activity1 to the already existing log, log2, log1 will no longer have activity1 and log2 will successfully save activity1 to itself.
This happens for every update or new log created. The problem is that apparently there can only be one log with a specific activity.
// Edits the log
func editLog(log: Log, rating: Int, activitiesToAddToLog: [Activity]) {
log.rating = Int16(rating)
log.removeFromActivities(log.activities) // Empties the activities from the log
let activitiesOrderedSet = NSOrderedSet(array: activitiesToAddToLog)
log.addToActivities(activitiesOrderedSet) // Adds all the activites to the log
saveToPersistentStore()
}
Is the only place that calls editLog()
#IBAction func saveActivitiesButtonTapped(_ sender: Any) {
// log is an optional because I use a landing pad for log.
if let log = log {
LogController.shared.editLog(log: log, rating: rating, activities: displayActivities[0])true)
}
}
I expect that my code would just add activities to logs when editLog() is called but instead it overrides other logs' activities.
I figured it out. It was a Xcode issue. It wasn't actually being one to many so I re added it and built on a generic device and it suddenly worked.

Call self.Class variable after multiple AlamoFire requests

I'm creating an app that creates a zoom meeting and joins a zoom room into the meeting.
I have got 2 Alamofire requests that I use to call Zoom REST API, mainly 1 to create a zoom meeting and another one to join a zoom meeting, which should be executed when a user clicks the submit button. And the returned result must be stored using a function call. Below is an abstract of the code.
User presses the checkin button
class MyViewController: UIViewController {
var Kiosk = OKKiosk.shared
#IBAction func checkInBtn(_ sender: UIButton) {
userid = FunctiontoGetUserid()
dispatchgroup.enter()
let meetingCredentials = createMeeting(user : userid)
disptachgroup.notify(queue: .main){ () in
joinMeeting(meetingCredentials.meeting_id)
self.Kiosk.currentuser.addReason(meetingCredentials.meeting_id)//doesnt get stored
self.Kiosk.currentuser.addReason(meetingCredentials.start_url)//doesnt get stored
}
Kiosk.currentuser.addReason(meeting_id)//this works
Kiosk.currentuser.addReason(start_url)//But start_url and Meeting id are empty
}
As you can see I need the result from my first call, createMeeting, in my second call joinMeeting.
The problem what I face is whenever I use self.kiosk, nothing gets stored inside the addreason(). But if i directly use kiosk.currentuser.addReason("Example") , it works.
Unfortunately, I'm forced to use self inside dispatchgroup because its closure, Otherwise I get the error :
Reference to property 'Kiosk' in closure requires explicit 'self.' to make capture semantics explicit
I feel the self inside the closure, and the one outside the closure are not pointing to the same Class instance.
Please help me with the above, I'm new to async programming and closures.
Thanks in advance.

Best practice for showing an error Alert

I am having trouble displaying an Alert in case of an Error properly.
My idea is: Everytime I download data from my backend with an completion block, I present an Alert if an error occurs.
query?.findObjectsInBackground(block: { (objects, error) -> Void in
if error != nil {
createAlert(error)
return
} else if let objects = objects {
}
Since I got more than one call in a ViewController at the same time, it may happen to find myself having more than 2 or 3 Alerts presenting at the same time saying e.g. "No Connection to the Internet".
It will constantly reload the Alert and it is a pain in terms of UI.
What is best practice to solve this issue?
My solution idea would be to put everything in a Singleton pattern and make sure no other other Alert is currently displayed.
Are there any better ways?
Instead of using a singleton pattern, you might prefer having an optional property (var noConnectivityAlert) in the class currently responsible for creating the alert.
Instead of the createAlert() method you would have a informUserAboutConnectivity() method.
func informUserAboutConnectivity() {
// If noConnectivityAlert is nil
// the method creates an alert and shows it.
// If the property is NOT nil
// do nothing (since the user is already informed).
}
When the internet connection would come back and then disappear again, some apps in the App Store would show an alert once again.
In that case, when the internet connection comes back you can directly set noConnectivityAlert = nil so that when the connection is lost, things will be handled nicely (a new alert will be created and shown).
By the way, in the iOS SDK, singletons are not used often. There are mostly used for providing a default and most common use case of a class (think of UserDefaults), or (of course) a shared manager/provider.

In Firebase, retrieved data doesn't get out from the .observeEventType method

I defined a class in a project, to manage my database set up in Firebase. The following is what I've done with the class so far.
import Foundation
import Firebase
class db{
class func getPrim() -> [String]{
var ret = [String]()
let ref = FIRDatabase.database().reference()
ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: {
s in
ret = s.value! as! [String]
})
print("ret: \(ret)")
return ret
}
}
And the method is called in a print() method, like print(db.getPrim()). But what the console(or terminal? anyway the screen on the bottom of xcode..) says is only an empty array. I embraced the statement above with print("-----------------------").
-----------------------
ret: []
[]
-----------------------
2016-09-07 20:23:08.808 이모저모[36962:] <FIRAnalytics/INFO> Successfully created Firebase Analytics App Delegate Proxy automatically. To disable the proxy, set the flag FirebaseAppDelegateProxyEnabled to NO in the Info.plist
2016-09-07 20:23:08.815 이모저모[36962:] <FIRAnalytics/INFO> Firebase Analytics enabled
Seems like ret in .observeEventType() method does not take its value out of the method block. As far as I know the data is supposed to be kept.. Can anyone give me a hint? I still don't understand how the code block as a method parameter works. Thnx!!
All firebase operations are by definition asynchronous which means your program doesn't wait for the data from firebase before going to the next statement in your code. So by the the time your print statements are called the data from firebase hasnt been fetched yet.
Take a look at this answer for more information.
André (and the link to Vikrum's answer) are indeed why this is happening. But it's usually easiest to understand if you add a few log statements to your code:
class func getPrim() -> [String]{
let ref = FIRDatabase.database().reference()
print("Before observer");
ref.child("bunya1").observeEventType(FIRDataEventType.Value, withBlock: {
s in
print("In observer block");
})
print("After observer");
return "..."
}
When you run this code, the logging will be in this order:
Before observer
After observer
In observer callback
This is probably not the order in which you expected them to appear. But it definitely explains why your returning an empty array in your snippet. If the code inside the block hasn't run yet, the item hasn't been added to the array yet.
The reason this order is inverted is as André and Vikrum say: the call to Firebase happens asynchronously. Since it can take some time (especially if this is the first time you're accessing the database), the Swift code continues executing to ensure the app stays responsive. Once the data comes back from Firebase, your block is called (for that reason it's sometimes referred to as a "callback") and you get the data.

EXC_BAD_ACCESS with Swift app using Core Data and Firebase

Problem:
I am getting an EXC_BAD_ACCESS error in my app and I think it is because of thread-safety related code (self.sharedContext.performBlockAndWait) in my closures. But I cannot figure out why the problem exists. I will appreciate any help in figuring this out.
My project is in Swift 2 on Xcode 7.
Project repository: https://github.com/qwertyshan/HungryBaby
My object graph looks like the following:
class Recipe:
var name: String
var version: Double
... // some more simple properties
var method: [Method] // object array
var ingredients: [Ingredient] // object array
var nutrition: Nutrition // object
The program flow is something like the following:
In LoginVC.swift:
Line 101: getDataOnLogin( ) downloads data from network and parses it as an array of "recipe" dictionaries
Line 148: generateRecipe( dictionary ) is called to create Recipe object graph
generateRecipe() in turn calls generateIngredients(), generateMethod(), and generateNutrition().
Each of these methods initialize their objects on the SharedContext and add a relationship to the calling Recipe object.
Crash occurs on line 154 in LoginVC.swift with error: "Thread 1: EXC_BAD_ACCESS(code=1, address=0x2)".
I know this is a memory error, but I don't know why it is being triggered. Can someone please look at my project and provide some insights into the cause of this crash?
Reproduction steps:
Run application workspace "HungryBaby.xcworkspace"
On UI, tap “Login Anonymously” to download recipe data.
Step through breakpoints until app crashes.
If you're taking the time to read this, thanks a ton!
The issue was with thread safety in Core Data. I am answering the question so others don't have to spend any more time on it.

Resources