Jody Heavener Jody Heavener - 1 year ago 229
Objective-C Question

How does this #define work in Swift?

I am new to iOS and am trying to tackle learning Swift (and a bit of Objective C) by converting a library I found to the former. So far I'm doing alright, but am having trouble understanding one part; how this

is supposed to work:

#define RunSafeBlock(block, ...) block ? block(__VA_ARGS__) : nil

Here it is with more context:

#import <AFNetworking.h>

// How would I write this in Swift?
#define RunSafeBlock(block, ...) block ? block(__VA_ARGS__) : nil

@interface Client ()

@implementation Client
- (void)requestWithBodyBlock:(void (^)(id<AFMultipartFormData> formData))bodyBlock completion:(ClientRequestCompletion)completion {
[self validateAccessToken:^(NSError *error) {
if (error) {
// What does RunSafeBlock do?
RunSafeBlock(completion, nil, error);

// ...

parts are not really relevant, but in this example we're performing a request and validating an access token. If
returns an error, we pass everything to
and exit out. Here we are in Swift:

import AFNetworking

// #define RunSafeBlock(block, ...) block ? block(__VA_ARGS__) : nil

class Client {
func requestWithBodyBlock(bodyBlock: (formData: AFMultipartFormData) -> Void, completion: ClientRequestCompletion) {
self.validateAccessToken({(error: NSError) -> Void in
if error != nil {
// RunSafeBlock(completion, nil, error)

// ...

I would really appreciate some guidance. Thanks in advance!

Answer Source

This macro is doing a null-check.

In Swift, unless you declare a variable as Optional, it cannot be null, so you do not have to do this check in Swift (and if it was Optional, you'd use optional unwrapping).

So just go ahead and call the completion.

(It seems the same reasoning would also apply to error. Don't you get a compile error there?)

(Also consider using the Swift version of AlamoFire).

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download