iGoApp
iGoApp

Reputation: 1

Fragment large size data sent and received using NSKeyedArchiver.archivedData in GameCenter

Trying to send and receive data in the GameCenter environment using the following methods:

func sendData(dictionaryWithData dictionary: Dictionary<String, Any>,toPeer targetPeers: [GKPlayer]) {
        guard let match = self.match else { return }
        do {
            let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false)
            try match.send(dataToSend, to: targetPeers, dataMode: .reliable)
        }
        catch {
            #if DEBUG
            print("CONNECTION MANAGER SEND DATA ERROR")
            #endif
        }
    }
public func match(_ theMatch: GKMatch,didReceive data: Data,forRecipient recipient: GKPlayer,fromRemotePlayer player: GKPlayer) { 
        if match != theMatch { return } 
        DispatchQueue.main.async { 
           do { 
               guard let message = NSDictionary.unsecureUnarchived(from: data) as? Dictionary<String, Any> else {return} 
...
<CODE> 
...
} 

///Source: https://stackoverflow.com/questions/51487622/unarchive-array-with-nskeyedunarchiver-unarchivedobjectofclassfrom 
static func unsecureUnarchived(from data: Data) -> Self? {
        do {
            let unarchiver = try NSKeyedUnarchiver(forReadingFrom: data)
            unarchiver.requiresSecureCoding = false
            let obj = unarchiver.decodeObject(of: self, forKey: NSKeyedArchiveRootObjectKey)
            if let error = unarchiver.error {
                print("Error:\(error)")
            }
            return obj
        } catch {
            print("Error:\(error)")
        }
        return nil
    }

Everything works great until the data exceeds 87K (which, I understand, is the limit for exchanging data in GameCenter).

The data is not sent and gives the following error: Async message[1FCA0D11-05DE-47D0-9714-983C8023F5C1] send error: FailedToSendData: , InternalError: reliable, maxPayloadSizeExceeded

Interesting enough, I do not have this problem when using MCSession, as follows:

func sendData(dictionaryWithData dictionary: Dictionary<String, Any>, toPeer targetPeers: [MCPeerID]) {
        do {
            let dataToSend = try NSKeyedArchiver.archivedData(withRootObject: dictionary, requiringSecureCoding: false)
            try session.send(dataToSend, toPeers: targetPeers, with: MCSessionSendDataMode.reliable)
        }
        catch {
            #if DEBUG
            print("CONNECTION MANAGER SEND DATA ERROR")
            #endif
        }
    }

I have been doing research and found that I need to fragment data and send and receive it in packages. But I could not find a good explanation how to do it.

Any help would be appreciated!

Upvotes: 0

Views: 19

Answers (0)

Related Questions