$30 off During Our Annual Pro Sale. View Details »

iosdc_2018.pdf

Kyohei Ito
August 31, 2018
2.4k

 iosdc_2018.pdf

Kyohei Ito

August 31, 2018
Tweet

Transcript

  1. grpc-swiftΛ࢖ͬͯ
    iOSΞϓϦͰ΋շదͳ
    gRPC௨৴Λߦ͏ɹɹ
    2018/08/31 iOSDC

    View Slide

  2. About Me
    ҏ౻ɹګฏ
    Github : KyoheiG3
    Twitter : @KyoheiG3

    View Slide

  3. About Me
    ΩϡϨʔγϣϯ
    Ameba OWND
    AbemaTV
    SUPERCHOICE
    ࠓ·ͨ৽ن

    View Slide

  4. gPRC

    View Slide

  5. gRPCͬͯԿʁ
    • Google͕࡞ͬͨRPCΛ࣮ݱ͢ΔͨΊͷϑϨʔϜϫʔΫ
    • ࣾ಺޲͚ͷStubbyΛɺ2015೥ʹΦʔϓϯԽͨ͠΋ͷ
    • HTTP2

    View Slide

  6. RPCͬͯԿʁ
    • ϦϞʔτϓϩγʔδϟίʔϧͷུ
    • ϓϩάϥϜ͔ΒผͷΞυϨεۭؒʹ͋Δαϒϧʔνϯ΍खଓ
    ͖Λ࣮ߦ͢Δ͜ͱΛՄೳʹ͢Δٕज़

    View Slide

  7. HTTP2
    • SPDYΛج൫ʹ࡞Γग़͞Εͨ
    • SPDY΋Google੡

    View Slide

  8. Մೳͳ௨৴ํࣜ

    View Slide

  9. Unaryʢ୯ൃͷ௨৴ʣ
    • 1ͭͷϦΫΤετʹର͠ɺϨεϙϯεΛ1ͭฦ͢
    • HTTP1ܥͱಉ͡Α͏ͳεςʔτϨεͳ௨৴ํࣜ

    View Slide

  10. Server StreamingʢαʔόετϦʔϛϯάʣ
    • 1ͭͷϦΫΤετʹର͠ɺϨεϙϯεΛෳ਺ฦ͢
    • αʔόpush ϙʔϦϯάʹஔ͖׵ΘΔ

    View Slide

  11. Client StreamingʢΫϥΠΞϯτετϦʔϛϯάʣ
    • ෳ਺ͷϦΫΤετʹର͠ɺϨεϙϯεΛ1ͭฦ͢
    • ϑΝΠϧΞοϓϩʔυͳͲ

    View Slide

  12. Bi-Directional Streamingʢ૒ํ޲ετϦʔϛϯάʣ
    • ෳ਺ͷϦΫΤετʹର͠ɺϨεϙϯεΛෳ਺ฦ͢
    • νϟοτͳͲ

    View Slide

  13. Αࣖ͘ʹ͢ΔProtocol Buffersͱͷҧ͍ͬͯʁ
    • Protocol Buffers͸௨৴͢Δσʔλͷܗࣜʢjson, xml...ʣ
    • gRPC͸௨৴ͷखஈ

    View Slide

  14. ͢͜͠Protocol Buffersͷ͓͞Β͍

    View Slide

  15. protobuf
    • protobufͱུ͞ΕΔ͜ͱ͕ଟ͍
    • όΠφϦϕʔε
    • .protoϑΝΠϧͰσʔλܗࣜΛఆٛ

    View Slide

  16. echo.proto
    syntax = "proto3";
    package echo;
    message EchoRequest {
    string text = 1;
    }
    message EchoResponse {
    string text = 1;
    }

    View Slide

  17. protobuf
    • .protoϑΝΠϧ͔Βɺswift΍goϑΝΠϧΛ࡞੒Մೳ

    View Slide

  18. protobuf
    $ protoc echo.proto --plugin=./protoc-gen-swift --swift_out=.

    View Slide

  19. echo.pb.swift
    struct Echo_EchoRequest {
    var text: String = String()
    var unknownFields = SwiftProtobuf.UnknownStorage()
    init() {}
    }
    struct Echo_EchoResponse {
    var text: String = String()
    var unknownFields = SwiftProtobuf.UnknownStorage()
    init() {}
    }

    View Slide

  20. protobuf
    • swiftͰ΋Apple͕ެࣜʹαϙʔτ1
    • όΠφϦͷγϦΞϥΠζɾσγϦΞϥΠζͷ଎౓͸ϥΠϒϥ
    Ϧʹґଘ
    • ܰͯ͘ܕ҆શ
    1 https://github.com/apple/swift-protobuf

    View Slide

  21. protobuf σϝϦοτ
    • ௨৴σʔλͷՄಡੑ͕௿͗͢Δʢͱ͍͏͔ಡΊͳ͍ʣ
    • ಋೖʹҰखؒඞཁ

    View Slide

  22. protobuf ϝϦοτ
    ׂѪ͠·͢ɻ
    ϝϦοτ͸ͨ͘͞Μ͋ΔͷͰɺσʔλܗࣜͷબ୒ࢶͷҰͭʹೖ
    ΕΔͷ͸͋Γͩͱࢥ͍·͢ɻ

    View Slide

  23. gRPC × protobuf
    • gRPC͕ར༻͢ΔσϑΥϧτͷσʔλܗ͕ࣜprotobuf
    • gRPC͸͋͘·Ͱ௨৴ͷखஈͳͷͰɺσʔλܗࣜ͸ҰԠjsonͱ
    ͔΋Մೳ
    • ͚ͲɺprotobufͱgRPC͸ζϒζϒͳͷͰҰॹʹ࢖͏લఏ

    View Slide

  24. SwiftGRPC

    View Slide

  25. SwiftGRPC
    • objective-cͰ͸c++Ͱ࣮૷͞ΕͨgrpcΛར༻2
    • swiftͰར༻͢Δʹ͸গʑ໘౗
    2 https://github.com/grpc/grpc

    View Slide

  26. SwiftGRPC
    • grpcͷΠϯλʔϑΣʔεΛswiftͰϥοϓ

    View Slide

  27. Officially Supported Platforms3
    C/C++, C#, Dart *, Go, Java, Node.js, PHP *, Python, Ruby
    * ͸·ͩbeta
    Swift͸ΞϯΦϑΟγϟϧͰ͔͢?!
    3 https://grpc.io/about/#osp

    View Slide

  28. ಋೖ

    View Slide

  29. ಋೖ
    • ͱʹ͔͘protobufલఏ
    • SwiftGRPCͷprotocϓϥάΠϯΛ࡞੒
    • .protoϑΝΠϧ͔Β.swiftϑΝΠϧΛ࡞੒

    View Slide

  30. protobufΛΠϯετʔϧ
    $ brew install protobuf

    View Slide

  31. SwiftGRPCͷprotocϓϥάΠϯΛ࡞੒
    • grpc-swiftΛcloneͯ͠build
    $ git clone https://github.com/grpc/grpc-swift.git
    $ cd grpc-swift
    $ make all
    > .protoc-gen-swift .protoc-gen-swiftgrpc

    View Slide

  32. ඞཁʹԠͯ͡pathΛ௨͢
    • ࣮ߦ࣌ʹϓϥάΠϯͷpathΛࢦఆͰ͖ΔͷͰඞਢͰ͸ͳ͍
    $ mkdir ~/.protoc
    $ cp ./protoc-gen-swift ./protoc-gen-swiftgrpc ~/.protoc
    $ echo 'export PATH=$PATH:$HOME/.protoc' >> ~/.bash_profile
    $ source ~/.bash_profile

    View Slide

  33. protoc-gen-swiftgrpc
    • SwiftGRPCͷprotocϓϥάΠϯ
    • protobufͱಉ༷ʹ.proto͔Β.swiftΛ࡞੒

    View Slide

  34. echo.protoʢbeforeʣ
    syntax = "proto3";
    package echo;
    message EchoRequest {
    string text = 1;
    }
    message EchoResponse {
    string text = 1;
    }

    View Slide

  35. echo.protoʢserviceʣ
    • serviceͷதʹɺrpcϑΟʔϧυΛఆٛ͢Δ
    service Echo {
    rpc
    }

    View Slide

  36. echo.protoʢserviceʣ
    • rpcϑΟʔϧυʹ೚ҙͷϝιουΛఆٛ͢Δ
    service Echo {
    rpc Get
    }

    View Slide

  37. echo.protoʢserviceʣ
    • ϦΫΤετͷΦϒδΣΫτΛఆٛ͢Δ
    service Echo {
    rpc Get(EchoRequest)
    }

    View Slide

  38. echo.protoʢserviceʣ
    • ϨεϙϯεͷΦϒδΣΫτΛఆٛ͢Δ
    service Echo {
    rpc Get(EchoRequest) returns(EchoResponse) {}
    }

    View Slide

  39. echo.protoʢserviceʣ
    • stream͸ෳ਺ճͷॲཧΛՄೳʹ͢Δఆٛ
    service Echo {
    rpc Get(EchoRequest) returns (EchoResponse) {}
    rpc Expand(EchoRequest) returns (stream EchoResponse) {}
    rpc Collect(stream EchoRequest) returns (EchoResponse) {}
    rpc Update(stream EchoRequest) returns (stream EchoResponse) {}
    }

    View Slide

  40. echo.protoʢafterʣ
    syntax = "proto3";
    package echo;
    message EchoRequest {
    string text = 1;
    }
    message EchoResponse {
    string text = 1;
    }
    service Echo {
    rpc Get(EchoRequest) returns (EchoResponse) {}
    rpc Expand(EchoRequest) returns (stream EchoResponse) {}
    rpc Collect(stream EchoRequest) returns (EchoResponse) {}
    rpc Update(stream EchoRequest) returns (stream EchoResponse) {}
    }

    View Slide

  41. protoc-gen-swiftgrpc
    $ protoc echo.proto --plugin=./protoc-gen-swiftgrpc --swiftgrpc_out=.

    View Slide

  42. echo.grpc.swift
    protocol Echo_EchoProvider: ServiceProvider {
    func get(request: Echo_EchoRequest, session: Echo_EchoGetSession) throws -> Echo_EchoResponse
    func expand(request: Echo_EchoRequest, session: Echo_EchoExpandSession) throws -> ServerStatus?
    func collect(session: Echo_EchoCollectSession) throws -> Echo_EchoResponse?
    func update(session: Echo_EchoUpdateSession) throws -> ServerStatus?
    }
    protocol Echo_EchoService: ServiceClient {
    func get(_ request: Echo_EchoRequest) throws -> Echo_EchoResponse
    func get(_ request: Echo_EchoRequest, completion: @escaping (Echo_EchoResponse?, CallResult) -> Void) throws -> Echo_EchoGetCall
    func expand(_ request: Echo_EchoRequest, completion: ((CallResult) -> Void)?) throws -> Echo_EchoExpandCall
    func collect(completion: ((CallResult) -> Void)?) throws -> Echo_EchoCollectCall
    func update(completion: ((CallResult) -> Void)?) throws -> Echo_EchoUpdateCall
    }

    View Slide

  43. EchoʢαϯϓϧʣͰίʔυղઆ

    View Slide

  44. Echoͷಈ͔͠ํ
    • SwiftGRPC.xcodeprojΛ࡞੒͢Δ
    $ make project

    View Slide

  45. Echoͷಈ͔͠ํ
    • ./third_party/swift-protobuf͕ඞཁ
    • ࠷ۙऔಘεΫϦϓτ͕࡟আ͞Εͨ4
    $ mkdir third_party
    $ cd third_party
    $ git clone https://github.com/apple/swift-protobuf.git
    4 https://github.com/grpc/grpc-swift/pull/296

    View Slide

  46. Echoͷಈ͔͠ํ
    • ./Examples/EchoXcode/Echo.xcodeprojΛ։͘

    View Slide

  47. Echoͷಈ͔͠ํ
    • ./SwiftGRPC.xcodeprojΛϓϩδΣΫτʹ௥Ճ͢Δ

    View Slide

  48. Echoͷಈ͔͠ํ
    • Target DependenciesʹSwiftGRPC.frameworkΛ௥Ճ͢Δ

    View Slide

  49. Echo for Client

    View Slide

  50. Echo_EchoServiceClient
    • ΫϥΠΞϯτ͔Βαʔό΁ͷ઀ଓΛ؅ཧ
    • ಺෦ͰChannelΦϒδΣΫτΛอ࣋
    • Echo_EchoServiceʹ४ڌ
    • get, expand, collect, updateϝιουΛ࣮ߦͯ͠ɺετ
    ϦʔϛϯάΛߦ͏ͨΊͷCallΦϒδΣΫτΛ࡞੒

    View Slide

  51. Echo_EchoServiceClient
    let service = Echo_EchoServiceClient(address: "YOUR_ADDRESS",
    secure: false)

    View Slide

  52. Echo_EchoExpandCallʢServerStreamingʣ
    • expand()ϝιουͰऔಘ
    • αʔόετϦʔϛϯά͕Մೳ
    • receive()ϝιουΛ࣮ߦՄೳ

    View Slide

  53. Echo_EchoExpandCallʢServerStreamingʣ
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    let expandCall = try service.expand(requestMessage) { _ in
    }
    try expandCall.receive { response in
    // ϨεϙϯεΛड͚औΔ
    }

    View Slide

  54. Echo_EchoCollectCallʢClientStreamingʣ
    • collect()ϝιουͰऔಘ
    • ΫϥΠΞϯτετϦʔϛϯά͕Մೳ
    • send(), closeAndReceive()ϝιουΛ࣮ߦՄೳ

    View Slide

  55. Echo_EchoCollectCallʢClientStreamingʣ
    let collectCall = try service.collect { _ in
    }
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    try collectCall.send(requestMessage) { error in
    // ΤϥʔΛड͚औΔ
    }
    try collectCall.closeAndReceive { response in
    // close࣌ʹ1౓͚ͩσʔλΛड͚औΕΔ
    }

    View Slide

  56. Echo_EchoUpdateCallʢBidirectionalStreamingʣ
    • update()ϝιουͰऔಘ
    • ૒ํ޲ετϦʔϛϯά͕Մೳ
    • send(), receive(), closeSend()ϝιουΛ࣮ߦՄೳ

    View Slide

  57. Echo_EchoUpdateCallʢBidirectionalStreamingʣ
    let updateCall = try service.update { _ in
    }
    try updateCall.receive { response in
    // ϨεϙϯεΛड͚औΔ
    }
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    try updateCall.send(requestMessage) { error in
    // ΤϥʔΛड͚औΔ
    }
    try updateCall.closeSend {}

    View Slide

  58. ΫϥΠΞϯτ࣮૷ͷجຊతͳྲྀΕ
    • Service͔ΒCallΦϒδΣΫτΛ࡞੒͢Δ
    • ࡞੒ͨ͠CallΦϒδΣΫτʹ༻ҙ͞Ε͍ͯΔstreamingͷϝ
    ιουΛݺͼग़͢
    • CallΦϒδΣΫτ͸streaming͕ऴྃ͢Δ·Ͱอ͓࣋ͯ͘͠
    ※ Unary͸ྫ֎

    View Slide

  59. Echo_EchoGetCallʢUnaryʣ
    • get()ϝιουͰऔಘ
    • streaming༻ͷϝιου͸༻ҙ͞Ε͍ͯͳ͍

    View Slide

  60. Echo_EchoGetCallʢUnaryʣ
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    let getCall = try service.get(requestMessage) { response, callResult in
    }

    View Slide

  61. ΫϥΠΞϯτ࣮૷ͷಛ௃
    • CallΦϒδΣΫτΛ࡞ͬͨ࣌఺͔ΒtimeoutΧ΢ϯτμ΢ϯ
    • σϑΥϧτ͸600ඵͰɺϦΫΤετݸผʹ͸ઃఆෆՄ
    • ClientStreamingͷsend()ʹҾ਺Ͱ౉ͤΔtimeout͸ɺಉظ
    ௨৴͢Δࡍͷsemaphoreͷ଴ػ࣌ؒ

    View Slide

  62. ΫϥΠΞϯτ࣮૷ͷಛ௃
    • receive()͸ɺ1౓Ͱ΋σʔλΛड͚औΔͱͦΕҎ࣮߱ߦ͞
    Εͳ͍ͷͰɺ࠶౓receive()ΛݺͿඞཁ͕͋Δ
    • ͳʹ͔͠ΒͷΤϥʔ͕ग़ͨΒͦΕҎ߱ૹड৴Ͱ͖ͳ͍ͷͰɺ
    CallΦϒδΣΫτ͔Β࠶౓࡞੒͢Δඞཁ͕͋Δ
    • throws͕΍ͨΒଟ͍

    View Slide

  63. ΫϥΠΞϯτͷstubʹ͍ͭͯ
    • ServerΛϩʔΧϧʹ࣮૷ͯ͠stubԽ

    View Slide

  64. Echo for Server

    View Slide

  65. ServiceServer
    • αʔό΁ͷΫϥΠΞϯτ͔Βͷ઀ଓΛ؅ཧ
    • ಺෦ͰServerΦϒδΣΫτΛอ࣋
    • Echo_EchoProviderʹ४ڌͨ͠ΦϒδΣΫτΛड͚औΔ
    • startϝιουͰɺ઀ଓͷड৴Λ։࢝

    View Slide

  66. ServiceServer
    class EchoProvider: Echo_EchoProvider {
    func get() {}
    func expand() {}
    func collect() {}
    func update() {}
    }
    let provider = EchoProvider()
    let server = ServiceServer(address: "YOUR_ADDRESS",
    serviceProviders: [provider])
    server.start()

    View Slide

  67. Echo_EchoProvider
    • get, expand, collect, updateϝιου಺ͰɺΫϥΠΞϯ
    τ΁ͷϨεϙϯεΛߦ͏
    • Ҿ਺Ͱ౉͞ΕΔSessionΦϒδΣΫτͰৼΔ෣͍Λ࣮૷

    View Slide

  68. Echo_EchoProviderʢget == Unaryʣ
    • Echo_EchoRequestΦϒδΣΫτΛऔಘ
    • Echo_EchoResponseΛฦͨ͠Βऴྃ

    View Slide

  69. Echo_EchoProviderʢget == Unaryʣ
    func get(request: Echo_EchoRequest,
    session _: Echo_EchoGetSession) throws -> Echo_EchoResponse {
    var response = Echo_EchoResponse()
    response.text = request.text + " response"
    return response
    }

    View Slide

  70. Echo_EchoProviderʢexpand == ServerStreamingʣ
    • Echo_EchoRequestΦϒδΣΫτΛऔಘ
    • ඞཁʹԠͯ͡sessionͷsend()Λ࣮ߦ
    • ServerStatusΛฦ͠ɺ͔ͭsend()͕׬ྃͨ͠Βऴྃ

    View Slide

  71. Echo_EchoProviderʢexpand == ServerStreamingʣ
    func expand(request: Echo_EchoRequest,
    session: Echo_EchoExpandSession) throws -> ServerStatus? {
    var response = Echo_EchoResponse()
    response.text = request.text + " response"
    try! session.send(response) {
    // ΤϥʔΛड͚औΔ
    }
    return .ok
    }

    View Slide

  72. Echo_EchoProviderʢcollect == ClientStreamingʣ
    • ϦΫΤετ͸sessionͷreceive()Ͱऔಘ
    • Echo_EchoResponseΛฦͨ͠Βऴྃ

    View Slide

  73. Echo_EchoProviderʢcollect == ClientStreamingʣ
    func collect(session: Echo_EchoCollectSession) throws -> Echo_EchoResponse? {
    var response = Echo_EchoResponse()
    let request = try! session.receive()
    response.text = request.text + " response"
    return response
    }

    View Slide

  74. Echo_EchoProviderʢupdate == BidiStreamingʣ
    • ϦΫΤετ͸sessionͷreceive()Ͱऔಘ
    • ඞཁʹԠͯ͡sessionͷsend()Λ࣮ߦ
    • ServerStatusΛฦ͠ɺ͔ͭsend()͕׬ྃͨ͠Βऴྃ

    View Slide

  75. Echo_EchoProviderʢupdate == BidiStreamingʣ
    func update(session: Echo_EchoUpdateSession) throws -> ServerStatus? {
    let request = try! session.receive()
    var response = Echo_EchoResponse()
    response.text = request.text + " response"
    try! session.send(response) {
    // ΤϥʔΛड͚औΔ
    }
    return .ok
    }

    View Slide

  76. αʔό࣮૷ͷجຊతͳྲྀΕ
    • Echo_EchoProviderʹ४ڌͨ͠ΦϒδΣΫτΛ࡞੒͢Δ
    • ProviderͷϝιουͰಉظతʹॲཧ͠ɺ஋Λฦͯ͠ऴྃ

    View Slide

  77. SwiftGRPCClient

    View Slide

  78. View Slide

  79. SwiftGRPCClient
    > https://github.com/cats-oss/grpc-swift-client
    • ΫϥΠΞϯτઐ༻ͷgRPCϥΠϒϥϦ
    • SwiftGRPCʹґଘ
    • timeoutΛϦΫΤετ୯ҐͰܾΊͨΓ
    • ϦΫΤετͷ్தͰॲཧΛΠϯλʔηϓτͨ͠Γ
    • receive()ΛࣗಈͰϦτϥΠͯ͘͠ΕͨΓ

    View Slide

  80. protoc-gen-swiftgrpc-client
    $ protoc echo.proto --plugin=./protoc-gen-swiftgrpc-client --swiftgrpc-client_out=.

    View Slide

  81. protoc-gen-swiftgrpc-client
    enum Echo_EchoMethod: String, CallMethod {
    case get = "Get"
    static let service = "echo.Echo"
    }
    protocol _Echo_EchoGetRequest {
    typealias InputType = Echo_EchoRequest
    typealias OutputType = Echo_EchoResponse
    }
    protocol Echo_EchoGetRequest: _Echo_EchoGetRequest, UnaryStreamingRequest {}
    extension Echo_EchoGetRequest {
    var method: CallMethod {
    return Echo_EchoMethod.get
    }
    }

    View Slide

  82. SwiftGRPCʢClientStreamingʣ
    let collectCall = try service.collect { _ in
    }
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    try collectCall.send(requestMessage) { error in
    // ΤϥʔΛड͚औΔ
    }
    try collectCall.closeAndReceive { response in
    // close࣌ʹ1౓͚ͩσʔλΛड͚औΕΔ
    }

    View Slide

  83. SwiftGRPCClientʢClientStreamingʣ
    let stream = Session.shared.stream(with: EchoClientRequest())
    stream
    .send("message") { response in
    // ૹ৴݁ՌΛड͚औΔ
    }
    stream
    .closeAndReceive { response in
    // close࣌ʹ1౓͚ͩσʔλΛड͚औΕΔ
    }

    View Slide

  84. SwiftGRPCʢServerStreamingʣ
    var requestMessage = Echo_EchoRequest()
    requestMessage.text = "message"
    let expandCall = try service.expand(requestMessage) { _ in
    }
    try expandCall.receive { response in
    // ϨεϙϯεΛड͚औΔ
    }

    View Slide

  85. SwiftGRPCClientʢServerStreamingʣ
    let stream = Session.shared.stream(with: EchoServerRequest(text: "message"))
    .receive { response in
    // ϨεϙϯεΛड͚औΔ
    }

    View Slide

  86. SwiftGPRCClientʢRxʣ
    extension Reactive where Base: Streaming, Base.Request: UnaryRequest {
    func data() -> Observable {
    return .create { observer in
    self.base.data { result in
    switch result {
    case .success(let data):
    observer.onNext(data)
    observer.onCompleted()
    case .failure(let error):
    observer.onError(error)
    }
    }
    return Disposables.create {
    self.base.cancel()
    }
    }
    }
    }

    View Slide

  87. SwiftGPRCClientʢRxʣ
    Session.shared.stream(with: EchoUnaryRequest()).rx.data()
    .subscribe(onNext: { response in
    // ϨεϙϯεΛड͚औΔ
    }, onError: { error in
    // ΤϥʔΛड͚औΔ
    })
    .disposed(by: disposeBag)

    View Slide

  88. SwiftGPRCClient
    • ΫϥΠΞϯτʹSwiftGPRCClientΛར༻ͯ͠ɺstubͱͯ͠
    SwiftGRPCͷαʔό࣮૷Λར༻͢Δ

    View Slide

  89. ॴײͱࠓޙ

    View Slide

  90. ॴײ
    • ࠷ॳ͸callͷcancel͢Βແ͔ͬͨ
    • ಋೖ͕ਏ͔ͬͨ
    • Τϥʔ࣌ͷࡉ͔͍ڍಈ͕௫ΈͮΒ͍

    View Slide

  91. Swift Summit

    View Slide

  92. ࠓޙ
    • ࠷ۙ͸υΠπਓͷΤϯδχΞ͕ฃಆͯ͠ϝϯςφϯε
    • Network.frameworkͷಋೖͷݕ౼ͳͲ͕͞Ε͍ͯΔ
    • ͱΓ͋͑ͣਖ਼ࣜʹgrpcҰ଒ʹೖͬͯཉ͍͠

    View Slide

  93. grpc-swiftΛ࢖ͬͯiOSΞϓϦͰ΋շదͳgRPC௨৴Λߦ͏ɹɹ
    https://github.com/cats-oss/grpc-swift-client
    Github : KyoheiG3
    Twitter : @KyoheiG3

    View Slide

  94. Thanks!

    View Slide