I'm starting to learn SwiftUI, and so I decided to write a simple password manager as a learning exercise. I've defined a protocol with the common attributes in my passwords:
protocol Secret: Codable {
var id: String { get set }
var name: String { get set }
var createdDate: Date { get set }
var favorite: Bool { get set }
var category: SecretCategory { get set }
var notes: String { get set }
init(_ id: String, name: String)
init(_ id: String, name: String, favorite: Bool)
}
Then, I've defined a couple of Swift structs that implement this protocol and define the properties of various types of secrets:
struct LoginSecret: Secret, Identifiable {
var id: String
var name: String
var createdDate: Date = Date()
var favorite: Bool = false
var category: SecretCategory = .login
var notes: String = ""
var username: String = ""
var encryptedPassword: String = ""
var websiteURLs: [String] = []
init(_ id: String, name: String) {
self.id = id
self.name = name
}
init(_ id: String, name: String, favorite: Bool) {
self.id = id
self.name = name
self.favorite = favorite
}
}
...and...
struct BankAccountSecret: Secret, Identifiable {
var id: String
var name: String
var createdDate: Date = Date()
var favorite: Bool = false
var category: SecretCategory = .bankAccounts
var notes: String = ""
var bankName: String = ""
var nameOnAccount: String = ""
var routingNumber: String = ""
var accountNumber: String = ""
var swift: String = ""
var iban: String = ""
var encryptedPIN: String = ""
var branchPhoneNumber: String = ""
var branchAddress: Address = Address()
init(_ id: String, name: String) {
self.id = id
self.name = name
}
init(_ id: String, name: String, favorite: Bool) {
self.id = id
self.name = name
self.favorite = favorite
}
}
These work just fine, and I'm able to Encode/Decode values in JSON for display later. However, now I'm working on my SwiftUI code. I want to display each item in a List, iterating over an Array of Secret objects using SwiftUI's ForEach. My code looks like this:
struct SecretsListView: View {
@State
var secrets: [Secret]
var body: some View {
NavigationView {
List {
ForEach(secrets) { secret in
<snip>
}
}
}
}
}
However, when I compile I get an error saying...
Value of protocol type 'Secret' cannot conform to 'Identifiable'; only struct/enum/class types can conform to protocols
Is there no way to iterate over an array of Secret objects? Is there a different way to accomplish this? Is this issue specific to SwiftUI's ForEach? Should I use the standard Swift Array forEach method instead? Any guidance you can provide is greatly appreciated. I've worked with Swift and UIKit for a while, but SwiftUI is new and I want to make sure I'm developing for the framework correctly.