![](https://github.com/bizz84/SwiftyStoreKit/raw/master/SwiftyStoreKit-logo.png)
[![License](https://img.shields.io/badge/license-MIT-blue.svg?style=flat)](http://mit-license.org)
[![Platform](http://img.shields.io/badge/platform-ios%20%7C%20macos%20%7C%20tvos-lightgrey.svg?style=flat)](https://developer.apple.com/resources/)
[![Language](https://img.shields.io/badge/swift-3.0-orange.svg)](https://developer.apple.com/swift)
[![Build](https://img.shields.io/travis/bizz84/SwiftyStoreKit.svg?style=flat)](https://travis-ci.org/bizz84/SwiftyStoreKit)
[![Issues](https://img.shields.io/github/issues/bizz84/SwiftyStoreKit.svg?style=flat)](https://github.com/bizz84/SwiftyStoreKit/issues)
[![Cocoapod](http://img.shields.io/cocoapods/v/SwiftyStoreKit.svg?style=flat)](http://cocoadocs.org/docsets/SwiftyStoreKit/)
[![Carthage compatible](https://img.shields.io/badge/Carthage-compatible-4BC51D.svg?style=flat)](https://github.com/Carthage/Carthage)
[![Twitter](https://img.shields.io/badge/twitter-@biz84-blue.svg?maxAge=2592000)](http://twitter.com/biz84)
SwiftyStoreKit is a lightweight In App Purchases framework for iOS 8.0+, tvOS 9.0+ and macOS 10.10+.
| Language | Branch | Pod version | Xcode version |
| --------- | ------ | ----------- | ------------- |
| Swift 3.0 | [master](https://github.com/bizz84/SwiftyStoreKit/tree/master) | >= 0.5.x | Xcode 8 or greater|
| Swift 2.3 | [swift-2.3](https://github.com/bizz84/SwiftyStoreKit/tree/swift-2.3) | 0.4.x | Xcode 8, Xcode 7.3.x |
| Swift 2.2 | [swift-2.2](https://github.com/bizz84/SwiftyStoreKit/tree/swift-2.2) | 0.3.x | Xcode 7.3.x |
### Preview
<img src="https://github.com/bizz84/SwiftyStoreKit/raw/master/Screenshots/Preview.png" width="320">
<img src="https://github.com/bizz84/SwiftyStoreKit/raw/master/Screenshots/Preview2.png" width="320">
## App startup
### Complete Transactions
Apple recommends to register a transaction observer [as soon as the app starts](https://developer.apple.com/library/ios/technotes/tn2387/_index.html):
> Adding your app's observer at launch ensures that it will persist during all launches of your app, thus allowing your app to receive all the payment queue notifications.
SwiftyStoreKit supports this by calling `completeTransactions()` when the app starts:
```swift
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
SwiftyStoreKit.completeTransactions(atomically: true) { products in
for product in products {
if product.transaction.transactionState == .purchased || product.transaction.transactionState == .restored {
if product.needsFinishTransaction {
// Deliver content from server, then:
SwiftyStoreKit.finishTransaction(product.transaction)
}
print("purchased: \(product)")
}
}
}
return true
}
```
If there are any pending transactions at this point, these will be reported by the completion block so that the app state and UI can be updated.
## Purchases
### Retrieve products info
```swift
SwiftyStoreKit.retrieveProductsInfo(["com.musevisions.SwiftyStoreKit.Purchase1"]) { result in
if let product = result.retrievedProducts.first {
let priceString = product.localizedPrice!
print("Product: \(product.localizedDescription), price: \(priceString)")
}
else if let invalidProductId = result.invalidProductIDs.first {
return alertWithTitle("Could not retrieve product info", message: "Invalid product identifier: \(invalidProductId)")
}
else {
print("Error: \(result.error)")
}
}
```
### Purchase a product
* **Atomic**: to be used when the content is delivered immediately.
```swift
SwiftyStoreKit.purchaseProduct("com.musevisions.SwiftyStoreKit.Purchase1", atomically: true) { result in
switch result {
case .success(let product):
print("Purchase Success: \(product.productId)")
case .error(let error):
print("Purchase Failed: \(error)")
}
}
```
* **Non-Atomic**: to be used when the content is delivered by the server.
```swift
SwiftyStoreKit.purchaseProduct("com.musevisions.SwiftyStoreKit.Purchase1", atomically: false) { result in
switch result {
case .success(let product):
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
print("Purchase Success: \(product.productId)")
case .error(let error):
print("Purchase Failed: \(error)")
}
}
```
### Restore previous purchases
* **Atomic**: to be used when the content is delivered immediately.
```swift
SwiftyStoreKit.restorePurchases(atomically: true) { results in
if results.restoreFailedProducts.count > 0 {
print("Restore Failed: \(results.restoreFailedProducts)")
}
else if results.restoredProducts.count > 0 {
print("Restore Success: \(results.restoredProducts)")
}
else {
print("Nothing to Restore")
}
}
```
* **Non-Atomic**: to be used when the content is delivered by the server.
```swift
SwiftyStoreKit.restorePurchases(atomically: false) { results in
if results.restoreFailedProducts.count > 0 {
print("Restore Failed: \(results.restoreFailedProducts)")
}
else if results.restoredProducts.count > 0 {
for product in results.restoredProducts {
// fetch content from your server, then:
if product.needsFinishTransaction {
SwiftyStoreKit.finishTransaction(product.transaction)
}
}
print("Restore Success: \(results.restoredProducts)")
}
else {
print("Nothing to Restore")
}
}
```
#### What does atomic / non-atomic mean?
When you purchase a product the following things happen:
* A payment is added to the payment queue for your IAP.
* When the payment has been processed with Apple, the payment queue is updated so that the appropriate transaction can be handled.
* If the transaction state is **purchased** or **restored**, the app can unlock the functionality purchased by the user.
* The app should call `finishTransaction()` to complete the purchase.
This is what is [recommended by Apple](https://developer.apple.com/reference/storekit/skpaymentqueue/1506003-finishtransaction):
> Your application should call finishTransaction(_:) only after it has successfully processed the transaction and unlocked the functionality purchased by the user.
* A purchase is **atomic** when the app unlocks the functionality purchased by the user immediately and call `finishTransaction()` at the same time. This is desirable if you're unlocking functionality that is already inside the app.
* In cases when you need to make a request to your own server in order to unlock the functionality, you can use a **non-atomic** purchase instead.
SwiftyStoreKit provides three operations that can be performed **atomically** or **non-atomically**:
* Making a purchase
* Restoring purchases
* Completing transactions on app launch
## Receipt verification
### Retrieve local receipt
```swift
let receiptData = SwiftyStoreKit.localReceiptData
let receiptString = receiptData.base64EncodedString
// do your receipt validation here
```
### Verify Receipt
```swift
SwiftyStoreKit.verifyReceipt(password: "your-shared-secret") { result in
if case .error(let error) = result {
if case .noReceiptData = error {
self.refreshReceipt()
}
}
}
func refreshReceipt() {
SwiftyStoreKit.refreshReceipt { result in
switch result {
case .success(let receiptData):
print("Receipt refresh success: \(receiptData.base64EncodedString)")
case .error(let error):
print("Receipt refresh failed: \(error)")
}
}
}
```
### Verify Purchase
```swift
SwiftyStoreKit.verifyReceipt(password: "your-shared-secret") { result in
switch result {
没有合适的资源?快使用搜索试试~ 我知道了~
9.31-IAP-iOS内购功能的具体实现和测试
共64个文件
swift:14个
plist:14个
xcuserstate:5个
需积分: 5 2 下载量 42 浏览量
2023-05-25
21:23:01
上传
评论
收藏 160KB ZIP 举报
温馨提示
9.31_IAP_iOS内购功能的具体实现和测试
资源推荐
资源详情
资源评论
收起资源包目录
9.31_IAP_iOS内购功能的具体实现和测试.zip (64个子文件)
9.31IAP内购功能的具体实现和测试
.DS_Store 8KB
SwiftyStoreKit
.DS_Store 8KB
DemoApp.xcworkspace
xcshareddata
swiftpm
configuration
IDEWorkspaceChecks.plist 238B
contents.xcworkspacedata 225B
xcuserdata
jerry.xcuserdatad
UserInterfaceState.xcuserstate 22KB
edy.xcuserdatad
UserInterfaceState.xcuserstate 14KB
fazhanli.xcuserdatad
UserInterfaceState.xcuserstate 36KB
Podfile 138B
DemoApp.xcodeproj
project.pbxproj 25KB
xcuserdata
jerry.xcuserdatad
xcdebugger
Breakpoints_v2.xcbkptlist 91B
xcschemes
DemoApp.xcscheme 4KB
xcschememanagement.plist 659B
edy.xcuserdatad
xcschemes
xcschememanagement.plist 342B
fazhanli.xcuserdatad
xcschemes
xcschememanagement.plist 342B
project.xcworkspace
xcshareddata
swiftpm
configuration
IDEWorkspaceChecks.plist 238B
contents.xcworkspacedata 152B
xcuserdata
jerry.xcuserdatad
UserInterfaceState.xcuserstate 30KB
fazhanli.xcuserdatad
UserInterfaceState.xcuserstate 13KB
DemoApp
Base.lproj
Main.storyboard 2KB
LaunchScreen.storyboard 2KB
SceneDelegate.swift 2KB
AppDelegate.swift 1KB
ViewController.swift 4KB
Info.plist 2KB
Assets.xcassets
AppIcon.appiconset
Contents.json 849B
DemoAppTests
DemoAppTests.swift 973B
Info.plist 733B
DemoAppUITests
Info.plist 733B
DemoAppUITests.swift 1KB
Pods
Pods.xcodeproj
project.pbxproj 29KB
xcuserdata
jerry.xcuserdatad
xcschemes
SwiftyStoreKit.xcscheme 2KB
Pods-DemoApp.xcscheme 2KB
xcschememanagement.plist 666B
edy.xcuserdatad
xcschemes
xcschememanagement.plist 463B
fazhanli.xcuserdatad
xcschemes
xcschememanagement.plist 463B
Manifest.lock 221B
Local Podspecs
SwiftyStoreKit
LICENSE.md 1KB
SwiftyStoreKit
InAppReceiptRefreshRequest.swift 3KB
SwiftyStoreKit.swift 13KB
SwiftyStoreKit+Types.swift 9KB
SKProduct+LocalizedPrice.swift 1KB
InAppProductPurchaseRequest.swift 8KB
InAppProductQueryRequest.swift 3KB
InAppCompleteTransactionsObserver.swift 3KB
OS.swift 2KB
InAppReceipt.swift 11KB
README.md 17KB
Headers
Target Support Files
Pods-DemoApp
Pods-DemoApp-frameworks.sh 4KB
Pods-DemoApp-acknowledgements.plist 2KB
Pods-DemoApp-dummy.m 128B
Pods-DemoApp.modulemap 114B
Pods-DemoApp-resources.sh 5KB
Pods-DemoApp-acknowledgements.markdown 1KB
Info.plist 828B
Pods-DemoApp.debug.xcconfig 687B
Pods-DemoApp-umbrella.h 169B
Pods-DemoApp.release.xcconfig 687B
SwiftyStoreKit
SwiftyStoreKit-umbrella.h 173B
SwiftyStoreKit-dummy.m 132B
SwiftyStoreKit.modulemap 118B
SwiftyStoreKit-prefix.pch 48B
Info.plist 828B
SwiftyStoreKit.xcconfig 496B
Podfile.lock 221B
共 64 条
- 1
资源评论
GotoLevel
- 粉丝: 23
- 资源: 37
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功