Nightmare Debate
Open in bitrigDownload Code
```swift
import SwiftUI
import FoundationModels
@main
struct NightmareDebateApp: App {
var body: some Scene {
WindowGroup {
ContentView()
}
}
}
struct ContentView: View {
@State private var languageModel = SystemLanguageModel.default
@State private var halloweenArgument: String = ""
@State private var christmasArgument: String = ""
@State private var isGeneratingHalloween = false
@State private var isGeneratingChristmas = false
@AppStorage("halloweenWins") private var halloweenWins = 0
@AppStorage("christmasWins") private var christmasWins = 0
@State private var currentRoundWinner: String?
var bothArgumentsGenerated: Bool {
!halloweenArgument.isEmpty && !christmasArgument.isEmpty
}
var body: some View {
NavigationStack {
ScrollView {
VStack(spacing: 30) {
VStack(spacing: 12) {
Text("🎃 🎬 🎄")
.font(.system(size: 60))
Text("The Nightmare Before Christmas")
.font(.title2.bold())
.multilineTextAlignment(.center)
Text("Halloween or Christmas movie? You decide.")
.font(.title3)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
.padding(.horizontal)
}
.padding(.top, 20)
if (halloweenWins > 0) || (christmasWins > 0) {
HStack(spacing: 30) {
VStack(spacing: 4) {
Text("🎃")
.font(.title2)
Text("\(halloweenWins)")
.font(.title.bold())
.foregroundStyle(.orange)
Text("wins")
.font(.caption)
.foregroundStyle(.secondary)
}
Text("VS")
.font(.headline.bold())
.foregroundStyle(.secondary)
VStack(spacing: 4) {
Text("🎄")
.font(.title2)
Text("\(christmasWins)")
.font(.title.bold())
.foregroundStyle(.green)
Text("wins")
.font(.caption)
.foregroundStyle(.secondary)
}
}
.padding()
.background(Color(.systemGray6))
.clipShape(RoundedRectangle(cornerRadius: 12))
}
if #available(iOS 26.0, *) {
switch languageModel.availability {
case .available:
VStack(spacing: 20) {
ArgumentCard(
title: "Halloween Movie",
icon: "🎃",
color: .orange,
argument: halloweenArgument,
isGenerating: isGeneratingHalloween,
showVoteButton: bothArgumentsGenerated && (currentRoundWinner == nil),
isWinner: currentRoundWinner == "halloween",
onGenerate: {
generateHalloweenArgument()
},
onVote: {
voteForHalloween()
}
)
ArgumentCard(
title: "Christmas Movie",
icon: "🎄",
color: .green,
argument: christmasArgument,
isGenerating: isGeneratingChristmas,
showVoteButton: bothArgumentsGenerated && (currentRoundWinner == nil),
isWinner: currentRoundWinner == "christmas",
onGenerate: {
generateChristmasArgument()
},
onVote: {
voteForChristmas()
}
)
}
.padding(.horizontal)
if currentRoundWinner != nil {
Button(action: startNewRound) {
HStack {
Image(systemName: "arrow.clockwise")
Text("New Round")
}
.font(.headline)
.foregroundStyle(.white)
.frame(maxWidth: .infinity)
.padding()
.background(Color.blue.gradient)
.clipShape(RoundedRectangle(cornerRadius: 12))
}
.padding(.horizontal)
}
case .unavailable:
VStack(spacing: 16) {
Image(systemName: "brain.fill")
.font(.system(size: 60))
.foregroundStyle(.secondary)
Text("AI Not Available")
.font(.headline)
Text("The on-device AI model is not available on this device.")
.font(.subheadline)
.foregroundStyle(.secondary)
.multilineTextAlignment(.center)
}
.padding()
}
} else {
VStack(spacing: 16) {
Image(systemName: "exclamationmark.triangle.fill")
.font(.system(size: 60))
.foregroundStyle(.orange)
Text("iOS 26 Required")
.font(.headline)
Text("This feature requires iOS 26 or later.")
.font(.subheadline)
.foregroundStyle(.secondary)
}
.padding()
}
}
.padding(.bottom, 30)
}
.navigationTitle("Movie Debate")
}
}
@available(iOS 26.0, *)
func generateHalloweenArgument() {
isGeneratingHalloween = true
halloweenArgument = ""
currentRoundWinner = nil
Task {
do {
let session = LanguageModelSession()
let response = try await session.respond(to: "Write a persuasive 3-4 sentence argument for why The Nightmare Before Christmas is a Halloween movie, not a Christmas movie. Be compelling and cite specific elements from the film.")
halloweenArgument = response.content
} catch {
halloweenArgument = "Failed to generate argument."
}
isGeneratingHalloween = false
}
}
@available(iOS 26.0, *)
func generateChristmasArgument() {
isGeneratingChristmas = true
christmasArgument = ""
currentRoundWinner = nil
Task {
do {
let session = LanguageModelSession()
let response = try await session.respond(to: "Write a persuasive 3-4 sentence argument for why The Nightmare Before Christmas is a Christmas movie, not a Halloween movie. Be compelling and cite specific elements from the film.")
christmasArgument = response.content
} catch {
christmasArgument = "Failed to generate argument."
}
isGeneratingChristmas = false
}
}
func voteForHalloween() {
currentRoundWinner = "halloween"
halloweenWins += 1
}
func voteForChristmas() {
currentRoundWinner = "christmas"
christmasWins += 1
}
func startNewRound() {
halloweenArgument = ""
christmasArgument = ""
currentRoundWinner = nil
}
}
struct ArgumentCard: View {
let title: String
let icon: String
let color: Color
let argument: String
let isGenerating: Bool
let showVoteButton: Bool
let isWinner: Bool
let onGenerate: () -> Void
let onVote: () -> Void
var body: some View {
VStack(alignment: .leading, spacing: 16) {
HStack {
Text(icon)
.font(.system(size: 40))
Text(title)
.font(.title3.bold())
.foregroundStyle(.white)
Spacer()
if isWinner {
HStack(spacing: 4) {
Image(systemName: "crown.fill")
Text("Winner")
}
.font(.subheadline.bold())
.foregroundStyle(.yellow)
}
}
if isGenerating {
HStack {
ProgressView()
.tint(.white)
Text("Generating argument...")
.font(.subheadline)
.foregroundStyle(.white.opacity(0.8))
}
.frame(maxWidth: .infinity, alignment: .center)
.padding(.vertical, 20)
} else if argument.isEmpty {
Button(action: onGenerate) {
HStack {
Image(systemName: "sparkles")
Text("Generate Argument")
}
.font(.headline)
.foregroundStyle(color)
.frame(maxWidth: .infinity)
.padding()
.background(Color.white)
.clipShape(RoundedRectangle(cornerRadius: 10))
}
} else {
VStack(alignment: .leading, spacing: 12) {
Text(argument)
.font(.body)
.foregroundStyle(.white)
.fixedSize(horizontal: false, vertical: true)
HStack(spacing: 12) {
if showVoteButton {
Button(action: onVote) {
HStack {
Image(systemName: "hand.thumbsup.fill")
Text("Pick This One")
}
.font(.subheadline.bold())
.foregroundStyle(color)
.frame(maxWidth: .infinity)
.padding(.horizontal, 16)
.padding(.vertical, 10)
.background(Color.white)
.clipShape(Capsule())
}
.sensoryFeedback(.success, trigger: isWinner)
}
if !showVoteButton && !isWinner {
Button(action: onGenerate) {
HStack {
Image(systemName: "arrow.clockwise")
Text("Regenerate")
}
.font(.subheadline.bold())
.foregroundStyle(color)
.padding(.horizontal, 16)
.padding(.vertical, 8)
.background(Color.white)
.clipShape(Capsule())
}
}
}
}
}
}
.padding(20)
.frame(maxWidth: .infinity, alignment: .leading)
.background(color.gradient)
.clipShape(RoundedRectangle(cornerRadius: 16))
.shadow(color: color.opacity(0.3), radius: 8, y: 4)
.overlay(
RoundedRectangle(cornerRadius: 16)
.strokeBorder(Color.yellow, lineWidth: isWinner ? 3 : 0)
)
}
}
```