Skip to main content
added 131 characters in body
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

Since the initializer ensures that both name and address are assigned a value, you don't have to declare them as optionals.

The currentUser(), setCurrentUser(), removeCurrentUser() methods can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. static means class final, i.e. it is a property of the type (and not an instance) and cannot be overridden in subclasses.

The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String
    public let address: String
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

If you change the initializer to

public init?(dictionary: [String : Any])

then you can pass a native Swift dictionary without casting, e.g.

User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

Since the initializer ensures that both name and address are assigned a value, you don't have to declare them as optionals.

The currentUser(), setCurrentUser(), removeCurrentUser() methods can be replaced by a static property

public static var currentUser: User?

if you make the initializer public.

The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String
    public let address: String
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

If you change the initializer to

public init?(dictionary: [String : Any])

then you can pass a native Swift dictionary without casting, e.g.

User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

Since the initializer ensures that both name and address are assigned a value, you don't have to declare them as optionals.

The currentUser(), setCurrentUser(), removeCurrentUser() methods can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. static means class final, i.e. it is a property of the type (and not an instance) and cannot be overridden in subclasses.

The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String
    public let address: String
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

If you change the initializer to

public init?(dictionary: [String : Any])

then you can pass a native Swift dictionary without casting, e.g.

User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])
deleted 136 characters in body
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

Since the initializer ensures that both name and address are assigned a value, you don't have to declare them as optionals.

The currentUser(), setCurrentUser(), removeCurrentUser() canmethods can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. 

The two guard statements can can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String?
    public let address: String?
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be simply set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

More thoughts:

  • The initializer ensures that both name and address are set, to there is no need to make the properties optional

      public let name: String
      public let address: String
    

unlessIf you want to allowchange the initializer to unset them later.

  • If you change the initializer to

      public init?(dictionary: [String : Any])
    
public init?(dictionary: [String : Any])

then you can pass a native Swift dictionary without casting, e.g.

    User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

The currentUser(), setCurrentUser(), removeCurrentUser() can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String?
    public let address: String?
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be simply set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

More thoughts:

  • The initializer ensures that both name and address are set, to there is no need to make the properties optional

      public let name: String
      public let address: String
    

unless you want to allow to unset them later.

  • If you change the initializer to

      public init?(dictionary: [String : Any])
    

then you can pass a native Swift dictionary without casting, e.g.

    User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

Since the initializer ensures that both name and address are assigned a value, you don't have to declare them as optionals.

The currentUser(), setCurrentUser(), removeCurrentUser() methods can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. 

The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String
    public let address: String
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

If you change the initializer to

public init?(dictionary: [String : Any])

then you can pass a native Swift dictionary without casting, e.g.

User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])
Source Link
Martin R
  • 24.2k
  • 2
  • 38
  • 96

(I am referring to the Swift code only.)

You can declare a property as

public private(set) var name: String?

to make it public read-only, but internally read-write. That makes the additional accessor getName() obsolete.

If the property is only assigned in the init method and never changed later, you can simply make it constant:

public let name: String?

The currentUser(), setCurrentUser(), removeCurrentUser() can be replaced by a static property

public static var currentUser: User?

if you make the initializer public. The two guard statements can be combined into one.

The class then looks like this:

public class User {
    
    public static var currentUser: User?
    
    public let name: String?
    public let address: String?
    
    public init?(dictionary: [String : AnyObject]) {
        
        guard let name = dictionary["name"] as? String,
            let address = dictionary["address"] as? String
        else { return nil }
        
        self.name = name
        self.address = address
    }
}

The "current user" can now be simply set, retrieved, and unset like this:

User.currentUser = User(dictionary: ...)
if let user = User.currentUser {
    // ...
}
User.currentUser = nil

More thoughts:

  • The initializer ensures that both name and address are set, to there is no need to make the properties optional

      public let name: String
      public let address: String
    

unless you want to allow to unset them later.

  • If you change the initializer to

      public init?(dictionary: [String : Any])
    

then you can pass a native Swift dictionary without casting, e.g.

    User.currentUser = User(dictionary: ["name": "Joe", "address": "San Francisco"])