Swift:Closure Declaration as Like Block Declaration

swift : Closure declaration as like block declaration

The syntax for function types is (in) -> out.

typealias CompletionBlock = (NSString?) -> Void
// or
typealias CompletionBlock = (result: NSData?, error: NSError?) -> Void
var completion: CompletionBlock = { reason in print(reason) }
var completion: CompletionBlock = { result, error in print(error) }

Note that the parentheses around the input type are only required as of Swift 3+.

swift : Closure declaration as like block declaration

The syntax for function types is (in) -> out.

typealias CompletionBlock = (NSString?) -> Void
// or
typealias CompletionBlock = (result: NSData?, error: NSError?) -> Void
var completion: CompletionBlock = { reason in print(reason) }
var completion: CompletionBlock = { result, error in print(error) }

Note that the parentheses around the input type are only required as of Swift 3+.

Swift escaping block declaration

func queryForParams(completion: @escaping queryCompletionBlock)

Closure containing a declaration cannot be used with function builder 'ViewBuilder'

you shouldn't create a variable inside the SwiftUI builder block, you should create it out of the body scope,

  var isPlaying = false

var body: some View {
Text("Levels \(isPlaying)")
}

Swift UI uses a function builders block that can only contain content that is understandable by the builder.
Then what you should write inside the builder block is only View Type and [View] 
However, if you want to declare a variable you could work around it by introducing it to a new subclass

The purpose of this feature is to enable the creation of embedded DSLs in Swift -- allowing you to define content that gets translated to something else down the line

Also, you could use.

 @State var isPlaying: Bool = false

Note

review your code twice before doing the workaround, probably you have
a misunderstanding about how swift-UI works?

Using closure Swift which is declared as block in Objective C in Swift 2.1

getUserCurrentProfile is an instance method, and you are calling it as a class method. You should call it on an instance of FBManager (sharedInstance maybe?):

FBManager.sharedInstance.getUserCurrentProfile { userInfo, error in)
appDelegate.showHomeView()
}

The error says that it cannot convert the closure to FBManager, and is correct, as you are calling it as a class function and the compiler expects and instance to operate on. The above call could have also been written in the curried function call:

FBManager.getUserCurrentProfile(FBManager.sharedInstance) { userInfo, error in)
appDelegate.showHomeView()
}

Store a closure as a variable in Swift

The compiler complains on

var completionHandler: (Float)->Void = {}

because the right-hand side is not a closure of the appropriate signature, i.e. a closure taking
a float argument. The following would assign a "do nothing" closure to the
completion handler:

var completionHandler: (Float)->Void = {
(arg: Float) -> Void in
}

and this can be shortened to

var completionHandler: (Float)->Void = { arg in }

due to the automatic type inference.

But what you probably want is that the completion handler is initialized to nil
in the same way that an Objective-C instance variable is inititialized to nil. In Swift
this can be realized with an optional:

var completionHandler: ((Float)->Void)?

Now the property is automatically initialized to nil ("no value").
In Swift you would use optional binding to check of a the
completion handler has a value

if let handler = completionHandler {
handler(result)
}

or optional chaining:

completionHandler?(result)

Closures(Swift) to closures(blocks?) in Objective-C

In Objective-C there are Blocks:

If you want to use them as property it goes like:

@property (nonatomic, copy, nullability) returnType (^blockName)(parameterTypes);

Or as method parameters:

- (void)method:(returnType (^nullability)(parameterTypes))blockName;

So for you example it will go like:

@property (nonatomic, copy, nullable) void (^didTimerFire)(UICollectionViewCell);

Closure default initializer missing - swift closure variable declaration?

You have 3 Options

  • default property:

    var completionHandler : completionBlock = { _ in }
  • Implicitly unwrapped Optional - only do this when you are 100% sure a value will be set before ever calling the completionHandler:

    var completionHandler: completionBlock!
  • "regular" Optional

    var completionHandler: completionBlock?

    // later callable via
    completionHandler?("hi")

What is the property block declaration equivalent in swift of the following block property?

The corresponding closure property would be declared as

class MyClass {
var completion : ((MyObject) -> Void)? // or ...! for an implicitly unwrapped optional
}

You can set the property like

completion = {
(obj : MyObject) -> Void in
// do something with obj ...
}

which can be shortened (due to the automatic type inference) to

completion = {
obj in
// do something with obj ...
}

Calling swift closure from Objective-c

According to F*ck*ngBlockSyntax, we write a block as a var that way:

returnType (^blockName)(parameterTypes) = ^returnType(parameters) {...};

var cancelledStateColorHandler: ((NSColor) -> NSColor)? would translated into swift as @property (nonatomic, copy) NSColor * _Nonnull (^ _Nullable cancelledStateColorHandler)(NSColor * _Nonnull);.
To simulate it, check your Project-Swift.h file.

I tested with

@objc class TestClass: NSObject {
@objc
var cancelledStateColorHandler: ((NSColor) -> NSColor)?
}

And got:

SWIFT_CLASS("_TtC10ProjectName9TestClass")
@interface TestClass : NSObject
@property (nonatomic, copy) NSColor * _Nonnull (^ _Nullable cancelledStateColorHandler)(NSColor * _Nonnull);
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

Now, we only focus on the second part of the syntax, since the left part, is yourInstance.cancelledStateColorHandler

^returnType         (parameters              ) {...};
^NSColor * _Nonnull (NSColor * _Nonnull input) {...};

So we got:

yourInstance.cancelledStateColorHandler = ^NSColor * _Nonnull(NSColor * _Nonnull input) { 
//Here that's sample code to show that we can use the input param, and that we need to return a value too.
if ([input isEqual:[NSColor whiteColor]])
{
return [NSColor redColor];
}
else
{
return NSColor.redColor;
}
};


Related Topics



Leave a reply



Submit