Unable to get PFUser field - ios

I want to get the xp of the current user and display it in a label. The xp field of the user is equal to 252 but it is displaying 0. I can get other fields like email, username and password but can't get the value for the xp field. Code:
xpRequiredLabel.text = "\(PFUser.currentUser()!["XP"])/300 XP"
What am I doing wrong ?

This expression PFUser.currentUser()!["XP"] returns AnyObject?. You need to unwrap this optional and cast it to string. Try this:
let userXP = PFUser.currentUser()!["XP"] as! String
xpRequiredLabel.text = "\(userXP)/300 XP"
Or this (less error-prone):
if let userXP = PFUser.currentUser()?["XP"] as? String {
xpRequiredLabel.text = "\(userXP)/300 XP"
}
Update
It turns out that you have to fetch the object from the server before accessing new properties. So, your code should look like:
let user = PFUser.currentUser()!
user.fetch()
let userXP = ["XP"] as! Int // If you have "Number" as your column datatype
xpRequiredLabel.text = "\(userXP)/300 XP"
Note that fetch() will block the UI. You can also make this code async:
if let user = User.currentUser() {
user.fetchInBackgroundWithBlock({ (result, error) -> Void in
if let u = result as? PFUser {
if let userXP = u["XP"] as? Int {
self.xpRequiredLabel.text = "\(userXP)/300 XP"
}
}
})
}

those are Int values
252 / 300 = 0 when ints invovled
you can do something like
xpRequiredLabel.text = "Float((PFUser.currentUser()!["XP"]))/300.0 XP"

Related

Not able to access values from dictionary

I have a dictionary like so..
{
"Due_Date" = "2020-06-09T15:00:13";
departmentID = 180075;
keyPointID = "";
id = 4;
jobID = 180093;
jobName = myLab;
plantID = 1232;
shiftID = 2;
"smat_Leader1ID" = 43232;
workshopID = 423423;
workstationID = 1892074;
}
I'm not able to get any values except those values whose key and value is string (Like Due_Date). I have fetched it like so...
var Due_Date = self.dictionary["Due_Date"]! as? String //This gives an answer
Similarely, if I try to fetch these values, I don't get the values
var Department_ID = self.dictionary["departmentID"]! as? Int ?? 0 //This gives 0
var smatLeader1ID = self.dictionary["smat_Leader1ID"]! as? Int ?? 0 //This gives 0
(I don't get the other values also. Just that I mentioned just 2 above)
Since you're force casting and not getting a crash you seem to be getting the value but you're trying to cast the value as Int which is failing here. Seems the value is not an Int type could be String try out this to fix it.
Replace this:
var Department_ID = self.dictionary["departmentID"]! as? Int ?? 0
With this:
var Department_ID = Int(self.dictionary["departmentID"] as? String ?? "0")

Swift Query Request crashing when value is null

Query results retrieved
"Adjusted_Lease_Value__c" = "0.0";
"Amount_Financed__c" = "23520.64";
"Assignment_Amount__c" = "19220.21";
"Category__c" = 4;
"Charge_Off_Amount__c" = "0.0";
"Committed_Funds__c" = "19220.21";
"Date_Assigned_Back_to_ACG__c" = "<null>"
How I'm retrieving them:
// Initial Access to Salesforce in order to query data
client.performLogin(accessUsername, password: accessPassword, fail:{ (fail) in
}) { (success) in
self.queryResult = self.client.query(getCasesSQL2)
for o: Any in self.queryResult.records() {
// This line fails
let test = (o as AnyObject).fieldValue("Date_Assigned_Back_to_ACG__c") as! String
// This works no problem
let AmountFinanced = ((o as AnyObject).fieldValue("Amount_Financed__c") as! String
}
When the query result is "null" it crashes the app. What should I do?
If it may nil then do not use forced conversion.
self.queryResult = self.client.query(getCasesSQL2)
for o: Any in self.queryResult.records() {
let test = (o as AnyObject).fieldValue("Date_Assigned_Back_to_ACG__c") as? String
let amountFinanced = ((o as AnyObject).fieldValue("Amount_Financed__c") as? String
}

Couchbase lite, Search query taking very long time

When I try to search the couchbase documents of size around 10K, the searching is taking very long time. Below are the code snippet. Can anyone optimize it or suggest me any alternative approach. Thank you.
1) Search function
func search(keyword:String) -> [[String:AnyObject]] {
var results:[[String:AnyObject]]=[]
let searchView = database.viewNamed(AppConstants().SEARCH)
if searchView.mapBlock == nil {
startIndexing()
}
let query = searchView.createQuery()
var docIds = Set<String>()
let result = try query.run()
while let row = result.nextRow() {
let key = "\(row.key)"
let keyArr = keyword.characters.split(" ")
for (index, element) in keyArr.enumerate() {
let keyItem = String(element)
if key.lowercaseString.containsString(keyItem.lowercaseString) {
let value = row.value as! [String:AnyObject]
let id = value["_id"] as? String
if id != nil && !docIds.contains(id!) {
results.append(value)
docIds.insert(id!)
}
}
}
}
}
2) Indexing
func startIndexing() {
let searchView = database.viewNamed(AppConstants().SEARCH)
if searchView.mapBlock == nil {
searchView.setMapBlock({ (doc, emit) in
let docType = doc[AppConstants().DOC_TYPE] as! String
if AppConstants().DOC_TYPE_CONTACT.isEqual(docType) {
self.parseJsonToKeyValues(doc)
for value in self.fields.values {
emit(value, doc)
}
self.fields.removeAll()
}
}, version: "1")
}
}
self.parseJsonToKeyValues(doc) will return me the key value store of my documents to index.
You're emitting the entire document along with every field for your view. This could easily cause your queries to be slow. It also seems unlikely you want to do this, unless you really need to be able to query against every field in your document.
It's considered best practice to set your map function right after opening the database. Waiting until right before you query may or may not slow you down.
See https://developer.couchbase.com/documentation/mobile/current/guides/couchbase-lite/native-api/view/index.html for more, especially the section labeled "Development Considerations".

iterating an array to extract a value from firebase database in swift

might sound like a basic question--but I'm not seeing where I am going wrong..
I end up with either of these two scenarios:
I keep getting the error "Could not cast value of type __NSCFNumber to NSSTring". if I use extractedSku = skuList[i]!.value["sku"] as! String
If I remove as! String it saves it, but it isn't saved as a string. How do I get this to be saved as a string?
I have appended data from firebase into an array
skuArray = [AnyObject?]()
in viewDidLoad, I am iterating skuArray to extract the 'sku' and store into a variable.
var skuArray = [AnyObject?]()
var productDetailArray = [AnyObject?]()
data stored in Sku Array is:
[Optional(Snap (aRandomKey) {
active = 1;
sku = 888888;
})]
viewDidLoad:
let skuList = self.skuArray
for var i = 0; i < skuList.count ; ++i{
let extractedSku = skuList[i]!.value["sku"] as! String
// go into database and extract "products" details by sku
self.databaseRef.child("products/\(extractedSku)").observeEventType(.ChildAdded, withBlock: { (snapshot:FIRDataSnapshot) in
self.productDetailArray.append(snapshot)
})
Since the underlying type is NSNumber, use the stringValue property to get a String:
if let extractedSku = (skuList[i]?.value["sku"] as? NSNumber)?.stringValue {
// use extractedSku which is of type String
}

How to compare values of NSDictionary with String

I have two orgunit_id's, test["orgunit_id"] and API.loginManagerInfo.orgUnit, which I would like to compare. The problem is that the variables have different types. test["orgunit_id"] is value of a NSDictionary and the other one is a String.
I've tried several ways to cast it into Integers, but without success.
Code:
if(!orgUnits.isEmpty){
print(orgUnits) //See at console-output
for test: NSDictionary in orgUnits {
println(test["orgunit_id"]) //See at console-output
println(API.loginManagerInfo.orgUnit) //See at console-output
if(Int(test["orgunit_id"]? as NSNumber) == API.loginManagerInfo.orgUnit?.toInt()){ // This condition fails
...
}
}
}
Output:
[{
name = Alle;
"orgunit_id" = "-1";
shortdescription = Alle;
}, {
name = "IT-Test";
"orgunit_id" = 1;
shortdescription = "";
}]
Optional(-1)
Optional("-1")
Edit:
Here's the definition of API.loginManagerInfo.orgUnit: var orgUnit:String?
Use if let to safely unwrap your values and typecast the result.
If test["orgunit_id"] is an Optional Int and if API.loginManagerInfo.orgUnit is an Optional String:
if let testID = test["orgunit_id"] as? Int, let apiIDString = API.loginManagerInfo.orgUnit, let apiID = Int(apiIDString) {
if testID == apiID {
// ...
}
}
You may have to adapt this example given what is in your dictionary, but you get the point: safely unwrap the optional value and either typecast it (with if let ... = ... as? ...) or transform it (with Int(...)) before comparing.

Resources