Skip to content
ย 
ย 

Latest commit

ย 

History

172 Commits

Folders and files

NameName
Last commit message
Last commit date
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

๐Ÿซ ํ•™๊ต ๋Œ€ํ•ญ์ „

๐Ÿ“– ๋ชฉ์ฐจ

  1. ์†Œ๊ฐœ
  2. ๊ฐœ๋ฐœํ™˜๊ฒฝ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ
  3. Tree
  4. ํ‚ค์›Œ๋“œ
  5. ํƒ€์ž„๋ผ์ธ
  6. ์‹คํ–‰ํ™”๋ฉด
  7. ํŠธ๋Ÿฌ๋ธ”์ŠˆํŒ…

๐ŸŒฑ ์†Œ๊ฐœ

ํ•™๊ต๋ฅผ ์„ ํƒํ•˜๊ณ  ๊ฒŒ์ž„ํ™”๋ฉด์œผ๋กœ ๊ฐ€์„œ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•˜๋ฉฐ ์ ์ˆ˜๋ฅผ ์˜ฌ๋ฆฌ๋Š” ์•ฑ์ž…๋‹ˆ๋‹ค.

๐Ÿง‘๐Ÿปโ€๐Ÿ’ป ํŒ€์›

์ตœ๋™ํ˜ธ ํ™ฉ์„ฑ์ง„ ๊น€์„ฑ์—ฝ ๊น€ํ˜œ๋ž€ ์œค์ค€์„ฑ
Kakao-Talk-Photo-2023-09-19-15-30-11 1f

โš™๏ธ ๊ฐœ๋ฐœ ํ™˜๊ฒฝ ๋ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

swift xcode Firebase Alamofire GoogleMobileAds

๐ŸŒฒ Tree

๐Ÿ“ฆTouchSchool
 โ”ฃ ๐Ÿ“‚iOS
 โ”ƒ โ”ฃ ๐Ÿ“‚AD
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œBannerView.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œBannerViewController.swift
 โ”ƒ โ”ฃ ๐Ÿ“‚Game
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œGameVM.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œGameView.swift
 โ”ƒ โ”ฃ ๐Ÿ“‚Helpers
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“‚Font
 โ”ƒ โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œGiants-Bold.otf
 โ”ƒ โ”ƒ โ”ƒ โ”— ๐Ÿ“œRecipekorea.ttf
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“‚Sound
 โ”ƒ โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œbuttomBGM.mp3
 โ”ƒ โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œbuttonBGM.mp3
 โ”ƒ โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œerrorBGM.mp3
 โ”ƒ โ”ƒ โ”ƒ โ”— ๐Ÿ“œmainBGM.mp3
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œActivityIndicator.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œAudio.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œColors.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œHelpers.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œinfoView.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œMultitouchRepresentable.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œMultitouchView.swift
 โ”ƒ โ”ฃ ๐Ÿ“‚Main
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œMainVM.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œMainView.swift
 โ”ƒ โ”ฃ ๐Ÿ“‚Model
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œSchool.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œSmoke.swift
 โ”ƒ โ”ฃ ๐Ÿ“‚Rank
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œRankView.swift
 โ”ƒ โ”— ๐Ÿ“‚Search
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œFirebaseManager.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œSearchBar.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œSearchGuide.swift
 โ”ƒ โ”ƒ โ”ฃ ๐Ÿ“œSearchVM.swift
 โ”ƒ โ”ƒ โ”— ๐Ÿ“œSearchView.swift
 โ”ฃ ๐Ÿ“œContentView.swift
 โ”ฃ ๐Ÿ“œGoogleService-Info.plist
 โ”ฃ ๐Ÿ“œInfo.plist
 โ”— ๐Ÿ“œTouchSchoolApp.swift

๐Ÿ”‘ ํ‚ค์›Œ๋“œ

  • MVVM
  • URLSession
  • Alamofire
  • Firebase

โฐ ํƒ€์ž„๋ผ์ธ

Step 1 ํƒ€์ž„๋ผ์ธ
  • 23.10.11 ~ 23.10.17
    • ํ”„๋กœ์ ํŠธ ์‹œ์ž‘
    • ํ•™๊ต๊ฒ€์ƒ‰ํ™”๋ฉด ๊ตฌํ˜„
    • ๋ฉ”์ธํ™”๋ฉด ๊ตฌํ˜„
  • 23.10.19 ~ 23.10.26
    • ์ดˆ,์ค‘,๊ณ ๋“ฑํ•™๊ต ๋ฐ์ดํ„ฐ ๊ฐ€์ ธ์™€์„œ ์ €์žฅ
    • URLSession -> Alamofire ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ ์šฉ
    • ํ•™๊ต์ •๋ณด ๊ฒ€์ƒ‰ ์‹œ ํ•„ํ„ฐ๋ง ๊ธฐ๋Šฅ ๊ตฌํ˜„
Step 2 ํƒ€์ž„๋ผ์ธ
  • 23.11.02 ~ 23.11.03
    • Firebase์™€ ๋ฐ์ดํ„ฐ ์ฃผ๊ณ  ๋ฐ›๋Š” ํ•จ์ˆ˜๋“ค ๊ตฌํ˜„
    • ํ•™๊ต ์„ ํƒ ์‹œ Firebase์— ์ถ”๊ฐ€ ๋ฐ ๋ฐ์ดํ„ฐ ์—ฐ๊ฒฐ
    • ๋ฐฐ๊ฒฝํ™”๋ฉด ์ˆ˜์ •
    • ๊นƒ ์ปจ๋ฒค์…˜ ํ…œํ”Œ๋ฆฟ ์ถ”๊ฐ€
  • 23.11.06 ~ 23.11.15
    • ๋žญํ‚น ํ™”๋ฉด ์ถ”๊ฐ€
    • ๊ฒŒ์ž„ ๊ธฐ๋Šฅ ๊ตฌํ˜„ ์™„๋ฃŒ
    • ์•ฑ ์‹คํ–‰ ์‹œ ๋ฉ”์ธํ™”๋ฉด์ด ๋จผ์ €๋‚˜์˜ค๋„๋ก ๋กœ์ง ์ˆ˜์ •
  • 23.11.16
    • ์•ฑ ์ข…๋ฃŒ ํ›„ ๋“ค์–ด์™”์„ ๋•Œ ๋ฐ์ดํ„ฐ ๋‚จ๊ฒŒ ์ˆ˜์ •
    • ํ„ฐ์น˜์‹œ ์ด๋ฒคํŠธ ์ถ”๊ฐ€
Step 3 ํƒ€์ž„๋ผ์ธ
  • 23.11.17
    • ๋น„์ •์ƒ์ ์ธ ๊ฐ’ ๊ฒ€์ถœ ๋ฐ ์ดˆ๊ธฐํ™” ๊ธฐ๋Šฅ ๊ตฌํ˜„
  • 23.11.19 ~ 23.11.21
    • UI ์ˆ˜์ • ๋ฐ sound๋ฐ์ดํ„ฐ ์ถ”๊ฐ€
    • ๊ฒŒ์ž„ ํ™”๋ฉด ํ„ฐ์น˜ ์• ๋‹ˆ๋ฉ”์ด์…˜ ์ถ”๊ฐ€
  • 23.11.22
    • ๋ฉ”์ธBGM, ํ„ฐ์น˜BGM, ์˜ค๋ฅ˜BGM ์ถ”๊ฐ€
    • ๊ฒŒ์ž„ํ™”๋ฉด ๋ฉ€ํ‹ฐํ„ฐ์น˜ ๊ธฐ๋Šฅ ๊ตฌํ˜„
    • ์•ฑ ์•„์ด์ฝ˜ ์ƒ์„ฑ
  • 23.11.23
    • ์ปค์Šคํ…€ ํฐํŠธ ์ ์šฉ
    • Sound ์ธ์Šคํ„ด์Šค ์ƒ์„ฑ ํ›„ ์žฌ์‚ฌ์šฉ ๋กœ์ง์œผ๋กœ ๋ณ€๊ฒฝ
    • ์˜ค๋””์˜ค ์žฌ์ƒ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ฒ˜๋ฆฌ

๐Ÿ“ฑ ์‹คํ–‰ ํ™”๋ฉด

์•ฑ ์‹คํ–‰ ํ•™๊ต์„ ํƒ
๊ฒŒ์ž„ํ™”๋ฉด ๋žญํ‚นํ™”๋ฉด

โ“ ํŠธ๋Ÿฌ๋ธ” ์ŠˆํŒ…

Step1

GameView ๋ฉ€ํ‹ฐ ํ„ฐ์น˜๊ฐ€ ์•ˆ๋˜๋˜ ์ด์Šˆ
  • GameView์—์„œ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•  ๋•Œ ์—ฌ๋Ÿฌ ์†๊ฐ€๋ฝ์œผ๋กœ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•˜๋ฉด ๋จนํžˆ๋Š” ํ˜„์ƒ์ด ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • SwiftUI๋Š” ์ง์ ‘์ ์ธ ๋ฉ€ํ‹ฐํ„ฐ์น˜ ์ฒ˜๋ฆฌ๋ฅผ ์œ„ํ•œ API๋ฅผ ์ œ๊ณตํ•˜์ง€ ์•Š๊ธฐ์— ๊ธฐ๋ณธ์ ์ธ onTapGesture ๋Œ€์‹ ์— ๋” ๋‚ฎ์€ ์ˆ˜์ค€์˜ ์ด๋ฒคํŠธ ์ฒ˜๋ฆฌ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค.

  • ๋ฉ€ํ‹ฐํ„ฐ์น˜ ๊ธฐ๋Šฅ์„ ํ™œ์„ฑํ™”ํ•˜๊ธฐ ์œ„ํ•ด UIViewRepresentableํ”„๋กœํ† ์ฝœ์„ ์ค€์ˆ˜ํ•˜๋Š” MultitouchRepresentable๊ณผ UIView์˜ ํ•˜์œ„ ํด๋ž˜์Šค์ธ MultitouchView๋ฅผ ์ถ”๊ฐ€ํ–ˆ์Šต๋‹ˆ๋‹ค.

  • makeUIView(context:) ์ด ๋ฉ”์†Œ๋“œ๋Š” MultitouchView ์ƒ์„ฑ์„ ๋‹ด๋‹นํ•ฉ๋‹ˆ๋‹ค. MultitouchView์˜ touchBegan ํด๋กœ์ €๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ์ด ํด๋กœ์ €๋Š” MultitouchView์—์„œ ํ„ฐ์น˜๊ฐ€ ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.

struct MultitouchRepresentable: UIViewRepresentable {
    var touchBegan: ((CGPoint) -> Void)

    func makeUIView(context: Context) -> MultitouchView {
        let view = MultitouchView()
        view.touchBegan = touchBegan
        return view
    }

    func updateUIView(_ uiView: MultitouchView, context: Context) {
    }
}
  • isMultipleTouchEnabled = true ์ด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ๋ทฐ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ ๋™์‹œ ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ๊ฐ์ง€ํ•  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • touchesBegan(_:with:) ์ด๋Š” ๋ทฐ์—์„œ ์ƒˆ๋กœ์šด ํ„ฐ์น˜๊ฐ€ ๊ฐ์ง€๋  ๋•Œ๋งˆ๋‹ค ํ˜ธ์ถœ๋˜๋Š” UIView์˜ ๋ฉ”์„œ๋“œ๋ฅผ ์žฌ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ฉ”์„œ๋“œ๋Š” ๊ฐ ํ„ฐ์น˜๋ฅผ ์ฒ˜๋ฆฌํ•˜๊ณ  ํ„ฐ์น˜ ์œ„์น˜์™€ ํ•จ๊ป˜ touchBeganํด๋กœ์ €๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
import UIKit

class MultitouchView: UIView {
    var touchBegan: ((CGPoint) -> Void)?

    override init(frame: CGRect) {
        super.init(frame: frame)
        isMultipleTouchEnabled = true 
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        touches.forEach { touch in
            let location = touch.location(in: self)
            touchBegan?(location)
        }
    }
}
  • ์‚ฌ์šฉ์ž๊ฐ€ ํ™”๋ฉด์„ ํ„ฐ์น˜ํ•  ๋•Œ๋งˆ๋‹ค MultitouchView์˜ touchesBegan(_:with:)๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ , ์ด๋Š” ์ฐจ๋ก€๋กœ touchBeganํด๋กœ์ €๋ฅผ ํ˜ธ์ถœํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ์ด ์ฝ”๋“œ๋ฅผ ํ†ตํ•ด ์—ฌ๋Ÿฌ ํ„ฐ์น˜ ์ด๋ฒคํŠธ๋ฅผ ๋™์‹œ์— ๊ฐ์ง€ํ•˜๊ณ  ์‘๋‹ตํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ•ด๊ฒฐํ–ˆ์Šต๋‹ˆ๋‹ค.

Step 2

ํ„ฐ์น˜ ํšจ๊ณผ์Œ ๊ด€๋ จ ์—๋Ÿฌ
  • SoundSetting ํด๋ž˜์Šค์—์„œ playSound๋ฉ”์„œ๋“œ๋กœ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํšจ๊ณผ์Œ์ด ๋‚˜์˜ค๋Š” ํšจ๊ณผ๋ฅผ ์ฃผ๋ ค๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • playSound ๋ฉ”์„œ๋“œ์—์„œ๋Š” ๋งค๋ฒˆ ์ƒˆ๋กœ์šด `AVAudioPlayer ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑํ•˜๊ณ  ์žˆ์—ˆ๊ณ , ์ด๋Š” ๋น„ํšจ์œจ์ ์ด๋ฉฐ ์„ฑ๋Šฅ ์ €ํ•˜๋ฅผ ์ผ์œผํ‚ค๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
  • ๋˜, playSound ๋ฉ”์„œ๋“œ๊ฐ€ ๋ฉ”์ธ ์Šค๋ ˆ๋“œ์—์„œ ์˜ค๋””์˜ค๋ฅผ ์žฌ์ƒํ•˜์—ฌ ํ™”๋ฉด์ด ๋š๋š ๋Š๊ธฐ๋Š” ๋ฌธ์ œ๊ฐ€ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.
//๋ณ€๊ฒฝ ์ „
class SoundSetting: ObservableObject {
    static let instance = SoundSetting()
    
    var player: AVAudioPlayer?
    
    enum SoundOption: String {
        case mainBGM = "mainBGM"
        case buttonBGM = "buttonBGM"
        case errorBGM = "errorBGM"
    }
    
    func playSound(sound: SoundOption) {
        
        guard let url = Bundle.main.url(forResource: sound.rawValue, withExtension: ".mp3") else { return }
        
        do {
            player = try AVAudioPlayer(contentsOf: url)
            player?.play()
            player?.volume = 1
        } catch {
            print("์žฌ์ƒํ•˜๋Š”๋ฐ ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. \(error.localizedDescription)")
        }
    }
  • ๊ฐ ์‚ฌ์šด๋“œ๋ณ„๋กœ AVAudioPlayer ์ธ์Šคํ„ด์Šค๋ฅผ ์‚ฌ์ „์— ์ƒ์„ฑํ•˜๊ณ  ์ €์žฅํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ SoundSetting ํด๋ž˜์Šค๋ฅผ ์ˆ˜์ •ํ–ˆ์Šต๋‹ˆ๋‹ค.
  • ๋˜ํ•œ, ์˜ค๋””์˜ค ์žฌ์ƒ์„ ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์Šค๋ ˆ๋“œ์—์„œ ์ˆ˜ํ–‰ํ•˜๋„๋ก ๋ณ€๊ฒฝํ–ˆ์Šต๋‹ˆ๋‹ค.
// ์ˆ˜์ • ํ›„
class SoundSetting: ObservableObject {
    static let instance = SoundSetting()
    private var players: [SoundOption: AVAudioPlayer] = [:]

    enum SoundOption: String, CaseIterable {
        case mainBGM = "mainBGM"
        case buttonBGM = "buttomBGM"
        case errorBGM = "errorBGM"
    }

    init() {
        for sound in SoundOption.allCases {
            if let url = Bundle.main.url(forResource: sound.rawValue, withExtension: "mp3") {
                do {
                    let player = try AVAudioPlayer(contentsOf: url)
                    player.prepareToPlay()
                    players[sound] = player
                } catch {
                    print("์˜ค๋””์˜ค ํ”Œ๋ ˆ์ด์–ด ์ดˆ๊ธฐํ™” ์‹คํŒจ: \(error)")
                }
            } else {
                print("์‚ฌ์šด๋“œ ํŒŒ์ผ ๋กœ๋“œ ์‹คํŒจ: \(sound.rawValue).mp3")
            }
        }
    }

    func playSound(sound: SoundOption) {
        DispatchQueue.global().async {
            if let player = self.players[sound], !player.isPlaying {
                player.play()
                player.volume = 0.1
            }
        }
    }
}

About

Team8 - 8

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages