SwiftyUserDefaults
SwiftyUserDefaults copied to clipboard
[Xcode 13.3] builtin extensions are missing
Problem
struct SomeStruct: Codable, DefaultsSerializable {}
=> type 'SomeStruct' does not conform to protocol 'DefaultsSerializable'
In Xcode 13.3, I can't build my apps about DefaultsSerializable.
struct SomeStruct: Codable, DefaultsSerializable {
public static var _defaults: DefaultsCodableBridge<SomeStruct> { .init() }
public static var _defaultsArray: DefaultsCodableBridge<[SomeStruct]> { .init() }
}
=> Build succeed
Then I added some default extension's implementations.
This problem is occurred about RowRepresentable, NSCoding, or more.
WHY
https://github.com/sunshinejr/SwiftyUserDefaults/blob/master/Sources/BuiltIns.swift extensions are missing?
Xcode 13.3 Beta 1
They're not missing. If you look at the build errors in the logs, it actually says something like:
ambiguous inference of associated type 'Bridge': 'DefaultsCodableBridge<Foo>' vs. 'DefaultsRawRepresentableBridge<Foo>'
matching requirement '_defaults' to this declaration inferred associated type to 'DefaultsCodableBridge<Foo>'
matching requirement '_defaults' to this declaration inferred associated type to 'DefaultsRawRepresentableBridge<Foo>'
In my testing, this only happens if the extensions with the default implementations are in another module. It looks like a compiler bug to me.
@robinkunde Thank you for your help 🙏
Filed here https://bugs.swift.org/browse/SR-15807
same with Xcode 13.3 Beta 3
same with RC, maybe a fix is needed here!
A simple workaround is change dependency to source code
Hi everyone,
This workaround worked for me:
- Create
SwiftyUserDefaults+Workaround.swiftin the module which is usingSwiftyUserDefaults. - Copy the codes below into
SwiftyUserDefaults+Workaround.swift
import SwiftyUserDefaults
import Foundation
extension DefaultsSerializable {
public static var _defaultsArray: DefaultsArrayBridge<[T]> { return DefaultsArrayBridge() }
}
extension Date: DefaultsSerializable {
public static var _defaults: DefaultsObjectBridge<Date> { return DefaultsObjectBridge() }
}
extension String: DefaultsSerializable {
public static var _defaults: DefaultsStringBridge { return DefaultsStringBridge() }
}
extension Int: DefaultsSerializable {
public static var _defaults: DefaultsIntBridge { return DefaultsIntBridge() }
}
extension Double: DefaultsSerializable {
public static var _defaults: DefaultsDoubleBridge { return DefaultsDoubleBridge() }
}
extension Bool: DefaultsSerializable {
public static var _defaults: DefaultsBoolBridge { return DefaultsBoolBridge() }
}
extension Data: DefaultsSerializable {
public static var _defaults: DefaultsDataBridge { return DefaultsDataBridge() }
}
extension URL: DefaultsSerializable {
#if os(Linux)
public static var _defaults: DefaultsKeyedArchiverBridge<URL> { return DefaultsKeyedArchiverBridge() }
#else
public static var _defaults: DefaultsUrlBridge { return DefaultsUrlBridge() }
#endif
public static var _defaultsArray: DefaultsKeyedArchiverBridge<[URL]> { return DefaultsKeyedArchiverBridge() }
}
extension DefaultsSerializable where Self: Codable {
public static var _defaults: DefaultsCodableBridge<Self> { return DefaultsCodableBridge() }
public static var _defaultsArray: DefaultsCodableBridge<[Self]> { return DefaultsCodableBridge() }
}
extension DefaultsSerializable where Self: RawRepresentable {
public static var _defaults: DefaultsRawRepresentableBridge<Self> { return DefaultsRawRepresentableBridge() }
public static var _defaultsArray: DefaultsRawRepresentableArrayBridge<[Self]> { return DefaultsRawRepresentableArrayBridge() }
}
extension DefaultsSerializable where Self: NSCoding {
public static var _defaults: DefaultsKeyedArchiverBridge<Self> { return DefaultsKeyedArchiverBridge() }
public static var _defaultsArray: DefaultsKeyedArchiverBridge<[Self]> { return DefaultsKeyedArchiverBridge() }
}
extension Dictionary: DefaultsSerializable where Key == String {
public typealias T = [Key: Value]
public typealias Bridge = DefaultsObjectBridge<T>
public typealias ArrayBridge = DefaultsArrayBridge<[T]>
public static var _defaults: Bridge { return Bridge() }
public static var _defaultsArray: ArrayBridge { return ArrayBridge() }
}
extension Array: DefaultsSerializable where Element: DefaultsSerializable {
public typealias T = [Element.T]
public typealias Bridge = Element.ArrayBridge
public typealias ArrayBridge = DefaultsObjectBridge<[T]>
public static var _defaults: Bridge {
return Element._defaultsArray
}
public static var _defaultsArray: ArrayBridge {
fatalError("Multidimensional arrays are not supported yet")
}
}
This is pretty much a copy from the BuiltIns.swift file in the Sources folder: https://raw.githubusercontent.com/sunshinejr/SwiftyUserDefaults/master/Sources/BuiltIns.swift
I just removed the last part due to an error that I didn't spend too much time to solve. Just removed this piece of code and the app compiled successfully.
extension Optional: DefaultsSerializable where Wrapped: DefaultsSerializable {
public typealias Bridge = DefaultsOptionalBridge<Wrapped.Bridge>
public typealias ArrayBridge = DefaultsOptionalBridge<Wrapped.ArrayBridge>
public static var _defaults: DefaultsOptionalBridge<Wrapped.Bridge> { return DefaultsOptionalBridge(bridge: Wrapped._defaults) }
public static var _defaultsArray: DefaultsOptionalBridge<Wrapped.ArrayBridge> { return DefaultsOptionalBridge(bridge: Wrapped._defaultsArray) }
}
This was based on a workaround shared here: https://github.com/sindresorhus/Defaults/issues/93#issuecomment-1053183113
FYI: in our project codebase that only using DefaultsSerializable with Codable, this small workaround code adding to main module is resolved compiler error too. But this is not maybe fit to all of the case.
extension DefaultsSerializable where Self: Codable {
typealias Bridge = DefaultsCodableBridge<Self>
typealias ArrayBridge = DefaultsCodableBridge<[Self]>
}
FYI: in our project codebase that only using
DefaultsSerializablewithCodable, this small workaround code adding to main module is resolved compiler error too. But this is not maybe fit to all of the case.extension DefaultsSerializable where Self: Codable { typealias Bridge = DefaultsCodableBridge<Self> typealias ArrayBridge = DefaultsCodableBridge<[Self]> }
Thanks, this avoided a ton of compiler warnings
can we update a new version and get this done?
This worked for me, having had classes/structs using RawRepresentable or Codable paired with DefaultsSerializable:
extension DefaultsSerializable where Self: Codable {
public typealias Bridge = DefaultsCodableBridge<Self>
public typealias ArrayBridge = DefaultsCodableBridge<[Self]>
}
extension DefaultsSerializable where Self: RawRepresentable {
typealias Bridge = DefaultsRawRepresentableBridge<Self>
typealias ArrayBridge = DefaultsRawRepresentableArrayBridge<[Self]>
}
Added this to our global constants file, got rid of the issues related to this post.
why not release new version to fix this bug
I checked Xcode 14 Beta ([email protected]) was resolved this problem!
I checked this bug was resolved in Xcode 14 RC too! So close this issue! Thanks!