taler-ios

iOS apps for GNU Taler (wallet)
Log | Files | Refs | README | LICENSE

URL+id+iban.swift (3755B)


      1 /*
      2  * This file is part of GNU Taler, ©2022-25 Taler Systems S.A.
      3  * See LICENSE.md
      4  */
      5 /**
      6  * @author Marc Stibane
      7  */
      8 import SwiftUI
      9 
     10 extension URL: Identifiable {
     11     public var id: URL {self}
     12 }
     13 
     14 extension URL {
     15     init(_ string: StaticString) {
     16         self.init(string: "\(string)")!
     17     }
     18 
     19     var trimmedString: String {
     20         absoluteString.trimmingCharacters(in: .whitespacesAndNewlines)
     21     }
     22 
     23     var cyclos: String? {
     24         /// "payto://cyclos/" host ["/" fpath] "/" account-id [ "?" opts ]
     25         if scheme == "payto", let host = host {
     26             let path = path.dropFirst(1)
     27             if host == "cyclos" {
     28                 return String(path)
     29             } else if host.hasPrefix("cyclos") {
     30                 let cyclos = host.dropFirst(6)
     31                 if path.hasPrefix("/") {
     32                     return String(cyclos + path)
     33                 }
     34                 return String(cyclos + "/" + path)
     35             }
     36         }
     37         return nil
     38     }
     39 
     40     var iban: String? {
     41         /// https://datatracker.ietf.org/doc/rfc8905/
     42         /// payto://iban/DE75512108001245126199?amount=EUR:200.0&message=hello
     43         if scheme == "payto" && host == "iban" {
     44             return lastPathComponent
     45         }
     46         return nil
     47     }
     48 
     49     var xTaler: String? {
     50         /// https://datatracker.ietf.org/doc/rfc8905/
     51         /// payto://x-taler-bank/BANK-HOST/ACCOUNT?receiver-name=…
     52         /// The bank host is part of the target, so return "BANK-HOST/ACCOUNT" —
     53         /// returning only lastPathComponent silently dropped the bank and made
     54         /// the account unaddressable when it was written back out.
     55         if scheme == "payto" && host == "x-taler-bank" {
     56             let target = path.hasPrefix("/") ? String(path.dropFirst()) : path
     57             return target.isEmpty ? nil : target
     58         }
     59         return nil
     60     }
     61 
     62     /// SwifterSwift: Dictionary of the URL's query parameters.
     63     var queryParameters: [String:String]? {
     64         guard let components = URLComponents(url: self, resolvingAgainstBaseURL: false),
     65               let queryItems = components.queryItems else { return nil }
     66 
     67         var items: [String:String] = [:]
     68 
     69         for queryItem in queryItems {
     70             items[queryItem.name] = queryItem.value
     71         }
     72         return items
     73     }
     74 
     75     static var docDirUrl: URL? {                    // accessible by FileSharing
     76         if #available(iOS 16.4, *) {
     77             return URL.documentsDirectory
     78         } else {
     79             let docDirNr: FileManager.SearchPathDirectory = .documentDirectory
     80             if let documentsDir = FileManager.default.urls(for: docDirNr, in: .userDomainMask).first {
     81                 return documentsDir
     82             }
     83         }
     84         return nil
     85     }
     86 
     87     static var appSuppUrl: URL? {
     88         if #available(iOS 16.4, *) {
     89             return URL.applicationSupportDirectory
     90         } else {
     91             let appDirNr: FileManager.SearchPathDirectory = .applicationSupportDirectory
     92             if let appSupportDir = FileManager.default.urls(for: appDirNr, in: .userDomainMask).first {
     93                 return appSupportDir
     94             }
     95         }
     96         return nil
     97     }
     98 
     99     func path(withSlash: Bool) -> String {
    100         let path: String
    101         if #available(iOS 16.4, *) {
    102             path = self.path(percentEncoded: false)
    103         } else {
    104             path = self.path
    105         }
    106         if let char = path.last {
    107             let slash: String.Element = "/"
    108 
    109             if withSlash {
    110                 if char != slash {
    111                     return path + String(slash)
    112                 }
    113             } else {
    114                 if char == slash {
    115                     return String(path.dropLast())
    116                 }
    117             }
    118         }
    119         return path
    120     }
    121 }