blocks in swift error - ios

I am trying to convert my objectiveC application into swift and i am able to do it most of the things but here is some confusion ...
My ObjectiveC code is
-(void)getResponseFromURL:(NSString *)strURL
withParams:(NSMutableDictionary *)dictParams
success:(void (^)(AFHTTPRequestOperation *operation, id responseObject, bool isSuccess))blockSuccess
failure:(void (^)(AFHTTPRequestOperation *operation, NSError *error))blockFailure
showLoader:(BOOL)isShowDefaultLoader
showAnimated:(BOOL)isShowLoaderAnimated hideLoader:(BOOL)isHideDefaultLoader
{ //some code here }
My Swift code
func getResponseFromURL(strURL: String, withParams dictParams:Dictionary,
Success:(operation:AFHTTPRequestOperation, responseobject:AnyObject, isSucces:Bool)->void,
Failure:(operation:AFHTTPRequestOperation, error:NSError)->void,
showLoader isShowDefaultLoader:Bool,
showAnimated isShowLoaderAnimated:Bool, hideLoader isHideDefaultLoader:Bool){
// Some code here
}
but it gives me some error
I think i missed some tricks...but i don't know what was that...
So how to get rid of this error?

In Swift, use Void, not void
Dictionary in Swift is Generic, you need specify it as Dictionary<AnyObject, AnyObject> or use NSDictionary directly. You can convert NSDictionary to Swift Dictionary following this answer
Update:
Thanks to Aviel Gross, use [AnyObject: AnyObject] instead of Dictionary<AnyObject, AnyObject>
As code of WenchenHuang shows, () is the same with Void in Swift, both represent empty tuple.

func getResponseFromURL(strURL: String, withParams dictParams:NSDictionary,
Success:(operation: AFHTTPRequestOperation, responseobject:AnyObject, isSucces:Bool)->(),
Failure:(operation: AFHTTPRequestOperation, error:NSError)->(),
showLoader isShowDefaultLoader:Bool,
showAnimated isShowLoaderAnimated:Bool, hideLoader isHideDefaultLoader:Bool){
// Some code here
}

In Swift it's Void. The "V" must be uppercase.

Related

convert obj-c block to swift 2 closure

I have the following code -
[self.camera capture:^(LLSimpleCamera *camera, UIImage *image, NSDictionary *metadata, NSError *error) {
if(!error) {
}
}];
which, to me, should translate to
self.camera.capture({(camera: LLSimpleCamera, image: UIImage, metadata: [NSObject : AnyObject], error: NSError) -> Void in
if !error {
}
})
but it's throwing all the errors about 'cannot convert value of type etc, between the front and the return Void in section. Can someone tell me, is this a place when you have to use unSafeMutablePointers? If so, how would i know that.
Thanks!
The problem is that these are nullables, so you need exclamation marks. So:
self.camera.capture {
(camera:LLSimpleCamera!, image:UIImage!, metadata:[NSObject : AnyObject]!, error:NSError!) -> Void in
// whatever
}
Or more compactly, just omit the types and let Swift infer them from the Objective-C declaration:
self.camera.capture {
camera, image, metadata, error in
// whatever
}
Also, you can't say !error in Swift, but you can cross that bridge when you come to it.

"Parameter name omitted" Error when migrate objc to swift , dealing with closure

I'm migrating my object-c project to swift, I can use closure for block , but there is error "Parameter name omitted", I have to add the paramater by my self, instead of generated automatically by xcode
here is my swift closure code, the closure has parameters
func GET(urlSting:String!,
parameters:[String: AnyObject]?,
success:((responseObject:AnyObject?) -> Void)?,
failure:((error:NSError?) -> Void)?){
// somethings
}
here is my code generated in project-Swift.h, block has no parameter
- (void)GET:(NSString * __null_unspecified)urlSting
parameters:(NSDictionary<NSString *, id> * __nullable)parameters
success:(void (^ __nullable)(id __nullable))success
failure:(void (^ __nullable)(NSError * __nullable))failure;
here is my code in objc.m, block has no parameter,
[[APIClientS sharedClient] GET:"www.google.com/xxxx"
parameters:nil
success:^(id _Nullable) {
} failure:^(NSError * _Nullable) {
}];
I need to add the parameters by myself,
failure:^(NSError * _Nullable error)
It is really a boring work , how can I generate the parameter name automatically ??
Edit -2015-11-22 09:48:24
Answer Bobj-C's Question:
what do you mean "block has no parameter" ?
As the Following the Pic show, the block not have parameter error, I have to add it by myself

using objective-c with swift : cannot invoke 'function' with an argument list of type

let's say I have in my objective-c this:
typedef void (^DirectionBlock)(NSArray *steps, NSError *error);
-(void)requestWithStartPoint:(CLLocationCoordinate2D)start endPoint:(CLLocationCoordinate2D)end travelMode:(NSString*)travel language:(NSString*)lng result:(DirectionBlock)resultBlock;
to call requestWithStartPoint in objective-c it will look like this:
Direction *direction = [[Direction alloc] init];
[direction requestWithStartPoint:startPoint endPoint:endPoint travelMode:#"driving" language:#"en" result:^(NSArray *steps, NSError *error) {
if (!error) {
NSLog(#"RESULT: %#", [steps[0] description]);
}
}];
I used this converter here t get the swift equivalent and I got this:
var direction: Direction = Direction()
direction.requestWithStartPoint(startPoint, endPoint: endPoint, travelMode: "driving", language: "en", result: {(steps: [AnyObject], error: NSErrorPointer) in if !error {
NSLog("RESULT: %#", steps[0].description())
}
})
But I got this error:
Cannot invoke 'requestWithStartPoint' with an argument list of type '(CLLocationCoordinate2D, endPoint: CLLocationCoordinate2D, travelMode: String, language: String, result: ([AnyObject], NSErrorPointer) -> _)'
I have a feeling it has something to do with NSArray pointer being converted to [AnyObject]. Any ideas how to solve this ?
thanks to #Aderstedt comment, by verifying method signature I found it used [AnyObject]! and NSError! and not [AnyObject] and NSErrorPointer.

Converting Obj C to Swift Error:type of expression is ambiguous without more context

I've been using an objC framework in my swift project so I'm converting an objC method to swift. The objC method is as follows:
[[MySingleton sharedInstance] provisionUserWithPIN:pin
organizationID:kOrgID
accessToken:kOrgToken
completion:^(NSString *UID, User *user) {
}];
My swift conversion is:
MySingleton.sharedInstance().provisionUserWithPIN(pin, organizationID: kOrgID, accessToken: kOrgToken) {(UID: String, user: User) in
}
I'm getting an Error:type of expression is ambiguous without more context pointed after the ( in provisionUserWithPIN.
I don't know what I'm doing wrong. Been stuck with this for hours.
Declaration:
- (void)provisionUserWithPIN:(NSString *)PIN organizationID:(NSString *)organizationID accessToken:(NSString *)accessToken completion:(void (^)(NSString *UID, User *user))completion;
You should note that a parameter declared like this in Objective-C
(NSString *)something
does not becomes this in Swift
something:String
but it actually is translated into this:
something:String!
So you can invoke your Objective-C method in Swift writing
MySingleton.sharedInstance().provisionUserWithPIN(
"pin",
organizationID: "orgID",
accessToken: "accessTken") { (UID: String!, user: User!) -> () in
}
Hope this helps.

Convert Objective-C block to Swift

I am simply trying to convert this Objective-C block to swift but there seems to be a problem, I am unable to solve. None of the variables are optional.
Objective-C - Works
[CLPlacemark hnk_placemarkFromGooglePlace:place
apiKey:YOUR_API_KEY
completion:^(CLPlacemark *placemark, NSString *addressString, NSError *error) {
}];
Swift - Gives error
CLPlacemark.hnk_placemarkFromGooglePlace(placeAtIndexPath(indexPath),"YOUR_API_KEY",
completion:{ (placemark:CLPlacemark!, addressString: NSString!, error: NSError!) -> Void in
})
Error Message:
Cannot invoke 'hnk_placemarkFromGooglePlace' with an argument list of type '(HNKGooglePlacesAutocompletePlace!, String, completion: (CLPlacemark!, NSString!, NSError!) -> Void)'
Swift Method Signature
CLPlacemark.hnk_placemarkFromGooglePlace(place:
HNKGooglePlacesAutocompletePlace!, apiKey:String!, completion:
((CLPlacemark!, String!, NSError!) -> Void)
Swift bridges NSString to String in blocks. You still use NSString in your callback, but should use String.
If you're using Swift 1.2 (or maybe even 1.1) String and NSString are compatible, but the compiler requires that you cast them. Think something like: NSString(string: mySwiftString) or String(myNSString). The error shows that you're using both a String and NSString, make sure you're using the right one in the right places.

Resources