steamclock / netable

A Swift library for encapsulating network APIs using Codable in a type-oriented way.
MIT License
99 stars 3 forks source link

Add Random Access Collection support to custom `LossyArray` element. #113

Closed amyoulton closed 1 year ago

amyoulton commented 1 year ago

When I began building out the project example to showcase working with the LossyArray features.

The method of decoding the top-level array by adding the arrayDecodingStrategy into the request works without this "issue", because we're not actually changing the type of any items within a structure.

However, when utilizing the custom LossyArray array container within an object, we need to access the internal element within the LossyArray, or we can't access any of the build in array/iteration methods we would typically use.

To showcase this, here is the example I created and the initial error I ran into. I want to note that this example decoded exactly as we would have hoped 🚀

My user object:

struct User: Decodable {
    let firstName: String
    let lastName: String
    let location: String
    let bio: String
    let age: Int
    let loginData: LossyArray<UserLoginData>
}

struct UserLoginData: Decodable, Hashable {
    let date: String
    let time: String
    let location: String
}

I then tried to do this within the view:

 List {
      ForEach(user.loginData, id: \.self) { item in
           Text("Location: \(item.location)")
      }
 }

And got this error: Generic struct 'ForEach' requires that 'LossyArray<UserLoginData>' conform to 'RandomAccessCollection'.

This issue does disappear if I actually access the elements within our LossyArray structure, as shown below:

 List {
      ForEach(user.loginData.elements, id: \.self) { item in
           Text("Location: \(item.location)")
       }
 }

After some research after the initial error, this seems like a really straightforward fix! While this is not a breaking issue, it would be an improvement to the feature so people could work with the LossyArray directly how they would work with a standard array!