Unity3D game development requires access to platform SDK before it can be officially released. This paper records the access process of iOS SDK.
Unity and iOS intermodulation
To realize the access of game SDK, the first thing to solve is the mutual call between Unity3D and native iOS code. Unity uses C# as the development language, IOS uses Objective-C as the development language, how to get C# to call OC code, or OC to call C# code. Fortunately, OC and C# both support direct embedding of C/C++ code, so C is used as a bridge between the two.
In order to simplify the interface call and data transfer between the two, when designing the interface between Unity and IOS SDK, Unity calls SDK with only one interface, and SDK calls Unity with only one interface. How to ensure that one interface can solve the problem since the SDKS on the platform vary greatly? Here we developed a common SDK layer, and the game only interacted with the common SDK layer, which in turn interacted with the specific platform SDK.
Calling the SDK layer in Unity:
using System.Runtime.InteropServices; using Cross; using UnityEngine; namespace MuGame { public class IOSPlatformSDK : IPlotformSDK { //! --IOS plugin declaration, [DllImport("__Internal")] public static extern void CallSDKFunc(string type, string jsonpara);Copy the code
All calls in Unity are converted to CallSDKFunc, which is provided by the common SDK. The parameter type represents the function classification, and jsonpara is a series of parameters represented by a JSON string.
Common SDK calls return results to Unity
/ /! -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- the external interface declaration -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- # if defined (__cplusplus) extern "C" { #endif extern void UnitySendMessage(const char*, const char*, const char*); #if defined(__cplusplus) } #endifCopy the code
The C interface UnitySendMessage provided by unityEngine.dll is used here, where the first char* represents the name of the GameObject that received the message, the second char* represents the name of the function that received the message in the script of this GameObject, and the third char* represents the data passed. Here we’ll use JSON for the delivery, along with the message type.
Declaration and definition of C interface exposed by SDK
# define (__cplusplus) extern "C" {# define (__cplusplus) extern "C" {# define (__cplusplus) extern "C" { char * jsonpara) { if(connector == NULL) { connector = [SDKConnector sharedInstance]; } [connector _CallSDKFunc :CreateNSString(type) :CreateNSString(jsonpara)]; } #if defined(__cplusplus) } #endifCopy the code
In this case, CallSDKFunc is the interface that Unity calls SDK above, which is directly received by SDKConnector class in OC layer and distributed for processing.
IOS development exchange technology group: 563513413, no matter you are big bull or small white are welcome to enter, share BAT, Ali interview questions, interview experience, discuss technology, we exchange learning and growth together!
General the SDK
SDKConnector is responsible for message distribution
- (void)_CallSDKFunc :(NSString*)type :(NSString*)jsonpara { NSLog(@"[SDK] Recevie cmd = %@ jsonpara = %@\n",type,jsonpara); If ([type isEqualToString:@"login"]) {// Login [LanPlatform login:[SDKListener sharedInstance]]; } else if ([type isEqualToString:@"loginout"]) {// logout of [LanPlatform logout:[SDKListener sharedInstance]]; } else if ([type isEqualToString:@"switchAccount"]) {LanPlatform switchAccount:[SDKListener sharedInstance]]; } else if ([type isEqualToString:@"pay"]) {LanPlatform pay:[SDKListener sharedInstance]]; }Copy the code
Here, the message is distributed to the corresponding processing module of the general SDK layer according to type type, and then the general SDK layer calls the PLATFORM SDK API for specific processing. Note that an instance SDKListener is passed in here, which is responsible for receiving the response from the platform SDK and sending the data to the Unity side.
Common SDK layer functionality
Currently includes the following common modules: login, logout, account switching, recharge, user center, user forum, user feedback, anti-addiction, real name authentication. Report game data: select server, enter the game, create character, upgrade, etc.
Application lifecycle SDK
A special class of APIS in SDKS, and one that almost all SDKS need access to, is the lifecycle API, and this article deals with item pairs in a special way.
@protocol SDKLifeCycleListener <NSObject> @optional - (void)didFinishLaunching:(NSNotification*)notification; - (void)didBecomeActive:(NSNotification*)notification; - (void)willResignActive:(NSNotification*)notification; - (void)didEnterBackground:(NSNotification*)notification; - (void)willEnterForeground:(NSNotification*)notification; - (void)willTerminate:(NSNotification*)notification; @ the end / / registered lifecycle callback function void SDKRegisterLifeCycleListener (id < SDKLifeCycleListener > obj) {# define REGISTER_SELECTOR (sel, notif_name) \ if([obj respondsToSelector:sel]) \ [[NSNotificationCenter defaultCenter] addObserver:obj \ selector:sel \ name:notif_name \ object:nil \ ]; \ REGISTER_SELECTOR(@selector(didFinishLaunching:), UIApplicationDidFinishLaunchingNotification); REGISTER_SELECTOR(@selector(didBecomeActive:), UIApplicationDidBecomeActiveNotification); REGISTER_SELECTOR(@selector(willResignActive:), UIApplicationWillResignActiveNotification); REGISTER_SELECTOR(@selector(didEnterBackground:), UIApplicationDidEnterBackgroundNotification); REGISTER_SELECTOR(@selector(willEnterForeground:), UIApplicationWillEnterForegroundNotification); REGISTER_SELECTOR(@selector(willTerminate:), UIApplicationWillTerminateNotification); #undef REGISTER_SELECTOR }Copy the code
It defines a SDK agreement SDKLifeCycleListener listening, life cycle and registered interface SDKRegisterLifeCycleListener of this agreement. When the App loads, the listener is registered with the SDKListener, which implements the protocol.
+(void)load {NSLog(@"[SDK] load\n"); SDKRegisterLifeCycleListener([SDKListener sharedInstance]); }Copy the code
Conclusion;
So far, I’ve outlined the implementation of the iOS SDK. In short, Unity invokes common SDK functionality via CallSDKFunc, and the common SDK distributes messages to specific common SDK modules via SDKConnector, which are then processed by the platform SDK. The SDKListener is responsible for receiving the results and lifecycle events processed by the platform and returning the desired results to Unity.
As far as the current implementation is concerned, the connection between the game and SDK can be relatively decoupled, and the game code will not be changed frequently due to the difference of the platform. Of course, there are still relatively few SDKS that need to be tested.