Initial commit
This commit is contained in:
11
QuizApp/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
11
QuizApp/Assets.xcassets/AccentColor.colorset/Contents.json
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"colors" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
35
QuizApp/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file
35
QuizApp/Assets.xcassets/AppIcon.appiconset/Contents.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"images" : [
|
||||||
|
{
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "dark"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"appearances" : [
|
||||||
|
{
|
||||||
|
"appearance" : "luminosity",
|
||||||
|
"value" : "tinted"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"idiom" : "universal",
|
||||||
|
"platform" : "ios",
|
||||||
|
"size" : "1024x1024"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
6
QuizApp/Assets.xcassets/Contents.json
Normal file
6
QuizApp/Assets.xcassets/Contents.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"info" : {
|
||||||
|
"author" : "xcode",
|
||||||
|
"version" : 1
|
||||||
|
}
|
||||||
|
}
|
||||||
76
QuizApp/ContentView.swift
Normal file
76
QuizApp/ContentView.swift
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
//
|
||||||
|
// ContentView.swift
|
||||||
|
// QuizApp
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 02.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
struct ContentView: View {
|
||||||
|
|
||||||
|
@ObservedObject var viewModel = ViewModel()
|
||||||
|
|
||||||
|
@State private var selectedAnswerIndex: Int? = nil
|
||||||
|
@State private var isAnswered = false
|
||||||
|
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
if let frage = viewModel.topics.first {
|
||||||
|
Text(frage.question)
|
||||||
|
.font(.title)
|
||||||
|
.multilineTextAlignment(.center)
|
||||||
|
.padding()
|
||||||
|
|
||||||
|
ForEach(frage.answers.indices, id: \.self) { index in
|
||||||
|
Button(action: {
|
||||||
|
selectedAnswerIndex = index
|
||||||
|
isAnswered = true
|
||||||
|
print("Selected:", index)
|
||||||
|
print("Correct:", frage.correctAnswer)
|
||||||
|
}) {
|
||||||
|
Text(frage.answers[index])
|
||||||
|
.padding()
|
||||||
|
.frame(maxWidth: 300)
|
||||||
|
.background(buttonColor(for: index, correctIndex: frage.correctAnswer))
|
||||||
|
.foregroundColor(.white)
|
||||||
|
.cornerRadius(10)
|
||||||
|
}
|
||||||
|
.disabled(isAnswered)
|
||||||
|
}
|
||||||
|
VStack {
|
||||||
|
if isAnswered {
|
||||||
|
Text(selectedAnswerIndex == frage.correctAnswer ? "✅ Richtig!" : "❌ Falsch")
|
||||||
|
.font(.headline)
|
||||||
|
.foregroundColor(selectedAnswerIndex == frage.correctAnswer ? .green : .red)
|
||||||
|
.padding()
|
||||||
|
}
|
||||||
|
if isAnswered {
|
||||||
|
Button("Nächste Frage") {
|
||||||
|
selectedAnswerIndex = nil
|
||||||
|
isAnswered = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.frame(height: 80)
|
||||||
|
} else {
|
||||||
|
Text("Fragen werden geladen...")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private func buttonColor(for index: Int, correctIndex: Int) -> Color {
|
||||||
|
guard isAnswered else { return .blue }
|
||||||
|
|
||||||
|
if index == correctIndex {
|
||||||
|
return .green
|
||||||
|
} else if index == selectedAnswerIndex {
|
||||||
|
return .red
|
||||||
|
} else {
|
||||||
|
return .gray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#Preview {
|
||||||
|
ContentView()
|
||||||
|
}
|
||||||
17
QuizApp/QuizAppApp.swift
Normal file
17
QuizApp/QuizAppApp.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// QuizAppApp.swift
|
||||||
|
// QuizApp
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 02.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import SwiftUI
|
||||||
|
|
||||||
|
@main
|
||||||
|
struct QuizAppApp: App {
|
||||||
|
var body: some Scene {
|
||||||
|
WindowGroup {
|
||||||
|
ContentView()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
16
QuizApp/Topic.swift
Normal file
16
QuizApp/Topic.swift
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
//
|
||||||
|
// Topic.swift
|
||||||
|
// QuizApp
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 03.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
struct Topic: Decodable, Hashable {
|
||||||
|
|
||||||
|
let question: String
|
||||||
|
let answers: [String]
|
||||||
|
let correctAnswer: Int
|
||||||
|
|
||||||
|
}
|
||||||
30
QuizApp/ViewModel.swift
Normal file
30
QuizApp/ViewModel.swift
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
//
|
||||||
|
// ViewModel.swift
|
||||||
|
// QuizApp
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 03.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Foundation
|
||||||
|
|
||||||
|
class ViewModel: ObservableObject {
|
||||||
|
|
||||||
|
let topics: [Topic]
|
||||||
|
|
||||||
|
@Published var currentQuestionIndex: Int = 0
|
||||||
|
|
||||||
|
init() {
|
||||||
|
guard let url = Bundle.main.url(forResource: "data", withExtension: "json") else {
|
||||||
|
topics = []
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
do {
|
||||||
|
let data = try Data(contentsOf: url)
|
||||||
|
topics = try JSONDecoder().decode([Topic].self, from: data)
|
||||||
|
} catch {
|
||||||
|
print("Fehler beim Laden des Inhalts: \(error)")
|
||||||
|
topics = []
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
12
QuizApp/data.json
Normal file
12
QuizApp/data.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"question": "Was ist die Hauptstadt von Frankreich?",
|
||||||
|
"answers": ["Rom", "Berlin", "Paris"],
|
||||||
|
"correctAnswer": 2
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"question": "Was ist die Hauptstadt von Deutschland?",
|
||||||
|
"answers": ["Rom", "Berlin", "Paris"],
|
||||||
|
"correctAnswer": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
17
QuizAppTests/QuizAppTests.swift
Normal file
17
QuizAppTests/QuizAppTests.swift
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
//
|
||||||
|
// QuizAppTests.swift
|
||||||
|
// QuizAppTests
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 02.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Testing
|
||||||
|
@testable import QuizApp
|
||||||
|
|
||||||
|
struct QuizAppTests {
|
||||||
|
|
||||||
|
@Test func example() async throws {
|
||||||
|
// Write your test here and use APIs like `#expect(...)` to check expected conditions.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
41
QuizAppUITests/QuizAppUITests.swift
Normal file
41
QuizAppUITests/QuizAppUITests.swift
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
//
|
||||||
|
// QuizAppUITests.swift
|
||||||
|
// QuizAppUITests
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 02.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class QuizAppUITests: XCTestCase {
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||||
|
|
||||||
|
// In UI tests it is usually best to stop immediately when a failure occurs.
|
||||||
|
continueAfterFailure = false
|
||||||
|
|
||||||
|
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
|
||||||
|
}
|
||||||
|
|
||||||
|
override func tearDownWithError() throws {
|
||||||
|
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testExample() throws {
|
||||||
|
// UI tests must launch the application that they test.
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Use XCTAssert and related functions to verify your tests produce the correct results.
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunchPerformance() throws {
|
||||||
|
// This measures how long it takes to launch your application.
|
||||||
|
measure(metrics: [XCTApplicationLaunchMetric()]) {
|
||||||
|
XCUIApplication().launch()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
33
QuizAppUITests/QuizAppUITestsLaunchTests.swift
Normal file
33
QuizAppUITests/QuizAppUITestsLaunchTests.swift
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
//
|
||||||
|
// QuizAppUITestsLaunchTests.swift
|
||||||
|
// QuizAppUITests
|
||||||
|
//
|
||||||
|
// Created by Paul Nowotka on 02.08.25.
|
||||||
|
//
|
||||||
|
|
||||||
|
import XCTest
|
||||||
|
|
||||||
|
final class QuizAppUITestsLaunchTests: XCTestCase {
|
||||||
|
|
||||||
|
override class var runsForEachTargetApplicationUIConfiguration: Bool {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
override func setUpWithError() throws {
|
||||||
|
continueAfterFailure = false
|
||||||
|
}
|
||||||
|
|
||||||
|
@MainActor
|
||||||
|
func testLaunch() throws {
|
||||||
|
let app = XCUIApplication()
|
||||||
|
app.launch()
|
||||||
|
|
||||||
|
// Insert steps here to perform after app launch but before taking a screenshot,
|
||||||
|
// such as logging into a test account or navigating somewhere in the app
|
||||||
|
|
||||||
|
let attachment = XCTAttachment(screenshot: app.screenshot())
|
||||||
|
attachment.name = "Launch Screen"
|
||||||
|
attachment.lifetime = .keepAlways
|
||||||
|
add(attachment)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user