CloudKit for near realtime exchange of small data?

I need to exchange small amounts of data in my app near realtime between users who could be anywhere with only an internet connection. One user becomes a team leader and needs to send data (just a few bytes) to all other users on their team - up to 50 - about each second. Then each team member needs to send data (again, just a few bytes) back to the leader about each second. The requirement is similar to the example app from last year's WWDC networking part 2 video called TicTacToe, except the users may not be local.


Is CloudKit a good fit for this requirement? I'd like to use it due to its easy integration with iOS apps, no need to setup or maintain a server environment and the way it deals with security. But I'm unclear as to whether CloudKit performance can deliver small records at that speed.


Does anyone have a voice of experience using CloudKit for small, quick data exchanges? If not, is there another iOS framework I should consider? I've looked at GameKit but asking users to initiate a session in gamekit is a requirement I'd rather avoid.


Thanks in advance for any guidance.

Replies

I have seen CloudKit deliver 1K of data in under 1 second, but I've also seen it take more 10 seconds or more to deliver the same 1K of data. As far as I know it makes no performance guarantees.


(I've used CloudKit many times to move small bits of data between devices, but never for time-critical use. It's certainly quick enough—by the time I've made a change on Device A and look over to Device B, the update's often already complete—but depending on your requirements the occasionally higher latency might make it unsuitable.)

Just the kind of experienced input I was hoping to find! Thanks so much for your quick and helpful reply.


If anyone else has had similar or differing experiences with CloudKit, I hope to hear you as well.

I tried to use CloudKit to deliver 'real time' info for a game (Go Game Connect). It started sending errors when I tried to access it repeatedly. I don't recall the cutoff rate but i do recall reading about some limit of 'calls per second'. It is not designed for this purpose. Game Center (GKMatch and GKMatchmakerViewController) has a real time match system that I ended up using, quite successfully.

While PBK's gamekit suggestion seemed perfect, after implementing, I see that Game Center limits to peer to peer are 4 players per GKMatch.


Could someone recommend another method of communicaing small amounts of near real-time data from one app instance to another across the internet for 20 or so users at a time? Extra credit for an Apple framework that can handle the security and server items.


Thanks in advance!

Sorry that the GC thing didn't work out for you. My recommendation for something like this would be either Firebase (use their Realtime Database, not Firestore, which has somewhat worse latency) or a combination of a slower persistence layer like CloudKit and a platform like Ably / PubNub / Pusher for the realtime component. Within the Apple ecosystemy I have not heard of somethign that would achieve what you are looking for and am even surprised GC lives up to this. Out of curiousity, could you confirm whether the GC implementation actually worked for you over internet vs just locally and whether performance was sufficient?

Game Center does work over the internet, and I'm currently experiementing with creating multiple GKMatch(es) on the "lead" device so that more than 4 'followers' can be connected.


Thanks for the recommendation of Firebase, I'll take a look if I can't get GameKit to work. I hope I can, as staying inside Apple walls makes me feel safe ;-)


I'll update in a few days when I have more experience with testing.

Ah interesting approach. Yes, I'd be extremely curious to hear how that panned out (and if you ran into any noteworthy pitfalls or documentation inaccuracies. Been having a lot of fun with the latter trying to mess with CloudKit.js). Really appreciate you sharing this experiment here.

I have mixed results to report. I've been able to achieve most of my objectives with an atypical GameKit implementation:


Follower starts:

[[GKLocalPlayer localPlayer] registerListener:self];

request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

request.playerAttributes = 0x0000000F;

request.playerGroup = groupName;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...


Leader starts:

[[GKLocalPlayer localPlayer] registerListener:self];

request = [[GKMatchRequest alloc] init];

request.minPlayers = 2;

request.maxPlayers = 2;

request.playerAttributes = 0xFFFFFFF0;

request.playerGroup = groupName;

[[GKMatchmaker sharedMatchmaker] findMatchForRequest:request...


You can update UI with the completion handlers, but don't count on a real match until:

- (void)match:(GKMatch *)match

player:(GKPlayer *)player

didChangeConnectionState:(GKPlayerConnectionState)state

{

use the match / player combo to note the connection for both leader and follower. Add to array of followers for leader. If Leader, call your leader code again

}


Send data to either with:

[match sendData:encoder.encodedData toPlayers:playerArray dataMode:GKMatchSendData(Un)reliableerror:&error];

and receive in:


- (void)match:(GKMatch *)match

didReceiveData:(NSData *)data

forRecipient:(GKPlayer *)recipient

fromRemotePlayer:(GKPlayer *)player

{ // you've got mail from player!

}


So far, so good. Here's the bad news: depending on network strength, connections disconnect regularly. Even though I've built in dependable reconnect code, it can take up to 15 seconds to reconnect so it really isn't a good "real-time" experience.


I'm currently testing with various combinations of data size (sometimes pad it so it's heft may keep the connection) or frequency (sometimes just send a "poke me" message) or tweaking the reliable vs unreliable flag in the send message calls.


I can get about 10 followers per leader on a good day, but other times, more than 3 followers cycle between connect, disconnect, reconnect in an unusable fashion.


I'm still trying to make usable, but wanted to document my success/failures so far in hopes that I can help many and perhaps get help from a few.


Any ideas would be welcomed and any tweaks will be tested and reported.

since this is no longer about CloudKit, close this thread by marking the suggestion above that you convert to Game Center as correct.