Skip to content

Commit

Permalink
[GameKit] Implement Xcode 16.0 beta 1-6 changes. (#20880)
Browse files Browse the repository at this point in the history
Note: there were no changes in beta 2, beta 3, beta 4, beta 5 or beta 6.
  • Loading branch information
rolfbjarne authored Aug 26, 2024
1 parent 6302fe7 commit 19b925e
Show file tree
Hide file tree
Showing 22 changed files with 188 additions and 140 deletions.
59 changes: 59 additions & 0 deletions src/GameKit/GKGameCenterViewController.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#if !WATCH
using System;

using Foundation;
using ObjCRuntime;

namespace GameKit {
/// <summary>This enum is used to select how to initialize a new instance of a <see cref="GKGameCenterViewController" />.</summary>
public enum GKGameCenterViewControllerInitializationOption {
/// <summary>The <c>id</c> parameter passed to the constructor is an achievement ID.</summary>
Achievement,
/// <summary>The <c>id</c> parameter passed to the constructor is a leaderboard set ID.</summary>
LeaderboardSet,
}

public partial class GKGameCenterViewController {
/// <summary>Create a new GKGameCenterViewController instance that presents an achievement.</summary>
/// <param name="achievementId">The ID of the achievement to show.</param>
#if NET
[SupportedOSPlatform ("ios14.0")]
[SupportedOSPlatform ("maccatalyst14.0")]
[SupportedOSPlatform ("macos11.0")]
[SupportedOSPlatform ("tvos14.0")]
#else
[TV (14, 0), Mac (11, 0), iOS (14, 0), MacCatalyst (14, 0)]
#endif
public GKGameCenterViewController (string achievementId)
: this (achievementId, GKGameCenterViewControllerInitializationOption.Achievement)
{
}

/// <summary>Create a new GKGameCenterViewController instance that presents an achievement or a leaderboard set.</summary>
/// <param name="id">The ID of the achievement or the leaderboard set to show.</param>
/// <param name="option">Use this option to specify whether the GKGameCenterViewController shows an achievement or a leader board set.</param>
#if NET
[SupportedOSPlatform ("ios18.0")]
[SupportedOSPlatform ("maccatalyst18.0")]
[SupportedOSPlatform ("macos15.0")]
[SupportedOSPlatform ("tvos18.0")]
#else
[TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
#endif
public GKGameCenterViewController (string id, GKGameCenterViewControllerInitializationOption option)
: base (NSObjectFlag.Empty)
{
switch (option) {
case GKGameCenterViewControllerInitializationOption.Achievement:
InitializeHandle (_InitWithAchievementId (id));
break;
case GKGameCenterViewControllerInitializationOption.LeaderboardSet:
InitializeHandle (_InitWithLeaderboardSetId (id));
break;
default:
throw new ArgumentOutOfRangeException (nameof (option), option, "Invalid enum value.");
}
}
}
}
#endif // !WATCH
4 changes: 4 additions & 0 deletions src/GameKit/GameKit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,10 @@ public enum GKPlayerConnectionState : long {
}

// NSInteger -> GKVoiceChat.h
[Deprecated (PlatformName.iOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacCatalyst, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.TvOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacOSX, 15, 0, message: "No longer supported.")]
[Native]
public enum GKVoiceChatPlayerState : long {
Connected,
Expand Down
1 change: 1 addition & 0 deletions src/frameworks.sources
Original file line number Diff line number Diff line change
Expand Up @@ -946,6 +946,7 @@ GAMEKIT_API_SOURCES = \
GameKit/GameKit.cs \

GAMEKIT_SOURCES = \
GameKit/GKGameCenterViewController.cs \
GameKit/GKLocalPlayerListener.cs \
GameKit/GameKit2.cs \
GameKit/GKCompat.cs \
Expand Down
55 changes: 41 additions & 14 deletions src/gamekit.cs
Original file line number Diff line number Diff line change
Expand Up @@ -535,10 +535,8 @@ interface GKLeaderboardSet : NSCoding, NSSecureCoding {
[Async]
void LoadLeaderboardsWithCompletionHandler (GKLeaderboardsHandler handler);

[NoMac]
[NoTV]
[NoWatch]
[NoMacCatalyst]
[Export ("loadImageWithCompletionHandler:")]
[Async]
void LoadImage ([NullAllowed] GKImageLoadedHandler completionHandler);
Expand Down Expand Up @@ -917,8 +915,7 @@ interface GKLocalPlayer
Action<NSViewController, NSError> AuthenticateHandler { get; set; }
#endif

[NoWatch, NoTV, Mac (12, 0), iOS (15, 0)]
[NoMacCatalyst]
[NoWatch, NoTV, Mac (12, 0), iOS (15, 0), MacCatalyst (15, 0)]
[Export ("isPresentingFriendRequestViewController")]
bool IsPresentingFriendRequestViewController { get; }

Expand Down Expand Up @@ -1160,6 +1157,10 @@ interface GKMatch {
[Export ("disconnect")]
void Disconnect ();

[Deprecated (PlatformName.iOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacCatalyst, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.TvOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacOSX, 15, 0, message: "No longer supported.")]
[Export ("voiceChatWithName:")]
[return: NullAllowed]
GKVoiceChat VoiceChatWithName (string name);
Expand Down Expand Up @@ -1254,6 +1255,10 @@ interface GKMatchDelegate {
void DataReceivedForRecipient (GKMatch match, NSData data, GKPlayer recipient, GKPlayer player);
}

[Deprecated (PlatformName.iOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacCatalyst, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.TvOS, 18, 0, message: "No longer supported.")]
[Deprecated (PlatformName.MacOSX, 15, 0, message: "No longer supported.")]
[NoWatch]
[MacCatalyst (13, 1)]
[BaseType (typeof (NSObject))]
Expand Down Expand Up @@ -1520,7 +1525,7 @@ interface GKMatchmaker {
[TV (17, 2), Mac (14, 2), iOS (17, 2), MacCatalyst (17, 2)]
[Async]
[Export ("findMatchedPlayers:withCompletionHandler:")]
void FindMatchedPlayers (GKMatchRequest request, [NullAllowed] Action<GKMatchedPlayers, NSError> completionHandler);
void FindMatchedPlayers (GKMatchRequest request, Action<GKMatchedPlayers, NSError> completionHandler);

// Not truly an [Async] method since the handler can be called multiple times, for each player found
[MacCatalyst (13, 1)]
Expand Down Expand Up @@ -2525,26 +2530,36 @@ interface GKGameCenterViewController
[Export ("initWithNibName:bundle:")]
NativeHandle Constructor ([NullAllowed] string nibNameOrNull, [NullAllowed] NSBundle nibBundleOrNull);

[TV (14, 0), NoWatch, Mac (11, 0), iOS (14, 0)]
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
[Export ("initWithLeaderboardID:playerScope:timeScope:")]
NativeHandle Constructor (string leaderboardId, GKLeaderboardPlayerScope playerScope, GKLeaderboardTimeScope timeScope);

[TV (14, 0), NoWatch, Mac (11, 0), iOS (14, 0)]
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
[Export ("initWithLeaderboard:playerScope:")]
NativeHandle Constructor (GKLeaderboard leaderboard, GKLeaderboardPlayerScope playerScope);

[TV (14, 0), NoWatch, Mac (11, 0), iOS (14, 0)]
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
[Export ("initWithAchievementID:")]
NativeHandle Constructor (string achievementId);
[Internal]
NativeHandle _InitWithAchievementId (string achievementId);

[TV (14, 0), NoWatch, Mac (11, 0), iOS (14, 0)]
[TV (14, 0), Mac (11, 0), iOS (14, 0)]
[MacCatalyst (14, 0)]
[Export ("initWithState:")]
NativeHandle Constructor (GKGameCenterViewControllerState state);

[TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("initWithLeaderboardSetID:")]
[Internal]
NativeHandle _InitWithLeaderboardSetId (string leaderboardSetId);

[TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("initWithPlayer:")]
NativeHandle Constructor (GKPlayer player);

[Export ("gameCenterDelegate", ArgumentSemantic.Weak), NullAllowed]
NSObject WeakDelegate { get; set; }

Expand Down Expand Up @@ -3110,6 +3125,22 @@ interface GKAccessPoint {

[Export ("triggerAccessPointWithState:handler:")]
void TriggerAccessPoint (GKGameCenterViewControllerState state, Action handler);

[Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("triggerAccessPointWithAchievementID:handler:")]
void TriggerAccessPointWithAchievementId (string achievementId, [NullAllowed] Action handler);

[Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("triggerAccessPointWithLeaderboardSetID:handler:")]
void TriggerAccessPointWithLeaderboardSetId (string leaderboardSetId, [NullAllowed] Action handler);

[Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("triggerAccessPointWithLeaderboardID:playerScope:timeScope:handler:")]
void TriggerAccessPoint (string leaderboardId, GKLeaderboardPlayerScope playerScope, GKLeaderboardTimeScope timeScope, [NullAllowed] Action handler);

[Watch (11, 0), TV (18, 0), Mac (15, 0), iOS (18, 0), MacCatalyst (18, 0)]
[Export ("triggerAccessPointWithPlayer:handler:")]
void TriggerAccessPoint (GKPlayer player, [NullAllowed] Action handler);
}

[Watch (7, 0), TV (14, 0), Mac (11, 0), iOS (14, 0)]
Expand All @@ -3120,9 +3151,6 @@ interface GKLeaderboardEntry {
[Export ("player", ArgumentSemantic.Strong)]
GKPlayer Player { get; }

#if false
// Some APIs missing on iOS, tvOS, watchOS as of Xcode 12 beta 3 - https://github.com/xamarin/maccore/issues/2269
// disabled since the selectors don't respond on macOS 11.0
[Export ("rank")]
nint Rank { get; }

Expand All @@ -3137,7 +3165,6 @@ interface GKLeaderboardEntry {

[Export ("date", ArgumentSemantic.Strong)]
NSDate Date { get; }
#endif

[NoWatch] // header lists watch as supported, but UIViewController is not available on Watch!
[MacCatalyst (13, 1)]
Expand Down
33 changes: 33 additions & 0 deletions tests/introspection/ApiSelectorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1031,6 +1031,35 @@ protected virtual bool Skip (Type type, string selectorName)
return !TestRuntime.CheckXcodeVersion (16, 0);
}
break;
case "GKLeaderboardEntry":
// It's not possible to create an instance of GKLeaderboardEntry, so I believe that whenever Apple
// returns an instance they return something that responds to these selectors, thus we have to
// provide bindings for them.
switch (selectorName) {
case "context":
case "date":
case "formattedScore":
case "rank":
case "score":
return true;
}
break;
#if __MACCATALYST__
case "GKLeaderboardSet":
switch (selectorName) {
case "loadImageWithCompletionHandler:":
// This exists in both iOS and macOS, so not existing in Mac Catalyst is weird - so just provide the binding.
return true;
}
break;
case "GKLocalPlayer":
switch (selectorName) {
case "isPresentingFriendRequestViewController":
// This exists in both iOS and macOS, so not existing in Mac Catalyst is weird - so just provide the binding.
return true;
}
break;
#endif // __MACCATALYST__
}

// old binding mistake
Expand Down Expand Up @@ -1287,6 +1316,10 @@ protected virtual bool SkipInit (string selector, MethodBase m)
// DDDevicePickerViewController
case "initWithBrowseDescriptor:parameters:":
return true;
// GKGameCenterViewController
case "initWithAchievementID:":
case "initWithLeaderboardSetID:":
return true;
default:
return false;
}
Expand Down
50 changes: 50 additions & 0 deletions tests/monotouch-test/GameKit/GKGameCenterViewControllerTest.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
//
// Unit tests for GKGameCenterViewControllerTest
//

#if !__WATCHOS__

using System;
using Foundation;
using ObjCRuntime;
#if MONOMAC
using AppKit;
#else
using UIKit;
#endif
using GameKit;
using NUnit.Framework;
using Xamarin.Utils;

namespace MonoTouchFixtures.GameKit {

[TestFixture]
[Preserve (AllMembers = true)]
public class GKGameCenterViewControllerTest {
[Test]
public void StringCtor ()
{
TestRuntime.AssertXcodeVersion (12, 0);
using var controller = new GKGameCenterViewController ("achievementId");
Assert.AreEqual (controller.ViewState, GKGameCenterViewControllerState.Achievements, "ViewState");
}

[Test]
public void StringOptionCtor_AchievementId ()
{
TestRuntime.AssertXcodeVersion (12, 0);
using var controller = new GKGameCenterViewController ("achievementId", GKGameCenterViewControllerInitializationOption.Achievement);
Assert.AreEqual (controller.ViewState, GKGameCenterViewControllerState.Achievements, "ViewState");
}

[Test]
public void StringOptionCtor_LeaderboardSetId ()
{
TestRuntime.AssertXcodeVersion (16, 0);
using var controller = new GKGameCenterViewController ("achievementId", GKGameCenterViewControllerInitializationOption.LeaderboardSet);
Assert.AreEqual (controller.ViewState, GKGameCenterViewControllerState.Leaderboards, "ViewState");
}
}
}

#endif // !__WATCHOS__

This file was deleted.

This file was deleted.

11 changes: 0 additions & 11 deletions tests/xtro-sharpie/api-annotations-dotnet/common-GameKit.ignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,3 @@

## enum size declared after the enum, e.g. `typedef NSInteger GKInviteeResponse;`, so we miss the metadata
!unknown-native-enum! GKInviteeResponse bound

# Xcode 12 beta 3 - these API are missing
# https://github.com/xamarin/maccore/issues/2269
!missing-selector! GKLeaderboardEntry::context not bound
!missing-selector! GKLeaderboardEntry::date not bound
!missing-selector! GKLeaderboardEntry::formattedScore not bound
!missing-selector! GKLeaderboardEntry::rank not bound
!missing-selector! GKLeaderboardEntry::score not bound

## unsorted

2 changes: 0 additions & 2 deletions tests/xtro-sharpie/api-annotations-dotnet/iOS-GameKit.ignore

This file was deleted.

8 changes: 0 additions & 8 deletions tests/xtro-sharpie/api-annotations-dotnet/iOS-GameKit.todo

This file was deleted.

12 changes: 0 additions & 12 deletions tests/xtro-sharpie/api-annotations-dotnet/macOS-GameKit.ignore
Original file line number Diff line number Diff line change
@@ -1,19 +1,7 @@
# The parent enum GKVoiceChatService is not available in macOS
# so to be honest it does not make much sense to expose this constant on macOS
# nor the below protocols

# This selector does not exist in macOS, confirmed by intro.

# Deprecated
!missing-protocol-member! GKInviteEventListener::player:didRequestMatchWithPlayers: not found
!missing-protocol-member! GKTurnBasedEventListener::player:didRequestMatchWithPlayers: not found

# We have bound GKVoiceChatServiceError as GKVoiceChatServiceError which has no support for macOS
!missing-field! GKVoiceChatServiceErrorDomain not bound
# https://developer.apple.com/documentation/gamekit/gkvoicechatserviceerror?language=objc

# This selector does not exist (respond?) in macOS either
!missing-selector! GKLeaderboardSet::loadImageWithCompletionHandler: not bound

# NullAllowed makes sense
!extra-null-allowed! 'System.Void GameKit.GKMatchmaker::FindMatchedPlayers(GameKit.GKMatchRequest,System.Action`2<GameKit.GKMatchedPlayers,Foundation.NSError>)' has a extraneous [NullAllowed] on parameter #1
8 changes: 0 additions & 8 deletions tests/xtro-sharpie/api-annotations-dotnet/macOS-GameKit.todo

This file was deleted.

2 changes: 0 additions & 2 deletions tests/xtro-sharpie/api-annotations-dotnet/tvOS-GameKit.ignore

This file was deleted.

8 changes: 0 additions & 8 deletions tests/xtro-sharpie/api-annotations-dotnet/tvOS-GameKit.todo

This file was deleted.

Loading

8 comments on commit 19b925e

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

@vs-mobiletools-engineering-service2

This comment was marked as outdated.

Please sign in to comment.