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      

BUILD THE ULTIMATE PORTFOLIO APP Most Swift tutorials help you solve one specific problem, but in my Ultimate Portfolio App series I show you how to get all the best practices into a single app: architecture, testing, performance, accessibility, localization, project organization, and so much more, all while building a SwiftUI app that works on iOS, macOS and watchOS.

Get it on Hacking with Swift+

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.