Example AuthenticateDocument Network Call
The AuthenticateDocument endpoint takes multipart/form-data in the request. If you’re not using a networking library, it may be a little confusing to write. Below is some basic code that will get you going.
Note
This is not production-ready code. Please make the necessary modifications to insert this code in your app.
import Foundation
import CFDocumentScanSDK
class ExampleNetworking {
/**
This method creates the image dictionary for use with the Authenticate Document request
- Parameter resultArray : An array of DSResult objects. The array is expected to be in the form of
[FrontResult, BackResult]
*/
func generateImageData(resultArray: [DSResult]) -> [String: Data] {
// We recommend using cropped images and setting the "AutoCrop" API header parameter to false.
// If the device cannot crop the document, then there is likely an issue with the document capture.
var imageData = [String: Data]()
if let frontResult = resultArray.first {
if let nonFlashImage = frontResult.croppedImage {
imageData["frontImage"] = nonFlashImage
}
if let flashImage = frontResult.croppedFlashImage {
imageData["frontFlashImage"] = flashImage
}
}
if resultArray.count > 1, let backResult = resultArray.last {
if let nonFlashImage = backResult.croppedImage {
imageData["backImage"] = nonFlashImage
}
if let flashImage = backResult.croppedFlashImage {
imageData["backFlashImage"] = flashImage
}
}
return imageData
}
/**
This method sends the request for Authenticate Document with URL, Headers and Parameters.
- Parameters:
- urlString : URL to send the request to.
- imageData : Dictionary of various images for upload. Valid keys are "frontImage", "frontFlashImage",
"backImage", and "backFlashImage". The data is the exact image data property from the DSResult object
- headers : HTTPHeaders object of Alamofire
- completion : Completion handler for the response
*/
func authenticateDocumentRequest(urlString: String,
imageData: [String: Data],
headers: [String: String] = [:],
completion: @escaping (Result<Data?, Error>) -> Void) {
var parameters = [[String: Any]]()
if let frontImage = imageData["frontImage"] {
parameters.append([
"key": "Front",
"filename": "front.jpg",
"src": frontImage,
"type": "image/jpg"
])
}
if let frontFlashImage = imageData["frontFlashImage"] {
parameters.append([
"key": "FrontFlash",
"filename": "frontFlash.jpg",
"src": frontFlashImage,
"type": "image/jpg"
])
}
if let backImage = imageData["backImage"] {
parameters.append([
"key": "Back",
"filename": "back.jpg",
"src": backImage,
"type": "image/jpg"
])
}
if let backFlashImage = imageData["backFlashImage"] {
parameters.append([
"key": "BackFlash",
"filename": "backFlash.jpg",
"src": backFlashImage,
"type": "image/jpg"
])
}
let boundary = "Boundary-\(UUID().uuidString)"
#warning("Avoid using force unwraps in production code")
let postData = NSMutableData()
for param in parameters {
let paramName = param["key"]!
postData.appendString("--\(boundary)\r\n")
postData.appendString("Content-Disposition:form-data; name=\"\(paramName)\"")
if param["contentType"] != nil {
postData.appendString("\r\nContent-Type: \(param["contentType"] as! String)")
}
let paramType = param["type"] as! String
if paramType == "text" {
let paramValue = param["value"] as! String
postData.appendString("\r\n\r\n\(paramValue)\r\n")
} else {
let paramSrc = param["filename"] as! String
let fileData = param["src"] as! Data
postData.appendString("; filename=\"\(paramSrc)\"\r\n"
+ "Content-Type: \"content-type header\"\r\n\r\n")
postData.append(fileData)
postData.appendString("\r\n")
}
}
postData.appendString("--\(boundary)--\r\n")
var request = URLRequest(url: URL(string: urlString)!,timeoutInterval: Double.infinity)
request.addValue("multipart/form-data; boundary=\(boundary)", forHTTPHeaderField: "Content-Type")
// Headers as described in CatfishAir API documentation
request.allHTTPHeaderFields = headers
request.httpMethod = "POST"
request.httpBody = postData as Data
// NOTE: Most iOS networking libraries (Alamofire, Moya, etc.) safely construct and
// send multipart/form-data requests. If this is an option for you, then it would
// be a cleaner approach.
let task = URLSession.shared.dataTask(with: request) { data, response, error in
if let error = error {
print(String(describing: error))
completion(.failure(error))
return
}
completion(.success(data))
}
task.resume()
}
}
// Helper extension used in the above code
extension NSMutableData {
/**
This method converts a string to Data (using utf8 encoding), then appends it to Self
- Parameter string : the String to be appended and converted.
*/
func appendString(_ string: String) {
if let data = string.data(using: .utf8) {
self.append(data)
}
}
}