|
I'm currently working on my project that has a quiz section and its function is similar to "Guss the Flag" but mine doesn't work as how it does. The thing is that you tap the speaker and it plays a sound of a japanese letter then you choose the button that has the correct letter out of three. the letters are shown randomly and it seems like working but when you even click the correct answer, it doesn't show that is correct. here's the code: import SwiftUI struct HiraganaQuiz: View { let hiraganas: [Japanese] = Bundle.main.decode("Hiragana.json") @State private var randomHiraganas: [Japanese]
} struct HiraganaQuiz_Previews: PreviewProvider { static var previews: some View { HiraganaQuiz() } } |
|
this is the DecodeManager: import Foundation struct Japanese: Codable, Identifiable { let id: Int let letter: String let image: String let example: String let voice1: String let voice2: String } extension Bundle { func decode<T: Codable>(_ file: String) -> T { guard let url = self.url(forResource: file, withExtension: nil) else { fatalError("Failed to locate (file) in bundle.") }
} |
|
I think you need to replace |
![]() SAVE 50% To celebrate Black Friday, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more. Sponsor Hacking with Swift and reach the world's largest Swift community! |
|
thank you for your response :) I replaced them with what you told me, but it did nothing to solve my problem... |
|
You mean you get the alert that your response is wrong correct? Or you don't get an alert at all? Moreover, how does your JSON look like? |
|
I was focussing on the json decoder, but other parts of your code probably need to be debugged too. For example, in the ForEach, why do you refer to the id instead of the index? The correctAnswer var holds the index, so that's probably what you should be using in the ForEach and the letterTapped() func: ForEach (0...2, id: .self) { index in I suggest putting a breakpoint at the first statement in func letterTapped(). When it stops at the breakpoint, inspect the values of aiueo and correctAnswer. Also put a breakpoint at the last statement of extension Bundle { func decode() and inspect whether loadedData is an array of elements of type Japanese whose properties have the expected values. A print statement before the breakpoint would be helpful. |
|
@Bnerd I just want my code to show that is correct when you tap the correct answer, but even when i correct the right one, it shows as it is incorrect. this is my json file: [ { "id": 0, "letter": "あ", "image": "candies", "example": "あめ", "voice1": "A.mp3", "voice2": "ame.mp3" }, { "id": 1, "letter": "い", "image": "dogs", "example": "いぬ", "voice1": "I.mp3", "voice2": "inu.mp3" }, { "id": 2, "letter": "う", "image": "rabbit", "example": "うさぎ", "voice1": "U.mp3", "voice2": "usagi.mp3" }, { "id": 3, "letter": "え", "image": "shrimp", "example": "えび", "voice1": "E.mp3", "voice2": "ebi.mp3" }, { "id": 4, "letter": "お", "image": "ax", "example": "おの", "voice1": "O.mp3", "voice2": "ono.mp3" }, { "id": 5, "letter": "か", "image": "shell", "example": "かい", "voice1": "ka.mp3", "voice2": "kai.mp3" }, { "id": 6, "letter": "き", "image": "kimono", "example": "きもの", "voice1": "ki.mp3", "voice2": "kimonoS.mp3" }, { "id": 7, "letter": "く", "image": "bear", "example": "くま", "voice1": "ku.mp3", "voice2": "kuma.mp3" }, { "id": 8, "letter": "け", "image": "yarn", "example": "けいと", "voice1": "ke.mp3", "voice2": "keito.mp3" }, { "id": 9, "letter": "こ", "image": "rice", "example": "こめ", "voice1": "ko.mp3", "voice2": "kome.mp3" }, { "id": 10, "letter": "さ", "image": "sakura", "example": "さくら", "voice1": "sa.mp3", "voice2": "sakuraS.mp3" }, { "id": 11, "letter": "し", "image": "newspaper", "example": "しんぶん", "voice1": "shi.mp3", "voice2": "shinnbunn.mp3" }, { "id": 12, "letter": "す", "image": "watermelon", "example": "すいか", "voice1": "su.mp3", "voice2": "suika.mp3" }, { "id": 13, "letter": "せ", "image": "laundrymachine", "example": "せんたくき", "voice1": "se.mp3", "voice2": "senntakuki.mp3" }, { "id": 14, "letter": "そ", "image": "sky", "example": "そら", "voice1": "so.mp3", "voice2": "sora.mp3" }, { "id": 15, "letter": "た", "image": "towel", "example": "たおる", "voice1": "ta.mp3", "voice2": "taoru.mp3" }, { "id": 16, "letter": "ち", "image": "map", "example": "ちず", "voice1": "chi.mp3", "voice2": "chizu.mp3" }, { "id": 17, "letter": "つ", "image": "table", "example": "つくえ", "voice1": "tsu.mp3", "voice2": "tsukue.mp3" }, { "id": 18, "letter": "て", "image": "angel", "example": "てんし", "voice1": "te.mp3", "voice2": "tennshi.mp3" }, { "id": 19, "letter": "と", "image": "tomato", "example": "とまと", "voice1": "to.mp3", "voice2": "tomatoS.mp3" }, { "id": 20, "letter": "な", "image": "pot", "example": "なべ", "voice1": "na.mp3", "voice2": "nabe.mp3" }, { "id": 21, "letter": "に", "image": "meat", "example": "にく", "voice1": "ni.mp3", "voice2": "niku.mp3" }, { "id": 22, "letter": "ぬ", "image": "plushtoy", "example": "ぬいぐるみ", "voice1": "nu.mp3", "voice2": "nuigurumi.mp3" }, { "id": 23, "letter": "ね", "image": "cat", "example": "ねこ", "voice1": "ne.mp3", "voice2": "neko.mp3" }, { "id": 24, "letter": "の", "image": "glue", "example": "のり", "voice1": "no.mp3", "voice2": "nori.mp3" }, { "id": 25, "letter": "は", "image": "toothbrush", "example": "はぶらし", "voice1": "ha.mp3", "voice2": "haburashi.mp3" }, { "id": 26, "letter": "ひ", "image": "ducks", "example": "ひよこ", "voice1": "hi.mp3", "voice2": "hiyoko.mp3" }, { "id": 27, "letter": "ふ", "image": "ship", "example": "ふね", "voice1": "fu.mp3", "voice2": "fune.mp3" }, { "id": 28, "letter": "へ", "image": "snake", "example": "へび", "voice1": "he.mp3", "voice2": "hebi.mp3" }, { "id": 29, "letter": "ほ", "image": "broom", "example": "ほうき", "voice1": "ho.mp3", "voice2": "houki.mp3" }, { "id": 30, "letter": "ま", "image": "window", "example": "まど", "voice1": "ma.mp3", "voice2": "mado.mp3" }, { "id": 31, "letter": "み", "image": "water", "example": "みず", "voice1": "mi.mp3", "voice2": "mizu.mp3" }, { "id": 32, "letter": "む", "image": "wheat", "example": "むぎ", "voice1": "mu.mp3", "voice2": "mugi.mp3" }, { "id": 33, "letter": "め", "image": "glasses", "example": "めがね", "voice1": "me.mp3", "voice2": "megane.mp3" }, { "id": 34, "letter": "も", "image": "peach", "example": "もも", "voice1": "mo.mp3", "voice2": "momo.mp3" }, { "id": 35, "letter": "や", "image": "mountain", "example": "やま", "voice1": "ya.mp3", "voice2": "yama.mp3" }, { "id": 36, "letter": "ゆ", "image": "snow", "example": "ゆき", "voice1": "yu.mp3", "voice2": "yuki.mp3" }, { "id": 37, "letter": "よ", "image": "clothes", "example": "ようふく", "voice1": "yo.mp3", "voice2": "youfuku.mp3" }, { "id": 38, "letter": "ら", "image": "lion", "example": "らいおん", "voice1": "ra.mp3", "voice2": "raionn.mp3" }, { "id": 39, "letter": "り", "image": "squarrel", "example": "りす", "voice1": "ri.mp3", "voice2": "risu.mp3" }, { "id": 40, "letter": "る", "image": "ruby", "example": "るびー", "voice1": "ru.mp3", "voice2": "rubii.mp3" }, { "id": 41, "letter": "れ", "image": "fridge", "example": "れいぞうこ", "voice1": "re.mp3", "voice2": "reizouko.mp3" }, { "id": 42, "letter": "ろ", "image": "candle", "example": "ろうそく", "voice1": "ro.mp3", "voice2": "rousoku.mp3" }, { "id": 43, "letter": "わ", "image": "cottoncandy", "example": "わたあめ", "voice1": "wa.mp3", "voice2": "wataame.mp3" }, { "id": 44, "letter": "を", "image": "drawing", "example": "えをかく(drawing picture)", "voice1": "wo.mp3", "voice2": "ewokaku.mp3" }, { "id": 45, "letter": "ん", "image": "gohann", "example": "ごはん", "voice1": "nn.mp3", "voice2": "gohannVoice.mp3" } ] |
|
@bobstern i used the id because that way code compiled but then when I tried the ForEach(0...2, id: .self), it gets errors like these: On the ForEach line: Cannot convert value of type 'ClosedRange<Int>' to expected argument type 'Binding<C>' Generic parameter 'C' could not be inferred On the Text label line: Initializer 'init(_:)' requires that 'Binding<Subject>' conform to 'StringProtocol' |
|
Oops — I omitted the backslash in the id parameter of ForEach. Without fully understanding your program, I think this is what you want:
If your label is only text, Apple's reference for Button shows a simpler form of Button with a string parameter instead of a Label:
|
|
I think one oversight in the 100 Days course is that it does not suggest how to debug a program. If a program doesn’t work, it's almost impossible to find the problem without inserting several print commands or breakpoints to see what's happening in different parts of the program. |
|
Bob's answer is correct, I think you need to change the below to
|
|
But if the |
|
You are correct, small correction as per below
|
|
I'm sorry for not being able to giving you a precise explanation but thank you @bobstern @Bnerd @roosterboy for helping me, it worked perfectly :) |
SAVE 50% To celebrate Black Friday, all our books and bundles are half price, so you can take your Swift knowledge further without spending big! Get the Swift Power Pack to build your iOS career faster, get the Swift Platform Pack to builds apps for macOS, watchOS, and beyond, or get the Swift Plus Pack to learn advanced design patterns, testing skills, and more.
Sponsor Hacking with Swift and reach the world's largest Swift community!
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.
Link copied to your pasteboard.