Ziti sdk installation in ios

Hello Team, How to use Ziti SDK in iOS which is implemented in objective c.

I recommend starting with the C-SDK: https://github.com/netfoundry/ziti-sdk-c. I’ve used it successfully in Swift applications on iOS and macOS. I expect calling C functions from Objective-C to be straightforward (though I haven’t done it while linking a static C library from Objective-C yet).

You may want to start with creating an Objective-C project based on one of the Ziti sample apps to work through any issues with Obj-C / C compatibly in a simple environment. https://github.com/netfoundry/ziti-sdk-c/tree/master/programs/sample_wttr is a simple project that access a weather service accessed over Ziti via a REST.

Note that working with the sample program can be built for macOS, but the project configuration and coding will be the same for an iOS target.

I set up a quick project to call the Ziti C SDK from Objective-C. I built this for macOS, but steps will be pretty much the same for iOS.

  1. I cloned https://github.com/netfoundry/ziti-sdk-c and built the SDK for macOS following the directions in the ziti-sdk-c/README.md. I used ziti-sdk-c/build-darwin-x86_64 as my build directory. (If I had been building for iOS, I would have built into the ziti-sdk-c/build-iOS-arm64 directory, using the toolchain supplied in the repo via cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/iOS-arm64.cmake && make
  2. I used Xcode to create a new Objective-C command line project (I called it objective-z)
  3. I added the appropriate header and library search paths:

    (note that I selected recursive for the Library Search path)
    4 I added the libraries built in step 1
  4. I edited the main.m file generated by the Xcode project to include the source code from the sample_wttr project
Copyright 2020 Netfoundry, Inc.

Licensed 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

https://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.
*/

#import <Foundation/Foundation.h>
#import <nf/ziti.h>

#define DIE(v) do { \
int code = (v);\
if (code != ZITI_OK) {\
fprintf(stderr, "ERROR: " #v " => %s\n", ziti_errorstr(code));\
exit(code);\
}} while(0)

static size_t total;
static nf_context nf;

void on_data(nf_connection c, uint8_t *buf, int len) {
    if (len == ZITI_EOF) {

        printf("request completed: %s\n", ziti_errorstr(len));
        NF_close(&c);
        NF_shutdown(nf);

    }
    else if (len < 0) {
        fprintf(stderr, "unexpected error: %s\n", ziti_errorstr(len));
        NF_close(&c);
        NF_shutdown(nf);
    }
    else {
        total += len;
        printf("%*.*s", len, len, buf);
    }

}

static void on_write(nf_connection conn, ssize_t status, void *ctx) {
    if (status < 0) {
        fprintf(stderr, "request failed to submit status[%zd]: %s\n", status, ziti_errorstr((int)status));
    }
    else {
        printf("request success: %zd bytes sent\n", status);
    }
}

void on_connect(nf_connection conn, int status) {
    DIE(status);

    printf("sending HTTP request\n");
    
    uint8_t *req = "GET /Rochester HTTP/1.0\r\n"
                   "Accept: */*\r\n"
                   "Connection: close\r\n"
                   "Host: wttr.in\r\n"
                   "User-Agent: curl/7.59.0\r\n"
                   "\r\n";

    DIE(NF_write(conn, req, strlen(req), on_write, NULL));
}

void on_nf_init(nf_context _nf, int status, void* ctx) {
    DIE(status);
    nf = _nf;

    nf_connection conn;
    DIE(NF_conn_init(nf, &conn, NULL));
    DIE(NF_dial(conn, "demo-weather", on_connect, on_data));
}

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        // insert code here...
        NSLog(@"Hello, World!");
        
        uv_loop_t *loop = uv_default_loop();

        DIE(NF_init(argv[1], loop, on_nf_init, NULL));

        // loop will finish afger the request is complete and NF_shutdown is called
        uv_run(loop, UV_RUN_DEFAULT);

        printf("========================\n");
    }
    return 0;
}
  1. I enrolled an identity with a Ziti system cofigured to support the demo-weather service referenced in the code, and stored the identity file at /Users/dhart/.netfoundry/id.json
  2. I updated the Run scheme to pass the identity file in as argv[1]
  3. I successfully accessed the service:
[        0.000] INFO	library/ziti.c:127 NF_init(): ZitiSDK version 0.5.13-local @54a0bd6(master)
[        0.000] INFO	library/ziti.c:174 NF_init_with_tls(): ZitiSDK version 0.5.13-local @54a0bd6(master)
[        0.000] INFO	library/ziti.c:51 init_work(): initializing ziti
[        0.200] INFO	library/controller.c:148 ziti_ctrl_version(): connected to controller demo.ziti.netfoundry.io:1080 version 0.5.6-2510(6d28275 Wed-10/30/2019-17:59:28-UTC)
[        7.887] INFO	library/channel.c:144 ziti_channel_connect(): opening new channel for ingress[tls://demo.ziti.netfoundry.io:3022] ch[0]
sending HTTP request
request success: 99 bytes sent
HTTP/1.1 200 OK
Server: nginx/1.10.3
Date: Sun, 22 Mar 2020 16:17:39 GMT
Content-Type: text/plain; charset=utf-8
Content-Length: 8816
Connection: close

Weather report: Rochester

 e[38;5;226m    \   /    e[0m Sunny
 e[38;5;226m     .-.     e[0m e[38;5;045m21e[0m..e[38;5;051m26e[0m °Fe[0m      
 e[38;5;226m  ― (   ) ―  e[0m e[1m↙e[0m e[38;5;154m5e[0m mphe[0m        
 e[38;5;226m     `-’     e[0m 9 mie[0m           
 e[38;5;226m    /   \    e[0m 0.0 ine[0m         
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Sun 22 Mar ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│ e[38;5;226m    \   /    e[0m Sunny          │ e[38;5;226m   \  /e[0m       Partly cloudy  │               Cloudy         │               Cloudy         │
│ e[38;5;226m     .-.     e[0m e[38;5;039m17e[0m..e[38;5;051m26e[0m °Fe[0m      │ e[38;5;226m _ /""e[38;5;250m.-.    e[0m e[38;5;045m23e[0m..e[38;5;050m32e[0m °Fe[0m      │ e[38;5;250m     .--.    e[0m e[38;5;045m24e[0m..e[38;5;050m+33e[0m °Fe[0m     │ e[38;5;250m     .--.    e[0m e[38;5;045m21e[0m..e[38;5;051m28e[0m °Fe[0m      │
│ e[38;5;226m  ― (   ) ―  e[0m e[1m←e[0m e[38;5;226m8e[0m-e[38;5;220m11e[0m mphe[0m     │ e[38;5;226m   \_e[38;5;250m(   ).  e[0m e[1m↙e[0m e[38;5;220m9e[0m-e[38;5;220m11e[0m mphe[0m     │ e[38;5;250m  .-(    ).  e[0m e[1m↙e[0m e[38;5;220m11e[0m-e[38;5;208m16e[0m mphe[0m    │ e[38;5;250m  .-(    ).  e[0m e[1m←e[0m e[38;5;220m11e[0m-e[38;5;196m19e[0m mphe[0m    │
│ e[38;5;226m     `-’     e[0m 6 mie[0m           │ e[38;5;226m   /e[38;5;250m(___(__) e[0m 6 mie[0m           │ e[38;5;250m (___.__)__) e[0m 6 mie[0m           │ e[38;5;250m (___.__)__) e[0m 6 mie[0m           │
│ e[38;5;226m    /   \    e[0m 0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Mon 23 Mar ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│ e[38;5;226m _`/""e[38;5;250m.-.    e[0m Patchy rain po…│ e[38;5;250m     .-.     e[0m Light rain     │ e[38;5;250m     .-.     e[0m Patchy light r…│               Mist           │
│ e[38;5;226m  ,\_e[38;5;250m(   ).  e[0m e[38;5;051m28e[0m..e[38;5;049m+37e[0m °Fe[0m     │ e[38;5;250m    (   ).   e[0m e[38;5;050m33e[0m..e[38;5;048m41e[0m °Fe[0m      │ e[38;5;250m    (   ).   e[0m e[38;5;049m37e[0m..e[38;5;048m41e[0m °Fe[0m      │ e[38;5;251m _ - _ - _ - e[0m e[38;5;049m35e[0m..e[38;5;048m39e[0m °Fe[0m      │
│ e[38;5;226m   /e[38;5;250m(___(__) e[0m e[1m↖e[0m e[38;5;208m15e[0m-e[38;5;196m24e[0m mphe[0m    │ e[38;5;250m   (___(__)  e[0m e[1m↑e[0m e[38;5;208m15e[0m-e[38;5;196m22e[0m mphe[0m    │ e[38;5;250m   (___(__)  e[0m e[1m↗e[0m e[38;5;190m6e[0m-e[38;5;220m11e[0m mphe[0m     │ e[38;5;251m  _ - _ - _  e[0m e[1m↗e[0m e[38;5;154m5e[0m-e[38;5;226m9e[0m mphe[0m      │
│ e[38;5;111m     ‘ ‘ ‘ ‘ e[0m 5 mie[0m           │ e[38;5;111m    ‘ ‘ ‘ ‘  e[0m 6 mie[0m           │ e[38;5;111m    ‘ ‘ ‘ ‘  e[0m 5 mie[0m           │ e[38;5;251m _ - _ - _ - e[0m 4 mie[0m           │
│ e[38;5;111m    ‘ ‘ ‘ ‘  e[0m 0.0 in | 74%e[0m   │ e[38;5;111m   ‘ ‘ ‘ ‘   e[0m 0.0 in | 65%e[0m   │ e[38;5;111m   ‘ ‘ ‘ ‘   e[0m 0.1 in | 72%e[0m   │               0.0 in | 58%e[0m   │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
                                                       ┌─────────────┐                                                       
┌──────────────────────────────┬───────────────────────┤  Tue 24 Mar ├───────────────────────┬──────────────────────────────┐
│            Morning           │             Noon      └──────┬──────┘     Evening           │             Night            │
├──────────────────────────────┼──────────────────────────────┼──────────────────────────────┼──────────────────────────────┤
│ e[38;5;226m   \  /e[0m       Partly cloudy  │ e[38;5;226m   \  /e[0m       Partly cloudy  │ e[38;5;226m   \  /e[0m       Partly cloudy  │ e[38;5;226m   \  /e[0m       Partly cloudy  │
│ e[38;5;226m _ /""e[38;5;250m.-.    e[0m e[38;5;050m32e[0m..e[38;5;049m35e[0m °Fe[0m      │ e[38;5;226m _ /""e[38;5;250m.-.    e[0m e[38;5;048m41e[0m..e[38;5;047m42e[0m °Fe[0m      │ e[38;5;226m _ /""e[38;5;250m.-.    e[0m e[38;5;050m33e[0m..e[38;5;048m41e[0m °Fe[0m      │ e[38;5;226m _ /""e[38;5;250m.-.    e[0m e[38;5;051m30e[0m..e[38;5;049m+37e[0m °Fe[0m     │
│ e[38;5;226m   \_e[38;5;250m(   ).  e[0m e[1m↘e[0m e[38;5;154m4e[0m-e[38;5;190m6e[0m mphe[0m      │ e[38;5;226m   \_e[38;5;250m(   ).  e[0m e[1m↗e[0m e[38;5;118m3e[0m-e[38;5;154m4e[0m mphe[0m      │ e[38;5;226m   \_e[38;5;250m(   ).  e[0m e[1m↙e[0m e[38;5;220m9e[0m-e[38;5;214m13e[0m mphe[0m     │ e[38;5;226m   \_e[38;5;250m(   ).  e[0m e[1m←e[0m e[38;5;226m8e[0m-e[38;5;208m14e[0m mphe[0m     │
│ e[38;5;226m   /e[38;5;250m(___(__) e[0m 6 mie[0m           │ e[38;5;226m   /e[38;5;250m(___(__) e[0m 6 mie[0m           │ e[38;5;226m   /e[38;5;250m(___(__) e[0m 6 mie[0m           │ e[38;5;226m   /e[38;5;250m(___(__) e[0m 6 mie[0m           │
│               0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │               0.0 in | 0%e[0m    │
└──────────────────────────────┴──────────────────────────────┴──────────────────────────────┴──────────────────────────────┘
Location: Rochester, Monroe County, New York, United States of America [43.157285,-77.6152139]

Follow e[46me[30m@igor_chubine[0m for wttr.in updates
request completed: Connection closed
[        8.403] INFO	library/ziti.c:214 NF_shutdown(): Ziti is shutting down
========================
Program ended with exit code: 0```

Re: the demo-weather service that is used in many of the sample applications. It’s a simple service that just routes calls from a ziti network to http://wttr.in. The service should be configured like this:

name = demo-weather
protocol = tcp
host = wttr.in
port = 80

Thank you for the information.

@dave - Thanks for great information. It makes sense a lot but I am facing difficulties regarding building SDK. I have followed the below steps :slight_smile:

Could you please suggest me that how to build SDK and then use it on my xcode project then it will be great help.

Thanks in advance.

Would you please share additional information about the commands you’ve run and the issues you’ve seen?

Here is a snaphot of the commands I used to build the SDK:

   1  git clone git@github.com:netfoundry/ziti-sdk-c.git
   2  cd ziti-sdk-c/
   3  git submodule update --init --recursive
   4  mkdir build-darwin-x86_64
   5  cd build-darwin-x86_64
   6  cmake .. && make

The most common mistake I’ve seen folks make is to forget the git submodule update --init --recursive. If you need to re-run cmake it’s best to start with an empty build-darwin-x86_64 directory.

Thanks @dave again for quickly reply. Actually i tried the steps you suggested but the thing is last command is not executing and getting error saying command not founc. See attached :

Hi @dave - We have tried few more tricks found from internet that i want to share with you, please have a look and let me know if you can help there.

That is using CMake software which i have installed on mac. Then followed the steps which needed to ask and in result it will generate one build folder which will have .xcodeproject file. I can open that file as well but the issue is i am not able to understand how to use that. Here is the screenshot of Cmake software and xcode project which generated.

Xcode image

Looks like an issue with your cmake installation. I usually use homebrew for this sort of thing (brew install cmake).

If you’re not already using homebrew you can install using ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

I’ve only used cmake from the command-line. You may need to install Xcode developer tools.

Thanks @dave - Yeah i also feel same that might be the issue with cmake which is not installed now i am installing it. And yeah we do have the xcode tool :slight_smile: i am professional IOS app developer so :wink:

Cool - you’ll know the Xcode tooling better than me. I couldn’t remember if I’d downloaded anything special from Apple to support building from the command-line somewhere along the line.

I just noticed that you’re cross-compiling for iOS looking back at your cmake command-line. The cmake command in that case should be cmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/iOS-arm64.cmake && make

Hi Dave - Yes i tried the same steps you told and also last i did this command : cmake … -DCMAKE_TOOLCHAIN_FILE=…/toolchains/iOS-arm64.cmake && make

But i am getting this error, see the attached :

I see this post that may help with the “iphoneos in not an iOS SDK” error message: https://github.com/leetal/ios-cmake/issues/52

As a follow-up, we’ve done some work to make this a bit easier. See https://github.com/openziti/ziti-sdk-swift.

Included is a class called ZitiUrlProtocol that implements a URLProtocol for intercepting URLSession requests. There are a few samples apps include that demonstrate using ZitiUrlProtocol, the “socket-level” Ziti calls (including operating as an app-embedded client or as an app-embedded service), and a sample that shows usage from Objective-C.