Questrade Client for iOS



After signing up and using Questrade's Trading platform I wanted a good mobile client that I could use. Sadly the one they have was just a poorly executed web app that was very slow and frustrating to use. So I decided to see if I could make my own.

Learn & Grow

Secondly I was interested in building a oAuth 2 based API from scratch and learning new iOS paradigms.


iOS Localization

Using Apple's built-in number and date formatters, stack views, controls, and NSLocalizedStrings allows easy and effective localization of UI.

UI Testing Automation

Building UITests to easily get an overview of all UI in all languages and device sizes.

class ObsidianUITests: XCTestCase {
    let app = XCUIApplication()
    var isLoggedOut = true
    func makeSureAppIsLoggedIn() {
        if isLoggedOut {
            app.images["AppIcon"].press(forDuration: 0.3);
            isLoggedOut = false
    func testPositions() {
        let button = app.tables.children(matching: .cell).element(boundBy: 1).buttons["PositionPriceLabel"]
        let expectation = XCTNSPredicateExpectation(predicate:NSPredicate(format: "exists == true"), object: button)
        wait(for: [expectation], timeout: 1)

        app.otherElements["Graph View"].press(forDuration: 1)
        snapshot("01-SymbolModalGraph", timeWaitingForIdle: 0)
        snapshot("02-Positions", timeWaitingForIdle: 0)

UI Themeing

Harnessing the power of protocols and the UIResponder chain to add a themeing system to UIKit.

struct UITheme {
    let statusBarStyle: UIStatusBarStyle
    let keyboardAppearance: UIKeyboardAppearance
    let barStyle: UIBarStyle
    let blurEffectStyle: UIBlurEffect.Style
    let tintColor: UIColor
    let scrollViewIndicatorStyle:UIScrollView.IndicatorStyle
    init(withBarStyle barStyle: UIBarStyle, tintColor: UIColor) {
        self.barStyle = barStyle
        self.blurEffectStyle = barStyle == .black ? .dark : .light
        self.keyboardAppearance = barStyle == .black ? .dark : .light
        self.tintColor = tintColor
        self.statusBarStyle = barStyle == .black ? .lightContent : .default
        self.scrollViewIndicatorStyle = barStyle == .black ? .white : .black
    func setAppearances() {
        UINavigationBar.appearance().barStyle = barStyle
        UITabBar.appearance().barStyle = barStyle
        UIToolbar.appearance().barStyle = barStyle
        UISearchBar.appearance().barStyle = barStyle
        ThemedEffectView.appearance().effect = UIBlurEffect(style: blurEffectStyle)
        UIScrollView.appearance().indicatorStyle = scrollViewIndicatorStyle
        UITextField.appearance().keyboardAppearance = keyboardAppearance
        UISearchBar.appearance().keyboardAppearance = keyboardAppearance

Swift API for Questrade

Using keychain storage, Codable structs, and generics, to make a lightweight, secure, powerful, and easy to use native Swift API.

See on GitLab
// First setup the keychain store for your app
let keychain = AuthKeychainStore(service: "Questrade", account: "Obsidian", data: [:])

// since the init could throw errors you will have to wrap it in a do catch
do {
    // Init iOSQuestAuth class with the keychain store
    let auth = try iOSQuestAuth(keychainStore: keychain)
    // Init QuestAPI with the authorizer
    let api = QuestAPI(authorizor: auth)
    // Optionally set a singleton to access the API
    QuestAPI.shared = api
} catch let err {
    // handle error

Automated App Store Distribution

Using fastlane to automate tedious tasks of capturing, uploading, and localizing App Store metadata.

See Fastlane
platform :ios do
    lane :test_beta do

            build_number: latest_testflight_build_number + 1,
            xcodeproj: "Obsidian.xcodeproj"

        commit_version_bump(xcodeproj: "Obsidian.xcodeproj")

            scheme: "Obsidian",
            workspace: "Obsidian.xcworkspace",
            include_bitcode: true,
            output_directory: "./fastlane/app"



A public Questrade API written in Swift, marketing site, and published Questrade client app. Expect continued improvements to the design and functionality of Obsidian.

Check it out if you live in Canada and use Questrade as a broker!

View Site Get on App Store

Let's Work Together

And make something beautiful!




Spa and Salon Booking App for iOS

Read More