Skip to content

Commit

Permalink
Merge pull request #8 from figo-connect/development
Browse files Browse the repository at this point in the history
Re-added macOS support
  • Loading branch information
Christian König authored Jan 14, 2017
2 parents ed868fa + 09aba0d commit 03644a2
Show file tree
Hide file tree
Showing 24 changed files with 675 additions and 279 deletions.
607 changes: 477 additions & 130 deletions Figo.xcodeproj/project.pbxproj

Large diffs are not rendered by default.

56 changes: 0 additions & 56 deletions Figo.xcodeproj/xcshareddata/xcschemes/Figo iOS Tests.xcscheme

This file was deleted.

4 changes: 2 additions & 2 deletions Figo.xcodeproj/xcshareddata/xcschemes/Figo iOS.xcscheme
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "83D3A6E91BFF5BA4003EDE45"
BuildableName = "Figo iOS Tests.xctest"
BlueprintIdentifier = "833C01391E2AAB4200AA5E7C"
BuildableName = "Figo-iOS-Tests.xctest"
BlueprintName = "Figo iOS Tests"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
Expand Down
99 changes: 99 additions & 0 deletions Figo.xcodeproj/xcshareddata/xcschemes/Figo macOS.xcscheme
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "0820"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "833C00EE1E2AA6A100AA5E7C"
BuildableName = "Figo.framework"
BlueprintName = "Figo macOS"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
<TestableReference
skipped = "NO">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "833C00FA1E2AA72A00AA5E7C"
BuildableName = "Figo-macOS-Tests.xctest"
BlueprintName = "Figo macOS Tests"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "833C00EE1E2AA6A100AA5E7C"
BuildableName = "Figo.framework"
BlueprintName = "Figo macOS"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "833C00EE1E2AA6A100AA5E7C"
BuildableName = "Figo.framework"
BlueprintName = "Figo macOS"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "833C00EE1E2AA6A100AA5E7C"
BuildableName = "Figo.framework"
BlueprintName = "Figo macOS"
ReferencedContainer = "container:Figo.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
68 changes: 37 additions & 31 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
This Framework wraps the figo Connect API endpoints in nicely typed Swift functions and types for your conveniece.

- We don't support Swift versions older than 3.0
- We are working on support for other platforms than iOS
- Supports iOS and macOS


## figo Connect API
Expand Down Expand Up @@ -39,13 +39,10 @@ Integrate the framework into your project:
* Select the Figo.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.
* Add the Figo.framework to your target(s) in the "Embedded Binaries" sections

### Carthage

We are working on bringing back Carthage support

## Usage

After creating an instance of `FigoClient` you can call functions on it representing the API endpoints. These functions will always return a `Result<T>`, where `T` will a corresponding type like `Account`, `[Account]` or `[Transaction]`.
After creating an instance of `FigoClient` you can call functions on it representing the API endpoints. These functions will always return a `FigoResult<T>`, where `T` will a corresponding type like `Account`, `[Account]` or `[Transaction]`.

import Figo
let figo = FigoClient()
Expand Down Expand Up @@ -88,11 +85,20 @@ To be able to login and use the figo API a user is required.
}
}

### Enable logging
### Logging

For now we have a very simple logging solution. By default logging is disabled. If you want to enable logging, you can pass a logger instance to the `FigoClient`.

let figo = FigoClient(logger: ConsoleLogger())

If you want control of what is logged or how, you can provide your own instance that conforms to the `Logger` protocol.

Since the `FigoClient` by default uses the default instance of `XCGLogger`, you can control logging from wherever you like. You can also provide your own `XCGLogger` instance in the initializer.
public protocol Logger {
var debug: (String) -> Void { get }
var verbose: (String) -> Void { get }
var error: (String) -> Void { get }
}

XCGLogger.default.setup(level: .verbose, showFunctionName: false, showThreadName: false, showLevel: false, showFileNames: false, showLineNumbers: false, showDate: false, writeToFile: nil, fileLevel: .none)

## Endpoints

Expand All @@ -101,16 +107,16 @@ Since the `FigoClient` by default uses the default instance of `XCGLogger`, you

The central element of this API is the figo user, who owns bank accounts and grants selective access to them to other applications. This account can either be a free or a premium account. While both support the same set of features, the free account can only be used with the application through it got created, while a premium account can be used in all applications integrating figo.

createNewFigoUser(user: CreateUserParameters, clientID: String, clientSecret: String, _ completionHandler: (Result<String>) -> Void)
retrieveCurrentUser(completionHandler: (Result<User>) -> Void)
createNewFigoUser(user: CreateUserParameters, clientID: String, clientSecret: String, _ completionHandler: (FigoResult<String>) -> Void)
retrieveCurrentUser(completionHandler: (FigoResult<User>) -> Void)
deleteCurrentUser(completionHandler: VoidCompletionHandler)


### Authorization

The figo API uses OAuth 2 for authentication purposes and you need a user to login.

loginWithUsername(username: String, password: String, clientID: String, clientSecret: String, _ completionHandler: (Result<String>) -> Void)
loginWithUsername(username: String, password: String, clientID: String, clientSecret: String, _ completionHandler: (FigoResult<String>) -> Void)
loginWithRefreshToken(refreshToken: String, clientID: String, clientSecret: String, _ completionHandler: VoidCompletionHandler)
revokeAccessToken(completionHandler: VoidCompletionHandler)
revokeRefreshToken(refreshToken: String, _ completionHandler: VoidCompletionHandler)
Expand All @@ -120,18 +126,18 @@ The figo API uses OAuth 2 for authentication purposes and you need a user to log

Bank accounts are the central domain object of this API and the main anchor point for many of the other resources. This API does not only consider classical bank accounts as account, but also alternative banking services, e.g. credit cards or Paypal. The API does not distinguish between these two in most points.

retrieveAccounts(completionHandler: (Result<[Account]>) -> Void)
retrieveAccount(accountID: String, _ completionHandler: (Result<Account>) -> Void)
retrieveAccounts(completionHandler: (FigoResult<[Account]>) -> Void)
retrieveAccount(accountID: String, _ completionHandler: (FigoResult<Account>) -> Void)
removeStoredPinFromBankContact(bankID: String, _ completionHandler: VoidCompletionHandler)
setupNewBankAccount(parameters: CreateAccountParameters, progressHandler: ProgressUpdate? = nil, _ completionHandler: VoidCompletionHandler)
### Transactions

Each bank account has a list of transactions associated with it. The length of this list depends on the bank and time this account has been setup. In general the information provided for each transaction should be roughly similar to the contents of the printed or online transaction statement available from the respective bank. Please note that not all banks provide the same level of detail.

retrieveTransactions(parameters: RetrieveTransactionsParameters = RetrieveTransactionsParameters(), _ completionHandler: (Result<TransactionListEnvelope>) -> Void)
retrieveTransactionsForAccount(accountID: String, parameters: RetrieveTransactionsParameters = RetrieveTransactionsParameters(), _ completionHandler: (Result<TransactionListEnvelope>) -> Void)
retrieveTransaction(transactionID: String, _ completionHandler: (Result<Transaction>) -> Void)
retrieveTransactions(parameters: RetrieveTransactionsParameters = RetrieveTransactionsParameters(), _ completionHandler: (FigoResult<TransactionListEnvelope>) -> Void)
retrieveTransactionsForAccount(accountID: String, parameters: RetrieveTransactionsParameters = RetrieveTransactionsParameters(), _ completionHandler: (FigoResult<TransactionListEnvelope>) -> Void)
retrieveTransaction(transactionID: String, _ completionHandler: (FigoResult<Transaction>) -> Void)


### Synchronization
Expand All @@ -147,9 +153,9 @@ Usually the bank accounts are synchronized on a daily basis. However, the synchr

To set up a new bank account in figo, you need to provide the right kind of credentials for each bank. These settings can be retrieved from the API aswell as a list of all supported banks and bank-like services.

retrieveSupportedBanks(countryCode: String = "de", _ completionHandler: (Result<[SupportedBank]>) -> Void)
retrieveSupportedServices(countryCode: String = "de", _ completionHandler: (Result<[SupportedService]>) -> Void)
retrieveLoginSettings(countryCode: String = "de", bankCode: String, _ completionHandler: (Result<LoginSettings>) -> Void)
retrieveSupportedBanks(countryCode: String = "de", _ completionHandler: (FigoResult<[SupportedBank]>) -> Void)
retrieveSupportedServices(countryCode: String = "de", _ completionHandler: (FigoResult<[SupportedService]>) -> Void)
retrieveLoginSettings(countryCode: String = "de", bankCode: String, _ completionHandler: (FigoResult<LoginSettings>) -> Void)
### Payments

Expand All @@ -159,29 +165,29 @@ Submitting a new payment generally is a two-phased process: 1. compile all infor

While the first part is normal live interaction with this API, the second one uses the task processing system to allow for more time as bank servers are sometimes slow to respond. In addition you will need a TAN (Transaktionsnummer) from your bank to authenticate the submission.

retrievePaymentProposals(completionHandler: Result<[PaymentProposal]> -> Void)
retrievePayments(completionHandler: Result<[Payment]> -> Void)
retrievePaymentsForAccount(accountID: String, _ completionHandler: Result<[Payment]> -> Void)
retrievePayment(paymentID: String, accountID: String, _ completionHandler: Result<Payment> -> Void)
createPayment(parameters: CreatePaymentParameters, _ completionHandler: Result<Payment> -> Void)
modifyPayment(payment: Payment, _ completionHandler: Result<Payment> -> Void)
retrievePaymentProposals(completionHandler: FigoResult<[PaymentProposal]> -> Void)
retrievePayments(completionHandler: FigoResult<[Payment]> -> Void)
retrievePaymentsForAccount(accountID: String, _ completionHandler: FigoResult<[Payment]> -> Void)
retrievePayment(paymentID: String, accountID: String, _ completionHandler: FigoResult<Payment> -> Void)
createPayment(parameters: CreatePaymentParameters, _ completionHandler: FigoResult<Payment> -> Void)
modifyPayment(payment: Payment, _ completionHandler: FigoResult<Payment> -> Void)
submitPayment(payment: Payment, tanSchemeID: String, pinHandler: PinResponder, challengeHandler: ChallengeResponder, _ completionHandler: VoidCompletionHandler)
### Securities

Each depot account has a list of securities associated with it. In general the information provided for each security should be roughly similar to the contents of the printed or online depot listings available from the respective bank. Please note that not all banks provide the same level of detail.

retrieveSecurities(parameters: RetrieveSecuritiesParameters = RetrieveSecuritiesParameters(), _ completionHandler: (Result<SecurityListEnvelope>) -> Void)
retrieveSecuritiesForAccount(accountID: String, parameters: RetrieveSecuritiesParameters = RetrieveSecuritiesParameters(), _ completionHandler: (Result<SecurityListEnvelope>) -> Void)
retrieveSecurity(securityID: String, accountID: String, _ completionHandler: (Result<Security>) -> Void)
retrieveSecurities(parameters: RetrieveSecuritiesParameters = RetrieveSecuritiesParameters(), _ completionHandler: (FigoResult<SecurityListEnvelope>) -> Void)
retrieveSecuritiesForAccount(accountID: String, parameters: RetrieveSecuritiesParameters = RetrieveSecuritiesParameters(), _ completionHandler: (FigoResult<SecurityListEnvelope>) -> Void)
retrieveSecurity(securityID: String, accountID: String, _ completionHandler: (FigoResult<Security>) -> Void)
### Standing orders

Bank accounts can have standing orders associated with it if supported by the respective bank. In general the information provided for each standing order should be roughly similar to the content of the printed or online standing order statement available from the respective bank. Please note that not all banks provide the same level of detail.

retrieveStandingOrders(completionHandler: (Result<[StandingOrder]>) -> Void)
retrieveStandingOrdersForAccount(accountID: String, _ completionHandler: (Result<[StandingOrder]>) -> Void)
retrieveStandingOrder(standingOrderID: String, _ completionHandler: (Result<StandingOrder>) -> Void)
retrieveStandingOrders(completionHandler: (FigoResult<[StandingOrder]>) -> Void)
retrieveStandingOrdersForAccount(accountID: String, _ completionHandler: (FigoResult<[StandingOrder]>) -> Void)
retrieveStandingOrder(standingOrderID: String, _ completionHandler: (FigoResult<StandingOrder>) -> Void)

Expand Down
2 changes: 1 addition & 1 deletion Source/Alias.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
/**
A closure which is used for API calls that return nothing
*/
public typealias VoidCompletionHandler = (Result<Void>) -> Void
public typealias VoidCompletionHandler = (FigoResult<Void>) -> Void

/**
A closure which is called periodically during task state polling with a status message from the server
Expand Down
6 changes: 3 additions & 3 deletions Source/Core/Response.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Foundation


internal func decodeVoidResponse(_ response: Result<Data>) -> Result<Void> {
internal func decodeVoidResponse(_ response: FigoResult<Data>) -> FigoResult<Void> {
switch response {
case .failure(let error):
return .failure(error)
Expand All @@ -18,7 +18,7 @@ internal func decodeVoidResponse(_ response: Result<Data>) -> Result<Void> {
}
}

internal func decodeUnboxableResponse<T: Unboxable>(_ data: Result<Data>, context: Any? = nil) -> Result<T> {
internal func decodeUnboxableResponse<T: Unboxable>(_ data: FigoResult<Data>, context: Any? = nil) -> FigoResult<T> {
switch data {
case .success(let data):
do {
Expand All @@ -34,7 +34,7 @@ internal func decodeUnboxableResponse<T: Unboxable>(_ data: Result<Data>, contex
}
}

internal func decodeUnboxableResponse<T: Unboxable>(_ data: Result<Data>, context: Any? = nil) -> Result<[T]> {
internal func decodeUnboxableResponse<T: Unboxable>(_ data: FigoResult<Data>, context: Any? = nil) -> FigoResult<[T]> {
switch data {
case .success(let data):
do {
Expand Down
Loading

0 comments on commit 03644a2

Please sign in to comment.