ForEach error with array of videos

I'm stuck on these errors

  • "Cannot declare entity named '$reel'; the '$' prefix is reserved for implicitly-synthesized declarations"

  • "Generic struct 'ForEach' requires that 'Binding<[Reel]>' conform to 'RandomAccessCollection'"

Both errors are on this line of code

ForEach($reels) { $reel in

          ReelsPlayer(reel: $reel)
}

I have a TabView {} and am trying to make each page a new video similar to tik tok or vine. It works when I pass in dummy data but when I pass from my array of videos I get those errors.

Here's the rest of the code

The View:

import SwiftUI
import AVKit

struct ReelsView: View {
   
  @State var currentReel = ""
     
  // extracting AVPlayer from media file
  @State var reels: [Reel] = MediaFileJSON.map { item -> Reel in
     
    let url = Bundle.main.path(forResource: item.url, ofType: "MP4") ?? ""
     
    let player = AVPlayer(url: URL(fileURLWithPath: url))
     
    return Reel(player: player, mediaFile: item)
  }
   
  var body: some View {
     
    // setting width and height for rotated view
    GeometryReader { proxy in
       
      let size = proxy.size
       
      // vertical page tab view
      TabView(selection: $currentReel) {
         
        ForEach($reels) { $reel in // ERRORS HERE

          ReelsPlayer(reel: $reel)
          // setting width
          .frame(width: size.width)
          .padding()
          // rotate content
          .rotationEffect(.init(degrees: -90))
        }
      }
      // Rotate View
      .rotationEffect(.init(degrees: 90))
      // setting height as width
      .frame(width: size.height)
      .tabViewStyle(PageTabViewStyle(indexDisplayMode: .never))
      // setting max width
      .frame(width: size.width)
       
    }
  }
}

struct ReelsView_Previews: PreviewProvider {
  static var previews: some View {
    ContentView()
  }
}

struct ReelsPlayer: View, Identifiable {
  var id: ObjectIdentifier
   
   
  @Binding var reel: Reel
   
  var body: some View {
     
    ZStack {
       
       
    }
  }
}

MediaFile struct:

struct MediaFile: Identifiable {
  var id = UUID().uuidString
  var url: String
  var title: String
  var isExpanded: Bool = false
}

var MediaFileJSON = [
   
  MediaFile(url: "Reel1", title: "Apple AirTag......."),
  MediaFile(url: "Reel2", title: "this is the second."),
  MediaFile(url: "Reel3", title: "the third"),
  MediaFile(url: "Reel4", title: "wooooooooooooo ya"),
  MediaFile(url: "Reel5", title: "ay ayayayayay ayay lsdfk sl"),
  MediaFile(url: "Reel6", title: "this is the last one....."),
   
]

Reel struct:

struct Reel: Identifiable {
   
  var id: String = UUID().uuidString
  var player: AVPlayer?
  var mediaFile: MediaFile
}
  • With Xcode 13 beta 3, your code causes Missing argument for parameter 'id' in call on the line ReelsPlayer(reel: $reel). Which version of Xcode are you using?

Add a Comment

Replies

Hi, Based on your error messages you have two separate problems.

Multiline "Cannot declare entity named '$reel'; the '$' prefix is reserved for implicitly-synthesized declarations"

This happens because $ is for Binding variables and ForEach does not work with Bindings. So you will have to remove the $ in the ForEach and also when declaring the variable inside the closure because you only get a one-way variable from ForEach.

That leads to the second problem. the view you have inside the ForEach requires a Binding Variable, which you can only get from @State, or @ObservedObject and because ForEach doesn't work with Bindings (yet) you will have to find a solution without binding the reel to the View. Maybe send the id of the reel into the next view and then fetch the full reel separately.

Take care, David

Did you find a solution to this? Despite Xcode 13 advertising that it now supports array element binding via

`ForEach($model.value) { $values in ...`

it is also not working for me.

  • And for me too 🤷‍♂️. Who knows how to do this?

  • @oleg48, you should better start your own thread including enough info.

  • A few more data points: this does work for iOS 14+ build targets in Xcode 13 13A233 (using swift 5.5). It also used to work on macOS build targets using Xcode 13 betas. It stopped working in Xcode 13 RC (13A233) for macOS build targets only.

    My assumption was that they temporarily pulled support for it on macOS build targets as of the Xcode 13 release candidate and until Monterey was released. And now Monterey is released and it appears the problem remains for macOS targets only.

Add a Comment