Parse won't compile - ios

So I'm just trying to set up my new app with parse. I've downloaded their SDK and I've pasted my applicationID. The problem is in push notifications (which I didn't even touch). Can someone please help me?
Thanks
ERROR CODE:
PFPush.subscribeToChannelInBackground("") { (succeeded: Bool, error: NSError?) in
if succeeded {
print("ParseStarterProject successfully subscribed to push notifications on the broadcast channel.\n");
} else {
print("ParseStarterProject failed to subscribe to push notifications on the broadcast channel with error = %#.\n", error)
}
}
}
It says:
Cannot invoke 'subscribeToChannelInBackground' with an argument list
of type '(String, (Bool, NSError?) -> ())'

The code you are showing is to subscribe to notification channel...and it is complaining that it doesn't expect these arguments type.
To set up Parse SDK follow this: https://www.parse.com/apps/quickstart#parse_data/mobile/ios/swift/existing
from the parse getting started guide, this is how they tested the installation was good to go (swift)
let testObject = PFObject(className: "TestObject")
testObject["foo"] = "bar"
testObject.saveInBackgroundWithBlock { (success: Bool, error: NSError?) -> Void in
print("Object has been saved.")
}

Clearly the syntax of the function call is wrong. Follow the function (right click on the function in Xcode and "Jump to definition") to find out which arguments exactly the function expects. I don't know the SDK, but I guess the function takes two arguments - a string and a closure (block). Then you need to use that in your call instead of whatever you are using now.

Related

Running Parse code after another has finished execution

I'm trying to query a class of objects with specific ID's to delete. When I run it however, I get an error for "This query has an outstanding network connection. You have to wait until it's done". I assume this is because I'm trying to delete an object while I'm still accessing it.
I've provided the deletion code in the closure because I'm assuming the closure statements only execute after the function call finishes, yet it's still giving me the error. I've also tried using DispatchGroups because it does seem like a concurrency issue, but I'm not too familiar with their usage yet. Here's my code:
let idList = [...] // Some list of ID's I would like to remove
let query = PFQuery(className: "Pictures")
for id in idList {
query.getObjectInBackground(withId: id) { (object: PFObject?, error:
Error?) in
if error == nil {
img?.deleteInBackground() { (success, error: Error?) ...
}
}
I'm expecting each object associated with an ID in my original IdList to be deleted from the Parse backend. However, it seems that getObjectInbackground() and deleteInBackground() are clashing. If anyone could provide some advice, that would be wonderful!
You can try
var idList = [...]
func delete(_ id:Int) {
query.getObjectInBackground(withId: id) { (object: PFObject?, error: Error?) in
if error == nil {
img?.deleteInBackground() { (success, error: Error?) ...
}
idList = Array(idList.dropFirst())
if !idList.isEmpty {
delete(idList.first!)
}
}
}
Initially call it like
delete(idList.first!)

Cannot convert ... to expected argument type 'PFIdResultBlock?'

In an iOS app using parse-server (on Heroku/mLab), I am having the following issue with a cloud function.
Here is the relevant code:
PFCloud.callFunction(inBackground: "myCloudFunction",
withParameters: ["lastTouch" : theLastTouchStamp]) {
(any: Any, error: Error) in
print("Now Inside Block (myCloudFunction)")
}
Here is the error message I get from the compiler:
Cannot convert value of type '(Any, Error) -> ()' to expected argument type 'PFIdResultBlock?'
I have browsed the net in search for some information, but eventhough I found a couple of related post; nothing led me to a solution.
Does anybody know how to solve this?
Remove the types from the closure:
PFCloud.callFunction(inBackground: "myCloudFunction", withParameters: ["lastTouch" : theLastTouchStamp]) {
(value, error) in
print("Now Inside Block (myCloudFunction)")
}

Kinvey Swift 3 KCSCustomEndpoints

I converted my project to swift 3 and am having issue with the kinvey conversion. I had this before but it now gives me this error: "Cannot convert value of type '(AnyObject!, NSError!) -> Void' to expected argument type 'KCSCustomEndpointBlock!'". How could I fix this issue?
KCSCustomEndpoints.callEndpoint("endpointName", params: params, completionBlock: {
(results: AnyObject!, error: NSError!) -> Void in
if results != nil {
}
})
Mitch94,
This has been escalated to the engineering team for adding Swift 3 example of invoking custom endpoint to the Kinvey documentation.
I will get back to you once I have more information on it.
Thanks,
Pranav
Kinvey Support

completion handler's error in swift 3 and Xcode 8

I have working project in Xcode 7.3 with swift 2.2 version. Now I have updated Xcode 8 and migrated to swift 3. Now my project contains errors specially for blocks like success block of afnetworking.
Which gives error as
Cannot convert value of type '() -> ()' to expected argument type '((URLSessionDataTask, Any?) -> Void)?'
I don't understand how to solve this to work as per swift 3.
And there is also same like error in Facebook login.
Which gives error as
Cannot convert value of type '(FBSDKLoginManagerLoginResult!, NSError!) -> Void' to expected argument type 'FBSDKLoginManagerRequestTokenHandler!'
and
Cannot convert value of type '(_, _, NSError!) -> Void' to expected argument type 'FBSDKGraphRequestHandler!'
This all errors are related to handler blocks in swift 3. I don't understand the errors and so that can't able to solve. Any help will be appreciated. Thanks in advance.
For facebook - the problem is in new Swift rules about converting objective-c function parameters into Swift.
Previously, if parameters in objective-c code did not have nullability attributes(like nonnull or nullable), Swift converts it with ! making them non optional(forced unwrapping). Now it convert it with ? making them optional. That why you are getting an error. Before you were putting as a callback for login:
(FBSDKLoginManagerLoginResult!, NSError!) -> Void
Now you need to put:
(FBSDKLoginManagerLoginResult?, Error?) -> Void
Also, as you see, now you will not see NSError class. Instead of that Swift will put Error.This is also new rule. Now all "NS" prefixed in class names is removed in Swift(NSObject -> Object; NSError -> Error).
Example of working code for facebook login in Swift 3.0:
let manager = FBSDKLoginManager()
manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) {
(loginResult: FBSDKLoginManagerLoginResult?, error: Error?) in
}
Example of working code for facebook request in Swift 3.0:
let request = FBSDKGraphRequest()
request.start {
(connection: FBSDKGraphRequestConnection?, result: Any?, error: Error?) in
}
As you see, now it is using Any type instead of objective-c id. In Swift 2.2 it was using AnyObject. It is also new Swift converting rule.
You do not need to specify callback parameters type. I did that in code for highlighting their real types. So you can just write code without them:
let manager = FBSDKLoginManager()
manager.logIn(withReadPermissions: ["public_profile"], from: self.controller) { (loginResult, error) in }
let request = FBSDKGraphRequest()
request.start { (connection, result, error) in }
But you need to remember that they are optional now.
In conclusion some converting rules that may affect you callback code:
Closure parameters are optional if in objective-c are not specified nullability attributes
All "NS" prefixes is removed for objective-c classes in Swift
If objective-c function had id parameter, in Swift 3.0 it will have type Any instead of AnyObject
Though I didn't know the error before that what Xcode want to inform me about the error, but I have removed type specification with object and it worked.
As
manager.post(methodname, parameters: param, progress: nil, success:{ (dataTask, responseObj) in
if let dict : NSDictionary = responseObj as? NSDictionary {
print("Response of \(methodname) : \(dict)")
if dict.object(forKey: "response") as? String == "success" {
CompletionHandler(true, dict)
} else {
CompletionHandler(false, dict)
}
}
})
Here with respect to question error is given at dataTask and responseObj which are with type specified. After removing type it worked fine.
Same as with facebook login
#IBAction func fbLoginClicked(_ sender: AnyObject) {
let app = UIApplication.shared.delegate as! AppDelegate
app.fbLoginManager = FBSDKLoginManager()
app.fbLoginManager.logOut()
app.fbLoginManager.loginBehavior = FBSDKLoginBehavior.native
app.fbLoginManager.logIn(withReadPermissions: ["email"], from: self, handler: { (result, error) -> Void in
if error != nil {
print(error?.localizedDescription)
} else {
if (result! as FBSDKLoginManagerLoginResult).isCancelled == true {
} else {
self.fetchFacebookUserDetail()
}
}
})
}
Here also I have removed type specification of result and error and problem solved. And followed this in whole app and it worked. I can run the project without error and also it is working. Thanks.

Cannot invoke 'saveInBackgroundWithBlock'

I've checked the syntax a gazillion times here, on GitHub, parse.com & elsewhere, without any luck. The problem is when I'm calling saveInBackgroundWithBlock for PFObject I get the the following error:
Cannot invoke 'saveInBackgroundWithBlock' with an argument list of type '((Bool, NSError) -> Void)'
I'm on Xcode 6.3 beta 2. All frameworks are loaded to the project (including Bolts & Parse, but not provided by parse.com ParseCrashReporting & ParseUI), <Parse/Parse.h> & even <Bolts/Bolts.h> are brought through the Bridge Header.
var score = PFObject(className: "score")
score.setObject("Rob", forKey: "name")
score.setObject(95, forKey: "scoreNumber")
score.saveInBackgroundWithBlock {
(success: Bool!, error: NSError) -> Void in
if success == true {
println("Score created with ID: \(score.objectId)")
} else {
println(error)
}
}
Any thoughts?
The error parameter is supposed to be an implicitly unwrapped optional, but not the success one:
(success: Bool, error: NSError!) -> Void in
^ ^
However unless you need to specify the type for whatever reason, I suggest you to use the closure simply as:
(success, error) in
less prone to type declaration errors.
In Swift 1.2 the declaration of .saveInBackgroundWithBlock should look like this:
Void saveInBackgroundWithBlock(block: PFBooleanResultBlock?(Bool, NSError?) -> Void)
So it should have been as follows:
score.saveInBackgroundWithBlock {
(success: Bool, error: NSError?) -> Void in
The method wants the success and error variables set like this with the ! on the error:
(success: Bool, error: NSError!)
^ ^
But you've set the ! to the wrong variable:
(success: Bool!, error: NSError)
As you see here:

Resources