Part 2: How to interact with vote contract using TezosSwift and Combine

Marek Fořt
Ackee
Published in
3 min readFeb 26, 2020

Following up on the first part of this tutorial, in this tutorial we shall see how we can leverage to easily interact with our contract in our SwiftUI/Combine codebase.

Generating our Contract

Once you deploy the contract using smartpy IDE at the bottom you should see “Contract data” and a tab “Code json”. From there we will need the contents of storage and parameter as shown in the image below:

You can find the final JSON file . To follow the rest of tutorial, I’d advise you to download the source code . Let’s see how we can generate a Swift code for our contract. After downloading , we can run tezosgen generate RateContract contract.json -x RateMyTeam.xcodeproj -o RateMyTeam/Generated --extensions combine -t RateMyTeam. What this will essentially do is translate contract.json to RateContract.swift with the added extensions for using Combine. Similarly to the previous tutorial, I will go through how to implement voting and ending functionality but feel free to roam through the rest of the codebase!

Vote Method

The interaction with our contract is handled in RateRepository.swift

For voting we will need three additional properties (apart from the vote function itself):

  • tezosClient for interacting with a given Tezos network node (for more about it see TezosSwift documentation )
  • userRepository: holds underlying Wallet (also from TezosSwift)
  • @Published var state: RateRepositoryState: Tracks currently available info about contracts in our app. It is annotated with @Published because we want to trigger changes for views that are bound to RateRepository.

This is what the final vote function looks like:

This function accepts a dictionary of votes - key being id of a candidate ( address), contractAddress is, surprisingly, the address of the contract we want to interact with.

In the #1 part we first unwrap our wallet to be able to sign a later transaction. nonZeroVotes is just a convenient variable to ensure that we do not cast any votes with value of zero.

#2 is the most important part of our code. tezosClient.rateContract(at: contractAddress) returns an invocable object of the previously generated RateContract. On that invocable object ( ContractBox in the generated code) we can call vote function with our nonZeroVotes. Finally, to send operation to the contract we run callPublisher(from: wallet, amount: Tez(0)) - that is send a new transaction from our wallet with zero amount of tez (fees will be automatically calculated by TezosSwift).

callPublisher returns a Publisher where output value is a signature of the transaction. If we do not receive that signature, it means the call has failed. If all succeeds, we add the votes to our rateRepositoryState in a helper function addVotes (this way the new changes will get propagated to all our views). And that's it for our vote function!

End Method

Our end method is very similar to a voting one (but even a little bit simpler!):

The only difference being at #1 where we call .end(). Then in #2 we will again call a helper function that locally updates our rateRepository.

Updating Contracts

So far, we have only updated the data locally — but what about syncing them with the current state on the blockchain? That becomes quite simple, too:

We leverage statusPublisher() method that returns RateContractStorage that holds the current contract's storage. Easy enough!

Final Notes

I hope this tutorial has given you enough information, so you can start working on your own Tezos smart contract iOS app. The generated code from tezosgen should make it really easy to start calling your smart contract and even incorporate into your iOS app (be it in SwiftUI, or not!). If you have any questions regarding app development using Tezos blockchain feel free to ask us at Ackee.

Originally published at https://www.ackee.cz on February 26, 2020.

--

--