Well the Instances need a page (Dictionary+SwiftUI)

Continued working on ActivityPubExplorer

Also traveled.


First order of business was prevent crashes when JSON was wobbly. This is on the list of things to refactor. It would be good to have it as a result type.

https://github.com/carlynorama/ActivityPubExplorer/blob/c42039acc880c8e9da41a66f6e09325d556e04a2/ActivityPubExplorer/Generaic%20Services/RequestService%2BJSON.swift#L12

Relevant Excerpt:

import Foundation

fileprivate struct NullableObject<Base: Decodable>: Decodable {
    public let value: Base?

    public init(from decoder: Decoder) throws {
        do {
            let container = try decoder.singleValueContainer()
            self.value = try container.decode(Base.self)
        } catch {
            self.value = nil
        }
    }
}

extension RequestService {
    
 
    func fetchOptional<SomeDecodable: Decodable>(ofType:SomeDecodable.Type, from url:URL) async throws -> SomeDecodable? {
        let data = try await httpFetch(from: url)
        let result = try JSONDecoder().decode(NullableObject<SomeDecodable>.self, from: data)
        return result.value
    }
        
    func fetchCollectionOfOptionals<SomeDecodable: Decodable>(ofType:SomeDecodable.Type, from url:URL) async throws -> [SomeDecodable?] {
        let data = try await httpFetch(from: url)
        
        let results = try JSONDecoder().decode([NullableObject<SomeDecodable>].self, from: data)
        return results.map { $0.value }
    }

Next things was to add instance profile pages. Instance JSON was interesting because I’m not sure how regular the information will be instance to instance. That meant displaying JSON that’s was punked straight into a Dictionary just to see what was there.

https://github.com/carlynorama/ActivityPubExplorer/blob/5da4591076eaef35576efc1e913e0b52013378d7/ActivityPubExplorer/StringDictionaryDisplay.swift

//
//  DictionaryDisplay.swift
//  ActivityPubExplorer
//
//  Created by Carlyn Maw on 11/9/22.
//
import SwiftUI

fileprivate extension Dictionary {
    var keyArray: [Dictionary.Key] {
        return self.keys.map { $0 }
    }
}

struct StringDictionaryDisplay: View {
    let dictionary:Dictionary<String, String>
    let keys:[String]
    
    init(_ dictionary: Dictionary<String, String>) {
        self.dictionary = dictionary
        self.keys = dictionary.keyArray
    }
    
    var body: some View {
        ForEach(keys, id:\.self) { key in
            LabeledContent(key, value: dictionary[key] ?? "-")
        }
    }
}

struct StringDictionaryDisplay_Previews: PreviewProvider {
    static var previews: some View {
        StringDictionaryDisplay(["hello":"world"])
    }
}