Search code examples
iosswiftin-app-purchase

Get duration of a `SKProduct` in Apple Subscriptions


The backend for my app needs two things along with receipt validation to ensure a user has access to a subscription. A subscriptionStartTimestamp and a subscriptionDuration. I was wondering if SKProduct offers something like this, and I stumbled upon SKProduct.subscriptionPeriod which contains a numberOfUnits and a unit. This unit could be day, month or other stuff.

Then another question hit me; "does Apple always consider a month 30 days?", "what about leap years?". How can I found a subscriptionDuration for a SKProduct?


Solution

  • I found this.

    According to the answer mention above, I designed a function which takes a SKProduct and returns a duration for the subscription.

    private func subscriptionDuration(product: SKProduct) -> TimeInterval {
    
        let currentDate = Date()
            
        guard let subscriptionPeriod = product.subscriptionPeriod else {
            return 0
        }
        
        let numberOfUnits = subscriptionPeriod.numberOfUnits
        let unit = subscriptionPeriod.unit
        
        var calendarComponent: Calendar.Component? = nil
        
        switch unit {
            
        case .day:
            calendarComponent = .day
            
        case .month:
            calendarComponent = .month
            
        case .week:
            calendarComponent = .weekOfYear
            
        case .year:
            calendarComponent = .year
            
        default:
            break
            
        }
        
        guard let component = calendarComponent else {
            return 0
        }
        
        let calendar = Calendar(identifier: .iso8601)
        
        guard let newDate = calendar.date(byAdding: component, value: numberOfUnits, to: currentDate) else {
            return 0
        }
        
        return newDate.timeIntervalSince1970 - currentDate.timeIntervalSince1970
    }