Amatino Swift 0.0.11 Released

Amatino Swift 0.0.11 has been released! This is a huge release with wide ranging changes and substantial new features. It is not backwards compatible with 0.0.10, but any code written for 0.0.10 will compile for 0.0.11 with minor adjustments.

  • Almost all asynchronous Amatino methods now accept a (Result<T, Error>) -> Void callback parameter, using the new Swift 5 Result type. The previous (Error?, T?) -> Void parameter remains available. You now have a choice to use either depending on your preferred style.
  • Add Denomination protocol, which codifies the characteristics of CustomUnit and GlobalUnit and allows method signatures accepting either of those classes to be streamlined.
  • Add Denominated protocol, which gives default behaviours to classes denominated in a Denomination, such as Transactions and Ledgers.
  • Renamed many method signatures parameters for more expressive syntax. For example, someMethod(then: (Error?, Object?) rather than someMethod(callback: (Error?, Object?)
  • Remove all use of Int64, replace with Int. Amatino Swift will not function on 32-bit platforms, so the occasional use of Int64 added needless confusion.
  • The AmatinoError case .inconsistentInternalState has been renamed .inconsistentState
  • Publicly exposed Account.create() taking Account.CreateArguments struct. Gives extra flexibility when designing GUI for account creation
  • GlobalUnitList now conforms to the Sequence protocol. I.e. you can loop over the list without needing to access the raw .units property.
  • TheGlobalUnitList units property is now sorted first by GlobalUnit.priority and then alphabetically by
  • AccountType has a new static method, .typeWith(:name), which returns an AccountType with the given name
  • Tree now conforms to the Sequence protocol, iterating over Node conforming objects
  • Multiline strings throughout the library are no longer peppered with \n newlines. For example, AmatinoError messages.
  • Account.CreateArguments now enforces a minimum .name character length of 1.
  • Tree now features a .flatAccounts property, which returns recursive flattened list of all Accounts in the Tree as Node objects. This is effectively a list of all Accounts in an Entity.
  • Add new AccountRepresentative protocol, to which Account, TreeNode and PlaceholderNode conform. Provides base Account metadata – accountId, name, type, and is accepted in many places where Account was formerly required.
  • Fixed an internal typo in Account.DeletionArguments (no effect on public API)
  • Transaction, Balance, Account, Ledger, GlobalUnitList, Performance, Position and Entity methods may no longer throw. Errors are now exclusively handled by the error parameter in respective callbacks.
  • Ledger may now be retrieved with an object conforming to the AccountRepresentative protocol. This saves an intermediary Account retrieval when, for example, retrieving a Ledger based on a Tree node
  • Add User class including create(), retrieve(), delete() methods
  • Add User class lifecycle testing
  • Ledger.nextPage() renamed .retrieveNextPage()
  • RecursiveLedger.nextPage() renamed .retrieveNextPage()
  • Add Session.delete() method

Amatino Swift source code is available on GitHub, and you can add Amatino accounting functionality to your macOS or iOS project via Carthage or CocoaPods.

Amatino Swift 0.0.10 Released

A new version of Amatino Swift has been released. 0.0.10 adds some Custom Unit capabilities, slims some method signatures, and various smaller bits and pieces.

Note that release 0.0.9 was skipped for reasons of… science. 0.0.8 is the previously released Swift library version.

  • Big breaking change: Session is no longer required as an argument for Performance, Position, Transaction, Balance, and RecursiveBalance
  • Build out the previously useless CustomUnit, including .retrieve().create(), .createMany(), and update() methods
  • Added unit tests for new CustomUnit methods.
  • Simplify internal AmatinoObject protocol (no change to public API)
  • Entity now conforms to Equatable protocol
  • Add Entity.delete() method
  • Add EntityList object
  • Fixed a bug causing Ledger and RecursiveLedger iterators to skip the first row in the Ledger

Amatino Swift 0.0.8 Released

A new version of Amatino Swift has been released. 0.0.8 makes Amatino Swift CocoaPods compatible. You can now install Amatino by adding it to your Podfile:

pod 'Amatino', '>= 0.0.8'

The underlying library is unchanged. Here’s the full changelog:

  • Added Amatino.podspec
  • Changed macOS target to 10.10 (arbitrary at this point)
  • Changed iOS target to 10.3 (arbitrary at this point)
  • Added MIT license
  • Updated to reflect latest development of the library

– Hugh

Amatino Swift v0.0.7 Released

Amatino Swift 0.0.7 is now available! You can install it via Carthage or get the source code from GitHub. 0.0.7 is a major new release that adds significant capability. The powerful Tree, Position, and Performance objects are now available. Here’s the full change-log:

    • Remove InternalLibraryError, which sneakily survived the error consolidation purge in 0.0.6
    • Add Account.update() method
    • Add Account.delete() method
    • Add Account.deleteRecursively() method
    • Add Tree class
    • Add Position class
    • Add Performance class
    • Add Node protocol
    • Add Node conforming TreeNode and PlaceholderNode classes (used by Tree, Position, and Performance)
  • Consolidate SessionCreateArguments & SessionAttributes into Session
  • Consolidate BalanceRetrieveArguments into Balance
  • Drastically simplified and empowered the internal EntityObject protocol, reducing code complexity and duplication (does not affect public API)
  • Added unit tests for new features

Plant some Trees

Trees present the entire chart of accounts of an Entity as a hierarchical object. Each node in the Tree summarises an Account, including an individual and recursive balances.

Each node is represented by an instance of a class conforming to the Node protocol. Two such classes existing: TreeNode and PlaceholderNode.

TreeNodes present summarised account data, including individual and recursive balances. PlaceholderNodes stand in for TreeNodes where the requesting User does not have read permissions for the Account in question. A PlaceholderNode still includes children, which may include TreeNodes if the User has permission to read from accounts further down the hierarchy.

Determine Position

Positions are generic representations of the accounting construct variously known as a balance sheet, statement of financial position, or something else depending on your jurisdiction. They include hierarchical representations of all asset, liability, and equity Accounts inside an Entity.

Like the Tree, each Account is represented by an instance of an object conforming to the Node protocol.

Measure Performance

Performances are generic representations of the accounting construct variously known as an income statement, statement of financial performance, or comprehensive income statement, depending on your jurisdiction. They include hierarchical representations of all income and expense accounts inside an Entity.

Like the Tree and Position objects, each Account is represented by an instance of an object conforming to the Node protocol.

Updating & Deleting Accounts

Account instances now feature .update() and delete() methods, which do what it says on the tin. Here’s an example of an update operation:

Delete operations require a bit of thought. Deleting an Account does not delete any Transactions with Entries party to that Account. As such, you must supply an Account you wish to transfer any Entries to upon deletion. Here’s an example:

What next…

0.0.8 will probably focus on units of account, i.e. GlobalUnits & CustomUnits. In particular, loading CustomUnits into an Entity so that you can denominate Transactions in whatever unit suits you.

– Hugh

Amatino Swift v0.0.6 Released

Amatino Swift 0.0.6 has arrived! 0.0.6 makes lots of under the hood changes, the most important being to the error types emitted by the library. Here’s the changelog:

  • Added Transaction.update() method
  • Added Transaction.delete() method
  • Added session and entity properties to Transaction(A side-effect of the addition of .update() and .delete())
  • Consolidated all errors emitted by Amatino Swift under a single error type, AmatinoError
  • Potential API response errors (e.g. server errors) are now gracefully & descriptively emitted by instances of AmatinoError.
  • Consolidated creation, update, and retrieval argument structs into Transaction, e.g. TransactionCreateArguments -> Transaction.CreateArguments
  • Consolidated AccountCreateArguments struct into Account as Account.CreateArguments
  • Replaced overloaded Account.create() & .retrieve() with Account.createMany() & .retrieveMany()
  • Internally re-plumbed Transaction to conform to a new internal EntityObject protocol, reducing code duplication (causes no changes to API)
  • Renamed UrlParameters(:Entity:[UrlTarget]) entity label from entityWithTargets to entity
  • Removed defunct ObjectCore, AmatinoObjectError, and ConstraintError types
  • Consolidated EntityCreateArguments struct into Entity.CreateArguments
  • New unit tests for new features

New Error Handling

Before 0.0.6, errors thrown by Amatino Swift were an absolute mess. There was AmatinoObjectError, ConstraintError, ResponseError, and even just plain old Error. Now, you can be sure that any error thrown by Amatino Swift will be of type AmatinoError.

AmatinoError provides an enum, Kind, off of which you can switch via AmatinoError.kind. For example, a Transaction.retrieve() request might yield a .notFound case when the Amatino API returns 404. You can get a verbose String description of an error by examining the AmatinoError.message property.

Some objects, such as Transaction, provide a superclass of AmatinoError called ConstraintError, which provides more detailed information about input constraint violations. For example, when you supply  Transaction.create() with a description that is too long.

You can still handled these more verbose ConstraintError cases with a plain AmatinoError handler, as AmatinoError will flag them with the .constraintViolated case.

Transaction Update & Deletion

Sometimes you might which to change a Transaction after storing it. Perhaps an error was made, or underlying facts have changed. You can now do so using the update() instance method. Here’s an example:

You may also flat out delete a Transaction using the delete() instance method. Example:

Consolidation of ancillary structs

Many Amatino Swift classes depend on a variety of ancillary structs to perform their work. For example, Transaction uses CreateArguments and UpdateArguments, as well as several internal types. These types were previously in their own files.

This arrangement was causing the Amatino Swift project to be a bit jumbled. Code completion when typing the start of an object name was also getting crowded. So, as a matter of preference, I’ve been moving all ancillary types into their relevant classes. For example, TransactionCreateArguments has become Transaction.CreateArguments.

This process started in 0.0.5, and is ongoing in 0.0.6. There are a few cases of the old style left, which I’ll probably get to in 0.0.7.


– Hugh

Amatino Swift v0.0.5 Released

Amatino is a double entry accounting API, and Amatino Swift allows macOS & iOS developers to utilise Amatino in a Swift application. v0.0.5 is a major new Alpha release introducing the Ledger class, and some attendant smaller changes.

  • Added new Ledger class
  • Added new RecursiveLedger class
  • Added new LedgerPage class, a low level class underpinning Ledger and RecursiveLedger
  • Added new LedgerRow struct, used by Ledgers
  • parentAccount renamed to parent in AccountCreateArguments initialisers
  • AccountType is now inferred by AccountCreateArguments when a parent is supplied
  • Added new Account.create() async initialisers for various attribute mixes
  • Transaction will now throw ConstraintError if debits & credits do not balance on creation
  • Fixed a bug whereby all times sent to the Amatino API were in local system timezone rather than UTC
  • Added new Ledger-related unit tests

Retrieving a Ledger

Multiple Ledger.retrieve() overloads are available, allowing you to tailor the Ledger to your needs. For example, you might want to retrieve a specific timeframe or denominate the ledger in a particular unit (e.g. a non-native currency). You can also reverse-order the Ledger such that the first pages retrieves the most recent transactions.

RecursiveLedger syntax is identical to Ledger, but delivers every Transaction in the target Account and all of its children.


Amatino Swift may be installed via Carthage. Add github "amatino-code/amatino-swift"to your Cartfile.

Enjoy, and be sure to tell me what you think!

– Hugh

Amatino Swift v0.0.4 Released

Amatino Swift allows MacOS and iOS developers to build double-entry accounting functionality into their apps. Until today’s v0.0.4 release, it was a bit tricky to install. To make installation easy, Amatino Swift is now compatible with Carthage. Carthage is a Swift dependency manager. In the project’s own words:

Carthage is intended to be the simplest way to add frameworks to your Cocoa application.

Carthage builds your dependencies and provides you with binary frameworks, but you retain full control over your project structure and setup. Carthage does not automatically modify your project files or your build settings.

You can install Carthage by downloading and running Carthage.pkg from the Carthage project releases page.

Installing Amatino Swift with Carthage

Navigate to your project directory, and create a file named “Cartfile“. Inside that file, add the line github "amatino-code/amatino-swift". You can create the file, and insert the required line into the file, with the following command:

$ echo 'github "amatino-code/amatino-swift"' > Cartfile

Next, tell Carthage to download the Amatino Swift repository and compile MacOS and iOS frameworks, by running the following command inside your project directory:

$ carthage update

Once the process is complete, you should have Amatino.framework binaries available in the Carthage/Build/Mac and Carthage/Build/iOS directories.

The following instructions are applicable to MacOS applications. Instructions for iOS are broadly similar, and all instructions are available in detailed form in the Carthage project documentation.

Embedding Amatino in a MacOS application

Drag the binaries for your target platforms to the Embedded Binaries section of your Xcode project.

Next, to enable debugging, create a Copy Files phase in your target’s Build Phases tab:

Inside the phase, select Products Directory from the Destination drop down menu.

Finally, drag the Amatino.framework.dSYMfile into the Add files here section.

For more detailed instructions, check out the Carthage project documentation.

Where to next?

Now that Amatino Swift is easier to install, it’s time to smash together more functionality. In particular, I’d like to get Ledgers working as soon as possible.

Have a preferred method of installing Swift Frameworks? Please tell me about it on Twitter, on the forums, or via email. I would love to hear from you, and develop Amatino Swift in such a way as to make it easy for you to install.

– Hugh

Amatino Swift v0.0.3 Released

A new version of Amatino Swift is available. Amatino Swift is library / framework that lets MacOS and iOS developers build double-entry accounting functionality into their applications. v0.0.3 is backwards compatible with v0.0.2, and makes the following changes:

  • Add new Balance class
  • Add new RecursiveBalance class
  • Add new GlobalUnitList class
  • Add new Transaction.createMany() method
  • Add unit tests covering all of the above
  • Remove some debugging cruft & dead code

These features build on v0.0.2’s progress toward making Amatino Swift easy to use. Where in the past you would need to manually encode and decode Data responses via the AmatinoAlpha class, you now have more expressive, clean, and simple syntax at your disposal.

Balance & RecursiveBalance

Balance and RecursiveBalance allow you to retrieve the balance of a particular account. In practice, that means the total of all debits & credits party to that account. A ‘recursive’ balance totals debits and credits for the target account, and any child accounts.

Balances can be retrieved for any combination of date and denomination. For example, you might have an account denominated in U.S. Dollars, but be interested in retrieving its balance in Euros.

Here’s an example of Balance.retrieve() in action:

RecursiveBalance.retrieve() syntax is identical.


You can already create single Transactions using Transaction.create(). createMany()allows you to create up to ten Transactions in a single request. This dramatically reduces the round-trip latency suffered when you have more than one Transaction to insert.

createMany() is fed by lists of TransactionCreateArguments structs. Here’s an example:


v0.0.2 introduced the GlobalUnit class, without a way to list available Global Units! Enter GlobalUnitList, which will provide you with, you guessed it, a list of all available Global Units! Here’s how to use it:

There are 36 currencies available. You can look for a specific GlobalUnit in the GlobalUnitList with it’s unitWith(code:) method:


I’m in the process of creating Carthage and Cocoapods distributions for Amatino Swift. In the mean time, compiled libraries are available on GitHub. You are also most welcome to clone the repo and compile Amatino Swift yourself.

Still to come

Many objects specified in the Amatino API HTTP documentation are not yet available in Amatino Swift. For example, account Ledgers. Further, available objects are missing some critical methods, like Transaction.delete().

Look out for v0.0.4 and onwards to add yet more capability to Amatino Swift. Let me know how you want Amatino Swift to develop on Twitter or on the forums. Sign up to the Development Newsletter to be notified when new versions of Amatino Swift are available.

– Hugh

Amatino Swift v0.0.2 Released

A new version of the Amatino API Swift library is available. Amatino Swift allows you to store double-entry accounting data in a Swift application, on iOS or MacOS.

v0.0.2 includes:

  • New Entity class, including create() & retrieve() methods
  • New Account class, including create() & retrieve() methods
  • New Transaction class, including create() & retrieve() methods
  • New Entry struct, with comprehensive initialisers
  • New GlobalUnit class, including retrieve() method
  • Expose Session class for use outside AmatinoAlpha instances
  • Unit tests for all of the above

Taken together, these changes allow you to interact with the Amatino API much more easily than in 0.0.1. 0.0.1 was fully dependent on the AmatinoAlpha class – A thin wrapper around HTTP requests that required you to deal with your own data encoding, and parse raw Data responses from the Amatino API.

Amatino Swift 0.0.2 tests
Some of the new tests included in 0.0.2


I’m still studying the best way to distribute iOS and MacOS libraries. Right now I am leaning towards CocoaPods, and would welcome any input you might have. In the mean time, compiled libraries are available on GitHub. You are also most welcome to clone the repo and compile Amatino Swift yourself.

Example Usage

Here are some examples the new capabilities available in Amatino Swift v0.0.2:

Create a Session

This is analogous to ‘logging in’. You’ll notice the session is passed as a parameter throughout following examples.

Create an Entity

Entities are beings you wish to describe with accounting information. For example, a person, company, country, or project.


Still to come

The majority of objects specified in the Amatino API HTTP documentation are still not available in Amatino Swift. One glaring example is the Global Unit List – How are you supposed to retrieve Global Units if you don’t know which ones are available!?

Look out for v0.0.3 and onwards to add the missing pieces of the puzzle. Let me know how you want Amatino Swift to develop on Twitter or on the forums. Sign up to the Development Newsletter to be notified when new versions of Amatino Swift are available.

– Hugh