Reputation: 3209
So I'm defining an objc method:
@objc func networkCall(action: NetworkAction) { //Error: Method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C
switch action {
case .post:
print("Posting")
case .get:
print("Getting")
case .delete:
print("Deleting")
case .update:
print("Updating")
}
}
That I would like to call here:
postButton.addTarget(self, action: #selector(networkCall(action: .post)), for: .touchUpInside) //Error: Argument of '#selector' does not refer to an '@objc' method, property, or initializer
Is it possible to pass enums as a parameter to objc?
Upvotes: 1
Views: 793
Reputation: 18924
You can fix your @objc
error from this link.
But you still face the problem for passing value to the parameter.
You can use the subclass of the UIButton.
Here is the demo
Custom Button Class
class CustomButton: UIButton {
var networkAction: NetworkAction = .post
}
Target Method
@objc func networkCall(sender: CustomButton) {
switch sender.networkAction {
case .post:
print("Posting")
case .get:
print("Getting")
case .delete:
print("Deleting")
case .update:
print("Updating")
}
}
Usage
let postButton = CustomButton()
postButton.networkAction = .post
postButton.addTarget(self, action: #selector(networkCall(sender:)), for: .touchUpInside)
Another approach you can use the tag.
enum NetworkAction: Int {
case post = 0
case get = 1
case delete = 2
case update = 3
}
@objc func networkCall(sender: UIButton) {
switch NetworkAction(rawValue: sender.tag) {
case .post:
print("Posting")
case .get:
print("Getting")
case .delete:
print("Deleting")
case .update:
print("Updating")
case .none:
print("none")
}
}
let postButton = UIButton()
postButton.tag = 0
postButton.addTarget(self, action: #selector(networkCall(sender:)), for: .touchUpInside)
You can simply use the addAction
instead of the target.
button.addAction(UIAction(handler: { [weak self] action in
self?.networkCall(sender: .post)
}), for: .touchUpInside)
Upvotes: 1
Reputation: 52538
You can move the enum itself into an Objective-C header file. Swift can use Objective-C enum without problems, but obviously without Swift features. That’s obviously unpleasant, so if possible you would convert the caller to Swift and move the enum back to the Swift file where it belongs.
Upvotes: 0
Reputation: 51945
You can make use of a enum raw value instead in this case.
Change the enum to have raw values, like an Int for example
enum NetworkAction: Int {
case post
case get
case delete
case update
}
Then change the signature of the method to take that raw value instead and inside the function you can convert it to an enum item
@objc func networkCall(action: NetworkAction.RawValue) {
let enumAction = NetworkAction(rawValue: action)
switch enumAction {
case .post:
print("Posting")
case .get:
print("Getting")
case .delete:
print("Deleting")
case .update:
print("Updating")
case .none: //If the above init(rawValue:) returned nil
fatalError("Unknow raw value sent: \(action)")
}
}
This fixes the @objc related error but note that you can not pass a custom argument when using #selector
Upvotes: 1