Author Topic: How to uses iCloud using Keystore for iOS (tested succes with iOS7 and iOS8).  (Read 6705 times)

Offline spacefractal

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 3482
    • View Profile
    • Space Fractal
First at all, you must get code signing with iCloud to work, this is something like this:
http://www.raywenderlich.com/6015/beginning-icloud-in-ios-5-tutorial-part-1

my Entitlements file look like this:
Code: GLBasic [Select]
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
        <key>com.apple.developer.ubiquity-container-identifiers</key>
        <array>
                <string>*TEAMID*.com.spacefractal.greedymouse</string>
        </array>
        <key>com.apple.developer.ubiquity-kvstore-identifier</key>
        <string>*TEAMID*.com.spacefractal.greedymouse</string>
        <key>keychain-access-groups</key>
        <array>
                <string>*APPID*.com.spacefractal.greedymouse</string>
        </array>
</dict>
</plist>
 

This is the hardest part to get working, because code signing is allways annoying with iOS. But when that is working, rest is pretty simple.

iCloud.m:
Code: GLBasic [Select]
#import <Foundation/NSObject.h>
#import <Foundation/NSString.h>
#import <Foundation/NSFileManager.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSBundle.h>
#import <string.h>
#import <Foundation/Foundation.h>

char iString[512]="";
NSUbiquitousKeyValueStore *keyStore;

int CloudInit()
{       keyStore = [[NSUbiquitousKeyValueStore alloc] init];
    if (keyStore)
        return 1;
    return 0;
}

void CloudPut(const char* name, const char* value)
{   NSString *nameID = [[NSString alloc] initWithUTF8String:name];
    NSString *valueID = [[NSString alloc] initWithUTF8String:value];
   // NSLog(@": put %@", valueID);
    [keyStore setString:valueID forKey:nameID];
}

const char* CloudGet(const char* name)
{   NSString *nameID = [[NSString alloc] initWithUTF8String:name];
    NSString *valueID = [keyStore objectForKey:nameID];
    if (valueID)
    { //  NSLog(@": get %@", nameID);
      //  NSLog(@": value %@", valueID);
        strcpy(iString, [valueID UTF8String]);
        return iString;
    }

    valueID = @"";
    strcpy(iString, [valueID UTF8String]);
    return iString;
}

void CloudSync()
{   [keyStore synchronize];
   // NSLog(@": CloudSync");
}
 

Glbasic:
Code: GLBasic [Select]
// --------------------------------- //
// Project: iCloud - Space Fractal
// Start: Friday, September 05, 2014
// IDE Version: 12.096

GLOBAL ISICLOUINIT=0

FUNCTION iCLOUDINIT:
        ?IFDEF IPHONE
                IF ISICLOUINIT=1 THEN RETURN
                IMPORT "C" int CloudInit()
                ISICLOUINIT=CloudInit()
        ?ELSE
                ISICLOUINIT=1
        ?ENDIF
ENDFUNCTION

FUNCTION iCLOUDPUT: name$, value$
        ?IFDEF IPHONE
                IF ISICLOUINIT=0 THEN RETURN
                IMPORT "C" void CloudPut(const char*, const char*)
                CloudPut(name$, value$)
                RETURN
        ?ENDIF
        DEPRINT("put: "+name$+" "+value$)
ENDFUNCTION

FUNCTION iCLOUDGET$: name$
        LOCAL value$=""
        ?IFDEF IPHONE
                IF ISICLOUINIT=0 THEN RETURN
                IMPORT "C" const char* CloudGet(const char*)
                value$=CloudGet(name$)
                RETURN value$
        ?ENDIF
        RETURN value$
ENDFUNCTION

FUNCTION iCLOUDSYNC:
        ?IFDEF IPHONE
                IF ISICLOUINIT=0 THEN RETURN
                IMPORT "C" void CloudSync()
                CloudSync()
        ?ENDIF
ENDFUNCTION
 

For uses:
Call iCLOUDINIT() top in your code or there the game got loading
Call value$=iCLOUDGET$(name$) to get value of a keystring.
Call iCLOUDPUT(name$, value$) to put a value to a keystring.

when you are finish all keys, then call a CloudSync() to sync with iCloud.

Example:
A example to uses iCloud in my games was to checking hiscores and medals for each levels and make sure only the highest score wins. if its local, then im PUT it, but when its from iCloud, make sure to update it. Here is a example for using with hiscore for a each level:
Code: GLBasic [Select]
FUNCTION Game_Synccloud: value$, name$

        LOCAL name2$=value$+name$
        name2$=REPLACE$(name2$, "_", "")
        name2$=TRIM$(name2$)

        LOCAL sc2=iCLOUDGET$(name2$)
        LOCAL sc=GetStr$(value$, name$)
        IF sc>sc2
                IF sc>0 THEN iCLOUDPUT(name2$, sc)
        ELSE
                IF sc2>0 THEN SetStr(value$, name$, sc2)
        ENDIF
ENDFUNCTION
 

GetStr and SetStr is from this thread (just to give the idea):
http://www.glbasic.com/forum/index.php?topic=6367.msg50949#msg50949

There is some limit on the size. Im wont replicate it here, so:
https://developer.apple.com/library/mac/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForKey-ValueDataIniCloud.html



« Last Edit: 2014-Sep-08 by spacefractal »
Greedy Mouse - Karma Miwa - Spot Race - CatchOut - Android Extras - is on a vacation trip, home before end of few days in jan.

Offline erico

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 4116
    • View Profile
    • Portfolio
I know it is somehow  :offtopic: but the work you push back into this community is really amazing! :good:

Offline Hemlos

  • To boldy go where no pixel has gone before!
  • Global Moderator
  • Prof. Inline
  • *******
  • Posts: 1579
  • Particle Hawk
    • View Profile
Definetely looks useful, going sticky mode.
Volume_of_Earth(km^3) = 4/3*3.14*POW(6371.392896,3)

Offline bigsofty

  • Community Developer
  • Prof. Inline
  • ******
  • Posts: 2542
    • View Profile
Cheers,

Ian.

“It is practically impossible to teach good programming style to students that have had prior exposure to BASIC.  As potential programmers, they are mentally mutilated beyond hope of regeneration.”
(E. W. Dijkstra)