Git Product home page Git Product logo

thrift-swift's Introduction

Thrift Swift Library

License

Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file distributed with this work for additional information regarding copyright ownership. The ASF licenses this file to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.

Brought to you by FiscalNote, Inc

Build

swift build

Test

swift test

Install Library

Cocoapods

Add the following to your podfile

    pod 'Thrift-swift3', :git => '[email protected]:apache/thrift.git', :branch => 'master'
SPM

Unfortunately due to some limitations in SPM, the Package manifest and Sources directory must be at the root of the project. To get around that for the time being, you can use this mirrored repo. Add the following to your Package.swift

dependencies: [
    .Package(url: "https://github.com/apocolipse/Thrift-Swift.git", majorVersion: 1)
]

Thrift Compiler

You can compile IDL sources for Swift 3 with the following command:

thrift --gen swift thrift_file

Client Example

let transport = TSocketTransport(hostname: "localhost", port: 9090)!

//  var proto = TCompactProtocol(transport: transport)
let proto = TBinaryProtocol(on: transport)
//  var client = HermesClient(inoutProtocol: proto)
let client = ThriftTestClient(inoutProtocol: proto)
do {
    try client.testVoid()
} catch let error {
    print("\(error)")
}

Library Notes

  • Eliminated Protocol Factories, They were only used in async clients and server implementations, where Generics provide a better alternative.
  • Swifty Errors, All TError types have a nested ErrorCode Enum as well as some extra flavor where needed.
  • Value typed everything. TTransport operates on value typed Data rather than reference typed NSData or UnsafeBufferPointers
  • Swift 3 Named protocols. Swift 3 naming conventions suggest the elimination of redundant words that can be inferred from variable/function signatures. This renaming is applied throughout the Swift 3 library converting most naming conventions used in the Swift2/Cocoa library to Swift 3-esque naming conventions. eg.
func readString() throws -> String
func writeString(_ val: String) throws

have been renamed to eliminate redundant words:

func read() throws -> String
func write(_ val: String) throws
  • Eliminated THTTPTransport that uses NSURLConnection due to it being deprecated and not available at all in Swift 3 for Linux. THTTPSessionTransport from the Swift2/Cocoa library that uses NSURLSession has been renamed to THTTPTransport for this library and leverages URLSession, providing both synchronous (with semaphores) and asynchronous behavior.
  • Probably some More things I've missed here.

Generator Notes

Generator Flags

Flag Description
async_clients Generate clients which invoke asynchronously via block syntax. Asynchronous classes are appended with _Async
no_strict* Generates non-strict structs
debug_descriptions Allow use of debugDescription so the app can add description via a cateogory/extension
log_unexpected Log every time an unexpected field ID or type is encountered.
safe_enums Generate enum types with an unknown case to handle unspecified values rather than throw a serialization error

*Most thrift libraries allow empty initialization of Structs, initializing required fields with nil/null/None (Python and Node generators). Swift on the other hand requires initializers to initialize all non-Optional fields, and thus the Swift 3 generator does not provide default values (unlike the Swift 2/Cocoa generator). In other languages, this allows the sending of NULL values in fields that are marked required, and thus will throw an error in Swift clients attempting to validate fields. The no_strict option here will ignore the validation check, as well as behave similar to the Swift2/Cocoa generator and initialize required fields with empty initializers (where possible).

Whats implemented

Library

Transports
  • TSocketTransport - CFSocket and PosixSocket variants available. CFSocket variant only currently available for Darwin platforms
  • THTTPTransport - Currently only available for Darwin platforms, Swift Foundation URLSession implementation needs completion on linux.
  • TSocketServer - Uses CFSockets only for binding, should be working on linux
  • TFramedTransport
  • TMemoryBufferTransport
  • TFileTransport - A few variants using File handles and file descriptors.
  • TStreamTransport - Fully functional in Darwin, Foundation backing not yet completed in Linux (This limits TCFSocketTransport to Darwin)
  • HTTPServer - Currently there is no lightweight HTTPServer implementation the Swift Standard Library, so other 3rd party alternatives are required and out of scope for the Thrift library. Examples using Perfect will be provided.
  • Other (gz, etc)
Protocols
  • TBinaryProtocol
  • TCompactProtocol
  • TJSONProtocol - This will need to be implemented
Generator
  • Code Complete Generator
  • Async clients
  • Documentation Generation - Generator will transplant IDL docs to Swift code for easy lookup in Xcode
  • Default Values - TODO
  • no_strict mode - TODO
  • Namespacing - Still haven't nailed down a good paradigm for namespacing. It will likely involve creating subdirectories for different namespaces and expecting the developer to import each subdirectory as separate modules. It could extend to creating SPM Package manifests with sub-modules within the generated module

Example HTTP Server with Perfect

import PerfectLib
import PerfectHTTP
import PerfectHTTPServer
import Dispatch

let logQueue = DispatchQueue(label: "log", qos: .background, attributes: .concurrent)
let pQueue = DispatchQueue(label: "log", qos: .userInitiated, attributes: .concurrent)


class TPerfectServer<InProtocol: TProtocol, OutProtocol: TProtocol> {

 private var server = HTTPServer()
 private var processor: TProcessor

 init(address: String? = nil,
      path: String? = nil,
      port: Int,
      processor: TProcessor,
      inProtocol: InProtocol.Type,
      outProtocol: OutProtocol.Type) throws {

   self.processor = processor

   if let address = address {
     server.serverAddress = address
   }
   server.serverPort = UInt16(port)

   var routes = Routes()
   var uri = "/"
   if let path = path {
     uri += path
   }
   routes.add(method: .post, uri: uri) { request, response in
     pQueue.async {
       response.setHeader(.contentType, value: "application/x-thrift")

       let itrans = TMemoryBufferTransport()
       if let bytes = request.postBodyBytes {
         let data = Data(bytes: bytes)
         itrans.reset(readBuffer: data)
       }

       let otrans = TMemoryBufferTransport(flushHandler: { trans, buff in
         let array = buff.withUnsafeBytes {
           Array<UInt8>(UnsafeBufferPointer(start: $0, count: buff.count))
         }
         response.status = .ok
         response.setBody(bytes: array)
         response.completed()
       })

       let inproto = InProtocol(on: itrans)
       let outproto = OutProtocol(on: otrans)

       do {
         try processor.process(on: inproto, outProtocol: outproto)
         try otrans.flush()
       } catch {
         response.status = .badRequest
         response.completed()
       }
     }
   }
   server.addRoutes(routes)
 }

 func serve() throws {
   try server.start()
 }
}

Example Usage

class ServiceHandler : Service {
    ...
}
let server = try? TPerfectServer(port: 9090,
                                processor: ServiceProcessor(service: ServiceHandler()),
                                inProtocol: TBinaryProtocol.self,
                                outProtocol: TBinaryProtocol.self)

try? server?.serve()

thrift-swift's People

Contributors

apocolipse avatar bm-w avatar cozality avatar eysteinbye avatar injeniero avatar luckfamousa avatar wyland avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

thrift-swift's Issues

Swift 4 support?

I'm trying to use this library in Swift 4. From what I see, there exist forks that have upgraded to swift 4 (https://github.com/apocolipse/Thrift-Swift/network). See https://github.com/Petro-Lomaka/Thrift-Swift, for example.
The framework they vend seems to work for me.

The command line thrift, on the other hand, seems not to. I'm trying to use @Petro-Lomaka's fork (same guy), but the generated code doesn't conform to the Thrift swift module. I'm currently trying to uninstall my thrift, then reinstall from brew, and then follow the instructions in #11 with the thrift fork.

Can we start the process of moving this library to swift 4?

Using Swift 4.2 with Thrift

Hello, I am a little new to Thrift, but it seems like according to http://thrift.apache.org/docs/Languages,
Swift 4.2 should be supported by Thrift. However, I cannot get it to compile in my project. I have Thrift version 0.12 downloaded on my mac, and used it to generate some swift files. However, all of these swift files have the line "Import Thrift" in them, to which the error "No such module 'Thrift' " pops up. If I place in my podfile [pod 'Thrift-swift3', :git => '[email protected]:apache/thrift.git', :branch => 'master'] or [pod "thrift"], the code does not compile because it seems the version of swift it was written is outdated. If anyone could give give me some insight that would be much appreciated. Sorry if this is a dumb question, but I am at a loss after searching the internet for hours for a solution. Thanks!

Let all socket communication go through a 3rd party library.

It's slightly related to #21

I'd like to see UDP support, but at the same time I'm not comfortable adding that myself since I'm pretty sure there's a lot of edge cases to tackle (especially when it comes to UDP). One thing I found that is that the on board radio on iPhones do not activate when using UDP, and you need to kick start it by using TCP first.

By using something like IBM/BlueSocket it would be easier to add support for both UDP and TCP by letting a different component handle network details.

Bug in TFileTransport.read(size:)?

Hello. I'm running into an issue trying to use TFileTransport. Up front, let me say that this might be a mistake on my part as I'm new to both Thrift-Swift and Thrift in general. However, in trying to read an existing thrift file using swift code, I'm seeing a crash in TFileTransport.swift where a Data buffer is set up using:

var read = Data(capacity: size)

and then used:

read[position] = nextChar

There's no operation that changes the Data object's actual size before that write, so I believe what's going on here is that while the object has the capacity for size bytes, it's count is still zero when the write is attempted. If I've understood the issue correctly, this could be fixed by creating the Data object as a fixed-sized buffer of zeroed bytes instead of just hinting at the capacity:

var read = Data(count: size)

For context, here's how I'm calling into the thrift code:

guard let transport = try? TFileTransport(filename: filename) else { fatalError() }
try transport.open()
let proto = TBinaryProtocol(on: transport)
let d = try? MyThriftStruct.read(from: proto)

Deploy new release with latest updates

It's been good to see this project spring back to life to, at least, get up to date with current tooling. That said, the last batch of updates won't get caught by the usual dependency managers because there is no release associated with them.

Whether there's more development planned for the near future or not, would it be a problem to add a new 1.1.1 release so folks using cocoapods/SPM will be able to grab it without forcing a dependency on master or a specific commit?

Thanks!

optional keyword is ignored in argument lists

Hi, how to be if I need to pass null value in method to the server,
for example
list<User> getUsers(1: AuthTokenBase64 token, 2: ID systemId, 3: othervalues othertypes);
ID is typealias for String. Parameter systemId can be value or null (on other platforms).
How do I set it as null / nil in swift ?
If thrift file has:
list<User> getUsers(1: AuthTokenBase64 token, 2: optional ID systemId, 3: othervalues othertypes);
we get this:
optional keyword is ignored in argument lists

'thrift --gen swift_3 thrift_file' not working

When I use the command will get error:

sh: thrift-gen-swift_3: command not found
plugin process returned non zero exit code: 32512
[WARNING:generation:1] Plugin generator for "swift_3" failed.

Enum failable initialization / tag 1.0.7

Hello!
Faced with issue (tag 1.0.7): 'nil' is the only return value permitted in an initializer

Enum in my .thrift file:

enum Gender {
	M = 0,
	F = 1
}

Thrift generated code:
enum-failable-init

TJSONProtocol support to Thrift-Swift package

I needed to use TJSONProtocol for a project and hence forked and implemented the json protocol in the following fork:

https://github.com/HojjatK/Thrift-Swift

Note that I have ported the code from C# lib to Swift, the code works fine for me However I need to add more unit-tests
What's the process of If I want to send a pull-request so that it will be part of the official package?

Thank you
Hojjat

Wrong git tag

Tag needs to be updated and it should be named โ€œ0.0.1โ€.

Thrift not compiles on Xcode 8

Hello! I have installed thrift via cocoapods. And my project not compiled on Xcode 8 with latest ios10.3 SDK. There are more then 100 errors in Thrift framework. What is problem? The library isn't contributed anymore?

Swift 4.1: '_rawValue' is inaccessible due to 'private' protection level

image

On TSocketTransport.swift:87:113, using Swift 4.1, there is a compiling issue of type '_rawValue' is inaccessible due to 'private' protection level. It looks like converting a string enum to raw value is deprecated start Swift 4.1
I wonder how we'd like to proceed with this change ๐Ÿค”

Contributing

I'd like to contribute to the repository by migrating it to the latest Swift version 5. Could someone please tell me how to set up the project on macOS 10.15.
swift build returns
"package is using Swift tools version 3.1.0 which is no longer supported; consider using '// swift-tools-version:5.1' to specify the current tools version"
After fixing this I got
"error: the package does not contain a buildable target"

Invalid redeclaration of 'description' / tag 1.0.7

Hello!
Faced with issue (tag 1.0.7): Invalid redeclaration of 'description'
appears in all classes where description property exists

Up to tag 1.0.6 there was no issue.

My struct in .thrift file:

struct TCountryInfo {
	1: ID id,
	2: string title,
	3: string subtitle,
	4: string description,
	5: string image,
	6: ID countryId,
	7: Attributes attributes
}

Thrift generated code for this struct:
class-property

class-extension

Enum property access level / tag 1.0.7

Hello!

Faced with error (tag 1.0.7): Property 'rawValue' must be declared public because it matches a requirement in public protocol 'TEnum'

Enum in my .thrift file:

enum Gender {
	M = 0,
	F = 1
}

Thrift generated code:

enum-property-access-level

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.