How to receive String Array from Parse Cloud Code in Swift? - ios

I've written a Parse cloud code function which returns some data from the database. I see those in the "response" when I do a println in XCode. It looks like it's wrapped in a double optional!?
What I'm making wrong in the if let and in the for loop? How do I get (unwrap) a String Array out of it?
My code in Swift:
PFCloud.callFunctionInBackground("TopTwo", withParameters: ["rating":5]) {
(response: AnyObject?, error: NSError?) -> Void in
if error == nil {
println("Successfully retrieved \(response!.count) scores.")
println("Here are the flower names: \(response)")
if let objects = response as? [PFObject] {
for object in objects {
println(object.objectId)
}
}
} else {
println("Error: \(error!) \(error!.userInfo!)")
}
}
What I see in the console:
Successfully retrieved 2 scores.
Here are the flower names: Optional((
rose,
"sunflower"
))
Maybe there is also an error in my cloude code. Here you can see what I've done:
Parse.Cloud.define("TopTwo", function(request, response) {
var query = new Parse.Query("Flowers");
console.error("Get flowers with the rating: " + request.params.rating);
query.equalTo("stars", request.params.rating);
query.find({
success: function(results) {
console.error("Results: " + results);
var list = [];
for (i = 0; i < results.length; i++) {
list[i] = results[i].get('flowerName');
}
console.error("Flower name list: " + list);
response.success(list);
},
error: function() {
response.error("lookup failed");
}
});
});
And here the parse logs:
Results: [object Object],[object Object]
Flower name list: rose,sunflower
(I'm using XCode 6.3.2 - Swift 1.2)
Many thanks in advance!

Okay, I could solve it on my own.
The object which is returned from cloud code is already an Array. Therefore a casting into NSArray has to be made instead of a casting into [PFObject].
Here is the working Swift code:
PFCloud.callFunctionInBackground("dayTopFive", withParameters: ["day":1]) {
(response: AnyObject?, error: NSError?) -> Void in
if error == nil {
println("Successfully retrieved \(response!.count) scores.")
// This is working:
let objects = response as! NSArray
for object in objects {
println("A top flower is: \(object)")
}
}
}

Related

How to get CGPDFDictionaryRef keys

I would like to get all the keys of an CGPDFDictionaryRef. so far this what I found from stackoverflow
Here is my code in swift:
func printPDFKeys(key: UnsafePointer<Int8>, ob: CGPDFObjectRef, info: UnsafeMutablePointer<()>) -> Void{
NSLog("key = %s", key);
//return (key, ob , info)
}
This function is then called like this.
let myDoc = CGPDFDocumentCreateWithURL(url)
if myDoc != nil {
let myCatalog=CGPDFDocumentGetCatalog(myDoc)
CGPDFDictionaryApplyFunction(myCatalog, printPDFKeys, nil);//Compiler error here
}
However I am getting an error that
a c function pointer can only be formed from a reference to a 'func'
or a literal closure
I have also tried using a Closure like this:
var printPDFKeys: ( UnsafePointer<Int8>, CGPDFObjectRef, UnsafeMutablePointer<()> )-> Void
printPDFKeys={
key,ob,info in
NSLog("key = %s", key);
}
I am still getting the same error. How could I go about it
the correct closure syntax would be:
CGPDFDictionaryApplyFunction(myCatalog, { (key, object, info) -> Void in
// do something
}, nil)

Why is the cloud code function not being called in the iOS application?

I am trying to get the title and artist from a certain user using cloud code. I have a pointer to the user class in the Pointer class. I am trying to get all the title and artists (strings) matched to the current user. For some reason the cloud code is not executing, I am not getting anything in the iOS log. I think the cloud code is working, but I feel I am missing something to send the data back to the iOS app.
iOS code
PFCloud.callFunctionInBackground("search", withParameters: ["user": currentUserID!]) {
(response: AnyObject?, error: NSError?) -> Void in
if(error == nil){
if let objects = response as? [PFObject]{
for object in objects{
print(object)
}
}
}else{
print(error)
}
}
Cloud code
Parse.Cloud.define("search", function(request, response){
var review = Parse.Object.extend("Pointer")
var query = new Parse.Query(review)
var userPointer = {
__type: 'Pointer',
className: '_User', // name of class
objectId: request.params.user
}
console.log(userPointer);
query.equalTo("user", userPointer);
console.log(query.equalTo("user", userPointer));
query.find().then(function(results){
var sum = 0;
for(var i = 0; i < results.length; i++){
sum += results[i].get("title");
sum += results[i].get("artist")
}
response.success(sum / results.length);
}, function(error){
response.error(error)
});
});

How to do a "not in" query in Parse

I'm building a sort of hot or not style app in Swift where the user can vote: HOT, NOT and MAYBE on an image, respectively.
For every time the user gets to a image, they vote by tapping the IBAction, which triggers a query that shows the result of the total votes and total hots from Parse as shown in my code below.
I plan to have 1,000 images.
Can I preload some of the objectIDs that correspond to each respective image, and then when the user votes on the image, the data is already preloaded/queried from parse? How would I go about that? Someone recommended in my previous question to use a NOT IN query in Parse. How do I do a NOT IN query in Parse and how would I go about doing that?
For now, I'm writing a query for each ObjectID which would take 1000 queries from 1000 different images... Obviously unscalable.
Further code explanations:
The swipePosition variable is just a counter that counts which image the user is on. The images being stored are in an Array for now stored on Xcode. Maybe they can be preloaded as well if they are stored on Parse?
(I am only showing the "hotButtonQuery" function, but there is also a Not and Maybe buttonQuery function.)
Is there a way to simply this code so that it's scalable? Because, as of now, there's no way I can scale past 25 images.
func hotButtonQuery() {
if swipePosition == 0 {
var query = PFQuery(className:"UserData")
query.getObjectInBackgroundWithId("RlvK3GhfqE") {
(userData: PFObject!, error: NSError!) -> Void in
if error != nil {
println(error)
}
else {
userData.incrementKey("totalVotes", byAmount: 1)
userData.incrementKey("hot", byAmount: 1)
var updateTotalVotesUILabel = userData.objectForKey("totalVotes") as NSInteger
var updateHotsUILabel = userData.objectForKey("hot") as NSInteger
userData.saveInBackground()
println("parse was updated!")
self.totalVotesLabel.text = String(updateTotalVotesUILabel)
self.totalHotsLabel.text = String(updateHotsUILabel)
}
}
} else if swipePosition == 1 {
var query = PFQuery(className:"UserData")
query.getObjectInBackgroundWithId("30WlVtgurP") {
(userData: PFObject!, error: NSError!) -> Void in
if error != nil {
println(error)
}
else {
userData.incrementKey("totalVotes", byAmount: 1)
userData.incrementKey("hot", byAmount: 1)
var updateTotalVotesUILabel = userData.objectForKey("totalVotes") as NSInteger
var updateHotsUILabel = userData.objectForKey("hot") as NSInteger
//println(userData.objectForKey("totalVotes"))
//println("total HOTs:")
//println(userData.objectForKey("hot"))
userData.saveInBackground()
println("parse was updated!")
self.totalVotesLabel.text = String(updateTotalVotesUILabel)
self.totalHotsLabel.text = String(updateHotsUILabel)
}
}
} else if swipePosition == 3 {
var query = PFQuery(className:"UserData")
query.getObjectInBackgroundWithId("5D6ARjk3xS") {
(userData: PFObject!, error: NSError!) -> Void in
if error != nil {
println(error)
}
else {
userData.incrementKey("totalVotes", byAmount: 1)
userData.incrementKey("hot", byAmount: 1)
var updateTotalVotesUILabel = userData.objectForKey("totalVotes") as NSInteger
var updateHotsUILabel = userData.objectForKey("hot") as NSInteger
//println(userData.objectForKey("totalVotes"))
//println("total HOTs:")
//println(userData.objectForKey("hot"))
userData.saveInBackground()
println("parse was updated!")
self.totalVotesLabel.text = String(updateTotalVotesUILabel)
self.totalHotsLabel.text = String(updateHotsUILabel)
}
}
}
just use
query.whereKey("key", doesNotMatchKey: "matchcheck", inQuery: innerQuery)
An example of Not In:
var query = PFUser.query()
if (friendsFilter){
var friendsRelation:PFRelation = PFUser.currentUser().relationForKey("friendsRelation")
query = friendsRelation.query()
}
else{
var friendsRelation:PFRelation = PFUser.currentUser().relationForKey("friendsRelation")
var innerQuery = friendsRelation.query()
query = PFUser.query()
query.whereKey("username", doesNotMatchKey: "username", inQuery: innerQuery)

Facebook SDK iOS with Swift - Requesting for Friend List - Explanation of the Method

Would anyone be able to explain this method that we should invoke to recieve the friend list?
var fbRequestFriends: FBRequest = FBRequest.requestForMyFriends()
fbRequestFriends.startWithCompletionHandler{
(connection:FBRequestConnection!,result:AnyObject?, error:NSError!) -> Void in
}
Specifically this line
(connection:FBRequestConnection!,result:AnyObject?, error:NSError!) -> Void in
It seems to me like we are calling a function "startWithCompletionHandler", after that I am lost to be honest. I can't understand what happens next. Can anyone please explain this?
Edit:
I understand this is the way to implement it. I'm Actually looking for an intuitive explanation like in this answer:
Method Syntax in Objective C
you can use below code to get the friend list
// Get List Of Friends
var friendsRequest : FBRequest = FBRequest.requestForMyFriends()
friendsRequest.startWithCompletionHandler
{
(connection:FBRequestConnection!, result:AnyObject!, error:NSError!) -> Void in
var resultdict = result as NSDictionary
println("Result Dict: \(resultdict)")
var data : NSArray = resultdict.objectForKey("data") as NSArray
for i in 0 ..< data.count
{
let valueDict : NSDictionary = data[i] as NSDictionary
let id = valueDict.objectForKey("id") as String
println("the id value is \(id)")
}
var friends = resultdict.objectForKey("data") as NSArray
println("Found \(friends.count) friends")
}
Well you can see the result of your request call in the closure that you are passing in . Try printing the result object to console like below .
var fbRequestFriends: FBRequest = FBRequest.requestForMyFriends()
fbRequestFriends.startWithCompletionHandler{
(connection:FBRequestConnection!,result:AnyObject?, error:NSError!) -> Void in
if error == nil && result != nil {
println("Request Friends result : \(result!)")
} else {
println("Error \(error)")
}
}
I have not worked with Swift sdk for Facebook yet but I think result object should be an array of facebook user objects ( friends ) .

StrongLoop Loopback example in Swift

I'm trying to implement the example LoopBack iOS app in Swift
Create a LoopBack iOS app: part one
and I'm having some trouble translating from the ObjectiveC
- (void) getBooks
{
//Error Block
void (^loadErrorBlock)(NSError *) = ^(NSError *error){
NSLog(#"Error on load %#", error.description);
};
void (^loadSuccessBlock)(NSArray *) = ^(NSArray *models){
NSLog(#"Success count %d", models.count);
self.tableData = models;
[self.myTable reloadData];
};
//This line gets the Loopback model "book" through the adapter defined in AppDelegate
LBModelRepository *allbooks = [[booksAppDelegate adapter] repositoryWithModelName:prototypeName];
//Logic - Get all books. If connection fails, load the error block, if it passes, call the success block and pass allbooks to it.
[allbooks allWithSuccess:loadSuccessBlock failure:loadErrorBlock];
};
Here's my version
func getBooks() {
var errorBlock = {
(error: NSError!) -> Void in
NSLog("Error on load %#", error.description)
}
var successBlock = {
(models: NSArray!) -> Void in
NSLog("Success count %d", models.count)
self.tableData = models
self.booksTable.reloadData()
}
// get the "book" model
var allBooks: LBModelRepository = adapter.repositoryWithModelName(prototypeName)
// get all books
allBooks.allWithSuccess(successBlock, errorBlock)
}
but I get a compiler error on the call to allWithSuccess:
Cannot convert the expressions type 'Void' to type 'LBModelAllSuccessBlock!'
What am I missing?
UPDATE:
If I declare the success block as follows, it works:
var successBlock = {
(models: AnyObject[]!) -> () in
self.tableData = models
self.booksTable.reloadData()
}
Thanks for the answer!!!!
If anyone is looking for the last version of Swift and LoopBack iOS SDK, it worked for me like this:
func getBooks() {
// Error Block
let errorBlock = {
(error: NSError!) -> Void in
NSLog("Error on load %#", error.description)
}
// Success Block
let successBlock = {
(models: [AnyObject]!) -> () in
self.tableData = models
self.myTable.reloadData()
}
// This line gets the Loopback model "book" through the adapter defined in AppDelegate
let allBooks:LBPersistedModelRepository = AppDelegate.adapter.repositoryWithModelName(prototypeName, persisted: true) as! LBPersistedModelRepository
// Logic - Get all books. If connection fails, load the error block, if it passes, call the success block and pass allbooks to it.
allBooks.allWithSuccess(successBlock, failure: errorBlock)
}

Resources