Problem with the preview on Apple developers SwiftUI tutorial - Framework Integration Interfacing with UIKit

Viewed 1797

I’m fairly new to Swift and Xcode. I’ve been following along with Apple’s SwiftUI tutorials and haven’t had much problem, until I got to here: Interfacing with UIKit (https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit)

When I get to step 5, the build is successful but there is no preview. The error I receive is:

“ RemoteHumanReadableError: Failed to update preview.

The preview process appears to have crashed.

Error encountered when sending 'render' message to agent.

==================================

| RemoteHumanReadableError: The operation couldn’t be completed. (BSServiceConnectionErrorDomain error 3.) |
| BSServiceConnectionErrorDomain (3): | ==BSErrorCodeDescription: OperationFailed”

Any help on what I’m doing wrong, and why it’s wrong would be great help :)

Edit: code added


import SwiftUI

struct PageView<Page: View>: View {
    var viewControllers: [UIHostingController<Page>]

    init(_ views: [Page]) {
        self.viewControllers = views.map { UIHostingController(rootView: $0) }
    }

    var body: some View {
        PageViewController(controllers: viewControllers)
    }
}

struct PageView_Previews: PreviewProvider {
    static var previews: some View {
        PageView(features.map { FeatureCard(landmark: $0) })
            .aspectRatio(3/2, contentMode: .fit)
    }
}

4 Answers

Using this page as inspiration, I was able to make this work in XCode 12 using the following code:

import SwiftUI

struct PageView<Page: View>: View {
    var viewControllers: [UIHostingController<Page>]

    init(viewControllers: [UIHostingController<Page>]) {
        self.viewControllers = viewControllers
    }
    
    init(_ views: [Page]) {
        self.viewControllers = views.map { UIHostingController(rootView: $0) }
    }
    
    var body: some View {
        PageViewController(controllers: viewControllers)
    }
}

struct PageView_Previews: PreviewProvider {
    // the static in the following line is critical to it working...
    static let controllers = features.map { UIHostingController(rootView: FeatureCard(landmark: $0)) }
    
    static var previews: some View {
        PageView(viewControllers: controllers).aspectRatio(3/2, contentMode: .fit)
    }
}

It appears that you need to pass a fully constructed UIHostingController array from within Preview, so I created an extra init overload to be used for preview mode. The [Page]-based init is to keep the code compatible with the downstream steps in the tutorial. As to why it works with the static let, sadly, I have no clue (i.e. if you put the let statement inside of previews as a non-static let, it will fail to generate the preview.

this worked for me. added the @State & $currentPage to make the Preview along with the swipe to change images in the Active Preview finally work!

you need to finish Section 3 of Interfacing With UIKit before it works because you have to add the necessary lines in the PageViewController.swift. keep the Preview pinned to see it finally work once you assign the coordinator as the delegate in Section 3 - step 6.


//  PageView.swift

import SwiftUI

struct PageView<Page: View>: View {
    @State var currentPage = 1
    
    var viewControllers: [UIHostingController<Page>]

    init(viewControllers: [UIHostingController<Page>]) {
        self.viewControllers = viewControllers
    }
    
    init(_ views: [Page]) {
        self.viewControllers = views.map { UIHostingController(rootView: $0) }
    }
    
    var body: some View {
        VStack {
            PageViewController(controllers: viewControllers, currentPage: $currentPage)
            Text("Current Page: \(currentPage)")
        }
    }
}

 struct PageView_Previews: PreviewProvider {
     static let controllers = features.map { UIHostingController(rootView: FeatureCard(landmark: $0)) }
     
     static var previews: some View {
         PageView(viewControllers: controllers).aspectRatio(3/2, contentMode: .fit)
     }
 }


I also have this problem. When running on a simulator is fine.

Try to comment out the didFinishLaunchingWithOptions method in AppDelegate , hope this should fix the issue . your application may be referring to external frameworks !!

Related