Part 2: How to interact with vote contract using TezosSwift and Combine
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 underlyingWallet
(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 toRateRepository
.
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.