Hello again the community,
I have a problem with an array that I made
This is the code:
import SwiftUI
struct ContentView: View {
@State private var allWords : [String] = []
func startGame() {
if let startWordsURL = Bundle.main.url(forResource: "start", withExtension: "txt") {
if let startWords = try? String(contentsOf: startWordsURL) {
allWords = startWords.components(separatedBy: "n")
return
}
}
if allWords.isEmpty {
allWords = ["silkworm"]
}
fatalError("Could not load start.txt from bundle.")
}
var body: some View {
VStack{
Text(String(allWords[1]))
.onAppear(perform: startGame)
.font(.system(size: 30))
.frame(width: 1000, height: 75)
.background(Rectangle()
.foregroundColor(.white))
.border(Color.black, width: 1)
}
}
I have a fatal error on the line Text(String(allWords[1]))
Which tell me that I’m out of range but when I try to print the size of the array with for example allWords.count it tells me that I have 11 elements.
Is it a problem with the declaration of my array ?
Thank you in advance everybody
2
Answers
This is a common mistake. When the view is rendered the first time the array is empty.
It’s highly recommended to get never elements of an array by index subscription in the rendering area of the view unless it’s guaranteed that the array contains the item at requested index.
Make a safe check and the
String
initializer is redundantA
List
orForEach
expression is safe because the body is not being executed if the array is empty.On the other hand the
if allWords.isEmpty
check is pointless because you know whether the file is empty or not at compile time.You called the function StartGame() inside onAppear. In this case Text load first then calls your function. So While loading Text(String(allWords[1])), allWords is Nil
You should handle it as
Text(allWords.count > 1 ? allWords[1] : "YourDefaultText")
OnAppear is a view that triggers action when this view appears.