Курс 4 Встроенные покупки. Урок 12

iap
swift
icloud
xcode

#1

Все перепроверил 1000 раз. Механизм покупки работает, но информация не сохраняется в iCloud. При каждом новом запуске приложения нужно повторно совершать покупку. Помогите пожалуйста.

import UIKit
import StoreKit

class Cat1TableViewController: UITableViewController, SKProductsRequestDelegate, SKPaymentTransactionObserver {

@IBOutlet weak var releaseBut1_5: UIButton!
@IBOutlet weak var releaseBut1_6: UIButton!
@IBOutlet weak var releaseBut1_7: UIButton!
@IBOutlet weak var releaseBut1_8: UIButton!
@IBOutlet weak var releaseBut1_9: UIButton!
@IBOutlet weak var releaseBut1_10: UIButton!
@IBOutlet weak var paymentBut: UIButton!

var productToPurchase = SKProduct()

override func viewDidLoad() {
    super.viewDidLoad()
    
    self.navigationItem.backBarButtonItem = UIBarButtonItem(title: "", style: UIBarButtonItemStyle.Plain, target: nil, action: nil) //убераем тайтл в кнопке "назад"
    
    let cloudStore = NSUbiquitousKeyValueStore.defaultStore() //контейнер для записи в айклауд
    
    //сверяем дату
    if let expirationDate = cloudStore.objectForKey("expDate") {
        
        let today = NSDate() //сегодняшняя дата
        let expireDate = expirationDate as! NSDate //дата в айклауд
        NSLog("ExpirationDate is \(expireDate) and today is \(today)")
        
        //сравниваем дату сегодня и окончания подписки
        if today.earlierDate(expireDate) == true {
            
            releaseBut1_5.enabled = false
            releaseBut1_5.hidden = true
            
            releaseBut1_6.enabled = false
            releaseBut1_6.hidden = true
            
            releaseBut1_7.enabled = false
            releaseBut1_7.hidden = true
            
            releaseBut1_8.enabled = false
            releaseBut1_8.hidden = true
            
            releaseBut1_9.enabled = false
            releaseBut1_9.hidden = true
            
            releaseBut1_10.enabled = false
            releaseBut1_10.hidden = true
            
            paymentBut.enabled = false
            paymentBut.hidden = true
        }
        
    }
    
    releaseBut1_5.enabled = true
    releaseBut1_5.hidden = false
    
    releaseBut1_6.enabled = true
    releaseBut1_6.hidden = false
    
    releaseBut1_7.enabled = true
    releaseBut1_7.hidden = false
    
    releaseBut1_8.enabled = true
    releaseBut1_8.hidden = false
    
    releaseBut1_9.enabled = true
    releaseBut1_9.hidden = false
    
    releaseBut1_10.enabled = true
    releaseBut1_10.hidden = false
    
    paymentBut.enabled = true
    paymentBut.hidden = false
    
    getProductInformation()
    SKPaymentQueue.defaultQueue().addTransactionObserver(self)
}

//отправляем запрос в appstore
func getProductInformation() {
    if SKPaymentQueue.canMakePayments() {
        let productIDs: Set<String> = ["28.03.1989"]
        let request = SKProductsRequest(productIdentifiers: productIDs)
        request.delegate = self
        request.start()
    }
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

//SKProductsRequestDelegate protocol
func productsRequest(request: SKProductsRequest, didReceiveResponse response: SKProductsResponse) {
    //обрабатываем ответ
    let products = response.products
    
    if products.count != 0 {
        productToPurchase = products.first!
        print("Наименование товара: \(productToPurchase.localizedTitle), описание товара: \(productToPurchase.localizedDescription)")
    }
    
}

//SKPaymentTransactionObserver protocol (очередь транзакций)
func paymentQueue(queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
    
    for transaction in transactions {
        switch transaction.transactionState {
        case .Purchased:
            print("Покупка совершена")
            self.openExercises()
            self.setExpireDate()
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            break
            
        case .Restored:
            SKPaymentQueue.defaultQueue().restoreCompletedTransactions()
            break
            
        case .Failed:
            print("Ошибка транзакции")
            SKPaymentQueue.defaultQueue().finishTransaction(transaction)
            break
            
        default:
            print("default case happened")
            break
            
        }
    }
    
}

func openExercises() {
    
    releaseBut1_5.enabled = false
    releaseBut1_5.hidden = true
    
    releaseBut1_6.enabled = false
    releaseBut1_6.hidden = true
    
    releaseBut1_7.enabled = false
    releaseBut1_7.hidden = true
    
    releaseBut1_8.enabled = false
    releaseBut1_8.hidden = true
    
    releaseBut1_9.enabled = false
    releaseBut1_9.hidden = true
    
    releaseBut1_10.enabled = false
    releaseBut1_10.hidden = true
    
    paymentBut.enabled = false
    paymentBut.hidden = true
    
}

//дата окончания подписки
func setExpireDate() {
    let today = NSDate()
    
    let dateComponent = NSDateComponents()
    dateComponent.setValue(1, forComponent: NSCalendarUnit.Month)
    
    let expirationDate = NSCalendar.currentCalendar().dateByAddingComponents(dateComponent, toDate: today, options: NSCalendarOptions())
    
    //сохраняем дату в айклауд
    let cloudStore = NSUbiquitousKeyValueStore.defaultStore()
    cloudStore.setObject(expirationDate, forKey: "expDate")
    cloudStore.synchronize()
    
}

//добавляем платеж в очередь
@IBAction func paymentButFinish(sender: UIButton) {
    let payment = SKPayment(product: productToPurchase)
    SKPaymentQueue.defaultQueue().addPayment(payment)    }

}


#2

Очень сложно подсказать по iap, так как миллион различных нюансов, но еще сложнее, когда кода не видно :slight_smile:


#3

Добавил код. ) Я немножко с кнопками эксперементировал, но от урока не сильно отличается. Сама покупка совершается, кнопки исчезают. Но все становится на круги своя после перезапуска приложения.


#4

А если Вы попытаетесь распечатать expirationDate при загрузке приложения, то что будет выводиться?


#5

2016-03-22 09:57:53.904 FitnessC[4015:960102] ExpirationDate is 2016-04-22 06:42:54 +0000 and today is 2016-03-22 06:57:53 +0000


#6

Значит записывается раз месяц в итоге прибавлен?


#7

Да, судя по логу - записывается. Но проблема при загрузке есть… И еще странно то, что время в today отличается от текущего времени в начале лога. Я к тому, что тестовую покупку провел с 8 до 9. А показало 6 часов…


#8

Добрый день.
Вам удалось импортировать Ваше приложение на swift3?
Все делаю, как в курсе, но появилась проблема, где используется NSDate. Ошибки в строках:
1)
if today.earlierDate(expireDate) == true {
Ошибка: NSDate is not implicitly convertible to Date; Did you mean to use as to explicitly convert?

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

Ошибка: NSDate is not implicitly convertible to Date; Did you mean to use as to explicitly convert?

После перехода на Swift3 может стоит NSDate везде заменить на Date?


#9

Да, в swift 3 нужно использовать Date


#11

Спасибо огромное! Сегодня вечером попробую исправить. Если у Вас код под рукой, подскажите, пожалуйста, как у Вас выглядят данные строки в Swift3?

  1. if today.earlierDate(expireDate) == true {

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


#12

Кода нет под рукой. Вот хороший материал: https://stackoverflow.com/questions/38248941/how-to-get-time-hour-minute-second-in-swift-3-using-nsdate


#13

Спасибо!

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