I have created a SPM package with a bunch of old Objective-C code (I want to convert some old code "Objective-C code with a big bridging header" into "Objective-C in some SPM packages") For most of the cases it works OK except for Objective-C categories like:
@import Foundation;
@interface NSURL (Additions)
@property (copy, readonly) NSDictionary<NSString *, NSString *> *queryParams;
@end
Problem: Property queryParams
is NOT available in Swift on URL
types but only on NSURL
types. This looks odd to me because when declaring the same category in an App and using the bridging header file, then queryParams
is also usable from URL
type too.
Tests/URLUtilsTests/URLUtilsTestsSwift.swift:18:31: error: value of type 'URL' has no member 'queryParams'
let queryParams = url.queryParams
~~~ ^~~~~~~~~~~
error: fatalError
Question: What do I need to have queryParams
in both NSURL and URL while using SPM?
I have created a repo in GitHub with reproducing problem
This is a screenshot of my entire package:
I asked the same question in Swift forums and I got the reason why this is not working.
NSURL and URL are not the same type. The first is a class, the second a struct. ObjC categories or Swift extensions to one do not apply to the other.
There's a runtime "magic" that ties them together, though. It is the URL conformance to ReferenceConvertible 5, and much probably some non-public tricks. But this does not make them the same type.
So the only solution is to have a special target for swift code.
import URLUtils
extension URL {
var queryParams: [String: String] {
(self as NSURL).queryParams
}
}
I have updated my original repository source code to and it works ok now!.