0

As I currently understand it one way to do it is to use JSON. But it would seem better and easier to just send the swift object to the server making sure the server has the same class available. This way I can just keep using swift every step of the way.

Is this possible and how would I go about doing this?

Current setup:

  1. Swift playground to send data.
  2. Kitura server to receive data.

Playground code:

import UIKit
import PlaygroundSupport

PlaygroundPage.current.needsIndefiniteExecution = true

struct TestObject {
    let foo = "just a string"
    let number = 125
    let array = ["bar", "foo"]

    func printSomeInfo() {
        print(foo + "\(number+25)")
    }
}

func send() {
    let request = NSMutableURLRequest(url: URL(string: "http://192.168.178.80:8090/test")!)
    request.httpMethod = "POST"

    let testObject = TestObject()

    let bodyData = "\(testObject)"
    request.httpBody = bodyData.data(using: String.Encoding.utf8)

    let task =  URLSession.shared.dataTask(with: request as URLRequest,
                                           completionHandler: {
                                            (data, response, error) -> Void in

    })

    task.resume()
}

send()

Kitura main.swift code:

import Kitura
import Foundation

let router = Router()

struct TestObject {
    let foo = "just a string"
    let number = 125
    let array = ["bar", "foo"]

    func printSomeInfo() {
        print(foo + "\(number+25)")
    }
}

router.post("/test") {request, response, next in
    response.headers["Content-Type"] = "text/plain; charset=utf-8"

    if let post = try request.readString() {
        // would like to cast to TestObject but that doesn't work
        // let postObject = post as TestObject
        print(post)
    }
}

Kitura.addHTTPServer(onPort: 8090, with: router)
Kitura.run()
Jeffrey
  • 3
  • 3
  • 1
    You need to encode the object in some way to send it across the network, even if you have Swift on both sides since you can't just send a chunk of memory. If you don't want to use JSON, Protocol Buffers are an option, but the Swift support is still early; https://github.com/apple/swift-protobuf – Paulw11 Oct 29 '16 at 12:26
  • Maybe I lack lower level understanding of how objects are stored, but isn't there be a way to transfer the state of the object, and then store it as an object again on the server? When I send the object as a string, the server prints: TestObject(foo: "just a string", number: 125, array: ["bar", "foo"]) Couldn't the object be restored from that information on the server side? – Jeffrey Oct 29 '16 at 13:58
  • You can't just send raw bytes across the network - a given set of bytes could be a string or an integer value or an object reference and this last is particularly difficult as memory addresses will be completly different in different devices; so you need to use some format to serialise the information so that the two ends can communicate clearly. In your sample code you are using the `description` method to "send" your test object and while this is "built-in" there is no built-in way to parse this back to an object and no standard for what `description` returns. – Paulw11 Oct 29 '16 at 20:27
  • I see, thanks for the clear explanation. It's a shame tough, I was hoping for some simple (included) form of abstraction to solve that, it would make sense wouldn't it? Since the front/backend have access to the same language/frameworks it seems it should be possible. Hopefully apple will implement this some day. Until then it seems JSON is the tried and tested way to go so I'll go look into that. – Jeffrey Oct 29 '16 at 20:45
  • This isn't something that is part of a language specification, so I can't see Apple adding it to Swift. As a programmer you can choose for any number of serialisation/deserialisation approaches; JSON, ProtocolBuffers, XML, even CSV if you wanted. By using an "open" standard your app can work with servers regardless of what language they are written in. Using REST and JSON, I can create an app that works with Facebook or Twitter or Salesforce.com or a million other sites without needing to know anything about there server side implementation – Paulw11 Oct 29 '16 at 20:49
  • `JSONSerializer` is part of the foundation libraries so in a sense, that is "built in" to Swift, but it is part of the platform, not the language. There is no networking in the swift language, let alone serialisation – Paulw11 Oct 29 '16 at 20:52
  • Yeah, I meant adding it to the foundation framework not the core language. In my case, my server needs are limited to one app that don't need to communicate with any other servers. That's why I'm attracted to using swift on the backend, to do as much as possible with as little as possible. :) – Jeffrey Oct 29 '16 at 21:09
  • Right, well in that case JSON serialization is in the foundation already. Protobufs may be added in the future. – Paulw11 Oct 29 '16 at 21:18

2 Answers2

1

You would need to serialize the data in some way across the wire. One of the most common way to do this is using JSON. This recent swift blog explains how you can do this. If you need to do this for a lot of different objects, you could abstract out the JSON serialization/deserialization to a common base.

Navneet
  • 81
  • 3
0

For your situation, there is a good library for JSON object mapping. https://github.com/Hearst-DD/ObjectMapper However, you'll need some additional code in your classes and structures to implement their ability to be mapped

valivaxa
  • 51
  • 4
  • This looks like a good way to use JSON, and if I decide to go that route I will absolutely check it out. But it does create more overhead than I was aiming for, so for now I'll keep looking. Maybe what I'm hoping for is simply not possible (yet). (also, I would up vote your answer, but don't have the reputation yet, this is my first question:)) – Jeffrey Oct 29 '16 at 13:45