I followed the example from here: SwiftUI 3 MacOs Table single selection and double click open sheet
But it's not working well for me.
I have a structure like this:
struct Response: Codable {
var items: [Repository]
}
struct Repository: Codable, Identifiable {
var number = UUID()
var id: Int = 0
let name: String
let updated_at: String
let owner: Owner
let stargazers_count: Int
let forks_count: Int
let language: String?
let description: String?
struct Owner: Codable {
let login: String
}
enum CodingKeys: String, CodingKey {
case name, updated_at, owner, stargazers_count, forks_count, language, description
}
}
class Api : ObservableObject{
func loadData(query: String = "javascript", completion:@escaping ([Repository]) -> ()) {
guard let url = URL(string: "https://api.github.com/search/repositories?q=\(query)") else {
print("Invalid url...")
return
}
URLSession.shared.dataTask(with: url) { data, response, error in
if let decodedResponse = try? JSONDecoder().decode(Response.self, from: data!) {
var id = 0
let results = decodedResponse.items.map { (repo: Repository) -> Repository in
var copyRepo = repo
copyRepo.id = id
id = 1
return copyRepo
}
print(results)
DispatchQueue.main.async {
completion(results)
}
}
}.resume()
}
}
...
@State var repositories = [Repository]()
@State private var sortOrder = [KeyPathComparator(\Repository.name)]
@State private var selectedRepository: Repository.ID?
public var body: some View {
if(selectedRepository != nil)//null??
Text(repositories[selectedRepository!].name)
Table(repositories, selection: $selectedRepository, sortOrder: $sortOrder) {
TableColumn("Name") {
Text($0.name)
.frame(
maxWidth: .infinity,
maxHeight: .infinity,
alignment: .leading
)
.contentShape(Rectangle())
.contextMenu {
Button(action: {}) { Text("Action") }
}
/*.gesture(TapGesture(count: 2).onEnded {
print("pr", selectedRepository )
})*/
}
TableColumn("Last updated"){
Text($0.updated_at)
}
TableColumn("Owner", value: \.owner.login)
}
.onAppear() {
Api().loadData { (repositories) in
self.repositories = repositories
self.isLoading = false
}
}
.onChange(of: sortOrder) {
print($0)
repositories.sort(using: $0)
}
}
I would like to make sure that when the user clicks on an element of the table, then activates the selection to show the data of the selected element in a Text field, I have tried to have the name printed but it is not working.
It gives me the following error after starting the app: Thread 1: Fatal error: Unexpectedly found nil while unwrapping an Optional value
Can you give me a hand?
CodePudding user response:
May be some missing character :
if(selectedRepository != nil)//null?? <- missing '{'
Text(repositories[selectedRepository!].name)
Also be writing like :
if let selectedRepository = selectedRepository {
Text(repositories[selectedRepository!].name)
...
}
Even if not necessary I always prefer to initialise properties (It is more an habit that something useful) :
@State private var selectedRepository: Repository.ID? = nil