skip to Main Content

I have a production-ready app where I need to run some code only on users with the previous versions installed but not on new installations. For instance, if 1.0 is the latest version in the AppStore and 2.0 is the new one that will introduce code that needs to run only on users with version 1.0 but not on new users.

e.g.

if isExistingUser{
    // run code
}

What would be the best way to run some code only for existing users? How can one determine whether it’s a new or existing user?

3

Answers


  1. Chosen as BEST ANSWER

    Here is what I came up with that I think works for 95-98% of the users. What I'm doing is basically comparing the date when the Documents folder was created and the date when version2 will be released. The only issue I see with this method is for users installing the app between the date you specified as the release date and the actual App Store release date. In other words, if you specify a date of June, 5 as the release date but the app isn't really approved until the 7th, users who installed the app on the 6th will be missed.

    Ideally and it's what I will start doing is what @Rudedog suggested, basically saving the versions to keep track of what version a user has.

     /// - Returns: Returns true if it's a new user otherwise returns false.
    func isExistingUser()->Bool{
        var isExistingUser:Bool?
        var appInstallationDate:Date?
        
        /// Set the date when the version two is released.
        var dateComponents = DateComponents()
        dateComponents.year = 2022
        dateComponents.month = 06
        dateComponents.day = 4
        let userCalendar = Calendar.current
        let versionsTwoReleaseDate = userCalendar.date(from: dateComponents)
        
        /// Get the date of when the documents folder was created to determine when the app was installed.
        let documentsDirectory = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask).first
        if let creationDate = (try? documentsDirectory!.resourceValues(forKeys: [.creationDateKey]))?.creationDate{
            appInstallationDate = creationDate
        }
        /// Compare dates
        if appInstallationDate! < versionsTwoReleaseDate!{
            // print("It's existing user")
            isExistingUser = true
        }else{
            // print("It's NEW user")
            isExistingUser = false
        }
        return isExistingUser!
    }
    

  2. I see this often and knowing how to do this can be extremely valuable, especially when doing something like introducing a new feature that changes the experience your previous users had.

    There are a few approaches you can take depending on your needs.

    Firstly, you could create a boolean variable in your user model class that is set during user registration in the standard user registration flow and indicates that this is a newly created user – and name it something like isNewOnVersionTwo which will indicate this user is a new user on this new version.

    Code Example:

    class User: Decodable { 
                    
        var uid: string! 
        var username: string!  
        var isNewOnVersionTwo: Bool = false 
    }
             
    class RegistrationViewController: UIViewController { 
                     
        var user: User!  
        var isNewOnVersionTwo: Bool = false 
                           
        override func viewDidLoad() {
           super.viewDidLoad()
                      
           user.isNewOnVersionTwo = true              
        }
    }
    
    class HomeViewController: UIViewController {
                
       var user: User!
                    
       override func viewDidLoad() {
          super.viewDidLoad()
                
          isNewOnVersionTwo == true ? normalInit() : showOldUserAView()
       }
                
       func normalInit() {
    
          // Run normal functions for the 'HomeViewController' or do nothing.
       }
                
       func showOldUserAView() {
    
           //Do something specific for only old users. 
        }
    }
    

    You can choose whether you want to hold onto this variable permanently or not – it could be useful for tracking the new users you’ve gained on this version versus the previous versions – and you could send it to your database along with the rest of the data from your user model.

    A second and cleaner approach…
    Could be to only set the boolean on the very last view controller of the registration flow and pass it to the home view controller when you push the user to the view controller.

    Like this:

    class ViewControllerOne: UIViewController {
    
         var isNewOnVersionTwo: Bool = false 
    
         private func pushToNewViewController() {
    
            let vc = HomeViewController()
            vc.isNewOnVersionTwo = true 
            navigationController?.pushViewController(vc, animated: true)
         } 
    }
    
    class HomeViewController: UIViewController { 
    
        var isNewOnVersionTwo: Bool = false 
    
        override func viewDidLoad() {
           super.viewDidLoad()
                    
           isNewOnVersionTwo == true ? normalInit() : showOldUserAView()
        }
                    
        func normalInit() {
    
           // Run normal functions for the 'HomeViewController' or do nothing.
        }
                    
        func showOldUserAView() {
    
           //Do something specific for only old users. 
         }
     }
    

    I wouldn’t take the approach of using UserDefaults for the few following reasons:

    1. Devices occasionally wipe this randomly and it’s not as reliable as hardcoding a flag in the source code.

    2. UserDefaults isn’t available for a few moments on cold app launches / initial startup which can complicate things, varying on when you want to show the older users whatever you want to show them.

    Login or Signup to reply.
  3. Does your app create any data? Maybe files in the Documents directory, or maybe a UserDefaults key? If so, check for the presence of one of those things very early in launch, which will signal to you that this must be an upgrade and you should do your thing.

    A lot of people store the app’s CFBundleShortVersionString Info.plist key into UserDefaults at launch, which makes it easy to know the last version that was run and let you write the logic of what needs to happen to migrate from that version to the new version. This is something you might want to think about doing in future versions.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search