IcpKit.swift (Submission ID: 46842913) - Candid service description file (.did) parser and code generator

I am applying for a $5k Developer Grant.

Please review my application and discuss! See DFINITY’s directions for becoming a registered reviewer here. They will be collected by DFINITY. When one week passes, DFINITY will release them and they will appear as a new section on this post.

Please review my application and discuss! If you would like to submit an official review, then please use the links below to register, see the rubric, and submit a review.

I’m looking forward to everyone’s input!

Reviewer Registration | Rubric for Evaluating | Submit a Review

MY APPLICATION:

REVIEWS:

We are back with the IcpKit.Swift for iOS!
This time we will be enhancing it with a command line tool that can :

  1. Parse a Candid service description file (.did as described here : 2.4 Introduction to Candid | Internet Computer)
  2. Generate Swift classes for each type in the file
  3. Generate Swift methods for each service function
  4. Generate Swift documentation for each class/method from the comments in the original .did file

The generated Swift classes can be directly used with the IcpKit.Candid implementation for interacting with a given canister without writing any of the encoding/serialisation code.
The generated Swift methods can be directly called in order to interact with the given canister.

This will further facilitate the writing of iOS mobile apps that can directly interact with any canister of the Internet Computer.

Here are some examples :

type Auth = variant { FreeRpc; PriorityRpc; RegisterProvider; Manage };

will generate a Auth.swift file with these contents :

enum Auth {
   case FreeRpc
   case PriorityRpc
   case RegisterProvider
   case Manage

   static var candidType: CandidType {
      .keyedContainer(.variant, [
         CandidKeyedItem("FreeRpc", .null),
         CandidKeyedItem("PriorityRpc", .null),
         CandidKeyedItem("RegisterProvider", .null),
         CandidKeyedItem("Manage", .null),
      ])
   }

   var candidValue: CandidValue {
      .variant(Self.candidType, self.rawValue)
   }
}

The candidValue and candidType properties allow this to be easily serialised and encoded for sending to a canister.

Similarly, services can be parsed :

service SomeService: {
  authorize : (principal, Auth) -> (success : bool);
}

will generate this Swift code

struct AuthorizeResponse {
   let success: Bool
}

class SomeService {
   func authorize(CandidPrincipal, Auth) -> AuthorizeResponse {
      ...
   }
}

We can simply call the SomeService.authorize(_,_) method using the CandidPrincipal (pre-built with IcpKit.Swift) and Auth (generated from the .did) structs. The implementation of this method makes the actual call/query to the canister and returns the decoded response in an easy to use AuthorizeResponse struct.

A question for which I can not find any answers in the docs :

In the evm_rpc.did file the service is defined as follows:

service : (InitArgs) -> {
   ...
};

What is the meaning of (InitArgs) -> in this syntax? I can not find any documentation for this. I would expect something like :

service: {
   ...
};

service : (InitArgs) -> { means that to instantiate one of these services, you need to supply (InitArgs) as an init argument. You can think of it as the deployment configuration.

@Jessie, can you get the Candid folks to document this somewhere nicely? The AskAI button points me to Roman’s blog, which is great, but it is pretty fundamental syntax that should be documented somewhere

2 Likes

kosta, please edit your post to include the code so that your full application (and reviews) appear. I have sent you the code twice via email from Submittable. It is an attachment.

1 Like

Thank you! Since next week is a US holiday and we have some team members on PTO, we will wait until July 8 to make the reviews public.