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.swift
in 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
DefaultsSerializable
withCodable
, 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!