Limiting functionality usage per month in Swift

Viewed 73

There are a lot of apps that allow the user to use a functionality a certain number of times per month. And when the quota is reached that functionality is blocked till the end of the month.

I am trying to do the same thing and I seem to have run into a bit of a problem.

struct Data{
    var text:String
    var date:Date
}

var array : [Data] = [
        Data(text: "Cars", date: Date()),
        Data(text: "Bikes", date: Date()),
        Data(text: "Trucks", date: Date())
    ]

func countForCurrentMonth(date: Date) -> Int{
    let currentMonth = Calendar.current.component(.month, from: date)
    print(currentMonth)
    var datesArray = [Int]()
    for item in array{
        let month = Calendar.current.component(.month, from: item.date)
        if month == currentMonth{
            datesArray.append(month)
        }
    }
    let itemCount = datesArray.count
    return itemCount
}


func addItem(){
    
    if countForCurrentMonth(date:Date()) > 120{
      //functionality locked
        print("subscribe to unlock")
   }else{
       //allowed
        print("allowed")
   }
}


The problem is here, the date property is compared with Date() which gives the users system date. As the users system date can be manually set, one could easily by bypass this limitation.

So my question is, how can I implement the same thing without using the system date and which doesn't require an internet connection.

One of the things that I tried was keeping a stored date on the device and every time the user opens the app it checks the system date and if it's not equal to the stored date incrementing the day count and replacing the stored date with the new date. However, this would only work if the user opens the app everyday of the month.

2 Answers

I don't think that there is a proper solution for this without an internet connection but you cloud also save the latest registered date your app has been used with. This way you could check if the current date is earlier and lock your app for instance and try to fetch the correct timestamp online, if possible.

But it may be possible this leads to other issues when the user travels and changes his timezone for example but generally this solution should work.

One option would be to store the date and have it be a crucial component. That way if a user was cheating, when compared to other users the date would be too far in the future to count in the app against the competition. Then you would just store the latest date and any earlier date would invalid the session or lock the progress of the app. For instance you could say apply changes to the user account if current date < item date. This could be a problem if you update all users every few seconds. But, in that case you'd probably be online. In this case it seems you want to limit by month though. So even if the user applied 120 changes this month and another 120 changes next month, the changes would only be valid in that next month. So they still get the number of changes applied in that month. Or the first 120 of them. Also, you may want to check the year while you're looking for valid dates.

Related