{"id":42710,"date":"2024-04-01T15:17:33","date_gmt":"2024-04-01T19:17:33","guid":{"rendered":"https:\/\/mjtsai.com\/blog\/?p=42710"},"modified":"2024-04-01T15:17:33","modified_gmt":"2024-04-01T19:17:33","slug":"app-store-subscriptions-and-family-sharing","status":"publish","type":"post","link":"https:\/\/mjtsai.com\/blog\/2024\/04\/01\/app-store-subscriptions-and-family-sharing\/","title":{"rendered":"App Store Subscriptions and Family Sharing"},"content":{"rendered":"<p><a href=\"https:\/\/furbo.org\/2024\/03\/29\/app-store-subscriptions-and-family-sharing\/\">Craig Hockenberry<\/a>:<\/p>\n<blockquote cite=\"https:\/\/furbo.org\/2024\/03\/29\/app-store-subscriptions-and-family-sharing\/\"><p>Your code and the App Store don&rsquo;t agree about when a subscription expired. The cause of this is Apple&rsquo;s StoreKit <a href=\"https:\/\/developer.apple.com\/documentation\/storekit\/in-app_purchase\/implementing_a_store_in_your_app_using_the_storekit_api\">sample code<\/a>. It&rsquo;s likely that you have some code similar to line 246 of <code>Store.swift<\/code>:<\/p><pre>subscriptionGroupStatus = <strong>try<\/strong>? <strong>await<\/strong> subscriptions.first?.subscription?.status.first?.state<\/pre><p>That code will work fine until you encounter a customer that has Family Sharing enabled, as most do. The issue is that the <code>Product.SubscriptionInfo<\/code> can contain multiple items, and the code above only checks the first one. <\/p><p>How can that happen? With Family Sharing, the people who are using the subscription act independently: one may subscribe for a year and then cancel. Then another could subscribe at a later date for only a month. You have to check all of the subscriptions, not just the first one.<\/p><\/blockquote>\n<p>As he notes, it&rsquo;s not documented that the sample code doesn&rsquo;t support Family Sharing. And, even if you&rsquo;re aware of this issue, there&rsquo;s no reasonable way to test your code in Xcode, TestFlight, or even production.<\/p>\n<p>Previously:<\/p>\n<ul>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2023\/11\/26\/receipt-validation-with-all-the-ethernet-interfaces\/\">Receipt Validation With All the Ethernet Interfaces<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2022\/05\/20\/new-receipt-validation-sample-code\/\">New Receipt Validation Sample Code<\/a><\/li>\n<li><a href=\"https:\/\/mjtsai.com\/blog\/2021\/06\/08\/storekit-2\/\">StoreKit 2<\/a><\/li>\n<\/ul>","protected":false},"excerpt":{"rendered":"<p>Craig Hockenberry: Your code and the App Store don&rsquo;t agree about when a subscription expired. The cause of this is Apple&rsquo;s StoreKit sample code. It&rsquo;s likely that you have some code similar to line 246 of Store.swift:subscriptionGroupStatus = try? await subscriptions.first?.subscription?.status.first?.stateThat code will work fine until you encounter a customer that has Family Sharing enabled, [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"apple_news_api_created_at":"2024-04-01T19:17:35Z","apple_news_api_id":"a746ecd9-53db-496c-9c23-d3b295c29184","apple_news_api_modified_at":"2024-04-01T19:17:35Z","apple_news_api_revision":"AAAAAAAAAAD\/\/\/\/\/\/\/\/\/\/w==","apple_news_api_share_url":"https:\/\/apple.news\/Ap0bs2VPbSWycI9OylcKRhA","apple_news_coverimage":0,"apple_news_coverimage_caption":"","apple_news_is_hidden":false,"apple_news_is_paid":false,"apple_news_is_preview":false,"apple_news_is_sponsored":false,"apple_news_maturity_rating":"","apple_news_metadata":"\"\"","apple_news_pullquote":"","apple_news_pullquote_position":"","apple_news_slug":"","apple_news_sections":"\"\"","apple_news_suppress_video_url":false,"apple_news_use_image_component":false,"footnotes":""},"categories":[4],"tags":[91,1421,1015,31,2321,30,39,2385,71,2016],"class_list":["post-42710","post","type-post","status-publish","format-standard","hentry","category-programming-category","tag-appstore","tag-app-subscriptions","tag-family-sharing","tag-ios","tag-ios-17","tag-mac","tag-macappstore","tag-macos-14-sonoma","tag-programming","tag-testflight"],"apple_news_notices":[],"_links":{"self":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42710","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/comments?post=42710"}],"version-history":[{"count":1,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42710\/revisions"}],"predecessor-version":[{"id":42711,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/posts\/42710\/revisions\/42711"}],"wp:attachment":[{"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/media?parent=42710"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/categories?post=42710"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mjtsai.com\/blog\/wp-json\/wp\/v2\/tags?post=42710"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}