Browse Source

Add StoreManager.swift to manage in-app purchases

main
FIGBERT 1 year ago
parent
commit
0d0d594504
Signed by: FIGBERT GPG Key ID: 67F1598D607A844B
  1. 88
      Shared/StoreManager.swift
  2. 14
      txtodo.xcodeproj/project.pbxproj

88
Shared/StoreManager.swift

@ -0,0 +1,88 @@
//
// StoreManager.swift
// txtodo
//
// Created by FIGBERT on 11/20/20.
//
import Foundation
import StoreKit
class StoreManager: NSObject, ObservableObject, SKProductsRequestDelegate, SKPaymentTransactionObserver {
@Published var myProducts = [SKProduct]()
@Published var transactionState: SKPaymentTransactionState?
var request: SKProductsRequest!
func getProducts(productIDs: [String]) {
let request = SKProductsRequest(productIdentifiers: Set(productIDs))
request.delegate = self
request.start()
}
func productsRequest(_ request: SKProductsRequest, didReceive response: SKProductsResponse) {
if !response.products.isEmpty {
for fetchedProduct in response.products {
DispatchQueue.main.async {
self.myProducts.append(fetchedProduct)
}
}
}
for invalidIdentifier in response.invalidProductIdentifiers {
print("Invalid identifiers found: \(invalidIdentifier)")
}
}
func request(_ request: SKRequest, didFailWithError error: Error) {
print("Request did fail: \(error)")
}
func purchaseProduct(product: SKProduct) {
if SKPaymentQueue.canMakePayments() {
let payment = SKPayment(product: product)
SKPaymentQueue.default().add(payment)
} else {
print("User can't make payment.")
}
}
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transaction in transactions {
switch transaction.transactionState {
case .purchasing:
transactionState = .purchasing
case .purchased:
UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
queue.finishTransaction(transaction)
transactionState = .purchased
case .restored:
UserDefaults.standard.setValue(true, forKey: transaction.payment.productIdentifier)
queue.finishTransaction(transaction)
transactionState = .restored
case .failed, .deferred:
print("Payment Queue Error: \(String(describing: transaction.error))")
queue.finishTransaction(transaction)
transactionState = .failed
default:
queue.finishTransaction(transaction)
}
}
}
func restoreProducts() {
SKPaymentQueue.default().restoreCompletedTransactions()
}
}
extension SKProduct {
func priceFormatted() -> String {
let roundedPrice = self.price.doubleValue.rounded()
let formatter = NumberFormatter()
formatter.locale = self.priceLocale
formatter.minimumFractionDigits = 0
formatter.maximumFractionDigits = String(roundedPrice).contains(".00") ? 0 : 2
formatter.numberStyle = .currency
return formatter.string(from: NSNumber(value: roundedPrice))!
}
}

14
txtodo.xcodeproj/project.pbxproj

@ -20,6 +20,8 @@
3A00ABFD24CF84110022FCCE /* Task+CoreDataClass.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A00ABFA24CF84110022FCCE /* Task+CoreDataClass.swift */; };
3A00ABFE24CF84110022FCCE /* Task+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A00ABFB24CF84110022FCCE /* Task+CoreDataProperties.swift */; };
3A00ABFF24CF84110022FCCE /* Task+CoreDataProperties.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A00ABFB24CF84110022FCCE /* Task+CoreDataProperties.swift */; };
3A1F81CF256875FE00E28B5F /* StoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1F81CE256875FE00E28B5F /* StoreManager.swift */; };
3A1F81D0256875FE00E28B5F /* StoreManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A1F81CE256875FE00E28B5F /* StoreManager.swift */; };
3A270E0024F2310600974CD5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3A270E0324F2310600974CD5 /* InfoPlist.strings */; };
3A270E0124F2310600974CD5 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 3A270E0324F2310600974CD5 /* InfoPlist.strings */; };
3A31869624DBDB8200619154 /* NoteSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A31869524DBDB8200619154 /* NoteSheet.swift */; };
@ -42,6 +44,8 @@
3AD708DB256392CE00809259 /* DonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD708DA256392CE00809259 /* DonationSection.swift */; };
3AD708DC256392CE00809259 /* DonationSection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AD708DA256392CE00809259 /* DonationSection.swift */; };
3ADE061524DFCF1E000C4289 /* HomeHeaderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3ADE061424DFCEFE000C4289 /* HomeHeaderView.swift */; };
3AE0CE87256864FB00AAFB15 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0CE86256864FB00AAFB15 /* StoreKit.framework */; };
3AE0CE892568651100AAFB15 /* StoreKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AE0CE882568651100AAFB15 /* StoreKit.framework */; };
3AE1AE1E24DCE6D7005D88E2 /* MenuView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE1AE1D24DCE6D7005D88E2 /* MenuView.swift */; };
3AE1AE2024DCECCC005D88E2 /* SettingsSheet.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE1AE1F24DCECCC005D88E2 /* SettingsSheet.swift */; };
3AE1AE2424DD19DC005D88E2 /* SettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3AE1AE2324DD19DC005D88E2 /* SettingsView.swift */; };
@ -65,6 +69,7 @@
3A00ABF724CF82A50022FCCE /* txtodo.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = txtodo.xcdatamodel; sourceTree = "<group>"; };
3A00ABFA24CF84110022FCCE /* Task+CoreDataClass.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+CoreDataClass.swift"; sourceTree = "<group>"; };
3A00ABFB24CF84110022FCCE /* Task+CoreDataProperties.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Task+CoreDataProperties.swift"; sourceTree = "<group>"; };
3A1F81CE256875FE00E28B5F /* StoreManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreManager.swift; sourceTree = "<group>"; };
3A270E0224F2310600974CD5 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
3A270E0424F2310900974CD5 /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/InfoPlist.strings; sourceTree = "<group>"; };
3A31869524DBDB8200619154 /* NoteSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NoteSheet.swift; sourceTree = "<group>"; };
@ -82,6 +87,8 @@
3ABD6A9424E0DB5800B22F4B /* he */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = he; path = he.lproj/Localizable.strings; sourceTree = "<group>"; };
3AD708DA256392CE00809259 /* DonationSection.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DonationSection.swift; sourceTree = "<group>"; };
3ADE061424DFCEFE000C4289 /* HomeHeaderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeHeaderView.swift; sourceTree = "<group>"; };
3AE0CE86256864FB00AAFB15 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS14.2.sdk/System/Library/Frameworks/StoreKit.framework; sourceTree = DEVELOPER_DIR; };
3AE0CE882568651100AAFB15 /* StoreKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = StoreKit.framework; path = System/Library/Frameworks/StoreKit.framework; sourceTree = SDKROOT; };
3AE1AE1D24DCE6D7005D88E2 /* MenuView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MenuView.swift; sourceTree = "<group>"; };
3AE1AE1F24DCECCC005D88E2 /* SettingsSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SettingsSheet.swift; sourceTree = "<group>"; };
3AE1AE2124DCECD5005D88E2 /* AboutSheet.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AboutSheet.swift; sourceTree = "<group>"; };
@ -96,6 +103,7 @@
buildActionMask = 2147483647;
files = (
3ABD6A8724E0AC9A00B22F4B /* CloudKit.framework in Frameworks */,
3AE0CE87256864FB00AAFB15 /* StoreKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -104,6 +112,7 @@
buildActionMask = 2147483647;
files = (
3ABD6A8924E0AD7900B22F4B /* CloudKit.framework in Frameworks */,
3AE0CE892568651100AAFB15 /* StoreKit.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
@ -132,6 +141,7 @@
3A57486B24DC9F9C00A4F8C0 /* AddNoteView.swift */,
3A5AC67924D0D24000DD482F /* SectionLabel.swift */,
3AE1AE2924DD27BB005D88E2 /* FrameModifier.swift */,
3A1F81CE256875FE00E28B5F /* StoreManager.swift */,
3A74457524E349B600788A32 /* DevicePaddingModifiers.swift */,
3A270E0324F2310600974CD5 /* InfoPlist.strings */,
3ABD6A9324E0DB1B00B22F4B /* Localizable.strings */,
@ -190,6 +200,8 @@
3ABD6A8524E0AC9A00B22F4B /* Frameworks */ = {
isa = PBXGroup;
children = (
3AE0CE882568651100AAFB15 /* StoreKit.framework */,
3AE0CE86256864FB00AAFB15 /* StoreKit.framework */,
3ABD6A8824E0AD7900B22F4B /* CloudKit.framework */,
3ABD6A8624E0AC9A00B22F4B /* CloudKit.framework */,
);
@ -324,6 +336,7 @@
3A74457324E33D8500788A32 /* NoteView.swift in Sources */,
3A3B864F24E0AA4600740360 /* HomeHeaderView.swift in Sources */,
3A00ABFE24CF84110022FCCE /* Task+CoreDataProperties.swift in Sources */,
3A1F81CF256875FE00E28B5F /* StoreManager.swift in Sources */,
3A00ABE424CF7B3C0022FCCE /* txtodoApp.swift in Sources */,
3A57486C24DC9F9C00A4F8C0 /* AddNoteView.swift in Sources */,
);
@ -343,6 +356,7 @@
3A00ABFF24CF84110022FCCE /* Task+CoreDataProperties.swift in Sources */,
3A74457724E349B600788A32 /* DevicePaddingModifiers.swift in Sources */,
3AE1AE2824DD2228005D88E2 /* NotificationSection.swift in Sources */,
3A1F81D0256875FE00E28B5F /* StoreManager.swift in Sources */,
3A00ABE524CF7B3C0022FCCE /* txtodoApp.swift in Sources */,
3A57486D24DC9F9C00A4F8C0 /* AddNoteView.swift in Sources */,
3AE1AE2424DD19DC005D88E2 /* SettingsView.swift in Sources */,

Loading…
Cancel
Save