Skip to content

Commit 3758f10

Browse files
author
Team Mobile Schorsch
committed
Release version 3.3.0
1 parent f1296a9 commit 3758f10

11 files changed

+147
-83
lines changed

Documentation/source/Installation.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@ Once you have your Swift package set up, adding `GiniBankAPILibrary` as a depend
1010

1111
```swift
1212
dependencies: [
13-
.package(url: "https://github.com/gini/bank-api-library-ios.git", .exact("3.2.0"))
13+
.package(url: "https://github.com/gini/bank-api-library-ios.git", .exact("3.3.0"))
1414
]
1515
```
1616

1717
In case that you want to use the certificate pinning in the library, add `GiniBankAPILibraryPinning`:
1818
```swift
1919
dependencies: [
20-
.package(url: "https://github.com/gini/bank-api-library-pinning-ios.git", .exact("3.2.0"))
20+
.package(url: "https://github.com/gini/bank-api-library-pinning-ios.git", .exact("3.3.0"))
2121
]
2222
```
2323

Documentation/source/License.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Always make sure to ship all license notices and permissions with your applicati
55

66
## The Gini Bank API Library for iOS is licensed under a Private License.
77

8-
Copyright (c) 2014-2023, Gini GmbH
8+
Copyright (c) 2014-2024, Gini GmbH
99
All rights reserved.
1010

1111
The Gini Bank API Library is licensed through Gini GmbH ("Gini") and may not be
@@ -20,7 +20,7 @@ Always make sure to ship all license notices and permissions with your applicati
2020

2121
## The Gini Bank API Library Pinning for iOS is licensed under a Private License.
2222

23-
Copyright (c) 2014-2023, Gini GmbH
23+
Copyright (c) 2014-2024, Gini GmbH
2424
All rights reserved.
2525

2626
The Gini Bank API Library Pinning is licensed through Gini GmbH ("Gini") and may not be

Sources/GiniBankAPILibrary/Documents/APIMethod.swift

+1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ enum APIMethod: ResourceMethod {
2626
case pages(forDocumentId: String)
2727
case page(forDocumentId: String, number: Int, size: Document.Page.Size?)
2828
case pagePreview(forDocumentId: String, number: Int)
29+
case documentPage(forDocumentId: String, number: Int, size: Document.Page.Size)
2930
case processedDocument(withId: String)
3031
case paymentRequest(id: String)
3132
case paymentRequests(limit: Int?, offset: Int?)

Sources/GiniBankAPILibrary/Documents/APIResource.swift

+4-2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ struct APIResource<T: Decodable>: Resource {
105105
}
106106
case .pagePreview(let id, let number):
107107
return "/documents/\(id)/pages/\(number)/large"
108+
case .documentPage(let id, let number, let sizeType):
109+
return "/documents/\(id)/pages/\(number)/\(sizeType)"
108110
case .partial:
109111
return "/documents/partial"
110112
case .processedDocument(let id):
@@ -134,9 +136,9 @@ struct APIResource<T: Decodable>: Resource {
134136
subtype: documentType?.name,
135137
mimeSubtype: mimeSubType).value
136138
]
137-
case .page, .pagePreview(_, _):
139+
case .page, .pagePreview, .documentPage:
138140
return [:]
139-
case .paymentRequests(_, _) :
141+
case .paymentRequests:
140142
return ["Accept": ContentType.content(version: apiVersion,
141143
subtype: nil,
142144
mimeSubtype: "json").value]

Sources/GiniBankAPILibrary/Documents/DefaultDocumentService.swift

+39-20
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ public final class DefaultDocumentService: DefaultDocumentServiceProtocol {
155155
/**
156156
* Retrieves the layout of a given document
157157
*
158-
* - Parameter id: The document's unique identifier
158+
* - Parameter document: The document from which to retrieve the layout
159159
* - Parameter completion: A completion callback, returning the requested document layout on success
160160
*/
161161
public func layout(for document: Document, completion: @escaping CompletionResult<Document.Layout>) {
@@ -165,7 +165,7 @@ public final class DefaultDocumentService: DefaultDocumentServiceProtocol {
165165
/**
166166
* Retrieves the pages of a given document
167167
*
168-
* - Parameter id: The document's unique identifier
168+
* - Parameter document: The document from which to retrieve the pages
169169
* - Parameter completion: A completion callback, returning the requested document layout on success
170170
*/
171171
public func pages(in document: Document, completion: @escaping CompletionResult<[Document.Page]>) {
@@ -190,7 +190,43 @@ public final class DefaultDocumentService: DefaultDocumentServiceProtocol {
190190
size: size,
191191
completion: completion)
192192
}
193-
193+
194+
/**
195+
* Retrieves the page preview of a document for a given page
196+
*
197+
* - Parameter documentId: Document id to get the preview for
198+
* - Parameter pageNumber: The document's page number starting from 1
199+
* - Parameter completion: A completion callback, returning the requested page preview as Data on success
200+
*/
201+
public func preview(for documentId: String,
202+
pageNumber: Int,
203+
completion: @escaping CompletionResult<Data>) {
204+
205+
preview(resourceHandler: sessionManager.download,
206+
with: documentId,
207+
pageNumber: pageNumber,
208+
completion: completion)
209+
}
210+
211+
/**
212+
* Retrieves the page data of a document for a given page number and size
213+
*
214+
* - Parameter document: The document from which to retrieve the page data
215+
* - Parameter pageNumber: The document's page number
216+
* - Parameter size: The size of the page to retrieve (e.g., large, medium)
217+
* - Parameter completion: A completion callback, returning the requested page preview on success, or an error on failure
218+
*/
219+
public func documentPage(for document: Document,
220+
pageNumber: Int,
221+
size: Document.Page.Size,
222+
completion: @escaping CompletionResult<Data>) {
223+
documentPage(resourceHandler: sessionManager.download,
224+
in: document,
225+
pageNumber: pageNumber,
226+
size: size,
227+
completion: completion)
228+
}
229+
194230
/**
195231
* Submits the analysis feedback for a given document.
196232
*
@@ -218,24 +254,7 @@ public final class DefaultDocumentService: DefaultDocumentServiceProtocol {
218254
completion: @escaping CompletionResult<Void>) {
219255
submitFeedback(resourceHandler: sessionManager.data, for: document, with: extractions, and: compoundExtractions, completion: completion)
220256
}
221-
222-
/**
223-
* Retrieves the page preview of a document for a given page
224-
*
225-
* - Parameter documentId: Document id to get the preview for
226-
* - Parameter pageNumber: The document's page number starting from 1
227-
* - Parameter completion: A completion callback, returning the requested page preview as Data on success
228-
*/
229-
public func preview(for documentId: String,
230-
pageNumber: Int,
231-
completion: @escaping CompletionResult<Data>) {
232257

233-
preview(resourceHandler: sessionManager.download,
234-
with: documentId,
235-
pageNumber: pageNumber,
236-
completion: completion)
237-
}
238-
239258
/**
240259
* Logs an error event.
241260
*

Sources/GiniBankAPILibrary/Documents/Document+Layout.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
// Document+Layout.swift
33
// GiniBankAPI
44
//
5-
// Created by Enrique del Pozo Gómez on 3/21/19.
5+
// Copyright © 2024 Gini GmbH. All rights reserved.
66
//
77

88
import Foundation

Sources/GiniBankAPILibrary/Documents/Document+Page.swift

+5-3
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,14 @@ extension Document.Page: Decodable {
1313
let container = try decoder.container(keyedBy: CodingKeys.self)
1414
let pageNumber = try container.decode(Int.self, forKey: .number)
1515
let images = try container.decode([String: String].self, forKey: .images)
16-
16+
1717
let imagesFormatted: [(size: Size, url: URL)] = images.compactMap { image in
18-
guard let imageSize = Size(rawValue: image.key) else {
18+
guard let imageSize = Size(rawValue: image.key),
19+
let url = URL(string: image.value) else {
1920
return nil
2021
}
21-
return (imageSize, URL(string: image.value)!)
22+
23+
return (imageSize, url)
2224
}
2325

2426
self.init(number: pageNumber, images: imagesFormatted)

Sources/GiniBankAPILibrary/Documents/Document.swift

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
//
22
// Document.swift
3-
// Pods-GiniExample
43
//
5-
// Created by Enrique del Pozo Gómez on 1/14/18.
4+
// Copyright © 2024 Gini GmbH. All rights reserved.
65
//
76

87
import Foundation
@@ -193,7 +192,7 @@ extension Document {
193192
public let number: Int
194193
/// Page image urls array, along with their sizes
195194
public let images: [(size: Size, url: URL)]
196-
195+
197196
//swiftlint:disable nesting
198197
enum CodingKeys: String, CodingKey {
199198
case number = "pageNumber"
@@ -207,8 +206,10 @@ extension Document {
207206

208207
/// 1280x1810
209208
case big = "1280x1810"
209+
210+
case large
211+
case medium
210212
}
211-
212213
}
213214

214215
/// The V2 document's type. Used when creating documents in multipage mode.

Sources/GiniBankAPILibrary/Documents/DocumentService.swift

+86-47
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,20 @@ public protocol DocumentService: AnyObject {
8585
pageNumber: Int,
8686
size: Document.Page.Size,
8787
completion: @escaping CompletionResult<Data>)
88-
88+
89+
/**
90+
* Retrieves the page data of a document for a given page number and size
91+
*
92+
* - Parameter document: The document from which to retrieve the page data
93+
* - Parameter pageNumber: The document's page number
94+
* - Parameter size: The size of the page to retrieve (e.g., large, medium)
95+
* - Parameter completion: A completion callback, returning the requested page preview on success, or an error on failure
96+
*/
97+
func documentPage(for document: Document,
98+
pageNumber: Int,
99+
size: Document.Page.Size,
100+
completion: @escaping CompletionResult<Data>)
101+
89102
/**
90103
* Submits the analysis feedback for a given document.
91104
*
@@ -217,8 +230,8 @@ extension DocumentService {
217230

218231
resourceHandler(resource, { result in
219232
switch result {
220-
case .success(let document):
221-
completion(.success(document))
233+
case .success(let documentLayout):
234+
completion(.success(documentLayout))
222235
case .failure(let error):
223236
completion(.failure(error))
224237
}
@@ -234,8 +247,8 @@ extension DocumentService {
234247

235248
resourceHandler(resource, { result in
236249
switch result {
237-
case .success(let document):
238-
completion(.success(document))
250+
case .success(let pages):
251+
completion(.success(pages))
239252
case .failure(let error):
240253
completion(.failure(error))
241254
}
@@ -285,33 +298,59 @@ extension DocumentService {
285298
}
286299

287300
func preview(resourceHandler: @escaping ResourceDataHandler<APIResource<Data>>,
288-
with documentId: String,
289-
pageNumber: Int,
290-
completion: @escaping CompletionResult<Data>) {
291-
let resource = APIResource<Data>(method: .pagePreview(forDocumentId: documentId,
292-
number: pageNumber),
293-
apiDomain: self.apiDomain,
294-
httpMethod: .get)
295-
resourceHandler(resource) { result in
296-
switch result {
297-
case let .success(data):
298-
completion(.success(data))
299-
case let .failure(error):
300-
if case .notFound = error {
301-
print("Document \(documentId) page not found")
302-
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
303-
self.preview(resourceHandler: resourceHandler,
304-
with: documentId,
305-
pageNumber: pageNumber,
306-
completion: completion)
307-
}
308-
} else {
309-
completion(.failure(error))
310-
}
311-
}
312-
}
313-
}
314-
301+
with documentId: String,
302+
pageNumber: Int,
303+
completion: @escaping CompletionResult<Data>) {
304+
let resource = APIResource<Data>(method: .pagePreview(forDocumentId: documentId,
305+
number: pageNumber),
306+
apiDomain: self.apiDomain,
307+
httpMethod: .get)
308+
resourceHandler(resource) { result in
309+
switch result {
310+
case let .success(data):
311+
completion(.success(data))
312+
case let .failure(error):
313+
if case .notFound = error {
314+
print("Document \(documentId) page not found")
315+
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
316+
self.preview(resourceHandler: resourceHandler,
317+
with: documentId,
318+
pageNumber: pageNumber,
319+
completion: completion)
320+
}
321+
} else {
322+
completion(.failure(error))
323+
}
324+
}
325+
}
326+
}
327+
328+
func documentPage(resourceHandler: @escaping ResourceDataHandler<APIResource<Data>>,
329+
in document: Document,
330+
pageNumber: Int,
331+
size: Document.Page.Size,
332+
completion: @escaping CompletionResult<Data>) {
333+
guard pageNumber > 0 else {
334+
preconditionFailure("The page number starts at 1")
335+
}
336+
337+
let resource = APIResource<Data>(method: .documentPage(forDocumentId: document.id,
338+
number: pageNumber,
339+
size: .medium),
340+
apiDomain: apiDomain,
341+
httpMethod: .get)
342+
343+
resourceHandler(resource) { result in
344+
switch result {
345+
case .success(let data):
346+
completion(.success(data))
347+
case .failure(let error):
348+
completion(.failure(error))
349+
}
350+
}
351+
}
352+
353+
315354
func submitFeedback(resourceHandler: ResourceDataHandler<APIResource<String>>,
316355
for document: Document,
317356
with extractions: [Extraction],
@@ -401,22 +440,22 @@ fileprivate extension DocumentService {
401440
fetchDocument(resourceHandler: resourceHandler,
402441
with: document.id,
403442
cancellationToken: cancellationToken) { [weak self] result in
404-
guard let self = self else { return }
405-
switch result {
406-
case .success(let document):
407-
if document.progress != .pending {
408-
completion(.success(()))
409-
} else {
410-
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
411-
self.poll(resourceHandler: resourceHandler,
412-
document: document,
413-
cancellationToken: cancellationToken,
414-
completion: completion)
415-
}
416-
}
417-
case .failure(let error):
418-
completion(.failure(error))
443+
guard let self = self else { return }
444+
switch result {
445+
case .success(let document):
446+
if document.progress != .pending {
447+
completion(.success(()))
448+
} else {
449+
DispatchQueue.global().asyncAfter(deadline: .now() + 1) {
450+
self.poll(resourceHandler: resourceHandler,
451+
document: document,
452+
cancellationToken: cancellationToken,
453+
completion: completion)
419454
}
455+
}
456+
case .failure(let error):
457+
completion(.failure(error))
458+
}
420459
}
421460
}
422461
}

Sources/GiniBankAPILibrary/GiniBankAPILibraryVersion.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,4 @@
55
// Copyright © 2024 Gini GmbH. All rights reserved.
66
//
77

8-
public let GiniBankAPILibraryVersion = "3.2.0"
8+
public let GiniBankAPILibraryVersion = "3.3.0"

Tests/GiniBankAPILibraryTests/DocumentServiceTests.swift

+1-1
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ final class DocumentServicesTests: XCTestCase {
179179
osName: UIDevice.current.systemName,
180180
osVersion: UIDevice.current.systemVersion,
181181
captureSdkVersion: "Not available",
182-
apiLibVersion: "3.2.0",
182+
apiLibVersion: "3.3.0",
183183
description: "Error logging test",
184184
documentId: "1234",
185185
originalRequestId: "5678")

0 commit comments

Comments
 (0)