Swift compiler crashes on associatedtype in @objc protocol
Associated types are Swift-only feature, not visible to Objective-C, so there should be compiler error.
Filed a bug https://bugs.swift.org/browse/SR-3850
Inherit from @objc protocol
From swift-users, seems like a known issue, to be fixed: https://bugs.swift.org/browse/SR-1175
Also now reported as https://bugs.swift.org/browse/SR-3882
Swift Protocol Oriented Networking code crashing Xcode
A crashing compiler is a bug and should be reported. Xcode 9 (beta) does not
crash with your code but gives helpful error messages leading to a solution:
error: generic parameter 'Content' could not be inferred
WebService().load(resource: RepoService) { res in
^
The generic placeholder Content
in class WebService<Content>
is
not used at all, remove it and make the class non-generic. Then:
error: generic parameter 'R' could not be inferred
WebService().load(resource: RepoService) { res in
^
You have to pass an instance of RepoService
to the load
method,
and res
inside the closure is an optional.
With these changes
final class WebService {
func load<R: Resource>(resource: R, completion: @escaping (R.Content?) -> ()) {
URLSession.shared.dataTask(with: resource.url) { data, _, _ in
let res = data.flatMap(resource.parse)
completion(res)
}.resume()
}
}
WebService().load(resource: RepoService()) { res in
guard let res = res else { return }
for elem in res {
print(elem)
}
}
your code compiles and runs as expected, in Xcode 8.3.3 and 9.
Swift 2.2 #selector in protocol extension compiler error
I had a similar problem. here is what I did.
- Marked the protocol as @objc.
- Marked any methods I extended with a default behavior as optional.
Then used Self. in the #selector.
@objc public protocol UpdatableUserInterfaceType {
optional func startUpdateUITimer()
optional var updateInterval: NSTimeInterval { get }
func updateUI(notif: NSTimer)
}
public extension UpdatableUserInterfaceType where Self: ViewController {
var updateUITimer: NSTimer {
return NSTimer.scheduledTimerWithTimeInterval(updateInterval, target: self, selector: #selector(Self.updateUI(_:)), userInfo: nil, repeats: true)
}
func startUpdateUITimer() {
print(updateUITimer)
}
var updateInterval: NSTimeInterval {
return 60.0
}
}
protocol with same associated type name
Another workaround is to create a third, combined protocol:
protocol ReadWrite {
associatedtype R
associatedtype W
func read() -> R
func write(a: W)
}
It's not pretty, since it forces you to redeclare the protocol members, but it does keep it generic (you're not limited to String and Int).
Related Topics
Inner Didset Protection Bizarrely Extends to The Whole Class
Nsmanagedobjectcontext's Propagatesdeletesatendofevent Set to False Causes Error on Save
Carthage Update Error: "Github API Request Failed: Bad Credentials"
Answers by Crashlytics - Adding Custom Event
Dynamic Dispatching Protocol Extension Doesn't Work Multiple Targets
Cannot Decode Object of Class (Ampathpopupbutton)'
Navigationlink Doesn't Work with New .Searchable Modifier on Swiftui 3.0
Load Viewcontroller Swift - Black Screen
Swift Cannot Convert The Expression's Type 'Void' to Type 'string!'
Different UIfont Sizes for Different iOS Devices in Swift
Check If Class Has a Value for a Key
Swift Type Inference and Type Checking Issue
Testing a Timer in Xcode with Xctest
How to Access to a Static Cell
How to Use Publishers.Combinelatest to Get 1 Publisher
Levenshtein Distance in Swift3
Access Id Does Not Work When Testing a Textfield with 'Issecuretextentry = True'
How to Get The Coordinates of The Point on a Line That Has The Smallest Distance from Another Point