< Back to articles

Interacting with the Tezos blockchain on iOS: Part 1

Interacting with the Tezos blockchain on an iOS device should be an easy task. With TezosSwift, we at Ackee are working to accomplish that goal. TezosSwift has been built with type-safety in mind and implements most of what you could possibly need for Tezos development on iOS. Parts of this tutorial are also applicable to Keefer Taylor's TezosKit, a library that TezosSwift is based on.

Let's Get Started

For this project we will use Xcode 10.0 and TezosSwift 1.0. First, we will create a new Xcode project, I will call it TezosContracts, but feel free to use your own name for it. Now what we need to do is to import TezosSwift, for which we will use cocoapods. Simply create a new Podfile, insert this code into it, and run pod install:

platform :ios, '10.0'  
inhibit_all_warnings!  
use_frameworks!  
  
target 'TezosContracts' do  
  pod 'TezosSwift'  
end  

OK, so now that we have TezosSwift installed, let's see what we can do! 😎

RPC GET Requests

We will start off with the easier part. TezosSwift includes quite a few RPC GET requests. Yes, you could call these by yourself, but why not let TezosSwift make it easier for you? But before getting our hands dirty we need to create a TezosClient instance that is the main component that you will use to make calls to the Tezos blockchain. Navigate to ViewController and create one like this:

let tezosClient = TezosClient(remoteNodeURL: URL(string: "https://rpcalpha.tzbeta.net/")!)  

Note this should be held strongly, so make this a property of ViewController (do not put it in the viewDidLoad() function). Also, do not forget to import TezosSwift at the top of the file.

The URL simply specifies the address of the node and you can choose a node of your liking (the one I have used here is public and should support most of the calls you will need during your Tezos development). With TezosClient instantiated, we can now, for example, use it to get the balance of an account. How do we do that? Simply write this in your viewDidLoad() function:

tezosClient.balance(of: "KT1BVAXZQUc4BGo3WTJ7UML6diVaEbe4bLZA", completion: { result in  
  
        switch result {  
  
        case .success(let balance):  
  
            print(balance.humanReadableRepresentation)  
  
        case .failure(let error):  
  
            print("Getting balance failed with error: \(error)")  
  
        }  
  
    })  

Now let's go through what this code does. First, we access the function we want through TezosClient. The function balance takes in a parameter of String that describes the address we want to get the balance of. This function then has a completion that returns a closure with a parameter Result. TezosError would specify what went wrong in the case of error, Tez is an important part of the library. It represents a value of one Tezos token, so for example to create a value of one Tezos token, you can write let oneTezos = Tez(1). There is also a Mutez type that corresponds to the value of one microtez (10^-6). Its property, humanReadableRepresentation, returns a String that you can then show to the user. And now you can know a balance of any account you desire 👀

But you probably want to do more, don't you? Read on!

Transaction

Using our framework, Tezos token holders can transact on the network. So... how do we send Tezos? 🤔 First, we need to create/import a wallet that has some funds in it. The easiest way to do this is using a Mnemonic sentence:

let mnemonic = "soccer click number muscle police corn couch bitter gorilla camp camera shove expire pill praise"  
  
let wallet = Wallet(mnemonic: mnemonic)!

This Mnemonic sentence gives you access to an alphanet wallet that has available funds, so you can test transactions. Please use it carefully and try not to send too many tez!

Now we can use this wallet to send some amount of tez. The call is quite similar to the previous one that enabled us to get a balance of an account:

tezosClient.send(amount: Tez(1), to: "tz1WRFiK6eGNvP3ioWkWeP6JwDaQjj95opnQ", from: wallet, completion: { result in  
           switch result {  
           case .success(let transactionHash):  
               print(transactionHash)  
           case .failure(let error):  
               print("Sending Tezos failed with error: \(error)")  
           }  
       })

This function takes in the amount of tez you want to send using the same structure as described earlier: the address we want to send Tez to described by a String, a wallet we want to send Tez from (use the one we have just created) and an optional parameter of OperationFees. If you do not describe OperationFees, default fees will be used (which is the minimal amount for the transaction to succeed). Lastly, you specify completion where you can act on the result of this call. It is also quite similar to the previous call, that is Result. We have already encountered TezosError but what is the String value about? Well, it is the hash of the operation (if the operation succeeds). And...that’s it! Sending tez is that easy 🚀

What’s next?

This is just the tip of the iceberg of what you can do with TezosSwift and so in this section, I will quickly skim through some of its other capabilities.

public func delegate(from source: String, to delegate: String, keys: Keys, operationFees: OperationFees? = default, completion: @escaping RPCCompletion) - this is one of the calls that handles baking. With this, you can delegate to the address you specify. There are also functions to undelegate and registerDelegate.

public func sendRPC(endpoint: String, method: HTTPMethod = default, payload: Encodable? = default, completion: @escaping RPCCompletion) where T : Decodable - this function is one of the lower-level parts of the code but with this, you can reproduce almost any RPC call. If you want to know how to implement one, look at the RPC calls in TezosClient file.

public func forgeSignPreapplyAndInjectOperation(operation: Operation, source: String, keys: Keys, completion: @escaping RPCCompletion) - with this function you can send batched operations (ie multiple transactions at once). Note that you have to specify the operations by yourself (for example, to send tez you need to initialize TransactionOperation).

Hey, but that’s not all!

Yes, it is not. We also created TezosGen that automatically generates Swift code for interactions with Tezos smart contracts. But to learn more about it, you will have to head to part 2 of this tutorial! 📚

You can also check out an example project here or see, how we bridge the world of mobile apps and blockchain as Ackee Blockchain.

Marek Fořt
Marek Fořt
iOS DeveloperMarek has a passion for opensource and developer tooling, he studies at Faculty of Information Technology at CTU and likes to ride a bike around the city.

Are you interested in working together? Let’s discuss it in person!

Get in touch >