Success & failure block written in Objective C, showing error in swift - ios

I have made a success & failure block in objC and I am trying to use that function in swift. Getting error, I'm stuck on it please help me.
Objective C :
-(void)registerAppWithSuccessBlock:(void (^)(id responseObject))success andFailureBlock:(void (^)(NSError *error))failure{}
I am calling the same function in swift its showing error.
Swift :
USSecService.sharedInstance().registerAppWithSuccessBlock({(responseObject : AnyObject) -> Void in{code}
}, andFailureBlock: { (error : NSError) -> Void in {code}
})
Getting this Error :
Cannot invoke 'registerAppWithSuccessBlock' with an argument list of type '((AnyObject) -> Void, andFailureBlock: (NSError) -> Void)'

USSecService.sharedInstance().registerAppWithSuccessBlock({ (responseObject) -> Void in
print("Success")
}, andFailureBlock: { (error) -> Void in
print("Failure")
})

You don't need to specify the argument type in those closures. Change your swift code like below:
Without second closure label syntax:
USSecService.sharedInstance().registerAppWithSuccessBlock({ (responseObject) -> Void in
// Your success code
}){ (error) -> Void in
// Your error code
}
or
With second closure label syntax:
USSecService.sharedInstance().registerAppWithSuccessBlock({ (responseObject) -> Void in
// Your success code
}, andFailureBlock: ({ (error) -> Void in
// Your error code
}))

Related

Unable to use then on ios swift promisekit

I created a promise which gets some data from API and returns it. Now what i am stuck is after getting the json data i need to store them on device storage (realm). After calling the promise when i try with then i get some error stating Cannot convert value of type '(Any) -> Void' to expected argument type '(_) -> _' . But when i try with done it works perfectly. But i need to use then to save the data on realm.
Following approch works fine
Translator().translators().done { data -> Void in
print(data[0].name)
}.catch { error in
print(error)
}
But following two approach fails
Translator().translators().then() { data -> Void in
print(data)
}.catch() {
(e: Error) in
print(e)
}
Above gives an error that says
Cannot convert value of type '(Any) -> Void' to expected argument type '(_) -> _'
and following approach gives another similar error
Translator().translators().then() {
(data: [Translator]) -> Void in
print(data[0].name)
}.catch() {
(e: Error) in
print(e)
}
error message:
Cannot convert value of type '([Translator]) -> Void' to expected argument type '([Translator]) -> _'
Promise i created:
func translators() -> Promise<[Translator]> {
return firstly {
Alamofire.request("http://192.168.0.107:3000/translatdors", method: .get).responseData()
}.map {
try JSONDecoder().decode([Translator].self, from: $0.data)
}
}
Image of my code and error
You have to return a promise when you do .then because until .done you are not finished. I don't see any issue in saving realm data in .done as your method has no return type.
Incase you still want to use .then, it can be done this way.
Translator().translators().then({ data -> Promise<[Translator]> in
return Promise.value(data)
}).done({ data in
// Save to realm
}).catch({ error in
print(error.localizedDescription)
})

Call Swift completion handler in objective c

I am trying to call a swift method, which is implemented like this:-
#objc class DataAPI: NSObject {
func makeGet(place:NSString , completionHandler: (String! , Bool!) -> Void)
{
var str:String = ""
let manager = AFHTTPSessionManager()
manager.GET("https://api.com", parameters: nil, success:
{ (operation, responseObject) -> Void in
str = "JSON: \(responseObject!.description)"
print(str)
completionHandler(str,false) //str as response json, false as error value
},
failure: { (operation,error: NSError!) in
str = "Error: \(error.localizedDescription)"
completionHandler("Error",true)
})
}}
Now when I am trying to call it in my Objective C class, it is throwing an error "No Visible interface for DataAPI declares selector makeGet:completionHandler"
This is how I am calling the method in my Objective C class:-
[[DataAPI new] makeGet:#"" completionHandler:^{
}];
Try to clean and Rebuild to generate the "YourModule-Swift.h" again with all your changes.
Then it should be something like this:
[[DataAPI new] makeGet:#"" withCompletionHandler:^(NSString* string, BOOl b){
// your code here
}];
If you still getting that error, your "YourModule-Swift.h" file hasn't been generated correctly. Check it!
I see that in Swift the completion handler has two arguments: String and Bool whereas in your Objective-C call you pass a block without any arguments. I think it may be the cause of the error.
Try:
[[DataAPI new] makeGet:#"" completionHandler:^(NSString* string, BOOl b){
}];
You shouldn't use !(ImplicitUnwrappedOptional) keyword in closure. That is not allow bridging to ObjC code. just remove ! from closure.
func makeGet(place:NSString , completionHandler: (String! , Bool!) -> Void)
to
func makeGet(place:NSString , completionHandler: (String , Bool) -> Void)

AFHTTPRequestOperation setCacheResponseBlock Cannot convert value of type

I’m using AFHTTPRequestOperation in swift like this :
let operation : AFHTTPRequestOperation? = manager.GET(requestURL, parameters: nil,
success: { (operation:AFHTTPRequestOperation!, responseObject:AnyObject!) -> Void in
...
...
...
success(downloadedItems: responseObject)
}, failure: { (operation: AFHTTPRequestOperation!, error: NSError!) in
failure(responseFromCache: responseFromCache, error: error);
})
and I’m using setCacheResponseBlock for application specific purpose (ETag etc.)
operation!.setCacheResponseBlock { (connection: NSURLConnection, cachedResponse: NSCachedURLResponse) -> NSCachedURLResponse in
print("Returns:200")
responseFromCache = false
return cachedResponse
}
Everything was OK until updating XCode to new version XCode7.1.
Here is my problem, I get this error when I build my application after update :
Cannot convert value of type '(NSURLConnection, NSCachedURLResponse) -> NSCachedURLResponse' to expected argument type '((NSURLConnection!, NSCachedURLResponse!) -> NSCachedURLResponse!)!'
How to fix this?
After checking error message I understand something wrong with my parameters. I check method’s declaration in XCode and I understand method’s declaration just updated :
func setCacheResponseBlock(block: ((NSURLConnection!, NSCachedURLResponse!) -> NSCachedURLResponse!)!)
I updated my method like this :
operation!.setCacheResponseBlock { (connection: NSURLConnection!, cachedResponse: NSCachedURLResponse!) -> NSCachedURLResponse! in
print("Returns:200")
responseFromCache = false
return cachedResponse
}
and another happy ending with build succeeded message in Xcode. Hope this will help someone.

MagicalRecord saveWithBlock usage now fails to compile under XCode 7 beta 5

I just updated to beta 5 of XCode 7 and am now getting a compliation error on the following Swift code:
MagicalRecord.saveWithBlock({ (localContext : NSManagedObjectContext!) in
// ... Save models here ...
}, completion: { (success : Bool, error : NSError!) in
// ... Handle completion here ...
})
Under previous builds of XCode 7, this compiled fine, but I'm now getting:
Cannot invoke 'saveWithBlock' with an argument list of type '((NSManagedObjectContext!) -> (), completion: (Bool, NSError!) -> ())'
I've tried adding -> Void (as autocompleted when I try to add the call afresh) and -> Void! to the parameters, but see the same error.
Is this a language change or a bug in this XCode build?
EDIT (5.42pm ETC 08/08/2015): Calling savedWithBlock without the completion handler appears to compile ok:
MagicalRecord.saveWithBlock { (localContext: NSManagedObjectContext!) -> Void in
// ... Save models here ...
}
EDIT (8.32am ETC 08/11/2015): Following recommendation by #Gerd Castan, I also tried changing the completion parameter to:
completion: { (success : Bool, error : ErrorType!)
and
completion: { (success : ObjCBool, error : ErrorType!)
Both of which gave the same error.
This appears to be fixed with XCode 7 Beta 6. The syntax:
MagicalRecord.saveWithBlock({ (localContext: NSManagedObjectContext!) -> Void in
// Save model here
}) { (success: Bool, error: NSError!) -> Void in
// Handle result here
}
Compiles without error.
Apple replaced NSError with ErrorType.
Replace your own explicit usage of NSError with ErrorType to avoid this type of compiler errors.

Swift Error - extra argument 'option' in call for SimpleAuth

Hi I have been battling with a swift error as I cannot match the arguments of an objective-c method
SimpleAuth.authorize("instagram",
options: ["scope" : "likes"], completion: {
(responseObject : NSDictionary!, error : NSError!) -> Void in
self.accessToken = responseObject["credentials"]["token"]
......
})
//error Extra argument 'options' in call
Declared as:
+ (void)authorize:(NSString *)provider options:(NSDictionary *)options completion:(SimpleAuthRequestHandler)completion;
Code completion is :
SimpleAuth.authorize(<#provider: String!#>, options: <#[NSObject : AnyObject]!#>, completion: <#SimpleAuthRequestHandler!##(AnyObject!, NSError!) -> Void#>)
I have tried type casting, down casting, declaring as a separate variables, but still cant get it to work.
Any ideas, will be much appreciated
It's your definition of your completion block. SimpleAuthRequestHandler is defined as:
typedef void (^SimpleAuthRequestHandler) (id responseObject, NSError *error);
But your completion block/closure is defined as:
(responseObject : NSDictionary!, error : NSError!) -> Void in
You can't just change the type from id (AnyObject in Swift) to NSDictionary! without explicitly casting it. Your call should look something like this:
SimpleAuth.authorize("instagram", options: ["scope" : "likes"], completion: {
(responseObject : AnyObject!, error : NSError!) -> Void in
/* ... */
})
You can then make responseObject an NSDictionary with a cast:
var response = responseObject as NSDictionary

Resources