Swift closure as AnyObject
How can I cast
()->()
intoAnyObject
?
Warning: This answer includes undocumented and unsafe feature in Swift. I doubt this passes AppStore review.
let f: ()->() = {
println("test")
}
let imp = imp_implementationWithBlock(
unsafeBitCast(
f as @objc_block ()->(),
AnyObject.self
)
)
Convert a swift closure into a block
It should be something like this:
-(void) testMethod:(void(^) (id gbRequest, ServiceStatus *serviceStatus, id response) ) blockName {
}
Swift's AnyObject equivalent is id in Objective-C.
Swift Cast AnyObject to Block
The best way to handle this situation is to create your own typealias for your block:
typealias MyFunBlock = @objc_block (dataResponse :AnyObject!) -> Void;
Then you can use that to unsafebitcast:
var block: MyFunBlock = unsafeBitCast(completeBlock, MyFunBlock.self) as MyFunBlock;
Closure inference in Swift
I don't think this has anything to do with closures or inference. It seems to be a simple matter of types and casting.
You cannot "sideways cast" an AnyObject to a Dictionary (or to anything else for that matter). You have to force-cast it, using as!
Plus, there is no such thing in Swift as a Dictionary plain and simple, because it is a generic. The most general type of dictionary is [AnyHashable:Any]
.
So the initial cast of s
needs to be:
(s as! [AnyHashable:Any])
And by the same token you cannot "sideways cast" the resulting value taken from the dictionary; you must force-cast it:
as! [AnyObject]
Now you can write the whole line as:
return (s as! [AnyHashable:Any])["availabilities"] as! [AnyObject]
Of course, what you're doing here seems completely crazy; you should not be turning anything into an AnyObject. But perhaps this is a toy example drawn from some other context, e.g. you've got JSON coming in? But in that case you should be using Codable to organize the JSON into real objects.
Pass a swift closure to an objective-C function which takes a block as parameter
I think this could be a shortcut to your problem:
func session(session: WCSession, didReceiveMessage message: [String : AnyObject], replyHandler: ([String : AnyObject]) -> Void){
let objCObject = ObjectiveCClass()
objCObject.fetchChannelListForWatch { (dict) -> Void in
replyHandler(dict as! [String : AnyObject]?)
}
}
Swift closure as values in Dictionary
Your basic problem is that in Objective-C closures (aka blocks) are represented as NSObject (or more precisely are transparently converted to NSObjects) while in Swift there is no such mapping. This means that closures can not be directly stored in a Dictionary (short of using objective-c glue)
The closest I can come up with is something along the lines of wrapping the value in an enum:
enum DataType {
case AsString(String)
case AsClosure((AnyObject)->String)
}
var dict:Dictionary<String,DataType> = [
"string":DataType.AsString("value"),
"closure":DataType.AsClosure({(argument:AnyObject) -> String in
return "value"
}
)
]
Which is probably a better solution anyway, because this way you have an explicit typing associated with individual arguments instead of it being implicit using some sort of inflection.
Alternatively, you could only wrap the closure and use a dictionary of type Dictionary<String,Any>
.
Convert Swift 2 closure to Objective-C block
EDIT : As of Swift 3, this is completely unnecessary (and doesn't even work). Adding closures to Objective-C arrays works out of the box in Swift 3. The answer below is valid for Swift 2 only.
I know this is a duplicate but I will still post a refactored answer from swift-closure-as-anyobject and cast-closures-blocks in case anyone lands on this one first.
The solution is to use the unsafeBitCast
function to convert the Swift closure to an Objective-C compatible object before adding it to an NSArray
and back before using it in Swift.
// The `@convention(block)` is important here in order to get
// Objective-C like memory management
typealias CompletionBlock = @convention(block) () -> Void
let aBlock:CompletionBlock = {
print("Hello world!")
}
let nsArray = NSMutableArray()
let blockObject = unsafeBitCast(aBlock, AnyObject.self)
nsArray.addObject(blockObject)
let closureObject = nsArray[0]
let closure = unsafeBitCast(closureObject, CompletionBlock.self)
closure()
Related Topics
Playing an Audio File Repeatedly with Avaudioengine
How to Pass in a Void Block to Objc_Setassociatedobject in Swift
Audiokit - How to Get Real Time Floatchanneldata from Microphone
What Are the First Two Columns in Scnmatrix4
Custom Sequence for Swift Dictionary
How to Get the Correct Current Time in iOS
How to Auto Call an @Ibaction Function
Swiftui Tabbedview Only Shows First Tab's Content
How to Use a Generic Class Without the Type Argument in Swift
Custom Uitoolbar Too Close to the Home Indicator on iPhone X
Alamofireimage Disk Cache Not Working
How to Use Gadbannerviewdelegate to Perform Action on Adviewdidreceivead
Show Two Different Custom Cells in Same Uitableview - Swift Firebase
How to Add a Ibaction to a Button Programmatically in Swift 4
How to Check If Device Orientation Is Landscape Left or Right in Swift
Swift Socket.Io .Emit() Doesn't Fire
Receipt Validation on iOS In-App-Purchase Returns Multiple Transaction