Before anyone rants and raves about checking documentation - I have spent the last 4 hours trying to solve this issue on my own before asking for help. Coding in Swift is VERY new for me and I'm banging my head against the wall trying to teach myself. I am very humbly asking for help. If you refer me to documentation, that's fine but I need examples or it's going to go right over my head. Teaching myself is hard, please don't make it more difficult.
I have ONE swift file with everything in it.
import Foundation
import Cocoa
import Observation
class GlobalString: ObservableObject {
@Published var apiKey = ""
@Published var link = ""
}
struct ContentView: View {
@EnvironmentObject var globalString: GlobalString
var body: some View {
Form {
Section(header: Text("WallTaker for macOS").font(.title)) {
TextField(
"Link ID:",
text: $globalString.link
)
.disableAutocorrection(true)
TextField(
"API Key:",
text: $globalString.apiKey
)
.disableAutocorrection(true)
Button("Take My Wallpaper!") {
}
}
.padding()
}
.task {
await Wallpaper().fetchLink()
}
}
}
@main
struct WallTaker_for_macOSApp: App {
@AppStorage("showMenuBarExtra") private var showMenuBarExtra = true
@EnvironmentObject var globalString: GlobalString
var body: some Scene {
WindowGroup {
ContentView()
.environmentObject(GlobalString())
}
// MenuBarExtra("WallTaker for macOS", systemImage: "WarrenHead.png", isInserted: $showMenuBarExtra) {
// Button("Refresh") {
//// currentNumber = "1"
// }
// Button("Love It!") {
//// currentNumber = "2"
// }
// Button("Hate It!") {
//// currentNumber = "3"
// }
// Button("EXPLOSION!") {
// // currentNumber = "3"
// }
////
// }
}
}
class Wallpaper {
var url: URL? = nil
var lastPostUrl: URL? = nil
let mainMonitor: NSScreen
init() {
mainMonitor = NSScreen.main!
}
struct LinkResponse: Codable {
var post_url: String?
var set_by: String?
var updated_at: String
}
struct Link {
var postUrl: URL?
var setBy: String
var updatedAt: Date
}
func parseIsoDate(timestamp: String) -> Date? {
let formatter = DateFormatter()
formatter.locale = Locale(identifier: "en_US_POSIX")
formatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ssZ"
return formatter.date(from: timestamp)
}
func fetchLink() async {
do {
url = URL(string: GlobalString().link)
let (data, _) = try await URLSession.shared.data(from: url!)
let decoder = JSONDecoder()
let linkResponse = try decoder.decode(LinkResponse.self, from: data)
let postUrl: URL? = linkResponse.post_url != nil ? URL(string: linkResponse.post_url!) : nil
let date = parseIsoDate(timestamp: linkResponse.updated_at)
let link = Link(
postUrl: postUrl,
setBy: linkResponse.set_by ?? "anon",
updatedAt: date ?? Date()
)
try update(link: link)
} catch {
}
}
func update(link: Link) throws {
guard let newPostUrl = link.postUrl else {
return
}
if (newPostUrl != lastPostUrl) {
lastPostUrl = newPostUrl
let tempFilePath = try getTempFilePath()
try downloadImageTo(sourceURL: newPostUrl, destinationURL: tempFilePath)
try applyWallpaper(url: tempFilePath)
} else {
}
}
private func applyWallpaper(url: URL) throws {
try NSWorkspace.shared.setDesktopImageURL(url, for: mainMonitor, options: [:])
}
private func getTempFilePath() throws -> URL {
let directory = NSTemporaryDirectory()
let fileName = NSUUID().uuidString
let fullURL = NSURL.fileURL(withPathComponents: [directory, fileName])!
return fullURL
}
private func downloadImageTo(sourceURL: URL, destinationURL: URL) throws {
let data = try Data(contentsOf: sourceURL)
try data.write(to: destinationURL)
}
}
The 'fetchLink' function is where things explode, specifically when setting the URL. I do not know what I'm doing wrong.