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
}
}