有没有办法在有人进行应用内购买时收到通知?
Is There A Way To Get Notified When Someone Makes An In-App Purchase?
我希望在有人在我的应用程序中进行应用程序内购买时收到通知,而不是等到第二天再检查 iTunes Connect 以了解我是否有任何销售。
有谁知道这样做的方法吗?如果没有,那就太酷了!
谢谢
跟踪 StoreKit 购买事件
发生购买时,给自己发送一个数据点(在此处跟踪...)
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transation in transactions {
switch transation.transactionState {
case .purchased:
queue.finishTransaction(transation)
// Track here...
case .purchasing: break
case .restored: break
case .deferred: break
case .failed: break
}
}
}
利用图书馆
使用分析。用下面的任何块替换上面的 // Track here...
注释。按字母顺序排列的非详尽列表:
参与
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
BMA4SPurchasedItem* item =
[BMA4SPurchasedItem itemWithId(t.payment.productIdentifier)
label:t.payment.productName
category:<product.type>
price:@(<SKProduct.price>)
quantity:t.payment.quantity
];
[BMA4STracker trackPurchaseWithId:transaction.identifier
currency:currencyCode
items:@[item]];
分行
NSDictionary *state = @{
@"itemId": @(t.payment.productIdentifier),
@"price": <SKProduct.price>,
@"itemName": <SKProduct.name>,
@"currency":currencyCode };
[[Branch getInstance] userCompletedAction:@"purchase" withState:state];
结构 (Crashlytics)
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
[Answers logPurchaseWithPrice:<SKProduct.price>
currency:currencyCode
success:@YES
itemName:<product name>
itemType:@"Purchase"
itemId:@(t.payment.productIdentifier)
customAttributes:@{}];
飞行记录器
FlightRecorder.sharedInstance().trackEventWithCategory(
"Actions",
action: "Purchase",
label: "productIdentifier",
value: t.payment.productIdentifier)
Flurry 分析
let properties = ["productIdentifier":t.payment.productIdentifier]
Flurry.logEvent("Purchase", withParameters: properties)
Google 分析
#import "GAI.h"
#import "GAIDictionaryBuilder.h"
id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
[tracker send:[[GAIDictionaryBuilder
createItemWithTransactionId:transactionIdentifier
name:<product.localizedTitle>
sku:t.payment.productIdentifier
category:@"Purchase"
price:<SKProduct.price>
quantity:@(t.payment.quantity)
currencyCode:currencyCode]
build]];
参见 In-app purchase tracking with Google Analytics iOS SDK。
堆分析
[Heap track:@"Purchase"
withProperties:@{@"productIdentifier":@(t.payment.productIdentifier)}
];
Mixpanel 分析(*)
Mixpanel.sharedInstance().track("Purchased",
properties: ["productIdentifier":transation.payment.productIdentifier])
properties:@{@"productIdentifier":@(t.payment.productIdentifier)};
(*) 提供对 WiFi 报告的支持(允许推迟所有报告直到 WiFi 网络可用,而不使用蜂窝数据)。请参阅下面的 mixpanelWillFlush
。
Parse.com
NSDictionary *dimensions =
@{@"productIdentifier":@(t.payment.productIdentifier)};
[PFAnalytics trackEvent:@“Purchase” dimensions:dimensions];
从服务器发送电子邮件
POST
购买 URL,然后服务器会向您发送邮件或其他通知。
iOS 实现使用 URLSession
:
if let url = URL(string: "https://<yoursite>/php/purchase.php") {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody =
"{\"productIdentifier\":\"\(transaction.payment.productIdentifier)\"}"
.data(using: .utf8)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request as URLRequest,
completionHandler: {_,_,_ in })
task.resume()
}
purchase.php
电子邮件发件人:
<?php
try {
header('Content-type: application/json');
$to = 'bounce@whosebug.com';
$subject = 'Purchase';
$message = $_POST['productIdentifier'];
$headers = "From: " . $to . "\n";
@mail($to, $subject, $message, $headers)
} catch (Exception $e) {}
?>
► 在 GitHub and additional details on Swift Recipes 上找到此解决方案。
将 Parse 添加到您的项目中。为此,请遵循快速入门指南:https://parse.com/apps/quickstart#parse_data/mobile/ios/native/existing
设置解析后,将 PFObject *testObject = [PFObject objectWithClassName:@"TestObject"];
testObject[@"foo"] = @"bar";
[testObject saveInBackground];
添加到每个应用内购买的 completeTransaction 代码中。例如:
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
// NEW CODE
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iapra"]){
[[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
// NEW CODE ^^
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
不要忘记将 #import <Parse/Parse.h>
添加到 header.h 文件的顶部。
我不太确定还有其他类似的方法。这非常酷,所以请尽情享受实时显示的应用内购买通知吧!
我在Parse.com中记录所有IAP购买到table。将 IAP 收据中的所有数据推送到解析非常容易。我也在做不可更新的订阅,我使用解析来同步用户设备之间的数据,因为 StoreKit 不会自动为不可更新的订阅执行此操作。
Fabric (formerly Crashlytics),除了是一个很棒的(免费的)崩溃日志系统外,还包括一个名为 Answers 的组件,它可以实时跟踪使用情况统计信息:
最近,他们添加了添加自定义事件跟踪的功能,因此向您的应用添加 "Product Purchased" 事件是一件简单的事情。将 Crashlytics 添加到您的应用程序需要几秒钟(他们会引导您完成整个过程),而添加这样的自定义事件只需一行代码。从那时起,您将能够跟踪有关已购买的商品、用户数量以及您想要记录的任何其他元数据的各种信息,所有这些信息的延迟大约为 3 秒。
多年来我一直在使用 Crashlytics(实际上是基于我自己的 Whosebug question),我对它的推荐程度不够高。它免费、简单且非常有效。
我希望在有人在我的应用程序中进行应用程序内购买时收到通知,而不是等到第二天再检查 iTunes Connect 以了解我是否有任何销售。
有谁知道这样做的方法吗?如果没有,那就太酷了!
谢谢
跟踪 StoreKit 购买事件
发生购买时,给自己发送一个数据点(在此处跟踪...)
func paymentQueue(_ queue: SKPaymentQueue, updatedTransactions transactions: [SKPaymentTransaction]) {
for transation in transactions {
switch transation.transactionState {
case .purchased:
queue.finishTransaction(transation)
// Track here...
case .purchasing: break
case .restored: break
case .deferred: break
case .failed: break
}
}
}
利用图书馆
使用分析。用下面的任何块替换上面的 // Track here...
注释。按字母顺序排列的非详尽列表:
参与
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
BMA4SPurchasedItem* item =
[BMA4SPurchasedItem itemWithId(t.payment.productIdentifier)
label:t.payment.productName
category:<product.type>
price:@(<SKProduct.price>)
quantity:t.payment.quantity
];
[BMA4STracker trackPurchaseWithId:transaction.identifier
currency:currencyCode
items:@[item]];
分行
NSDictionary *state = @{
@"itemId": @(t.payment.productIdentifier),
@"price": <SKProduct.price>,
@"itemName": <SKProduct.name>,
@"currency":currencyCode };
[[Branch getInstance] userCompletedAction:@"purchase" withState:state];
结构 (Crashlytics)
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
[Answers logPurchaseWithPrice:<SKProduct.price>
currency:currencyCode
success:@YES
itemName:<product name>
itemType:@"Purchase"
itemId:@(t.payment.productIdentifier)
customAttributes:@{}];
飞行记录器
FlightRecorder.sharedInstance().trackEventWithCategory(
"Actions",
action: "Purchase",
label: "productIdentifier",
value: t.payment.productIdentifier)
Flurry 分析
let properties = ["productIdentifier":t.payment.productIdentifier]
Flurry.logEvent("Purchase", withParameters: properties)
Google 分析
#import "GAI.h"
#import "GAIDictionaryBuilder.h"
id<GAITracker> tracker = [[GAI sharedInstance] defaultTracker];
NSString *currencyCode = [<SKProduct.priceLocale>
objectForKey:NSLocaleCurrencyCode];
[tracker send:[[GAIDictionaryBuilder
createItemWithTransactionId:transactionIdentifier
name:<product.localizedTitle>
sku:t.payment.productIdentifier
category:@"Purchase"
price:<SKProduct.price>
quantity:@(t.payment.quantity)
currencyCode:currencyCode]
build]];
参见 In-app purchase tracking with Google Analytics iOS SDK。
堆分析
[Heap track:@"Purchase"
withProperties:@{@"productIdentifier":@(t.payment.productIdentifier)}
];
Mixpanel 分析(*)
Mixpanel.sharedInstance().track("Purchased",
properties: ["productIdentifier":transation.payment.productIdentifier])
properties:@{@"productIdentifier":@(t.payment.productIdentifier)};
(*) 提供对 WiFi 报告的支持(允许推迟所有报告直到 WiFi 网络可用,而不使用蜂窝数据)。请参阅下面的 mixpanelWillFlush
。
Parse.com
NSDictionary *dimensions =
@{@"productIdentifier":@(t.payment.productIdentifier)};
[PFAnalytics trackEvent:@“Purchase” dimensions:dimensions];
从服务器发送电子邮件
POST
购买 URL,然后服务器会向您发送邮件或其他通知。
iOS 实现使用 URLSession
:
if let url = URL(string: "https://<yoursite>/php/purchase.php") {
var request = URLRequest(url: url)
request.httpMethod = "POST"
request.httpBody =
"{\"productIdentifier\":\"\(transaction.payment.productIdentifier)\"}"
.data(using: .utf8)
request.addValue("application/json", forHTTPHeaderField: "Content-Type")
request.addValue("application/json", forHTTPHeaderField: "Accept")
let task = URLSession.shared.dataTask(with: request as URLRequest,
completionHandler: {_,_,_ in })
task.resume()
}
purchase.php
电子邮件发件人:
<?php
try {
header('Content-type: application/json');
$to = 'bounce@whosebug.com';
$subject = 'Purchase';
$message = $_POST['productIdentifier'];
$headers = "From: " . $to . "\n";
@mail($to, $subject, $message, $headers)
} catch (Exception $e) {}
?>
► 在 GitHub and additional details on Swift Recipes 上找到此解决方案。
将 Parse 添加到您的项目中。为此,请遵循快速入门指南:https://parse.com/apps/quickstart#parse_data/mobile/ios/native/existing
设置解析后,将 PFObject *testObject = [PFObject objectWithClassName:@"TestObject"];
testObject[@"foo"] = @"bar";
[testObject saveInBackground];
添加到每个应用内购买的 completeTransaction 代码中。例如:
- (void)completeTransaction:(SKPaymentTransaction *)transaction {
NSLog(@"completeTransaction...");
[self provideContentForProductIdentifier:transaction.payment.productIdentifier];
// NEW CODE
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iapra"]){
[[NSUserDefaults standardUserDefaults] setObject: @"No" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
if ([transaction.payment.productIdentifier isEqualToString:@"company.app.iap"]){
[[NSUserDefaults standardUserDefaults] setObject: @"YES" forKey:KEY];
[[NSUserDefaults standardUserDefaults] synchronize];
PFObject *testObject = [PFObject objectWithClassName:@"IAP"];
testObject[@"TEST"] = @"Purchase Successful";
[testObject saveInBackground];
}
// NEW CODE ^^
[[SKPaymentQueue defaultQueue] finishTransaction:transaction];
}
不要忘记将 #import <Parse/Parse.h>
添加到 header.h 文件的顶部。
我不太确定还有其他类似的方法。这非常酷,所以请尽情享受实时显示的应用内购买通知吧!
我在Parse.com中记录所有IAP购买到table。将 IAP 收据中的所有数据推送到解析非常容易。我也在做不可更新的订阅,我使用解析来同步用户设备之间的数据,因为 StoreKit 不会自动为不可更新的订阅执行此操作。
Fabric (formerly Crashlytics),除了是一个很棒的(免费的)崩溃日志系统外,还包括一个名为 Answers 的组件,它可以实时跟踪使用情况统计信息:
最近,他们添加了添加自定义事件跟踪的功能,因此向您的应用添加 "Product Purchased" 事件是一件简单的事情。将 Crashlytics 添加到您的应用程序需要几秒钟(他们会引导您完成整个过程),而添加这样的自定义事件只需一行代码。从那时起,您将能够跟踪有关已购买的商品、用户数量以及您想要记录的任何其他元数据的各种信息,所有这些信息的延迟大约为 3 秒。
多年来我一直在使用 Crashlytics(实际上是基于我自己的 Whosebug question),我对它的推荐程度不够高。它免费、简单且非常有效。