From 93b87c30bb19b23f2816d97dbdb06c72539199f8 Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 22 Apr 2026 19:31:22 +0200 Subject: [PATCH 1/3] [StoreKit] Fix StoreKit iTunes identifier width. Fixes #25219. Keep StoreProductParameters and related StoreKit numeric identifiers on long values so App Store IDs above Int32.MaxValue compile and round-trip correctly. Fixes https://github.com/dotnet/macios/issues/25219. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/StoreKit/StoreProductParameters.cs | 50 +++++++++++++++---- .../Foundation/DictionaryContainerTest.cs | 24 +++++++++ .../StoreKit/StoreProductParametersTest.cs | 49 ++++++++++++++++++ 3 files changed, 114 insertions(+), 9 deletions(-) create mode 100644 tests/monotouch-test/StoreKit/StoreProductParametersTest.cs diff --git a/src/StoreKit/StoreProductParameters.cs b/src/StoreKit/StoreProductParameters.cs index fb9848156928..52175b034c88 100644 --- a/src/StoreKit/StoreProductParameters.cs +++ b/src/StoreKit/StoreProductParameters.cs @@ -27,6 +27,8 @@ #nullable enable +using System.ComponentModel; +using System.Runtime.CompilerServices; using CoreFoundation; namespace StoreKit { @@ -38,25 +40,55 @@ namespace StoreKit { #endif public partial class StoreProductParameters : DictionaryContainer { #if !COREBUILD - /// To be added. - /// Creates a new for the specified ITunes identifier. - /// To be added. +#if !XAMCORE_5_0 + /// Creates a new for the specified iTunes identifier. + /// The 32-bit App Store item identifier to display. + /// Use to support identifiers larger than . + [OverloadResolutionPriorityAttribute (-1)] + [EditorBrowsable (EditorBrowsableState.Never)] + [Obsolete ("Use 'StoreProductParameters (long)' instead.")] public StoreProductParameters (int iTunesItemIdentifier) + : this ((long) iTunesItemIdentifier) + { + } +#endif + + /// Creates a new for the specified 64-bit iTunes identifier. + /// The App Store item identifier to display. + public StoreProductParameters (long iTunesItemIdentifier) : this () { - ITunesItemIdentifier = iTunesItemIdentifier; + ITunesItemIdentifierLong = iTunesItemIdentifier; } - // TODO: What is real iTunes Store item identifier length - /// Gets or sets the identifier for the ITunes item being advertised. - /// To be added. - /// To be added. +#if !XAMCORE_5_0 + /// Gets or sets the legacy 32-bit iTunes item identifier for the App Store product to display. + /// The 32-bit App Store item identifier, or if not set. + /// Use for current identifiers and values larger than . + [EditorBrowsable (EditorBrowsableState.Never)] + [Obsolete ("Use 'ITunesItemIdentifierLong' instead.")] public int? ITunesItemIdentifier { + set { + ITunesItemIdentifierLong = value; + } + get { + var value = ITunesItemIdentifierLong; + if (!value.HasValue) + return null; + + return checked ((int) value.Value); + } + } +#endif + + /// Gets or sets the 64-bit iTunes item identifier for the App Store product to display. + /// The App Store item identifier, or if not set. + public long? ITunesItemIdentifierLong { set { SetNumberValue (SKStoreProductParameterKey.ITunesItemIdentifier, value); } get { - return GetInt32Value (SKStoreProductParameterKey.ITunesItemIdentifier); + return GetLongValue (SKStoreProductParameterKey.ITunesItemIdentifier); } } diff --git a/tests/monotouch-test/Foundation/DictionaryContainerTest.cs b/tests/monotouch-test/Foundation/DictionaryContainerTest.cs index 1ca025969141..e07ebca50d71 100644 --- a/tests/monotouch-test/Foundation/DictionaryContainerTest.cs +++ b/tests/monotouch-test/Foundation/DictionaryContainerTest.cs @@ -70,6 +70,11 @@ public void SetNumberValue_ (NSString key, nint? value) SetNumberValue (key, value); } + public void SetNumberValue_ (NSString key, long? value) + { + SetNumberValue (key, value); + } + public void SetNumberValue_ (NSString key, nuint? value) { SetNumberValue (key, value); @@ -225,6 +230,25 @@ public void SetNumberValue_UInt32 () Assert.That ((int) dc.Dictionary.Count, Is.EqualTo (0), "0"); } + [Test] + public void SetNumberValue_Int64 () + { + const long value = 2147483648L; + var dc = new DictionaryContainerPoker (); + + Assert.Throws (delegate + { + dc.SetNumberValue_ (null, value); + }, "null key"); + + dc.SetNumberValue_ (key, value); + Assert.That ((int) dc.Dictionary.Count, Is.EqualTo (1), "1"); + Assert.That (((NSNumber) dc.Dictionary [key]).Int64Value, Is.EqualTo (value), "value"); + + dc.SetNumberValue_ (key, (long?) null); + Assert.That ((int) dc.Dictionary.Count, Is.EqualTo (0), "0"); + } + [Test] public void SetStringValue () { diff --git a/tests/monotouch-test/StoreKit/StoreProductParametersTest.cs b/tests/monotouch-test/StoreKit/StoreProductParametersTest.cs new file mode 100644 index 000000000000..07c7f9e0816e --- /dev/null +++ b/tests/monotouch-test/StoreKit/StoreProductParametersTest.cs @@ -0,0 +1,49 @@ +// Copyright (c) Microsoft Corporation. +// Licensed under the MIT License. + +#if !MONOMAC + +using Foundation; +using StoreKit; + +namespace MonoTouchFixtures.StoreKit { + + [TestFixture] + [Preserve (AllMembers = true)] + public class StoreProductParametersTest { + + [Test] + public void ITunesItemIdentifier_64BitRoundtrip () + { + const long identifier = 2147483648L; + + var withCtor = new StoreProductParameters (identifier); + var withSetter = new StoreProductParameters { + ITunesItemIdentifierLong = identifier, + }; + + Assert.That (withCtor.ITunesItemIdentifierLong, Is.EqualTo (identifier), "Ctor"); + Assert.That (withSetter.ITunesItemIdentifierLong, Is.EqualTo (identifier), "Setter"); + Assert.That (((NSNumber) withSetter.Dictionary [SKStoreProductParameterKey.ITunesItemIdentifier]).Int64Value, Is.EqualTo (identifier), "Dictionary"); + } + +#if !XAMCORE_5_0 +#pragma warning disable 618 + [Test] + public void ITunesItemIdentifier_LegacyRoundtrip () + { + const int identifier = 123456789; + + var parameters = new StoreProductParameters { + ITunesItemIdentifier = identifier, + }; + + Assert.That (parameters.ITunesItemIdentifier, Is.EqualTo (identifier), "Legacy"); + Assert.That (parameters.ITunesItemIdentifierLong, Is.EqualTo (identifier), "Long"); + } +#pragma warning restore 618 +#endif + } +} + +#endif From 678260fdf4c22925b84697753c604c49f5d6b447 Mon Sep 17 00:00:00 2001 From: GitHub Actions Autoformatter Date: Wed, 22 Apr 2026 18:29:48 +0000 Subject: [PATCH 2/3] Auto-format source code --- src/StoreKit/StoreProductParameters.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/StoreKit/StoreProductParameters.cs b/src/StoreKit/StoreProductParameters.cs index 52175b034c88..0df519fae233 100644 --- a/src/StoreKit/StoreProductParameters.cs +++ b/src/StoreKit/StoreProductParameters.cs @@ -76,7 +76,7 @@ public int? ITunesItemIdentifier { if (!value.HasValue) return null; - return checked ((int) value.Value); + return checked((int) value.Value); } } #endif From 209830fed1e2bc9642bb5753e47b254a3aaa2dbd Mon Sep 17 00:00:00 2001 From: Rolf Bjarne Kvinge Date: Wed, 22 Apr 2026 21:10:29 +0200 Subject: [PATCH 3/3] Keep existing behavior identical. --- src/StoreKit/StoreProductParameters.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/StoreKit/StoreProductParameters.cs b/src/StoreKit/StoreProductParameters.cs index 0df519fae233..23703195c8b1 100644 --- a/src/StoreKit/StoreProductParameters.cs +++ b/src/StoreKit/StoreProductParameters.cs @@ -69,14 +69,10 @@ public StoreProductParameters (long iTunesItemIdentifier) [Obsolete ("Use 'ITunesItemIdentifierLong' instead.")] public int? ITunesItemIdentifier { set { - ITunesItemIdentifierLong = value; + SetNumberValue (SKStoreProductParameterKey.ITunesItemIdentifier, value); } get { - var value = ITunesItemIdentifierLong; - if (!value.HasValue) - return null; - - return checked((int) value.Value); + return GetInt32Value (SKStoreProductParameterKey.ITunesItemIdentifier); } } #endif