Google刚推出Voided Purchases API
通过Google Play Voided Purchases API,您可以撤消对与用户无效的购买相关联的应用内商品的访问权限.用户可以通过以下方式取消购买:
- 用户请求退款.
- 用户取消订单.
- 订单会被退回.
但是,我对用例感到困惑.
目前,我有一个应用程序与非消费类应用内购买项目(一次性购买).
每当我的应用程序启动时,我将使用以下代码检查用户是否已购买该项目.
inventory.getPurchase如果用户决定取消他们的采购订单,我希望在下次应用启动期间返回null.
那么,如何Voided Purchases API适应"用户已决定取消其采购订单"的案例?
我想通过使用onQueryInventoryFinished,我们可以确定用户目前拥有哪个项目?
最近,我们刚刚完成了使用 Docker 的 Web 应用程序解决方案。
https://github.com/yccheok/celery-hello-world/tree/nginx(实际解决方案托管在私有存储库中。这个例子只是快速浏览一下我们的项目结构的样子)
我们计划在其上部署时购买 1 台空 Linux 机器。未来我们可能会购买更多机器,但以目前的流量,1 台机器就足够了。
我在单台空机上部署的计划是
git pull <from private code repository>
docker-compose build
docker-compose up -d
Run Code Online (Sandbox Code Playgroud)
由于我们将在不久的将来部署到多台机器上,我想知道,这是将 docker 应用程序部署到新的空机器上的常见做法吗?
有什么我们可以从https://hub.docker.com/使用而无需我们git pull在部署阶段执行的吗?
目前,我仅使用 1 个 Firebase 产品 - Firebase Messaging。(我没有使用 Firebase Analytics)
implementation 'com.google.firebase:firebase-messaging:18.0.0'
Run Code Online (Sandbox Code Playgroud)
根据https://firebase.google.com/docs/cloud-messaging/android/client#prevent-auto-init
Firebase 生成一个实例 ID,FCM 使用该 ID 生成注册令牌,Analytics 使用该 ID 进行数据收集。生成实例 ID 后,库会将标识符和配置数据上传到 Firebase。如果您希望阻止实例 ID 自动生成,请通过将这些元数据值添加到 AndroidManifest.xml 来禁用 FCM 和 Analytics 的自动初始化(您必须禁用两者):
楼上的我实在是不太明白。
我唯一的用例是
FirebaseInstanceId.getInstance().getInstanceId()MyFirebaseMessagingService extends FirebaseMessagingService我想知道,在什么情况下,我应该关心“防止自动初始化”,“自动初始化”有什么问题?
我们计划存储以下用户文件
我们还为用户提供了将上述文件上传和下载到第三方云存储的选项。
我想知道,我们应该使用
FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)
Run Code Online (Sandbox Code Playgroud)
或者
FileManager.default.urls(for: .applicationSupportDirectory, in: .userDomainMask)
Run Code Online (Sandbox Code Playgroud)
用于上述文件存储目的?
给定一个Array与struct
import Foundation
struct Card {
var flag: String = ""
}
var cards = Array<Card>()
cards.append(Card())
Run Code Online (Sandbox Code Playgroud)
以下操作不会修改原始数组元素
// A copy is created.
var cardCopy = cards[0]
// Will NOT modify cards[0]
cardCopy.flag = "modify0"
print(cards[0].flag)
Run Code Online (Sandbox Code Playgroud)
以下操作将修改原始数组元素
// We can modify cards[0] by
cards[0].flag = "modify"
print(cards[0].flag)
Run Code Online (Sandbox Code Playgroud)
然而,它在某种意义上并不高效,我们每次都需要执行索引访问。想象
cards[0].flag0 = "modify"
cards[0].flag1 = "modify"
cards[0].flag2 = "modify"
cards[0].flag3 = "modify"
...
Run Code Online (Sandbox Code Playgroud)
有没有办法,我们可以创建对结构数组元素的引用?这样我们就可以写
// How to create a reference to cards[0]?
var cardReference = ...
Run Code Online (Sandbox Code Playgroud)
// How …Run Code Online (Sandbox Code Playgroud) 目前,如果我想在文档目录中创建目录层次结构,我将执行以下操作
\nlet paths = NSSearchPathForDirectoriesInDomains(.documentDirectory, .userDomainMask, true)\nlet documentsDirectory = paths[0]\nlet documentUrl1 = URL(string: documentsDirectory)!\n//\n// /Users/yccheok/Library/Developer/...\n//\nprint("documentUrl1 -> \\(documentUrl1)")\n\nlet dataPath = documentUrl1.appendingPathComponent("SubFolder1").appendingPathComponent("SubFolder2")\nprint("dataPath.absoluteString -> \\(dataPath.absoluteString)")\nif !FileManager.default.fileExists(atPath: dataPath.absoluteString) {\n do {\n try FileManager.default.createDirectory(atPath: dataPath.absoluteString, withIntermediateDirectories: true, attributes: nil)\n print("Folder creation done!")\n } catch {\n print(error.localizedDescription)\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n但是,如果我使用以下
\nlet documentUrl0 = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]\n//\n// file:///Users/yccheok/Library/Developer/...\n//\nprint("documentUrl0 -> \\(documentUrl0)")\n\nlet dataPath = documentUrl0.appendingPathComponent("SubFolder1").appendingPathComponent("SubFolder2")\nprint("dataPath.absoluteString -> \\(dataPath.absoluteString)")\nif !FileManager.default.fileExists(atPath: dataPath.absoluteString) {\n do {\n try FileManager.default.createDirectory(atPath: dataPath.absoluteString, withIntermediateDirectories: …Run Code Online (Sandbox Code Playgroud) 在我们的后端服务器中,当用户
对我们来说至关重要的是,旧的购买令牌和新的购买令牌都指的是同一用户。
原因是,之前,用户已经使用旧的取消的订阅购买令牌在服务器中创建了一些数据。
当用户取消订阅并再次重新订阅时,我们希望确保用户仍然有权使用新的购买令牌访问旧数据。
我们希望可以从 获取信息linkedPurchaseToken,其中新的购买令牌将指向旧的购买令牌。
https://medium.com/androiddevelopers/implementing-linkedpurchasetoken- Correctly-to-prevent-duplicate-subscriptions-82dfbf7167da 中对此进行了描述
然而,根据我们的测试结果,情况并非如此。
credentials = service_account.Credentials.from_service_account_file(
constant.PATH_TO_SERVICE_ACCOUNT_JSON,
scopes = constant.SCOPES
)
androidpublisher = googleapiclient.discovery.build(
'androidpublisher',
'v3',
credentials = credentials
)
product = androidpublisher.purchases().subscriptions().get(
packageName = "com.xxx.yyy",
subscriptionId = product_id,
token = token
).execute()
return product
Run Code Online (Sandbox Code Playgroud)
{
'startTimeMillis':'1619245597271',
'expiryTimeMillis':'1619246015249',
'autoRenewing':True,
'priceCurrencyCode':'SGD',
'priceAmountMicros':'6980000',
'countryCode':'SG',
'developerPayload':'',
'paymentState':1,
'orderId':'GPA.3314-4833-2752-47988',
'purchaseType':0,
'acknowledgementState':1,
'kind':'androidpublisher#subscriptionPurchase'
}
Run Code Online (Sandbox Code Playgroud)
{
'startTimeMillis':'1619244776697',
'expiryTimeMillis':'1619245074590',
'autoRenewing':False,
'priceCurrencyCode':'SGD',
'priceAmountMicros':'6980000',
'countryCode':'SG',
'developerPayload':'',
'cancelReason':3,
'orderId':'GPA.3358-9904-1003-13416',
'purchaseType':0,
'acknowledgementState':1,
'kind':'androidpublisher#subscriptionPurchase'
} …Run Code Online (Sandbox Code Playgroud) android in-app-billing google-play google-play-developer-api google-play-console
我遇到过 2 个演示 CoreData 项目,其中涉及事务历史记录。
两者都在使用
viewContext.setQueryGenerationFrom(.current)
Run Code Online (Sandbox Code Playgroud)
当他们初始化 CoreData 堆栈时。
该演示摘自https://www.raywenderlich.com/14958063-modern-efficient-core-data
作者试图演示如何利用事务历史记录,在批量插入后正确更新 UI。
然而,尚不清楚viewContext.setQueryGenerationFrom(.current)试图解决什么问题。
文章的简要解释https://www.raywenderlich.com/14958063-modern-efficient-core-data并没有过多讲述背后的想法setQueryGenerationFrom。
您通过调用 setQueryGenerationFrom(_:) 将视图上下文固定到持久存储中的最新事务。但是,由于设置查询生成仅与 SQLite 存储兼容,因此仅当 inMemory 为 false 时才执行此操作。
该演示选自https://developer.apple.com/documentation/coredata/synchronizing_a_local_store_to_the_cloud
它试图演示如何使用事务历史记录来防止与 CloudKit 同步后的数据重复。
然而,目前尚不清楚viewContext.setQueryGenerationFrom(.current)要解决什么问题。
关于这个想法背后没有给出太多解释setQueryGenerationFrom。
无论我在 CoreData 堆栈中包含viewContext.setQueryGenerationFrom(.current)还是排除viewContext.setQueryGenerationFrom(.current),我在这两种情况下都会得到相同的观察结果。
NSManagedObject在我保存一个新的, 并调用后,能够立即观察 UI 更新context.save。NSManagedObject在我编辑现有的并调用后,能够立即观察 UI 更新context.save。NSBatchUpdateRequest并 …我尝试转发declare concurrent_bounded_queue;
class MyClass {
namespace tbb {
template<typename T> class cache_aligned_allocator;
template<class T, class A = cache_aligned_allocator> class concurrent_bounded_queue;
};
// I wish to maintain this syntax.
tbb::concurrent_bounded_queue<std::string>& concurrentBoundedQueue;
}
Run Code Online (Sandbox Code Playgroud)
我收到以下错误:
error C3203: 'cache_aligned_allocator' : unspecialized class template can't be used as a template argument for template parameter 'A', expected a real type
error C2955: 'tbb::cache_aligned_allocator' : use of class template requires template argument list c:\projects\vitroxreport\src\Executor.h(21) : see declaration of 'tbb::cache_aligned_allocator'
Run Code Online (Sandbox Code Playgroud)
我可以知道如何避免吗?
谢谢.
std::map<std::string, int> m;
// Can I make assumption that m["NoSuchKey"] will return 0?
std::cout << m["NoSuchKey"] << std::endl;
Run Code Online (Sandbox Code Playgroud)