BLACK FRIDAY: Save 50% on all my Swift books and bundles! >>

SOLVED: Preview Crashing When Trying To Iterate Relationship

Forums > SwiftUI

I am currently teaching myself Swift and Swiftui, to that end I am creating an app that is semi useful to me. I have created a peice of functionality that works within the simulator as well as on a physical device but seems to cause a crash in the preview.

I have created the following model:

@Model
final class Hosts{
    @Attribute(.unique)
    var ip: String?

    @Attribute(.unique)
    var api_url: URL

    var connected_too: Hosts? = nil

    @Relationship(inverse: \Hosts.connected_too)
    var connected_from: [Hosts] = []

    var host_description: String?
    var hostname: String

    init(api_url: URL, hostname: String, ip: String?, host_description: String?){
        self.api_url = api_url
        self.host_description = host_description
        self.hostname = hostname.lowercased()
        self.ip = ip
    }
}

I have a view that lists each instance of an object of this model type and I pass in the instance to a further view so that I can see the full details.

so the detail view is is like:

struct HostDetailView: View {
    public var host: Hosts
    .....
}

During processing of this view a method is called:

func get_connected_too(host: Hosts) -> [Hosts]{
    var current_host: Hosts = host
    var connected_hosts: [Hosts] = []
    while (current_host.connected_too != nil) {
        connected_hosts.append(current_host.connected_too!)
        current_host = current_host.connected_too!
    }
    return connected_hosts
}

this produces a list of connected too hosts or an empty list (so think device a is connected to switch b which is connected to router c). As I say this works perfectly on a defvice or on the simulator.

The issue is coming in when I try to create a preview. I have created the following:

struct HostDetailView_Previews: PreviewProvider {
    static var previews: some View {
        Group {
            HostDetailView(host: test_data())
                .previewDisplayName("Default mode")

            HostDetailView(host: test_data())
                .preferredColorScheme(.dark)
                .previewDisplayName("Dark mode")
        }
    }
}

func test_data() -> Hosts{
    let router: Hosts = Hosts(api_url: URL(string: "http://google.com")!, hostname: "router", ip: "1.2.3.4", host_description: "Main router")
    let host: Hosts = Hosts(api_url: URL(string: "http://yahoo.com")!, hostname: "router", ip: "2.3.4.5", host_description: "Main router")
    host.connected_too = router
    return host
}

Unfortunately this causes the preview to crash, the pertinent part of the crash report is:

5   HostDetailView.1.preview-thunk.dylib           0x14edb51b4 __preview__get_connected_too(host:) + 140 (HostDetailView.swift:73)
6   HostDetailView.1.preview-thunk.dylib           0x14edb57cc closure #1 in HostLinksStruct.__preview__body.getter + 372 (HostDetailView.swift:44)
7   HostDetailView.1.preview-thunk.dylib           0x14edb5968 partial apply for closure #1 in HostLinksStruct.__preview__body.getter + 16

If I remove the while clause in the get_connected_too function the preview will work, but if I either comment out the content of the while or only the while start and end block the preview wil crash.

I suspect the issue might be with how I am constructing or providing the test data. Can anyone identfy what I might be doing wrong.

2      

Turns out I have actually just managed to fix it myself. by creating a preview in this way instead:

#Preview {
    let config_mem = ModelConfiguration(isStoredInMemoryOnly: true)
    let container = try! ModelContainer(for: Hosts.self, configurations: config_mem)
    let router: Hosts = Hosts(api_url: URL(string: "http://google.com")!, hostname: "router", ip: "1.2.3.4", host_description: "Main router")
    let host: Hosts = Hosts(api_url: URL(string: "http://yahoo.com")!, hostname: "router", ip: "2.3.4.5", host_description: "Main router")
    router.connected_from.append(host)
    container.mainContext.insert(host)
    return HostDetailView(host: host)
            .modelContainer(container)
}

2      

Save 50% in my WWDC sale.

SAVE 50% All our books and bundles are half price for Black Friday, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.

Save 50% on all our books and bundles!

Archived topic

This topic has been closed due to inactivity, so you can't reply. Please create a new topic if you need to.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.