I cannot find the currentUser() in parse - parse-platform

I am making an app so whenever somebody can press the add button and then type in one of their family member's emails and it will add the email to an array in parse. This is what my code looks like:
func Save() {
PFUser.currentUser()!.addObject(memberName.text!, forKey: "Family_Emails")
}
memberName is the TextField's IBOutlet connection name
"Family_Emails" is the parse array object I have set up
Whenever I click the save button it doesn't do anything. What do I do?

You're just not calling save on the user object.
PFUser.currentUser().saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
if (success) {
// The object has been saved.
} else {
// There was a problem, check error.description
}
}
https://parse.com/docs/ios/guide#objects-saving-objects

Related

Prevent NSDocument's auto-saving while its content is editing

I develop a document-based Cocoa application allowed saving documents asynchronous. Namely, my NSDocument subclass returns ture on canAsynchronouslyWrite(to:typeOf:for:).
I want dynamically and silently delay (or cancel) regular auto-saving if the document content is editing. At first, I thought it's enough when I throw an error in checkAutosavingSafety(), but it displays an error message dialog for user.
I believe there is a standard way for such a standard demand. But I'm not sure either where in a NSDocument subclass I should prevent saving and to which method I should say "please wait".
Does someone have any idea for this?
For the reference, the content of document is text which is managed by NSTextView subclass.
I finally found that throwing an .userCalcelled error in a saving process with autosavingIsImplicitlyCancellable can cancel autosaving.
/// make autosaving cancellable
override var autosavingIsImplicitlyCancellable: Bool {
return true
}
/// save or autosave the document contents
override func save(to url: URL, ofType typeName: String, for saveOperation: NSDocument.SaveOperationType, completionHandler: #escaping (Error?) -> Void) {
// cancel if something is working
guard saveOperation != .autosaveInPlaceOperation || !self.isEditing else {
completionHandler(CocoaError(.userCancelled))
return
}
super.save(to: newUrl, ofType: typeName, for: saveOperation, completionHandler: completionHandler)
}
/// whether your document is currently being edited
var isEditing: Bool {
// check your document state
}

iOS Swift 3 Deleting a row from TableView Using Parse

I am building an iOS app and I am trying to delete a row from the UITableView. I am also using Parse as the mobile-backend of the app. Here is code for the delete method:
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
// Delete the row from the data source
let query = PFQuery(className: "Receipts")
let currReceipt = receipts[indexPath.row]
query.whereKey("objectId", equalTo: currReceipt.objectId!)
query.findObjectsInBackground(block: { (objects, error) in
if error != nil {
self.createAlert(title: "Oops! Something went wrong number 1!", message: "We could not delete the receipt")
print("THERE WAS AN ERROR DELETING THE OBJECT")
}else{
for object in objects!{
self.receipts.remove(at: indexPath.row)
object.deleteInBackground()
self.table.reloadData()
}
}
})
}
}
Just to clarify, there will only be one receipt in the database with any given "objectId", so the query.findObjectsInBackground should only be returning a single object.
When I try to delete a row in the simulator, I get the error "Object not found" even though I can see that the object exists in the database. What am I doing wrong?
UPDATE
Found my solution after a long time looking. For anyone interested, it had to do with the default ACL values for Read and Write permissions. Here is the link to the answer: Parse weird bug in Swift that causes ACL write permissions to change to an objectId
It might be a typo, but why do you have ! in this line?
query.whereKey("objectId", equalTo: currReceipt.objectId!)

Is it possible to automatically fetch parse objects?

Many im services automatically display messages once the user on the other end has sent a message.
Right now, the only way I can think of to do this is to use an nstimer which will run the appropriate block of code which fetches the messages and updates the table view. This is resources intensive and can waste one of the requests per second. Is there any way to automate this process and make it happen only when a new message has been sent/received?
Here's an example of using didReceiveRemoteNotification inside of your app delegate to respond to push notifications. In particular, you care about the case where you are receiving the notification while the app is active.
func application(application: UIApplication, didReceiveRemoteNotification userInfo: [NSObject : AnyObject]) {
if (PFUser.currentUser() == nil) {
return
}
if (application.applicationState == UIApplicationState.Inactive || application.applicationState == UIApplicationState.Background) {
// Received the push notification when the app was in the background
PFAnalytics.trackAppOpenedWithRemoteNotificationPayload(userInfo)
// Inspect userInfo for the push notification payload
if let notificationPayloadTypeKey: String = userInfo["someKey"] as? String {
// Do something
}
} else {
// Received the push notification while the app is active
if let notificationPayloadTypeKey: String = userInfo["someKey"] as? String {
// Use NSNotificationCenter to inform your view to reload
NSNotificationCenter.defaultCenter().postNotificationName("loadMessages", object: nil)
}
}
}
Then you just need to add a listener inside of your view controller. Inside of viewDidLoad add the following which will call the function loadMessages whenever a notification is received.
NSNotificationCenter.defaultCenter().addObserver(self, selector: "loadMessages", name: "loadMessages", object: nil)
If you download the code for Parse's Anypic example project you can see how they handle remote notifications.

Storing a Boolean for access by Parse login

I want to store a Boolean which grants access to certain options when a user logs in with Parse, but when I log in and declare it to be true, the variable seems to remain false.
I tried using NSUserDefaults and storing a global variable.
This is where I log in on one view controller:
PFUser.logInWithUsernameInBackground(userName.text!, password: password.text!) {
(user: PFUser?, error: NSError?) -> Void in
if user != nil {
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "accessGranted")
}
This functions fine and prints "Success" if I try.
On another view controller I have things like this:
addButton.enabled = NSUserDefaults.standardUserDefaults().boolForKey("accessGranted")
You can use NSUserDefaults to store your Bool globally this way:
Set your Bool this way:
NSUserDefaults.standardUserDefaults().setBool(false, forKey: "YourKey")
Then you can access it anywhere in your project this way:
let yourBool = NSUserDefaults.standardUserDefaults().boolForKey("YourKey")
Hope this will help.
NSUserDefaults:
Your are missing key component for it to work - you have to save the settings:
NSUserDefaults.standardUserDefaults().setBool(true, forKey: "accessGranted")
NSUserDefaults.standardUserDefaults().synchronize()
After that, your data that you stored will be stored to disk and you can access them anytime.
One-time assign to property:
After reading through comment, in order to access property only once, you can use something like this:
var accessGranted : Bool?
if accessGranted == nil {
accessGranted = yourValue
}
or as of Swift 2.0 (more on it here):
var accessGranted : Bool?
guard let granted = accessGranted else {
accessGranted = yourValue
}
Edit 2:
To notify second VC about changes, you can use multiple mechanisms (protocols / delegates etc.), but usually for this kind of message you would use Notifications (so your whole application can listen to that).
Notifications
You can use notifications like this:
In your "login" call, notify application that your access status changed, like this:
let NOTIFICATION_ACCESS_CHANGED_KEY = "NotificationAccessChanged"
NSNotificationCenter.defaultCenter().postNotificationName(NOTIFICATION_ACCESS_CHANGED)
then, everywhere where you are interested to listen to that change, put notification listener:
NSNotificationCenter.defaultCenter().addObserverForName(NOTIFICATION_ACCESS_CHANGED, object: nil, queue: nil) { (notification) -> Void in
// This block will be called when you post notification
self.doSomething()
}
Hope it helps!

Parse query returning nothing from findObjectsInBackgroundWithBlock

EDIT:
I changed the question title.
and I changed the function to findObjectsInBackgroundWithBlock -
override func viewDidAppear(animated: Bool) {
let predicate = NSPredicate(format: "username != '"+userName+"'")
var query = PFQuery(className: "_User", predicate: predicate)
var objects = query.findObjectsInBackgroundWithBlock({
(objects:[AnyObject]!, error: NSError!) in
if(error == nil){
for object in objects {
self.resultsUsernameArray.append(object.username)
self.resultsProfileNameArray.append(object.email)
self.resultsImageFiles.append(object["photo"] as PFFile)
self.resultsTable.reloadData()
}
}else{
println("error in quert execution \(error)")
}
})
}
There is one warning [variable 'objects' inferred to have type 'Void', which may be unexpected], and the code still returns nothing. I have 3 users in my Parse account for this app.
There's no error anymore, I guess that's good at least?
I'm new to xcode, and can't find how to search for this function. I'm having the same issue with Parse that others have had. My find query worked twice, and now (with no changes to the code) it stops returning anything. I want to do as suggested and 'Break on warnBlockingOperationOnMainThread() to debug,' but the only project search feature I can find (right clicking the project and doing 'Find in selected groups') doesn't bring anything up.
So, how do I find this function to add a breakpoint? Or, better yet, why did this query stop working?
override func viewDidAppear(animated: Bool) {
let predicate = NSPredicate(format: "username != '"+userName+"'")
var query = PFQuery(className: "_User", predicate: predicate)
var objects = query.findObjects()
for object in objects {
self.resultsUsernameArray.append(object.username)
self.resultsProfileNameArray.append(object.email)
self.resultsImageFiles.append(object["photo"] as PFFile)
self.resultsTable.reloadData()
}
}
Thanks!
From: https://developer.apple.com/library/mac/recipes/xcode_help-breakpoint_navigator/articles/adding_a_symbolic_breakpoint.html
In the bottom-left corner of the breakpoint navigator, click the Add button.
Choose Add Symbolic Breakpoint.
Enter the symbol name in the Symbol field.
If the symbol is declared in more than one library, enter the name of the appropriate library in the Module field.
To specify that program execution be suspended only if an expression evaluates to true, enter the expression in the Condition field.
Click Done.

Resources