Property Wrapped Value if accessed from other files give non optional type

// MARK: UserDefault Property Wrapper


@propertyWrapper
struct UserPreferenceField<T : Codable> {
    let key: UserPreferenceFieldKey
    var wrappedValue : T? {
        get {
            guard let decodedData = UserDefaults.standard.value(forKey: key.rawValue) as? Data else { return nil }
            return try? JSONDecoder().decode(T.self, from: decodedData)
            
        }
        set {
            do {
                let encodedValue = try JSONEncoder().encode(newValue)
                 UserDefaults.standard.set(encodedValue, forKey: key.rawValue)
            } catch {
                 print("Error in saving codable value - \(error.localizedDescription)")
            }
        }
    }
    
    init(key:UserPreferenceFieldKey) {
        self.key = key
        
    }
}


enum UserPreferenceFieldKey : String {
   
    case userSelectedTags = "MLQUserSelectedTags"
    case userLastActivePlalist = "MLQUserLastActivePlalist"
    case userLastActivePlayableEntityMeta = "MLQUserLastActivePlayableEntityMeta"
    case currentUSer
    
}


struct HarkAppPreference {
    
    @UserPreferenceField(key: .userSelectedTags)
    static var userSelectedTags: [MLQTag]
    
    @UserPreferenceField(key: .userLastActivePlalist)
    static var userLastActivePlaylist: [PlayableEntity]
    
    @UserPreferenceField(key: .userLastActivePlayableEntityMeta)
    static var userLastActivePlayableEntityMeta: LastPlayableEntityMeta
    
    @UserPreferenceField(key: .currentUSer)
    static var user: User
    
}


This is my PropertyWrapper which I created to use for saving data to UserDefault, this worked to my expectations to use the value with optional chaining if used from within the file where I have written the PropertyWrapper code.

But this given an error Initializer for conditional binding must have Optional type, not 'User' when used in another file like below

class ABC {

    func sss(){
        if let _ = HarkAppPreference.user { // here is gives errorwhen used in other file but work ok if used in same file

        }
    }

}
Answered by ankitfromnull in 398869022

on Xcode 11.2.1 it compiled for me and worked too if I use it from file1.swift

I took your code, cut out all the extraneous stuff, and added my best guess as to the definition of the

User
type. The end result was this:
// file1.swift

import Foundation

@propertyWrapper
struct UserPreferenceField<T: Codable> {

    init(key: UserPreferenceFieldKey) {
        self.key = key
    }

    let key: UserPreferenceFieldKey

    var wrappedValue : T? {
        get { fatalError() }
        set { fatalError() }
    }
}


enum UserPreferenceFieldKey: String {
    case currentUser
}

struct User: Codable {
    var name: String
}

struct HarkAppPreference {

    @UserPreferenceField(key: .currentUser)
    static var user: User?
}
// file2.swift

import Foundation

class ABC {
    func sss(){
        if let _ = HarkAppPreference.user {

        }
    }
}

This compiles for me (using Xcode 11.3). The key difference is line 32 of

file1.swift
, where I declare the property type to be
User?
not
User
. Without that,
file1.swift
wouldn’t compile at all, even if I removed
file2.swift
.

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"

ps DTS is closed 21 Dec through 1 Jan.

Accepted Answer

on Xcode 11.2.1 it compiled for me and worked too if I use it from file1.swift

Property Wrapped Value if accessed from other files give non optional type
 
 
Q