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.
- 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 usedziti-sdk-c/build-darwin-x86_64
as my build directory. (If I had been building for iOS, I would have built into theziti-sdk-c/build-iOS-arm64
directory, using the toolchain supplied in the repo viacmake .. -DCMAKE_TOOLCHAIN_FILE=../toolchains/iOS-arm64.cmake && make
- I used Xcode to create a new Objective-C command line project (I called it
objective-z
) - I added the appropriate header and library search paths:
(note that I selectedrecursive
for the Library Search path)
4 I added the libraries built in step 1
- I edited the
main.m
file generated by the Xcode project to include the source code from thesample_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;
}
- 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
- I updated the Run scheme to pass the identity file in as argv[1]
- 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
- Clone the SDK from https://github.com/netfoundry/ziti-sdk-c
- Now to build SDK for IOS, i installed CMAKE on my mac system and followed the steps as explained but no luck there
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.
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 i am professional IOS app developer so
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.