UPGRADE YOUR SKILLS: Learn advanced Swift and SwiftUI on Hacking with Swift+! >>

SOLVED: ShareLink with a SwiftUI View - Runtime error creating/using file

Forums > SwiftUI

Used Paul's sample code to share a PDF render of my ResultsView page, but XCode complains bitterly and PDF is empty. first part of log is:

2023-02-22 12:24:19.236643-0500 iFlag3[38256:28901583] [ShareSheet] Failed to request default share mode for fileURL:file:///Users/gcobley/Library/Developer/CoreSimulator/Devices/3041C0B8-288B-4D89-92BF-1E9F469F423C/data/Containers/Data/Application/D51E0A9C-EC3E-40CC-AE13-15C0EB3FD224/Documents/regattaScores.pdf error:Error Domain=NSOSStatusErrorDomain Code=-10814 "(null)" UserInfo={_LSLine=1538, _LSFunction=runEvaluator} 2023-02-22 12:24:19.258445-0500 iFlag3[38256:28901583] [ShareSheet] Only support loading options for CKShare and SWY types.

In case it is not obvious, this is my debut App. Just completed 100 Days, so please excuse any horrendous coding faux pas ;-)

Code:

import SwiftUI

struct RegattaResults: View {
    @EnvironmentObject var regattaList : RegattaList
    @Environment(\.dismiss) var dismiss

    var body: some View {
        if regattaList.selectedRegatta.name == "Default Regatta" {
                Text("Please return to the Regatta tab to select a regatta")
        } else {
            Spacer()
            VStack {
                HStack {
                    Text("  < Regattas").onTapGesture {
                        dismiss()
                    }.foregroundColor(.blue)
                    Spacer()
                    Text(regattaList.selectedRegatta.name).font(.title2)
                    Spacer()
                    ShareLink("", item: render())

                }
                ResultsView(regatta: regattaList.selectedRegatta)
            }.onAppear {
                ProcessScores()
                regattaList.save()
            }
        }
    }
    func ProcessScores() {
        // Process each skippers scores for throwouts and totals
        for skipper in regattaList.selectedRegatta.skippers {
            var skipRaceScores: [RaceScore] = []
            for race in regattaList.selectedRegatta.races {
                let ss: RaceScore = race.raceScores.first {$0.skipID == skipper.id}!
                skipRaceScores.append(ss)
            }
            skipper.firsts = skipRaceScores.filter {
                $0.raceRawScore == 1.0
            }.count
            skipper.onetwos = skipRaceScores.filter {
                $0.raceRawScore <= 2.0
            }.count
            skipper.onethrees = skipRaceScores.filter {
                $0.raceRawScore <= 3.0
            }.count
            skipper.onefours = skipRaceScores.filter {
                $0.raceRawScore <= 4.0
            }.count
            //

            for rs in skipRaceScores {
                rs.isThrownOut = false
            }

            skipRaceScores.sort {
                $0.raceRawScore > $1.raceRawScore
            }
            let throwableRaceScores = skipRaceScores.filter {
                $0.canThrowOut
            }
            for i in 0..<regattaList.selectedRegatta.throwouts[regattaList.selectedRegatta.races.count] {
                throwableRaceScores[i].isThrownOut = true
                // what else?
            }
            //print("processing - throwouts = \(regattaList.selectedRegatta.throwouts[regattaList.selectedRegatta.races.count])")

            skipper.regattaGross = 0
            skipper.regattaNet = 0
            for skipRaceScore in skipRaceScores {
                skipper.regattaGross = skipper.regattaGross + skipRaceScore.raceRawScore
                if !skipRaceScore.isThrownOut {
                    skipper.regattaNet = skipper.regattaNet + skipRaceScore.raceRawScore
                }
            }
        }
        // Rank skippers on score and tie-breakers
        regattaList.selectedRegatta.skippers.sort {
            return ($0.regattaNet, $1.firsts, $1.onetwos, $1.onethrees, $1.onefours) < ($1.regattaNet, $0.firsts, $0.onetwos, $0.onethrees, $0.onefours)
        }
        for i in 0..<regattaList.selectedRegatta.skippers.count {
            regattaList.selectedRegatta.skippers[i].regattaPlace = i+1
        }
    }
    func render() -> URL {
        // 1: Render Results with some modifiers
        let renderer = ImageRenderer(content:
                ResultsView(regatta: regattaList.selectedRegatta)
        )

        // 2: Save it to our documents directory
        let url = URL.documentsDirectory.appending(path: "regattaScores.pdf")

        // 3: Start the rendering process
        renderer.render { size, context in
            // 4: Tell SwiftUI our PDF should be the same size as the views we're rendering
            var box = CGRect(x: 0, y: 0, width: size.width, height: size.height)

            // 5: Create the CGContext for our PDF pages
            guard let pdf = CGContext(url as CFURL, mediaBox: &box, nil) else {
                return
            }

            // 6: Start a new PDF page
            pdf.beginPDFPage(nil)

            // 7: Render the SwiftUI view data onto the page
            context(pdf)

            // 8: End the page and close the file
            pdf.endPDFPage()
            pdf.closePDF()
        }

        return url
    }

}

1      

Looks as if the runtime error logs in the console are also genertaed by Paul's example code, and don't stop the share from working. Now my issue is the blank pdf generated. It seems to be sized for the view OK, but no visible content. Any ideas?

2      

In case you encounter this, I was able to make the render work by removing the scrolling from the View. It seems that ScrollView interferes with render?

2      

TAKE YOUR SKILLS TO THE NEXT LEVEL If you like Hacking with Swift, you'll love Hacking with Swift+ – it's my premium service where you can learn advanced Swift and SwiftUI, functional programming, algorithms, and more. Plus it comes with stacks of benefits, including monthly live streams, downloadable projects, a 20% discount on all books, and free gifts!

Find out more

Sponsor Hacking with Swift and reach the world's largest Swift community!

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.