Files
Thijooree-iOS/Thijooree iOS/API/MIB/MibFinancingClient.swift
T

81 lines
3.6 KiB
Swift

import Foundation
// Mirrors Kotlin MibFinancingClient exactly.
// Fetches the /financing?dashurl=1 HTML page and parses finance-card-holder data attributes.
actor MibFinancingClient {
private let wvBase = "https://faisamobilex-wv.mib.com.mv"
private let session: MibSession
private let urlSession: URLSession = {
let cfg = URLSessionConfiguration.ephemeral
cfg.timeoutIntervalForRequest = 30
cfg.timeoutIntervalForResource = 60
return URLSession(configuration: cfg)
}()
init(session: MibSession) {
self.session = session
}
func fetchFinancing() async throws -> [MibFinanceDeal] {
var req = URLRequest(url: URL(string: "\(wvBase)/financing?dashurl=1")!)
req.setValue(cookieHeader, forHTTPHeaderField: "Cookie")
req.setValue(
"Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148",
forHTTPHeaderField: "User-Agent"
)
req.setValue("mv.com.mib.faisamobilex", forHTTPHeaderField: "X-Requested-With")
let (data, response) = try await urlSession.data(for: req)
let code = (response as? HTTPURLResponse)?.statusCode ?? 0
if code == 419 { throw MibError.sessionExpired }
if code >= 500 { throw MibError.networkError("HTTP \(code)") }
guard let html = String(data: data, encoding: .utf8) else { return [] }
return parseHtml(html)
}
// MARK: - HTML parsing (mirrors Kotlin regex approach)
private func parseHtml(_ html: String) -> [MibFinanceDeal] {
guard let cardRe = try? NSRegularExpression(pattern: #"finance-card-holder[^>]+>"#),
let attrRe = try? NSRegularExpression(pattern: #"data-(\w+)\s*=\s*"([^"]*)""#) else {
return []
}
let ns = html as NSString
return cardRe.matches(in: html, range: NSRange(location: 0, length: ns.length)).compactMap { m in
let cardStr = ns.substring(with: m.range)
let cardNS = cardStr as NSString
var attrs: [String: String] = [:]
attrRe.matches(in: cardStr, range: NSRange(location: 0, length: cardNS.length)).forEach { a in
let key = cardNS.substring(with: a.range(at: 1))
let val = cardNS.substring(with: a.range(at: 2))
attrs[key] = val
}
guard let dealNo = attrs["dealNo"] else { return nil }
return MibFinanceDeal(
dealNo: dealNo,
productDesc: attrs["productDesc"] ?? "",
dealStatus: attrs["dealStatus"] ?? "",
statusDesc: attrs["statusDesc"] ?? "",
dealAmount: Double(attrs["dealAmount"] ?? "") ?? 0,
paidAmount: Double(attrs["paidAmount"] ?? "") ?? 0,
outstandingAmount: Double(attrs["outstandingAmount"] ?? "") ?? 0,
dealDate: attrs["dealDate"] ?? "",
overdueAmount: Double(attrs["overdueAmount"] ?? "") ?? 0,
installmentAmount: Double(attrs["installmentAmount"] ?? "") ?? 0,
noOfInstallments: Int(attrs["noOfInstallments"] ?? "") ?? 0,
lastPaidDate: attrs["lastPaidDate"] ?? "",
lastPayAmount: Double(attrs["lastPayAmount"] ?? "") ?? 0,
currency: attrs["curCodeDesc"] ?? "MVR"
)
}
}
private var cookieHeader: String {
"mbmodel=IOS-1.0; xxid=\(session.xxid); IBSID=\(session.xxid); mbnonce=\(session.nonceGenerator); time-tracker=597"
}
}