Page 1 of 1

Swift - Setting room variable

Posted: 10 May 2019, 04:35
by intomo
I'm having trouble setting roomVariables in Swift

Code: Select all

let updatedVar = SFSRoomVariable(name: "lastCommand", value: "myString")
        smartFox.send(SetRoomVariablesRequest.request(withRoomVariables: updatedVar) as? IRequest)
Errors are, first line, it's saying a need a third parameter. The docs indicate that this is optional.
Second line, Cannot convert value of type 'SFSRoomVariable' to expected argument type '[Any]?'

Thanks very much for your help in advance.

Re: Swift - Setting room variable

Posted: 10 May 2019, 07:22
by Lapo
Hi,
it looks like in Swift the optional params from Objective-C are not that optional :)

In order to make this work you should do the following:

1) In the bridging header file add an extra import:

Code: Select all

#import <SFS2XAPIIOS/VariableType.h>
2) Build the variable with the extra parameter:

Code: Select all

let updateVar = SFSRoomVariable(name: "VarName", value: "VarValue", type: VariableType_STRING);
Via auto-completion you can find all the VariableType_XYZ available.
Hope it helps

Re: Swift - Setting room variable

Posted: 10 May 2019, 07:24
by Lapo
For the sake of completeness the full code should look like this:

Code: Select all

let updateVar = SFSRoomVariable(name: "VarName", value: "VarValue", type: VariableType_STRING);
sfs!.send(updateVar as! IRequest!);
Cheers

Re: Swift - Setting room variable

Posted: 10 May 2019, 16:13
by intomo
Thank you. That helped with the compiling.
This is my revised code. Still having trouble.

Code: Select all

let updateVar = SFSRoomVariable(name: "strobeOn", value: true, type: VariableType_BOOL);
        smartFox.send(updateVar as? IRequest);
The Room Variable strobeOn is a persistent room variable set up in the admin tool as false. When I send this command it doesn't change in the admin tool and I don't get a onRoomVariablesUpdate event triggered.

Re: Swift - Setting room variable

Posted: 10 May 2019, 16:47
by Lapo
Do you see errors on client or server side?
Are you setting the RoomVariable after having joined a Room?

Thanks

Re: Swift - Setting room variable

Posted: 10 May 2019, 17:16
by intomo
Here's what happens when I send the RoomVariable with the above code:

com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.validateIncomingDataSize(BinaryIoHandler.java:511)
com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.handleDataSize(BinaryIoHandler.java:295)
com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.handleRead(BinaryIoHandler.java:183)
com.smartfoxserver.v2.protocol.SFSIoHandler.onDataRead(SFSIoHandler.java:143)
com.smartfoxserver.bitswarm.core.SocketReader.readTcpData(SocketReader.java:336)
com.smartfoxserver.bitswarm.core.SocketReader.readIncomingSocketData(SocketReader.java:220)
com.smartfoxserver.bitswarm.core.SocketReader.run(SocketReader.java:171)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)

Re: Swift - Setting room variable

Posted: 10 May 2019, 22:21
by intomo
intomo wrote:Here's what happens when I send the RoomVariable with the above code:

com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.validateIncomingDataSize(BinaryIoHandler.java:511)
com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.handleDataSize(BinaryIoHandler.java:295)
com.smartfoxserver.v2.protocol.binary.BinaryIoHandler.handleRead(BinaryIoHandler.java:183)
com.smartfoxserver.v2.protocol.SFSIoHandler.onDataRead(SFSIoHandler.java:143)
com.smartfoxserver.bitswarm.core.SocketReader.readTcpData(SocketReader.java:336)
com.smartfoxserver.bitswarm.core.SocketReader.readIncomingSocketData(SocketReader.java:220)
com.smartfoxserver.bitswarm.core.SocketReader.run(SocketReader.java:171)
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
java.lang.Thread.run(Thread.java:745)
The variables are persistent and set in the Admin tool.
No errors on client.

Re: Swift - Setting room variable

Posted: 11 May 2019, 15:55
by Lapo
Sorry, I made a mistake in my previous post. I was sending the Room Variable without wrapping it in a SetRoomVariableRequest, silly me! :D

Example:

Code: Select all

func onRoomJoin(_ evt: SFSEvent!)
    {
        let room = evt.params["room"] as! Room;
        let updateVar = SFSRoomVariable(name: "MyName", value: "MyValue", type: VariableType_STRING);
        sfs!.send(SetRoomVariablesRequest(roomVariables: [updateVar], room: room));
    }
    
Hope it helps

Re: Swift - Setting room variable

Posted: 12 May 2019, 01:00
by intomo
Thanks Lapo! Both of these seem to work. But Swift is asking me to cast updateVar as Any.

Code: Select all

 let updateVar = SFSRoomVariable(name: "strobeOn", value: true, type: VariableType_BOOL);
        //smartFox.send(SetRoomVariablesRequest(roomVariables: [updateVar as Any], room: room ))
        smartFox.send(SetRoomVariablesRequest.request(withRoomVariables: [updateVar as Any]) as? IRequest)

Re: Swift - Setting room variable

Posted: 13 May 2019, 07:20
by Lapo
Interesting, I did not see that in my environment. Maybe we're using different versions of XCode. I am still using version 8.x

Cheers

Re: Swift - Setting room variable

Posted: 15 May 2019, 19:20
by intomo
I'm using Xcode 10.2, iOS 12, Swift 5.
Thanks again for all your help!

Next question:
How many room variables is too many?
I'm trying to save the game state so that if a user joins late they are in sync with everyone else.
What I think I'd love to do is just save a state object instead of individual persistent room vars.
Basically saving this struct

Code: Select all

struct LastState {
    var color: Bool = false
    var video: Bool = false
    var image: Bool = false
    var strobe: Bool = false
    var blink: Bool = false
    var clear: Bool = false
    var pulse: Bool = false
    var vidInd: Int = 0
    var imgInd: Int = 0
    var clrInd: Int = 0
    
    init(color: Bool = false, video: Bool = false, strobe: Bool = false, blink: Bool = false, clear: Bool = false, pulse: Bool = false, vidInd: Int = 0, imgInd: Int = 0, clrInd: Int = 0) {
        self.strobe = strobe
        self.blink = blink
        self.clear = clear
        self.pulse = pulse
        self.vidInd = vidInd
        self.imgInd = imgInd
        self.clrInd = clrInd
    }
}
Can I save the struct with VariableType_Object?
I tried that and it wanted an SFSObject.
Also can I save multiple variables in 1 call? Currently doing this to save 2.

Code: Select all

 let var1 = SFSRoomVariable(name:"color", value: true, type: VariableType_STRING);
        smartFox.send(SetRoomVariablesRequest(roomVariables: [var1 as Any], room: room ))
        let var2 = SFSRoomVariable(name:"clrInd", value: color, type: VariableType_INT);
        smartFox.send(SetRoomVariablesRequest(roomVariables: [var2 as Any], room: room ))

Re: Swift - Setting room variable

Posted: 16 May 2019, 07:03
by Lapo
intomo wrote: How many room variables is too many?
There isn't a set limit. It depends on many parameters:
- how ofter they are updated
- content of the variables (simple numeric values vs long strings or nested objects)
- game client (mobile vs desktop)

The most important aspect is how many of these variables are updated and how often. If you find yourself updating 20+ variables every few hundred milliseconds you might need to rethink your strategy.

Even in that case you should probably check with a network monitor to see how much bandwidth a single client requires.
I'm trying to save the game state so that if a user joins late they are in sync with everyone else.
What I think I'd love to do is just save a state object instead of individual persistent room vars.
The separate variable approach would be fine unless these values are changed super fast multiple times a second.
Can I save the struct with VariableType_Object?
No, but you could wrap those values in a single SFSObject which would then act as a single Room Variable.
The problem with this approach, however, is that every time you need to change one of the values of the SFSObject you would re-transmit the whole object to everyone.

I would probably opt for the separate values unless, again, these values are all updating super-fast.

Hope it helps