skip to Main Content

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


  1. 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 redundant

    Text(allWords.count > 1 ? allWords[1] : "")
    

    A List or ForEach 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.

    Login or Signup to reply.
  2. 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.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search