Get PFUser object custom values - swift

I have custom value in a PFUser column called "website". I am trying to get this value using the code below but it does not seem to change on the device if I update the value from Parse.com on their website using the data viewer. It also does not update across devices.
Any Ideas?
websiteField.text = currentUser.objectForKey("website") as String

I have managed to get it working with the code below.
var currentUser = PFUser.currentUser()
currentUser.refreshInBackgroundWithBlock { (object, error) -> Void in
println("Refreshed")
currentUser.fetchIfNeededInBackgroundWithBlock { (result, error) -> Void in
self.websiteStr = currentUser.objectForKey("website") as String
self.websiteField.text = self.websiteStr
println("Updated")
println(self.websiteStr)
}
}

Related

Swift DynamoDB Mapper Sending Empty Values

I'm trying to use DynamoDB using the iOS Swift SDK. I'm using Cognito with Facebook as an external identity provider. Cognito is working fine - I've tested user sync and it works OK, so I believe I have the authentication set up. Here's how I'm setting up the SDK (I have the actual values of my identity pool in my code):
let credentialsProvider = AWSCognitoCredentialsProvider(regionType:.USEast1,
identityPoolId:"<my-identity-pool-id>", identityProviderManager: FacebookProvider())
let configuration = AWSServiceConfiguration(region:.USEast1, credentialsProvider:credentialsProvider)
AWSServiceManager.default().defaultServiceConfiguration = configuration
And here's my DynamoDB mapped class:
import Foundation
import AWSDynamoDB
class SavedItem : AWSDynamoDBObjectModel, AWSDynamoDBModeling {
var userId : Int?
var timestamp : Int?
class func dynamoDBTableName() -> String {
return "my-table"
}
class func hashKeyAttribute() -> String {
return "userId"
}
class func rangeKeyAttribute() -> String {
return "timestamp"
}
}
I've verified that my code has the correct table and attribute names and that the hash key and range key values on the table are identical, including case sensitivity, with the fields in my SavedItem class.
Here's how I'm instantiating the mapper:
let dynamoDBObjectMapper = AWSDynamoDBObjectMapper.default()
let savedItem = SavedItem()
savedItem?.userId = 1
savedItem?.timestamp = 2
dynamoDBObjectMapper.save(savedItem!).continueWith(block: { (task:AWSTask<AnyObject>!) -> Any? in
if let error = task.error as? NSError {
print("The request failed. Error: \(error)")
} else {
print("Save callback executing")
}
return nil
})
That code's more or less straight out from the AWS Documentation example. But, here's what I get back in the console when that code executes:
Error Domain=com.amazonaws.AWSCognitoIdentityErrorDomain Code=0 "(null)" UserInfo={__type=com.amazon.coral.validate#ValidationException, message=Supplied AttributeValue is empty, must contain exactly one of the supported datatypes}
I bumped console logging up to debug, and it looks like the mapper is not sending any attributes from the SavedItem object. Here's what's in the console for the save request body:
Request body:
{"Key":{"userId":{},"timestamp":{}},"TableName":"my-table","AttributeUpdates":{}}
Any idea why the values are not getting included in the save request body?
Using aws-sdk-ios v2.6.1 on in Swift 4 on iOS 11.
The problem seems to be the type of userId and timestamp. Changing them from Int to NSNumber fixed the problem.
Yes i faced this same issue. and after struggling for 3 days.i found that AWSDynamoDBObjectModel not support in swift 4. please try in swift 3 version. You will get success.

parse.com swift return values from class after query

I have a second class in parse where each row is linked to the user and stores an int number. This is already setup.
Now I want to check for the current user and get the int that is saved and put that in a label. Any Ideas?
you will need to query with constraints ("meaning that get data only for the currentUser"). Then you have two options to retrieve their data either use getfirstobjectinbackgroundwithblock() method which will get at least one row of data from parse. Or use findObjectsInBackgroundWithBlock() method which will return multiple rows from parse.
if in parse, the user is being saved as pointer use that line:
let userT = PFUser.CurrentUser() //<-- to get CurrentUser
if in parse, the user is being saved as string use that line
let userT = PFUser.CurrentUser().username //<-- to get CurrentUser
In this code, I use the getFirstObjectInBackgroundWithBlock method because I think you are only displaying one thing for the user, So if I am wrong use the second method findObjectsInBackgroundWithBlock
let query = PFQuery(className:"whateverNameYourClassIs")
let userT = PFUser.CurrentUser() //<-- to get CurrentUser
query.whereKey("NameOfUserColummInParse" equalTo:userT!)
query.getFirstObjectInBackgroundWithBlock { (object: PFObject?, error: NSError?) -> Void in
if error == nil
{
if let retreiveObject = object
{
let data = retreiveObject["IntValue"] as! Int //<-- IntValue supposed to be the name of your class column in parse where you want to retrieve the value.
}
}
})

How to properly Pin in Parse localDataStore?

I have Parse.enableLocalDatastore() in my app delegate before Parse.setApplicationId
Then I have var newPosts = PFObject(className: "Post") as a global variable.
Then I want to get 1,000 latest objects from the "Post" table from localDataStore that I enabled earlier so I do this:
var getNewPosts = PFQuery(className: "Post")
getNewPosts.fromLocalDatastore()
getNewPosts.limit = 1000
getNewPosts.orderByDescending("createdAt")
getNewPosts.findObjectsInBackgroundWithBlock {
(downloadedPosts, error) -> Void in
if downloadedPosts != nil && error == nil {
println(downloadedPosts) // I am getting table with no data
}
}
But I only get empty data rows.
If I comment out the getNewPosts.fromLocalDatastore() line results are fine.
I understand that I am missing the critical Pinning step but not sure from Parse documentation hoe and where to implement it. Can you please help?
You are getting no data....
reasons my be...
Wrong name of class (class names are case sensitive)
Data is not there in local storage
Try synchronous version of findObject: method and pin: method.

How do you store a dictionary on Parse using swift?

I am very new to swift and I don't know Obj C at all so many of the resources are hard to understand. Basically I'm trying to populate the dictionary with PFUsers from my query and then set PFUser["friends"] to this dictionary. Simply put I want a friends list in my PFUser class, where each friend is a PFUser and a string.
Thanks!
var user = PFUser()
var friendsPFUser:[PFUser] = []
var friendListDict: [PFUser:String] = Dictionary()
var query = PFUser.query()
query!.findObjectsInBackgroundWithBlock {
(users: [AnyObject]?, error: NSError?) -> Void in
if error == nil {
// The find succeeded.
println("Successfully retrieved \(users!.count) users.")
// Do something with the found objects
if let users = users as? [PFUser] {
friendsPFUser = users
for user in friendsPFUser{
friendListDict[user] = "confirmed"
}
user["friends"] = friendListDict //this line breaks things
user.saveInBackground()
}
} else {
// Log details of the failure
println("Error: \(error!) \(error!.userInfo!)")
}
}
To be clear, this code compiles but when I add
user["friends"] = friendListDict
my app crashes.
For those who might have this issues with. "NSInternalInconsistencyException" with reason "PFObject contains container item that isn't cached."
Adding Objects to a user (such as arrays or dictionaries) for security reasons on Parse, the user for such field that will be modified must be the current user.
Try signing up and using addObject inside the block and don't forget do save it!
It helped for a similar problem I had.

How to work with custom user columns in Parse.com and swift

I am using parse.com to create my swift app backend.
I want to add columns to my user and then refer to the current user's new columns/fields throughout my code.
What is the best way to do this?
When I create my user in my swift code I add the columns
func signUpViewController(signUpController: PFSignUpViewController!, didSignUpUser user: PFUser!) {
user["points"] = 0
user.saveInBackgroundWithBlock { (success: Bool!, error: NSError!) -> Void in
if success == false || error != nil {
println(error)
}
}
I tried creating a User class which inherited from PFUser
class User: PFUser {
var points = 0
}
I want to be able to check if the user has points in various controllers. I tried something like this
var query = PFUser.query()
query.whereKey("user", equalTo:PFUser.currentUser().username)
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if error == nil {
var user = objects.first? as? User
if user != nil {
if user!["points"] as Int == 0 {
println("You have no points")
}
}
}
}
I also tried:
var points = PFUser.currentUser()["points"]
You could just refresh the user in background then the user object will contain the new/refresh data/fields.
There is additional field to fill in.
For example, I have one extra field to fill in the password one more time. I make it like this:
In viewDidLoad method:
// Change "Additional" to "Confirm password"
[self.signUpView.additionalField setPlaceholder:NSLocalizedString(#"Confirm password",nil)];
Remember also to set the position of this field in viewDidLayoutSubviews method
[self.signUpView.additionalField setFrame:CGRectMake(fieldFrame.origin.x + 5.0f,fieldFrame.origin.y + yOffset+ 35.0f,fieldFrame.size.width - 10.0f, fieldFrame.size.height)];