Type NSError? does not conform to protocol '_RawOptionSetType' - swift

I have the following statement:
func sessionStateChanged(session:FBSession, state:FBSessionState, error:NSError?) {
// If the session was opened successfully
if error == nil && state == FBSessionStateOpen {
println("Session opened");
}
}
which has the following error on the line of the if-statement:
Type NSError? does not conform to protocol '_RawOptionSetType'
However if I remove the second condition, so the code reads:
if error == nil {
println("Session opened");
}
There is no error. This leads me to believe tat the NSError? type is not the issue and that it has something to do with the multiple conditions.

One way to get clearer error messages might be to start a new if statement inside the first rather than combining with && .

Related

Ambiguous Without More Context Error in Parse Query

I’m experimenting with Parse in a swift app and running through some of the examples but I can’t get the query to run. I’m getting the “ambiguous without more context” error in XCode. Here’s the code:
var query = PFQuery(className: "MyFirstClass")
query.getObjectInBackground(withId: "Jl0SUJWCQg") {
(myFirstClass: PFObject?, error: NSError?) -> Void in
if error == nil && myFirstClass != nil {
print(myFirstClass)
} else {
print(error)
}
}

Confused on Error Handling in Swift 3

I got confused error handling in swift3. I try to do like "if XX function got error then try YY function"
Let me show you what I try:
class MyClass {
enum error: Error
{
case nilString
}
func findURL() {
do {
let opt = try HTTP.GET(url_adr!)
opt.start { response in
if let err = response.error {
print("error: \(err.localizedDescription)")
return //also notify app of failure as needed
}
do
{
/* This is func1. and got error. I want to if this function has error then go next function. */
try self.stringOperation(data: response.description)
}
catch{
print("doesn't work on func1. trying 2nd func")
self.stringOperation2(data:response.descritption)
}
}
} catch let error {
print("got an error creating the request: \(error)")
}
}
func stringOperation(data:String)throws -> Bool{
do{
/** 1 **/
if let _:String = try! data.substring(from: data.index(of: "var sources2")!){
print("its done")
}else{
throw error.nilString
}
IN 1: I got this fatal error on this line:
"fatal error: unexpectedly found nil while unwrapping an Optional value" and program crashed.
I googled error handling try to understand and apply to in my code. However not succeed yet. Can someone explain where did I wrong?
Additional info: I got String extension for .substring(from:...) , and .index(of:"str"). So these lines doesn't got you confused.
As a general rule, try avoiding using force unwrapping (!), where you have
if let _: String= try! data.substring...
Instead use
if let index = data.index(of: "var sources2"),
let _: String = try? data.substring(from: index) { ... } else { ... }
That way you remove the two force unwraps that may be causing your crash. You already have the if let protection for catching the nil value, so you can make the most of it by using the conditional unwrapping.

Know if error exist or not if Swift function

Sometimes the function has this structure:
func prueba(................, error: Error?){
//Code here
//How I can validate if error really exist?
}
If I use if to make error!=nil, always is not true but the error don't exist.
For functions that actually have an optional Error parameter, you can do something like this:
if let error = error {
// there is an error, handle as needed
print("Error: \(error)")
} else {
// no error
}

Difference between error = error vs error != nil

I would like to know is there big difference between
if let error = error{} vs if error != nil? Or is it just how people are different, like how they express themselves in code?
For example if I take this code:
user?.delete { error in
if let error = error {
print(error)
} else {
}
Because I can do the same like this and the output is the same:
user?.delete { error in
if error != nil {
print(error)
}else{
}
The only difference I can see other than "people are different" is that if I do not print error it would be better to use if error != nil because otherwise it would be declaring variable you do not use. Am I right?
As you already recognized at the end of your question, I would agree with you, that I would use if let, if I want to use the error variable to print it out for example. If I would just check if it's not nil and don't need the error variable, I would use if error != nil. You could also do if let _ = error, which is the same as if error != nil as Eric Aya mentioned in the comments of your question

Accessing code in Swift 3 Error

New in Xcode 8 beta 4, NSError is bridged to the Swift Error protocol type. This affects StoreKit when dealing with failed SKPaymentTransactions. You ought to check to be sure the error didn't occur because the transaction was cancelled to know whether or not to show an error message to the user. You do this by examining the error's code. But with Error instead of NSError, there is no code defined. I haven't been able to figure out how to properly get the error code from Error.
This worked in the previous version of Swift 3:
func failedTransaction(_ transaction: SKPaymentTransaction) {
if let transactionError = transaction.error {
if transactionError.code != SKErrorCode.paymentCancelled.rawValue {
//show error to user
}
}
...
}
Now that error is an Error not NSError, code is not a member.
Another option to access code and domain properties in Swift 3 Error types is extending it as follow:
extension Error {
var code: Int { return (self as NSError).code }
var domain: String { return (self as NSError).domain }
}
Now in Xcode 8 and swift 3 the conditional cast is always succeeds, so you need do following:
let code = (error as NSError).code
and check the code for your needs. Hope this helps
Casting to SKError seems to be working for me in xCode 8 and Swift 3...
guard let error = transaction.error as? SKError else {return}
switch error.code { // https://developer.apple.com/reference/storekit/skerror.code
case .unknown: break
case .paymentCancelled: break
case .clientInvalid: break
case .paymentInvalid: break
case .paymentNotAllowed: break
case .cloudServiceNetworkConnectionFailed: break
case .cloudServicePermissionDenied: break
case .storeProductNotAvailable: break
}
No need for rawValue.
This is correct (Apple's own tests use this approach):
if error._code == SKError.code.paymentCancelled.rawValue { ... }
On the other hand, casting to NSError will probably be deprecated soon:
let code = (error as NSError).code // CODE SMELL!!
if code == SKError.code.paymentCancelled.rawValue { ... }
Use
error._code == NSURLErrorCancelled
to match the error code.
A lot is changing. Here's update for Xcode 11.
if let skError = transaction.error as? SKError, skError.code == .paymentCancelled {
print("Cancelled")
}