Search Unity

[Utility library - iOS] GKNativeExtensions - The missing iOS cloud save feature!

Discussion in 'Assets and Asset Store' started by Dark-1-Games, Mar 13, 2019.

  1. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    We are excited to announce the release of GKNativeExtensions, a small native utility library made to support iOS Cloud save by using the apple-recommended GKSavedGame API.

    The utility library currently supports the following operations:
    • Fetching existing save games
    • Saving a game by name
    • Loading a game by name
    • Deleting a game by name
    • Resolve multiple conflicting saves
    • Registering a callback to be called when a conflict is detected
    • Registering a callback to be called when a save occurs on a different device (not properly tested)
    The project can be found on Github:
    https://github.com/dark-1-games/GKNativeExtensions

    It is licensed under the Mozilla Public License 2.0.

    This should technically work on OSX, but our focus has been iOS. Please let us know if you get it working on OSX.

    The library was made to be integrated in our upcoming cross-platform integration system, DarkCPS, for which we're currently looking for testers
    https://forum.unity.com/threads/darkcps-game-services-simplified-looking-for-testers.697136/

    Comments and feedback are welcome!
     

    Attached Files:

    Last edited: Oct 17, 2019
  2. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Conflict resolution and native callbacks (conflicts and new save) have been added, and version 0.2 is now available for download on github.
    Do note that the conflicting save games callback is only called if two devices save with the same name while disconnected, and only after restarting the game.
    It is possible to manually fetch games and detect the conflict by looking for multiple games with the same name but different deviceName.
     
    OlivierEsolu likes this.
  3. CoCoNutti

    CoCoNutti

    Joined:
    Nov 30, 2009
    Posts:
    496
    Thank you will check this out
     
  4. Zimbres

    Zimbres

    Joined:
    Nov 17, 2014
    Posts:
    100
    Hi there!

    It's great to count with some help on handling data with iCloud. I... i'm not much into c coding or osx, and I'm not sure if I got the whole thing.
    For example, importing the v0.2 unity package gives some errors, like this one:
    Assets/GKNativeExtensions/GKNativeExtensions.cs(83,13): error CS0019: Operator `+=' cannot be applied to operands of type `System.IntPtr' and `int'

    I'm not exactly used to... never touched a IntPtr to be honest. Any clue on why I'm having this problem? Something with Unity3d version? I'm using 2018.2.21f1.
     
  5. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Hey!
    Could you try replacing the contents of GKNativeExtensions.cs with this?
    https://raw.githubusercontent.com/d...ns/master/UnityBindings/GKNativeExtensions.cs

    The release version worked on .NET 4.5+. Since then, a small change by JBurkeKF added support for older versions, but we didn't make a new release.
     
    Zimbres likes this.
  6. Zimbres

    Zimbres

    Joined:
    Nov 17, 2014
    Posts:
    100
    Wow, thanks for the quick reply! I've replaced the code, all fine now! Will be testing the solution on various situations.
     
  7. Headup_Dev

    Headup_Dev

    Joined:
    Sep 18, 2013
    Posts:
    16
    Hi Dark-1-Games,

    have you tried this on tvos too?

    thx for the puplic repo btw :)
     
  8. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Hey there,
    Tvos has never been tested, since we don't have a device to test on but i assume the iOS version would work either OOB or with a couple of small tweaks.
    Please let me know if you manage to get it working, PRs are welcome.
     
    Zimbres and Headup_Dev like this.
  9. Zimbres

    Zimbres

    Joined:
    Nov 17, 2014
    Posts:
    100
    Dark-1, maybe it's a little too much to ask but... would you have a snippet on how to implement your solution? It's not only lazyness of mine, but it would help a lot on the ios building/xcode/iDevice upload routine.
     
  10. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Sure, we really didn't do any documenting on it, so here goes:

    • GKInit(Action<SavedGameDataGameCenter[]> conflictCallback, Action<SavedGameDataGameCenter> modifiedCallback)
      This will initialize the library and give you conflicts, if any exist, and call back the modifiedCallback once a saved game has been modified remotely.

    • GKFetchSavedGames(Action<SavedGameDataGameCenter[]> callback)
      Gets the available save games

    • GKResolveConflicts(SavedGameDataGameCenter[] sgData, byte[] saveArray, Action<bool> callback)
      Resolves the conflicts with the given new data. sgData is a list of conflicted save games, saveArray is the new data to save in bytes, callback executes once the command is finished.

    • GKDeleteGame(string savedGame, Action<bool> callback)
      Deletes a saved game by it's name.

    • GKSaveGame(byte[] data, string savedGameName, Action<SavedGameDataGameCenter> callback)
      Saves given data with a saved game name. The callback gets executed once done, with the resulting game data, or null if failed.

    • GKLoadGame(SavedGameDataGameCenter savedGame, Action<byte[]> savedDataCallback)
      Loads a saved game, and gives you back the loaded data in bytes.

    Note: If conflicts occur, GameKit doesn't ALWAYS tell you through the GKInit. It is necessary to find conflicts yourself by comparing names of SavedGameDataGameCenter returned by GKFetchSavedGames.

    Hope you find this short doc useful, i'll try to add it somewhere in the repo.
     
    Last edited: Jul 4, 2019
    RaL, Headup_Dev and Zimbres like this.
  11. Zimbres

    Zimbres

    Joined:
    Nov 17, 2014
    Posts:
    100
    Absolutely! Hope to report something useful as the time goes.
     
  12. Zimbres

    Zimbres

    Joined:
    Nov 17, 2014
    Posts:
    100
    Nothing really useful... I feel like I should update myself more on the field of delegates. I'm trying to initialize the plugin, but I'm not getting a sign of life. Is the following code correct?

    Code (CSharp):
    1. private void InitializeGKNE() {
    2.         Debug.Log("testando as coisa,");
    3.         GKNativeExtensions.GKInit(ConflictHappened, InitSuccessfull);
    4.     }
    5.     void ConflictHappened(SavedGameDataGameCenter[] ps) {
    6.         Debug.Log("params" + ps);
    7.         base.Initialize();
    8.     }
    9.     void InitSuccessfull(SavedGameDataGameCenter savedGameMeta) {
    10.         Debug.Log("initSuccessfull" + savedGameMeta);
    11. GKNativeExtensions.GKFetchSavedGames(FetchSavedGames);
     
  13. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Hey, sorry, it seems i got something mixed up, you don't need to wait for GKInit callbacks to begin working with the library.

    Code (CSharp):
    1.  
    2. Social.localUser.Authenticate((bool success) =>
    3. {
    4.     GKNativeExtensions.GKInit((conflicts) =>
    5.     {
    6.         Debug.Log("Conflicts received by C#");
    7.  
    8.     }, (modified) =>
    9.     {
    10.         Debug.Log("Modified game received by C#");
    11.     });
    12.  
    13.     if (!success)
    14.     {
    15.         callback(null);
    16.         return;
    17.     }
    18. });
    19.  
    20. // ... After GKInit is called...
    21.  
    22. GKNativeExtensions.GKFetchSavedGames((savedGameData) =>
    23. {
    24.     Debug.Log("Got saved games!");
    25. });
    26.  
    Also, may i interest you in another higher-level library we're working on, essentially covering the same stuff?
    https://forum.unity.com/threads/darkcps-game-services-simplified-looking-for-testers.697136/
     
    Headup_Dev likes this.
  14. Headup_Dev

    Headup_Dev

    Joined:
    Sep 18, 2013
    Posts:
    16
    Hey there,

    it looks like the class GKSavedGame from GameKit does not support tvOS at all. Other classes from GameKit work but GKSavedGame is excluded. I tried to build the library from XCode but could not get past this error. I am not a pro though so let me know if you have an idea how to fix this.
     
  15. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    I guess you're right, i can't see tvos listed here:
    https://developer.apple.com/documentation/gamekit/gksavedgame
    But it's available in GKLocalPlayer:
    https://developer.apple.com/documentation/gamekit/gklocalplayer

    Guess no tvOS :(
     
    Headup_Dev likes this.
  16. dotsquid

    dotsquid

    Joined:
    Aug 11, 2016
    Posts:
    146
    @Dark-1-Games, hi! Thanks for the library.
    Can you please explain the procedure of initialization and loading of games stored in the cloud?
    As far as I understand, I should call GKInit and then call GKFetchSavedGames to get all the saved games and use one of them in GKLoadGame. If there are any conflicts I should get an array of conflicting games through the callback passed to GKInit. However, if there are no conflicts the callback won't be invoked, right?
    So on which stage should I wait for any conflicts to resolve them before loading actual data and use them in the game? Or do I misunderstand the concept behind GKResolveConflicts?
     
  17. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Hi,
    It's not super clear from apple's documentation when the conflicts callback is called exactly, but from prior testing i believe it's called if the game is running on one device and then another device saves the data at the same time (with a delay of a minute or more). However, if you're just starting the app and there's already a conflict, the callback won't be called. You need to also manually check for conflicting save game names when you get the loaded games back and call GKResolveConflicts with the resolution.

    To save yourself the headache of managing most of cloud features on iOS, Android and Steam, i would like to invite you to try out our unity asset, DarkCPS
     
  18. dotsquid

    dotsquid

    Joined:
    Aug 11, 2016
    Posts:
    146
    Thank you for a quick reply.
    Now it's a little bit clearer for me =)
    Thanks for your invitation, but the problem is the we've already released on Steam and now we are in a process of porting to iOS. So we already have an integration with Steam and switching to a 3rd-party plugin would take unnecessary time.
    Good luck with DarkCPS!
     
  19. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Sure, good luck with the project!
     
  20. denkacn

    denkacn

    Joined:
    May 13, 2011
    Posts:
    9
    Hi @Dark-1-Games
    An error occurred while building in Xcode
    Bitcode bundle could not be generated because '/Libraries/GKNativeExtensions/Plugins/IOS/libGKNativeExtensions.a(GKNativeExtensions.o)' was built without full bitcode. All object files and libraries for bitcode must be generated from Xcode Archive or Install build for architecture armv7
     
  21. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    Hi,

    You can build from source with whichever options you want, just open up the GKNativeExtensions Xcode project and you're good to build.
     
  22. denkacn

    denkacn

    Joined:
    May 13, 2011
    Posts:
    9
    Ok, I try it, Thanks))
     
  23. Jeeeenunity

    Jeeeenunity

    Joined:
    Sep 16, 2017
    Posts:
    2
    Hi, thanks for the good lib.

    Unfortunately I am faced with the problem that iCloud synchronization doesn’t work at the first launch after installing of the app. Although I see that there are some save files on iCloud, GKNativeExtensions tells me that there are 0 save games for me. And after the second launch of the app synchronization works as it should.

    The second problem is that from time to time I receive an error «You don’t have permission to save the file “com~apple~CloudDocs_0456C65C-D519-481E-AB31-C94777627A03_15up.bundle” in the folder “com.apple.ubiquity”. This error blocks me from saving games to iCloud. It worth to mention that I have iCloud capability enabled, correct entitlements, and iCloud container for the app.

    Please tell me if there are some ways to solve these issues.

    Thanks.
     
  24. Dark-1-Games

    Dark-1-Games

    Joined:
    Mar 26, 2014
    Posts:
    29
    The first one is a known issue that's been reported to apple, and it seems like it's fixed in the latest beta of iOS. Meanwhile, a workaround is to wait for some time (like 5-10s) and poll for changes, only on the first launch.

    I've never encountered the second issue, but i think the issue might be that user is not successfully authenticated on gamecenter before the games are loaded.
     
    dotsquid likes this.
  25. Jeeeenunity

    Jeeeenunity

    Joined:
    Sep 16, 2017
    Posts:
    2
    Thanks! I'll give your workaround a try.
     
unityunity