The problem

In mobile application development, the complex business logic layer implementation is usually placed on the server side, and the client side is only responsible for the presentation layer. However, for some mobile applications, it is not safe or reasonable to implement the business logic on the server side. Instead, the logic needs to be implemented directly on the mobile side.

purpose

It is not a best practice to repeatedly implement the same business logic for mobile clients with different systems. The purpose of this research is how to package the business logic into a library through the third-party language Go, and provide it to the mobile phone clients of different systems in a static packaging way.

Ideal target chart:



Specific research contents include:

  • GRPC calls are implemented in iOS applications
  • Android applications implement gRPC calls
  • GoMobile SDK integration on iOS & Android
  • GoMobile SDK boundaries on iOS & Android
  • C/S architecture or static library

Among them, the implementation of gRPC in iOS and Android itself has officially provided a sample. Relevant content will be used in this research, so write it down as part of the research for later readers to read.

1. Environment installation

In fact, a lot of things are not that difficult, just need to start. In order to complete the target research, start the first part of the research. Record in the form of words, convenient later.

1.1 the XCode installation

Nothing to say, download and install directly from AppStore. It’s a bit slow, preparing for other environments while downloading.

1.2 Cocoapod installation

Similar to third-party library management tools in other languages. There’s nothing to say, go to the official website and follow the instructions.

$: sudo gem install cocoapods
Copy the code

1.3 Protoc Command Installation

Due to the widespread use of gRPC, the ProtoBuf protocol is widely used as a protocol for byte encoding and decoding. For details, refer to the official website. Without further ado, install:

$: $: curl - LOk https://github.com/protocolbuffers/protobuf/releases/download/v3.5.1/protoc-3.9.0-rc-1-osx-x86_64.zip Unzip protoc-3.9.0-RC-1-osx-x86_64. zip -d proto_buffer && CD proto_buffer $: sudo cp bin/protoc /usr/local/bin $: sudo cp -R include/google/protobuf/ /usr/local/include/google/protobuf $: protoc --versionCopy the code

1.4 Protoc Plug-in Installation

Protoc mainly parses.proto format files and generates corresponding language codes according to specific plug-ins. Considering the need to implement both client-side and server-side code, the following three plug-ins must be installed:

  • swift
  • swiftgrpc
  • Go mainly generates go code for server-side implementation

Swift plug-in installation:

$: git clone https://github.com/grpc/grpc-swift.git $: $CD GRPC - swift: git checkout tags / 0.5.1 $: $: make sudo cp protoc-gen-swift protoc-gen-swiftgrpc /usr/local/binCopy the code

Go plug-in installation:

The prerequisite is to install the Go development environment. For details, see the official website. Protoc-gen -go Installation details guide.

$: go get -u github.com/golang/protobuf/protoc-gen-go
Copy the code

2 Define the Proto interface

Since it is the simplest survey, I will use the simplest Hello service. Create the project path and define:

$: mkdir grpc-apps
$: cd grpc-apps
$: mkdir proto
$: cat <<EOF > proto/hello.proto
syntax = "proto3";

option java_multiple_files = true;
option java_package = "com.gitdig.helloworld";
option java_outer_classname = "HelloWorldProto";

package helloworld;

service Greeter {
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

message HelloRequest {
  string name = 1;
}

message HelloReply {
  string message = 1;
}
EOF
Copy the code

3. Server implementation

Create the server directory and proto build directory in the project directory, and write a simple server:

$: CD grpc-apps $: mkdir go go/client go/server go/hello protoc -I proto proto/hello.proto --go_out=plugins=grpc:./go/hello/Copy the code

Edit client and Server implementations of Go versions respectively. Verify that services are running properly.

3.1 Go Server

Edit the server/server.go file:

package main import ( pb "github.com/liujianping/grpc-apps/go/helloworld" ) import ( "context" "fmt" "log" "net" "google.golang.org/grpc" ) type HelloServer struct{} // SayHello says 'hi' to the user. func (hs *HelloServer) SayHello(ctx context.Context, req *pb.HelloRequest) (*pb.HelloReply, error) { // create response res := &pb.HelloReply{ Message: fmt.Sprintf("hello %s from go", req.Name), } return res, nil } func main() { var err error // create socket listener l, err := net.Listen("tcp", ":50051") if err ! = nil { log.Fatalf("error: %v\n", err) } // create server helloServer := &HelloServer{} // register server with grpc s := grpc.NewServer() pb.RegisterGreeterServer(s, helloServer) log.Println("server serving at: :50051") // run s.Serve(l) }Copy the code

Run the server program:

$: cd grpc-apps/go
$: go run server/server.go
2019/07/03 20:31:06 server serving at: :50051
Copy the code

3.2 Go Client

Edit the client/client.go file:

package main import ( pb "github.com/liujianping/grpc-apps/go/helloworld" ) import ( "context" "fmt" "log" "google.golang.org/grpc" ) func main() { var err error // connect to server conn, err := grpc.Dial("localhost:50051", grpc.WithInsecure()) if err ! = nil { log.Fatalf("error: %v\n", err) } defer conn.Close() // create client client := pb.NewGreeterClient(conn) // create request req := &pb.HelloRequest{Name: "JayL"} // call method res, err := client.SayHello(context.Background(), req) if err ! = nil { log.Fatalf("error: %v\n", err) } // handle response fmt.Printf("Received: \"%s\"\n", res.Message) }Copy the code

Execute client program:

$: cd grpc-apps/go
$: go run client/client.go
Received: "hello JayL from go"
Copy the code

The Go client communicates with the server successfully.

4. The iOS project

4.1 Create the simplest single view project

Create a single view project named iosDemo, select Swift, and store it in grPC-apps. After the creation is complete, the program runs normally and exits.

4.2 Initializing the Project Pod

Perform initialization at the command line:

$: CD grpc-apps/iosDemo # Init $: pod init $: vim PodfileCopy the code

Edit the Podfile as follows:

# Uncomment the next line to define a global platform for your project
# platform :ios, '9.0'

target 'iosDemo' do
  # Comment the next line if you don't want to use dynamic frameworks
  use_frameworks!

  # Pods for iosDemo
  pod 'SwiftGRPC'
end
Copy the code

After editing, save and execute installation command:

$: pod install
Copy the code

After installation, the project directory changes as follows:

$: git status
On branch master
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

    modified:   iosDemo.xcodeproj/project.pbxproj

Untracked files:
  (use "git add <file>..." to include in what will be committed)

    Podfile
    Podfile.lock
    Pods/
    iosDemo.xcworkspace/

no changes added to commit (use "git add" and/or "git commit -a")
Copy the code

Run the open iosDemo.xcworkspace command to open the project and modify the following Settings of the info.list in the project:



This section describes how to enable an insecure HTTP access mode.

4.3 Generating gRPC Swift Code

Similar to Go code generation, now generate swift code:

$: grpc-apps # create swift file directory $: swift # create swift file directory $: Protoc -i proto proto/hello.proto \ --swift_out=./swift/ \ --swiftgrpc_out=Client=true,Server=false:. Heavy exercises ── heavy exercises ── heavy exercisesCopy the code

4.4 Integrate generated code into iOS projects

Adding generated code to XCode requires drag and drop, which is a bit ridiculous for back-end development. But if you have to, follow the rules:

Now add gRPC call procedure in iOS view load function:

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
        let client = Helloworld_GreeterServiceClient(address: ":50051", secure: false)
        var req = Helloworld_HelloRequest()
        req.name = "JayL"
        do {
            let resp = try client.sayHello(req)
            print("resp: \(resp.message)")
        } catch {
            print("error: \(error.localizedDescription)")
        }
    }
}
Copy the code

Resp: Hello iOS from Go, the iOS application successfully invoked the gRPC service.

Recommended at the end of the article: iOS hot interview bottom collection

  • 1.IOS engineers soar secrets

  • 2.Must-see videos for Advanced Development in iOS (Must-see Classics)