GameCenter and CloudKit on macOS?

My team is trying to integrate the Mac version of our game with Apple’s iCloud and GameCenter leaderboards. We noticed that Unreal has built-in support for these things for iOS targets via OnlineSubsystemIOS, but we don’t see any support for macOS/OSX.

On a whim we tried including OnlineSubsystemIOS in our Mac build but is seemed to be rejected due to build rules. I’m bummed to see this since the objective-C interface for the SDKs is the same for iOS and macOS.

Is there any way we’re missing to get access to Unreal’s wrappers around GameKit and CloudKit on a Maxc

After digging through the source code I think this is a pretty firm no. GameKit support is pretty trivial to add with Objective-C++, but CloudKit seems to be a bit harder.

Hi!, 'm working in a project that also needs GameKit on MacOS, but we are having problems trying to execute Objetive-C on the project, do you have any idea how can we create an Objective-C class and call it from the c++ class?

Yes! The Xcode compiler supports writing Objective-C inline with your C++ without any additional steps. As an example, here’s a snippet from a blueprint-callable function we wrote as a proof-of-concept for unlocking an achievement using Objective-C++:

void UMacOS::WriteAchievement(FString ID, float Percent)
{
#if PLATFORM_MAC
	if (![[GKLocalPlayer localPlayer] isAuthenticated])
		return;

    NSString *nsID = [NSString stringWithUTF8String:TCHAR_TO_ANSI(*ID)]; // convert to NSString

	GKAchievement *achievement = [[GKAchievement alloc] initWithIdentifier:nsID];
	achievement.percentComplete = Percent;
	achievement.showsCompletionBanner = YES;
	[GKAchievement reportAchievements:@[ achievement ]withCompletionHandler:^(NSError *error) {
		if (error != nil)
		{
			// log error
		}
	}];
#else
	// do nothing
#endif
}

I used #if PLATFORM_MAC preprocessor directives here so the compiler only tries to compile the mixed code on macOS, which prevents errors when building on windows. I’m sure there are cleaner ways to do this, but it was enough to prove to ourselves that gamekit integration works.

If you want do define an entire Obj-C class you can just add it in your file like normal. Some of the ios-specific code in the engine uses Objective-C++ if you want more examples.

Thank you very much! I manage to create my own Objective C class. But when I try to use the GKLocalPlayer the xcode project fails to compile :frowning:

// On the .h file 

#pragma once

#import <Foundation/Foundation.h>
#import <GameKit/GKLocalPlayer.h>

#if PLATFORM_MAC

@interface OnlineSubsystemMacOSObj: NSObject

-(void)printSomething;

@end

#endif

//On .cpp

@implementation OnlineSubsystemMacOSObj

- (void)printSomething {
	GKLocalPlayer *localPlayer = [GKLocalPlayer localPlayer];
	if (![localPlayer isAuthenticated]){
        UE_LOG(LogTemp, Warning, TEXT("Test - user is not loged"));
	}
}

@end

The idea is to call the printSomething function to check if there is any user loged.

I got this error on Xcode:

Undefined symbols for architecture x86_64:
  "_OBJC_CLASS_$_GKLocalPlayer", referenced from:
      objc-class-ref in OnlineSubsystemMacOSObj.cpp.o
ld: symbol(s) not found for architecture x86_64

Any ideas?

I’m absolutely not an expert with Unreal’s build systems but I think we had to add something like

PublicFrameworks.AddRange(new string[] {"Foundation", "GameKit" });

to our code’s Build.cs file. Unreal doesn’t surface symbols for GameKit in macOS builds by default.

It works!!! Thank you very much man!!!