Вопрос по Автовозобновляемой подписке

swift
xcode
ios

#1

(дебютное приложение)

В приложении есть покупка - Автовозобновляемая подписка.

В первой версии (и до сих пор) я при покупке сохраняю с PayViewController

`userDefaultsL.set (true, forKey: "alreadyPaid")` 

А потом в ViewController где происходит выбор “Открыть доступ” или “Не открыть доступ” к контенту я проверяю этот самый “alreadyPaid” на соответствие true - если true - контент открыт, false - закрыт

То что это совсем не так как следовало бы — это я уже понял.
Сейчас добавил проверку даты оформления подписки и today на предмет закончилась ли она.

В этом плане с не продляемыми подписками вроде понятно - вышел срок - покупай новую. А вот как быть с автопродляемыми подписками?

Возможно что для начала нужно проверить закончился ли срок подписки,
потом выяснить прошла ли очередная транзакция или нет - отменил пользователь подписку или нет.
Либо есть способ сразу от Apple получить ответ действует ли подписка или нет…

Поделитесь опытом Как это реализовать?
Заранее признателен.


#2

Добрый день. У Вас получилось это реализовать на swift3?


#3

Нет… третьи сутки вокруг этой задачи. Есть идеи?


#4
  1. Посмотрите здесь, может будет что-то полезное:
    https://www.youtube.com/playlist?list=PLToZZkMSuXIQ5bygvm5nhT86M0m7gBQ2i

  2. Вы в своем коде используете класс NSDate? С переходом на Swift3 у меня ошибки для этого класса, тк появился класс Date. Пока что нет понимания, это одно и тоже или нет((


#5

у меня не сработала проверка даты как в курсе указано
сделал так:

// create default container cloudKit
let cloudStore = NSUbiquitousKeyValueStore.default()

if let expirationDate = cloudStore.object(forKey: "expDate") {
    let today = NSDate()
    let expireDate = expirationDate as! NSDate
    
    switch today.compare(expireDate as Date) {
      case .orderedAscending: //раньше окончания срока
        print("Подписка действует")
        alreadyPaid = true

      default:
        print("Подписка закончилась или ее нет--")

        break
    }

    print("сегодня \(today) ")
    print("окончание \(expireDate) ")
    
} else {
    alreadyPaid = false
}

#6

Спасибо, попробую!
А что Вы сделали с этой частью кода:

//дата окончания подписки
func setExpireDate() {
let today = NSDate()

let dateComponent = NSDateComponents()
dateComponent.setValue(1, forComponent: NSCalendarUnit.Month)

let expirationDate = NSCalendar.currentCalendar().dateByAddingComponents(dateComponent, toDate: today, options: NSCalendarOptions())

Ошибка из-за NSDate и Date компонентов. Пока что не могу разобраться(
https://drive.google.com/open?id=0B5kQjFFo8RHjbkNVeGR0RXhHQnM4Y1Y2ME5WUnJwdFFnS2Nz


#7

Я весь блок проверки времени поменял на тот что указал выше. Т.е. тот метод что указан в курсе я реализовать не смог и заменил его полностью другим.

а функция которая задает время выглядит у меня так:

func setExpireDate () {                
    let today = Date()
    
    let expirationDate = NSCalendar.current.date(byAdding: Calendar.Component.month, value: 1, to: today)
    
    let cloudStore2 = NSUbiquitousKeyValueStore.default()
    cloudStore2.set(expirationDate, forKey: "expDate")
    cloudStore2.synchronize()
}

#9

В функции setExpireDate Вы перестаете использовать следующие 2 строки, см ниже. Так и должно быть?
let dateComponent = NSDateComponents()
dateComponent.setValue(1, forComponent: NSCalendar.Unit.month)

В курсе функция setExpireDate изначально выглядела так:
func setExpireDate() {
let today = NSDate()
let dateComponent = NSDateComponents()
dateComponent.setValue(1, forComponent: NSCalendar.Unit.month)
let expirationDate = NSCalendar.current.date(byAdding: dateComponent, to: today)
let cloudStore = NSUbiquitousKeyValueStore.default()
cloudStore.setObject(expirationDate, forKey: “expDate”)
cloudStore.synchronize()


#10

Да
Эта другая реализация


#12

Спасибо! Ошибки исчезли, сборка собралась:) Удалось выполнить покупку, используя тестового пользователя. Все сработало корректно. Для теста поставил срок покупки на 1 минуту вместо месяца. То есть, через минуту опять появилась кнопка “Купить”, а кнопка с переходом к контенту исчезла. НО когда нажимаешь кнопку “Купить”, появляется сообщение с подтверждением встроенной покупки, нажимаю “Купить” и он пишет, что “Вы уже купили эту подписку”. Так и должно работать с тестовым пользователем? Или что-то пошло не так…


#13

Вы же установили 1 мин. не срок подписки, а срок проверки.
А срок подписки в App Store установлен. Поэтому метод проверяет существующие транзакции и восстанавливает покупку.


#15

Добрый день!
В функции setExpireDate вместо month установил 1 минуту:
let expirationDate = NSCalendar.current.date(byAdding: Calendar.Component.minute, value: 1, to: today)
Это же вроде не срок проверки, а функция установления даты истечения подписки? Поэтому через минуту появляется опять кнопка “Купить”, но непонятно, почему при повторной покупке он пишет, что товар уже куплен. Если это ошибка, то будет не очень хорошо, если опубликую так в AppStore и пользователи, купив 1 раз, далее смогут продлевать бесплатно))
В non-renewable subscription в iTunes Connect нет параметра “длительность”. Он устанавливается только для products с автоматическим продлением подписки.


#16

Срок подписки хранит Apple - поэтму восстанавливат ее бесплатно

В функции setExpireDate вместо month установил 1 минуту:
let expirationDate = NSCalendar.current.date(byAdding: Calendar.Component.minute, value: 1, to: today)

эта функция как раз и отвечает за срок проверки в случае с non-renewable, и как следствие за длительность подписки.


#17

То есть, через 30 дней (месяц) Apple перестанет восстанавливать бесплатно, даже если в коде написано ‘minute’?
let expirationDate = NSCalendar.current.date(byAdding: Calendar.Component.minute, value: 1, to: today)


#18

по идее да… я так думаю. Сам буду проверять эмпирическим путем.

Не возьмусь категорично заявлять (пусть более опытные коллеги меня поправят если что…), но если я правильно понимаю то весь процесс проверки будет состоять из двух частей:

1 проверка срока действия подписки (реализована в коде, сравнивает сегодня и дату окончания подписки - если не закончилась - открывает контент (или что там еще может быть)

2 если подписка закончилась - идет проверка существующих транзакций на стороне Apple … вот тут я не очень то уверен как это будет работать. Я в этом случае запускаю метод

            SKPaymentQueue.default().restoreCompletedTransactions()

по задумке он должен восстановить покупки если они есть действующие.


#19

Огромное Вам спасибо за ответы! Подумаю, почитаю еще про эту тему. У меня еще 1 вопросик… Возможно Вы сталкивались.

  1. Если запустить приложение без подключения к интернету и нажать кнопку “Купить”, приложение вылетает.
  2. Если запустить приложение без интернета, когда оно запустилось, включить интернет и нажать кнопку “Купить”, оно вылетает
  3. Если запустить приложение с подключенным интернетом, то всё срабатывает корректно при нажатии кнопки “Купить”.
    Не сталкивались с таким?

#20

с таким не сталкивался… я бы искал в методах покупки - они без сети не работают.


#21

Спасибо!

С уважением,
Роман