Why isn't a new room created in the Rooms project? SwiftUI, WWDC19-204

Hi everyone,

I want to perform the tutorial from video WWDC19 - 204. Here is an example of building the "Rooms" application. At 42 minutes, the author of the video, Jacob Xiao, shows how to add a new room. But when I try to repeat it, nothing happens. The new room is not added.

My code and code of Jacob Xiao are the same.

import SwiftUI

struct ContentView: View {

    @ObservedObject var store = RoomStore()

    // Instead of //var rooms: [Room] = []

    // @ObservedObject is instead of @ObjectBinding

    var body: some View {

        NavigationView {
            List {
                Button(action: addRoom) {
                    Text("Add Room")
                }

                ForEach(store.rooms) { room in
                    RoomCell(room: room)
                }
            }
            .navigationBarTitle(Text("Rooms"))
        }
    }

    func addRoom() {
        store.rooms.append(Room(name: "Hall 2", capacity: 2000))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(store: RoomStore(rooms: testData))
    }
}

struct RoomCell: View {
    var room: Room
    var body: some View {
        NavigationLink(destination: RoomDetail(room: room)) {

            Image(room.thumbnailName)
                .cornerRadius(8)

            VStack(alignment: .leading) {
                Text(room.name)
                Text("\(room.capacity) people")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

My project has also an image named "Hall 2".

What could be the reason that a new room is not being added? Any ideas, please.

Answered by OOPer in 692706022

Thanks for showing your code.

Unfortunately, the session video was made while SwiftUI was in beta, and you need to make the code updated in many, many points.

And BindableObject having didChange does not work in the released version of SwiftUI.

Please try this:

class RoomStore: ObservableObject { // Instead of BindableObject
    @Published var rooms: [Room] //Use `@Published` here, no need to use `didChange`

    init(rooms: [Room] = []) {
        self.rooms = rooms
    }
}

There are many good tutorials and sample codes written for the released version of SwiftUI. You should better find a good one unless you want to study how the beta version of SwiftUI was.

The language has changed a lot since the tutorial.

You replaced @ObjectBinding with @ObservedObject ; but there may be other places to change.

There are many tutorial, if this one (1 year old though) may help;

h t t p s : / / jaredsinclair.com/2020/05/07/swiftui-cheat-sheet.html

Yes, I understand that the language has changed, and I even tried to find these changes, but it did not work out. That's why I asked a question on this forum. Perhaps there is someone here who has done this tutorial and can say what has changed?

ok, thanks for helping. Below is the complete project code for files. At the very end, there is a link to the full project in the archive.

This is a RoomsApp.swift file code:

import SwiftUI

@main

struct RoomsApp: App {

    var body: some Scene {

        WindowGroup {

            ContentView()
        }
    }
}

This is ContentView.swift code:

import SwiftUI

struct ContentView: View {

    @ObservedObject var store = RoomStore()

    var body: some View {

        NavigationView {
            List {
                Button(action: addRoom) {
                    Text("Add Room")
                }

                ForEach(store.rooms) { room in
                    RoomCell(room: room)
                }
            }
            .navigationBarTitle(Text("Rooms"))
        }
    }

    func addRoom() {
        store.rooms.append(Room(name: "Hall 2", capacity: 2000))
    }
}

struct ContentView_Previews: PreviewProvider {
    static var previews: some View {
        ContentView(store: RoomStore(rooms: testData))
    }
}

struct RoomCell: View {
    var room: Room    

    var body: some View {
        NavigationLink(destination: RoomDetail(room: room)) {            

            Image(room.thumbnailName)
                .cornerRadius(8)

            VStack(alignment: .leading) {
                Text(room.name)
                Text("\(room.capacity) people")
                    .font(.subheadline)
                    .foregroundColor(.secondary)
            }
        }
    }
}

RoomDetail.swift file code:

import SwiftUI

struct RoomDetail: View {
    var room: Room
    @State private var zoomed = false

    var body: some View {

        ZStack(alignment: .topLeading) {

            Image(room.imageName)

                .resizable()

                .aspectRatio(contentMode: zoomed ? .fill : .fit)

                .navigationBarTitle(room.name, displayMode: .inline )

                .onTapGesture { // Instead of TapAction

                    withAnimation(.easeIn(duration: 1)) { zoomed.toggle() } // .easyIn is instead of basic(duration)
                }
                .frame(minWidth: 0, maxWidth: .infinity, minHeight: 0, maxHeight: .infinity)

            if room.hasVideo && !zoomed {

                Image(systemName: "video.fill")

                    .font(.title)

                    .padding(.all)

                    .transition(.move(edge: .leading))
            }
        }
    }
}

struct RoomDetail_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            NavigationView{RoomDetail(room: testData[0])}
            NavigationView{RoomDetail(room: testData[1])}
        }
    }
}

Room

import SwiftUI
struct Room: Identifiable {
    var id = UUID()
    var name: String
    var capacity: Int
    var hasVideo: Bool = false

    var imageName: String {
        return name
    }

    var thumbnailName: String {
        return name  + "Thumb"
    }
}

let testData = [

    Room(name: "room-1", capacity: 6, hasVideo: true),

    Room(name: "room-2", capacity: 8, hasVideo: false),

    Room(name: "room-3", capacity: 16, hasVideo: true),

    Room(name: "room-4", capacity: 10, hasVideo: true),

    Room(name: "room-5", capacity: 12, hasVideo: false),

    Room(name: "room-6", capacity: 8, hasVideo: false),

    Room(name: "room-7", capacity: 10, hasVideo: true),

    Room(name: "room-8", capacity: 7, hasVideo: false),

    Room(name: "room-9", capacity: 11, hasVideo: false)
]

RoomStore

import SwiftUI
import Combine

class RoomStore: ObservableObject { // Instead of BindableObject
    var rooms: [Room] {
        didSet { didChange.send() }
    }

    init(rooms: [Room] = []) {
        self.rooms = rooms
    }

    var didChange = PassthroughSubject<Void, Never>()
}

This is a link to the complete project in the archive.

https://drive.google.com/file/d/1Sis3r57S9n9Uf4Pd8dFSyMoM-Z0vsj9K/view?usp=sharing

Accepted Answer

Thanks for showing your code.

Unfortunately, the session video was made while SwiftUI was in beta, and you need to make the code updated in many, many points.

And BindableObject having didChange does not work in the released version of SwiftUI.

Please try this:

class RoomStore: ObservableObject { // Instead of BindableObject
    @Published var rooms: [Room] //Use `@Published` here, no need to use `didChange`

    init(rooms: [Room] = []) {
        self.rooms = rooms
    }
}

There are many good tutorials and sample codes written for the released version of SwiftUI. You should better find a good one unless you want to study how the beta version of SwiftUI was.

Thank you very very much!

It works!

There are many good tutorials and sample codes written for the released version of SwiftUI. You should better find a good one unless you want to study how the beta version of SwiftUI was.

Yes, you are right! I just want to go to the end in this tutorial)) And then go to the released version. And the second reason that the basics are well shown here, the main ideas of SwiftUI. When I see the general idea, it is easier for me to understand the specific methods.

Thanks a lot again!

Why isn't a new room created in the Rooms project? SwiftUI, WWDC19-204
 
 
Q