我们有一个应用程序,可以像往常一样查询StoreKit的产品详细信息(你可以忽略它是Xamarin应用程序,除非Xamarin中有错误,否则它不会有什么不同):
var request = new SKProductsRequest( new NSSet( ... ) );
_runningRequests.Add( request );
request.ReceivedResponse += HandleReceivedResponse;
request.RequestFailed += HandleRequestFailed;
request.RequestFinished += HandleRequestFinnished;
request.Start();
// ....
void HandleReceivedResponse( object sender, SKProductsRequestResponseEventArgs e )
{
ViewModel.IsProcessing = false;
foreach (var item in e.Response.InvalidProducts)
Console.WriteLine( "Invalid product: " + item );
var products = e.Response.Products.Select( x => new InAppProductViewModel( x.LocalizedTitle, x.ProductIdentifier, x.LocalizedDescription, LocalizedPrice( x ), IsPurchased( x ), () => Purchase( x ) ) );
var vms = products.ToList();
ViewModel.UpdateProducts( vms );
}
发生的是:
- 在Sandbox/Test环境中,我们可以在iOS7和iOS8设备上查询产品ID,并收到正确的响应
- 该应用程序通过了审查,我们已经成功销售了商品,因此它对一些用户有效
- 然而,我们有客户报告说,他们在我们的应用内商店里看不到任何东西。他们都有一个共同点,那就是他们运行的是iOS 7设备我们可以重现这个问题-在控制台上的应用商店上发布的版本中,我们会看到我们传递到
SKProductRequest
中的每个标识符的输出"无效产品id"。标识符与我们在代码中指定的完全匹配
这似乎只发生在iOS 7设备上,在实时应用商店环境中。我想他们已经通过iTunes更新或其他方式破坏了iOS 7上的应用内购买。Sandbox环境没有显示这个问题,这真的很奇怪。我们在多台设备和多个iTunes帐户上进行了测试,并安装了该应用程序。客户也遇到了这些问题。
我已经与苹果开发者技术支持和iTunes提供商支持合作过,他们无法/不愿与工程团队一起诊断问题。因此,在这里问这个问题,看看是否有其他人也遇到了同样的问题,或者是否能够使用他们的应用程序进行检查。我们已经等了24个多小时才进行"产品更新",本应解决问题,但事实并非如此。
任何拥有应用内购买功能的应用程序的人都能测试应用商店的实时版本是否仍然适用于iOS7吗?
注:这种情况已经持续了72个多小时,这表明这不是像那样的暂时侥幸
- iOS应用内购买-";无效的产品ID";发布中,非开发版本
- 应用内购买仅在发布版本上无效的产品id
此后,我们在AppStore中发布了两个应用程序更新,但都没有解决问题。在iOS8上运行良好,在iOS7上使ProductIdentifiers无效。
这是我们从应用程序中获得的控制台输出(略微修改了日志记录)。TASK-ASSERT
错误可能暗示出了问题,但我找不到任何有关该错误的信息。
Mar 10 08:08:28 iDevPad01 itunesstored[832] <Error>: TASK-ASSERT: cfurlcache - ProcessCacheTask - FAILED to get task-assertion, going commando with 1 items to process.
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Received SKProductResponse, debugdescription: <SKProductsResponse: 0x1776d950>
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Received SKProductResponse, description: <SKProductsResponse: 0x1776d950>
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Received SKProductResponse, products: 0
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Invalid product: coach
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Invalid product: boat
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Invalid product: com.rowinginmotion.mobile.boatapp.ios.solo.boat
Mar 10 08:08:28 iDevPad01 RowingInMotionMobileBoatAppiOSSolo[855] <Warning>: Invalid product: com.rowinginmotion.mobile.boatapp.ios.solo.coach
我们在三天前提交了一份支持DTS的事件,并最终得到了回复。他们同意我们的观点,即这似乎是处理InApp购买的iTC网络服务的内部问题。我会及时更新这条线索的。
好消息-苹果终于找到了问题的原因。Xamarin.iOS似乎在构建过程中开始向应用程序捆绑包添加iTunesMetadata.plist
文件(尽管我们没有构建IPA并通过xcode归档进行部署)。
引用我们的iOS支持工程师:
问题似乎是,在您上传到iTunesConnect的可交付资产中,有一个"rogue iTunesMetadata.plist",在iOS 6/7下运行的其他应用内购买应用程序中不存在。这里的问题是,当应用程序从应用商店安装到设备时,应用程序中内置了相同的文件。由于此文件已存在于应用程序捆绑包中,因此不会使用StoreKit安装的文件。这是一个问题的原因是iTunesMetaData.plist缺少通常包含在调用SKProductsRequest时生成的fetchSoftwareAddOns URL请求中的2个字段值。
作为一个临时解决方案,我已经修补了"_CompileITunesMetadata"msbuild任务,以防止生成iTunesMetadata.plist
<Import Project="$(MSBuildExtensionsPath)XamariniOSXamarin.iOS.CSharp.targets" />
<!-- NOP out CompileITunesMetadata task, which creates a rogue metadata plist file that can break In App Purchases on iOS7 -->
<Target Name="_CompileITunesMetadata" DependsOnTargets="_DetectSdkLocations;_DetectAppManifest;_GenerateBundleName;_CompileAppManifest">
<Message Text="Skipping CompileITunesMetadata task, which creates a rogue metadata plist file that can break In App Purchases on iOS7" />
</Target>
我们的iOS支持工程师向我表示,iTunesConnect可能会内置验证例程,以防止/拒绝包含流氓iTunesMetadata.plist
的应用程序提交,这样希望其他人不会受到这种奇怪行为的影响。