damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

MediaUploader.swift (3428B)


      1 //
      2 //  MediaUploader.swift
      3 //  damus
      4 //
      5 //  Created by Daniel D’Aquino on 2023-11-24.
      6 //
      7 
      8 import Foundation
      9 
     10 protocol MediaUploaderProtocol: Identifiable {    
     11     var nameParam: String { get }
     12     var mediaTypeParam: String { get }
     13     var supportsVideo: Bool { get }
     14     var requiresNip98: Bool { get }
     15     var postAPI: String { get }
     16     
     17     func getMediaURL(from data: Data) -> String?
     18     func mediaTypeValue(for mediaType: ImageUploadMediaType) -> String?
     19 }
     20 
     21 enum MediaUploader: String, CaseIterable, MediaUploaderProtocol, StringCodable {
     22     var id: String { self.rawValue }
     23     case nostrBuild
     24     case nostrcheck
     25     
     26     init?(from string: String) {
     27         guard let mu = MediaUploader(rawValue: string) else {
     28             return nil
     29         }
     30         
     31         self = mu
     32     }
     33     
     34     func to_string() -> String {
     35         return rawValue
     36     }
     37     
     38     var nameParam: String {
     39         switch self {
     40         case .nostrBuild:
     41             return "\"fileToUpload\""
     42         default:
     43             return "\"file\""
     44         }
     45     }
     46     
     47     var mediaTypeParam: String {
     48         return "media_type"
     49     }
     50     
     51     func mediaTypeValue(for mediaType: ImageUploadMediaType) -> String? {
     52         switch mediaType {
     53         case .normal:
     54             return nil
     55         case .profile_picture:
     56             return "avatar"
     57         }
     58     }
     59     
     60     var supportsVideo: Bool {
     61         switch self {
     62         case .nostrBuild:
     63             return true
     64         case .nostrcheck:
     65             return true
     66         }
     67     }
     68     
     69     var requiresNip98: Bool {
     70         switch self {
     71         case .nostrBuild:
     72             return true
     73         case .nostrcheck:
     74             return true
     75         }
     76     }
     77     
     78     struct Model: Identifiable, Hashable {
     79         var id: String { self.tag }
     80         var index: Int
     81         var tag: String
     82         var displayName : String
     83     }
     84     
     85     var model: Model {
     86         switch self {
     87         case .nostrBuild:
     88             return .init(index: -1, tag: "nostrBuild", displayName: "nostr.build")
     89         case .nostrcheck:
     90             return .init(index: 0, tag: "nostrcheck", displayName: "nostrcheck.me")
     91         }
     92     }
     93     
     94     var postAPI: String {
     95         switch self {
     96         case .nostrBuild:
     97             return "https://nostr.build/api/v2/nip96/upload"
     98         case .nostrcheck:
     99             return "https://nostrcheck.me/api/v2/media"
    100         }
    101     }
    102     
    103     func getMediaURL(from data: Data) -> String? {
    104         do {
    105             if let jsonObject = try JSONSerialization.jsonObject(with: data, options: .allowFragments) as? [String: Any],
    106                let status = jsonObject["status"] as? String {
    107                 
    108                 if status == "success", let nip94Event = jsonObject["nip94_event"] as? [String: Any] {
    109                     
    110                     if let tags = nip94Event["tags"] as? [[String]] {
    111                         for tagArray in tags {
    112                             if tagArray.count > 1, tagArray[0] == "url" {
    113                                 return tagArray[1]
    114                             }
    115                         }
    116                     }
    117                 } else if status == "error", let message = jsonObject["message"] as? String {
    118                     print("Upload Error: \(message)")
    119                     return nil
    120                 }
    121             }
    122         } catch {
    123             print("Failed JSONSerialization")
    124             return nil
    125         }
    126         return nil
    127     }
    128 }