WWDC25 μŠ€ν„°λ”” μ—¬μ •: iOS νŒ€μ΄ 배운 것, λ§Œλ“  것, λŠλ‚€ 것

Jimin
  • #iOS
  • #WWDC25
  • #Live Activity
  • #SpeechAnalyzer

λ“€μ–΄κ°€λ©°

μ•ˆλ…•ν•˜μ„Έμš”. 프둬 iOS 개발자 λ°•μ§€λ―Όμž…λ‹ˆλ‹€.

저희 iOS νŒ€μ—μ„œλŠ” λ§€λ…„ WWDCμ—μ„œ μŸμ•„μ§€λŠ” μƒˆλ‘œμš΄ 기술과 λ³€ν™” μ†μ—μ„œ, λ‹¨μˆœν•œ ν•™μŠ΅μ„ λ„˜μ–΄ μ‹€ν—˜ 기반 ν•™μŠ΅μ„ λͺ©ν‘œλ‘œ iOS μŠ€ν„°λ””λ₯Ό μ‹œμž‘ν–ˆμŠ΅λ‹ˆλ‹€.

WWDC 2025의 핡심 μ„Έμ…˜μ„ ν•™μŠ΅ν•˜κ³ , μ‹€μ œ μ„œλΉ„μŠ€μΈ 프둬앱에 적용 κ°€λŠ₯ν•œ 아이디어λ₯Ό 직접 λ§Œλ“€μ–΄λ³΄λŠ” μ—¬μ •μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 이 κΈ€μ—μ„œλŠ” 저희가 μ–΄λ–»κ²Œ μŠ€ν„°λ””λ₯Ό μš΄μ˜ν–ˆκ³ , 무엇을 λ°°μ› μœΌλ©°, 프둬앱에 μ–΄λ–€ κΈ°λŠ₯듀을 μ‹€ν—˜ν–ˆλŠ”μ§€ κ³΅μœ ν•˜κ³ μž ν•©λ‹ˆλ‹€.

μ™œ WWDC25 μŠ€ν„°λ””λ₯Ό μ‹œμž‘ν–ˆλŠ”κ°€?

WWDCλŠ” iOS κ°œλ°œμžμ—κ²Œ κ°€μž₯ 큰 μ΄λ²€νŠΈμž…λ‹ˆλ‹€. 저희 νŒ€μ˜ λͺ©ν‘œλŠ” λͺ…ν™•ν–ˆμŠ΅λ‹ˆλ‹€.

1. WWDC 2025μ—μ„œ λ°œν‘œλœ μ΅œμ‹  iOS 기술과 νŠΈλ Œλ“œλ₯Ό ν•™μŠ΅ν•˜μ—¬ ν”Œλž«νΌμ˜ 변화에 λΉ λ₯΄κ²Œ μ μ‘ν•œλ‹€.

2. ν•™μŠ΅ν•œ λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ 프둬앱에 직접 적용 κ°€λŠ₯ν•œ κΈ°λŠ₯을 νƒμƒ‰ν•œλ‹€.

3. μž‘μ€ ν˜•νƒœλ‘œλΌλ„ 프둬앱에 μ‹€ν—˜ μ μš©ν•΄λ³΄λ©° 우리 μ„œλΉ„μŠ€μ™€ νŒ€μ— λ§žλŠ” 기술 λ„μž… λ°©μ•ˆμ„ κ³ λ―Όν•΄λ³Έλ‹€.

μ €ν¬λŠ” μŠ€ν„°λ”” κΈ°κ°„ 내에 λͺ¨λ“  μ„Έμ…˜μ„ λ§ˆμŠ€ν„°ν•˜λŠ” κ²ƒμ΄λ‚˜, λ‹Ήμž₯ μŠ€ν† μ–΄μ— 배포할 μˆ˜μ€€μ˜ 완성도λ₯Ό λ§Œλ“œλŠ” 것을 λͺ©ν‘œλ‘œ ν•˜μ§€ μ•Šμ•˜μŠ΅λ‹ˆλ‹€. λŒ€μ‹ , μƒˆλ‘œμš΄ κΈ°μˆ μ„ λΉ λ₯΄κ²Œ κ²€μ¦ν•˜κ³  μ„œλΉ„μŠ€ κ΄€μ μ—μ„œ μƒˆλ‘œμš΄ μΈμ‚¬μ΄νŠΈλ₯Ό μ–»λŠ” 것에 μ§‘μ€‘ν–ˆμŠ΅λ‹ˆλ‹€.

μŠ€ν„°λ”” μ§„ν–‰ 방식 & μ„Έμ…˜

저희 iOSνŒ€μ€ μ•„λž˜μ™€ 같이 μŠ€ν„°λ””λ₯Ό μ§„ν–‰ν•˜μ˜€μŠ΅λ‹ˆλ‹€.

1. ν•™μŠ΅: λͺ¨λ“  μ„Έμ…˜μ„ λ‹€ λ³΄λŠ” λŒ€μ‹ , 효율적인 ν•™μŠ΅μ„ μœ„ν•΄ μ½˜ν…μΈ λ₯Ό 두 κ°€μ§€ νŠΈλž™μœΌλ‘œ λ‚˜λˆ„κΈ°

핡심 곡톡 μ„Έμ…˜: νŒ€μ› λͺ¨λ‘κ°€ μ•Œμ•„μ•Ό ν•  iOS ν”Œλž«νΌμ˜ 핡심 λ³€ν™”λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. Platforms State of the Union, What’s new in Swift, SwiftUI, UIKit 등이 여기에 ν•΄λ‹Ήν–ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 νŒ€ 전체가 μ΅œμ‹  기술 동ν–₯에 λŒ€ν•œ κ³΅ν†΅μ˜ 이해 κΈ°λ°˜μ„ λ‹€μ§ˆ 수 μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

κ°œμΈλ³„ 관심 μ„Έμ…˜: 곡톡 μ„Έμ…˜ 외에, 각자 프둬앱에 μ μš©ν•΄λ³΄κ³  μ‹Άκ±°λ‚˜ 개인적으둜 관심 μžˆλŠ” μ„Έμ…˜μ„ 자유둭게 선택해 ν•™μŠ΅ν–ˆμŠ΅λ‹ˆλ‹€.

2. 곡유: ν•™μŠ΅ λ‚΄μš© κ³΅μœ ν•˜κΈ°

μ €ν¬λŠ” ν•™μŠ΅ν•œ λ‚΄μš©μ„ λ™λ£Œλ“€κ³Ό 효과적으둜 κ³΅μœ ν•˜κΈ° μœ„ν•΄ κ°œμΈλ³„ Learning Notesλ₯Ό μž‘μ„±ν–ˆμŠ΅λ‹ˆλ‹€.

각자 μŠ€ν„°λ””ν•œ μ„Έμ…˜μ˜ 링크와 ν•¨κ»˜, κ·Έ λ‚΄μš©μ„ λ°”νƒ•μœΌλ‘œ 슀슀둜 질문 3개λ₯Ό λ§Œλ“€μ–΄ κ³΅μœ ν–ˆμŠ΅λ‹ˆλ‹€.

이 방식을 톡해 μ„Έμ…˜μ˜ 핡심을 더 깊이 κ³ λ―Όν•  수 μžˆμ—ˆκ³ , νŒ€μ›λ“€μ˜ Learning Notesλ₯Ό 보며 μ„œλ‘œ λ‹€λ₯Έ 관점을 ν™•μΈν•˜κ³  μƒˆλ‘œμš΄ μΈμ‚¬μ΄νŠΈλ₯Ό μ–»λŠ” 계기가 λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

3. 적용: ν•™μŠ΅μ„ 결과물둜 λ§Œλ“  λ―Έλ‹ˆ 해컀톀

저희 μŠ€ν„°λ””μ˜ μ΅œμ’… λͺ©ν‘œλŠ” 프둬앱에 μ‹€ν—˜ μ μš©μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό μœ„ν•΄ μŠ€ν„°λ”” ν›„λ°˜λΆ€λŠ” 아이디어λ₯Ό μ‹€μ œ μ½”λ“œλ‘œ κ΅¬ν˜„ν•˜λŠ” 데 μ§‘μ€‘ν–ˆμŠ΅λ‹ˆλ‹€.

κ·Έλ™μ•ˆ ν•™μŠ΅ν•œ λ‚΄μš©μ„ 기반으둜 각자 아이디어λ₯Ό ꡬ상해 λ°œν‘œν–ˆκ³ , νŒ€ 토둠을 거쳐 μ΅œμ’… 주제λ₯Ό μ„ μ •ν–ˆμŠ΅λ‹ˆλ‹€. μ΄μ–΄μ„œ β€˜λ―Έλ‹ˆ 해컀톀’을 μ—΄μ–΄ 프둬앱에 직접 κΈ°λŠ₯을 κ΅¬ν˜„ν•˜κ³ , κ·Έ 결과물을 κ³΅μœ ν•˜λ©° μŠ€ν„°λ””μ˜ 여정을 λ§ˆλ¬΄λ¦¬ν–ˆμŠ΅λ‹ˆλ‹€.

Fromm 앱에 μ μš©ν•΄λ³΄κΈ°!

πŸ’‘ 아이디어 μ„ μ • κΈ°μ€€ ν•΄μ»€ν†€μ—μ„œ κ΅¬ν˜„ν•  아이디어λ₯Ό μ„ μ •ν•˜κΈ° μœ„ν•΄, μ €ν¬λŠ” μ„Έ κ°€μ§€ 핡심 기쀀을 μ μš©ν–ˆμŠ΅λ‹ˆλ‹€.

λ‹¨μˆœνžˆ WWDC25μ—μ„œ 배운 μƒˆλ‘œμš΄ 기술, μŠ€ν„°λ”” κΈ°λ°˜μ„ μ μš©ν•΄λ³΄λŠ” 것을 λ„˜μ–΄, 이 기술이 μ‹€μ œ μ‚¬μš©μžμ˜ λ‹ˆμ¦ˆλ₯Ό ν•΄κ²°ν•  수 μžˆλŠ”μ§€, 그리고 개발자 μž…μž₯μ—μ„œ 고객 λ§Œμ‘±λ„λ₯Ό ν™•μ‹€νžˆ 높일 수 μžˆλŠ”μ§€λ₯Ό μ€‘μ μ μœΌλ‘œ κ²€ν† ν•˜μ—¬ μ΅œμ’… 주제λ₯Ό μ„ μ •ν–ˆμŠ΅λ‹ˆλ‹€.

이 기쀀에 따라 μ„ μ •λœ μ•„μ΄λ””μ–΄λŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

  • SpeechAnalyzer - μŒμ„±λ©”μ‹œμ§€ λ²ˆμ—­ STT(Speech-to-Text)
  • Live Activity - μ•„ν‹°μŠ€νŠΈ 이벀트 μ•Œλ¦Ό

SpeechAnalyzer

프둬 μ„œλΉ„μŠ€μ—λŠ” μ•„ν‹°μŠ€νŠΈκ°€ νŒ¬λ“€μ—κ²Œ μŒμ„± λ©”μ‹œμ§€λ₯Ό λ³΄λ‚΄λŠ” κΈ°λŠ₯이 μžˆμŠ΅λ‹ˆλ‹€. ν•˜μ§€λ§Œ 이 경우, ν•΄μ™Έ νŒ¬λ“€μ€ μ–Έμ–΄μ˜ μž₯벽으둜 인해 μ•„ν‹°μŠ€νŠΈκ°€ ν•˜λŠ” 말을 λ°”λ‘œ μ•Œμ•„λ“£μ§€ λͺ»ν•˜λŠ” λΆˆνŽΈν•¨μ΄ μžˆμ—ˆμŠ΅λ‹ˆλ‹€.

μ €ν¬λŠ” 이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•œ 첫걸음으둜, WWDC25μ—μ„œ μ†Œκ°œλœ SpeechAnalyzerλ₯Ό μ μš©ν•˜μ—¬ μŒμ„± λ©”μ‹œμ§€λ₯Ό ν…μŠ€νŠΈλ‘œ λ³€ν™˜(STT)ν•˜λŠ” μ‹€ν—˜μ„ μ§„ν–‰ν–ˆμŠ΅λ‹ˆλ‹€. 이번 μ‹€ν—˜μ„ 톡해, μΆ”ν›„ 이 ν…μŠ€νŠΈλ₯Ό 기반으둜 λ²ˆμ—­ κΈ°λŠ₯κΉŒμ§€ ν™•μž₯ν•œλ‹€λ©΄, κ·Έλ™μ•ˆ μ†Œν†΅μ— λΆˆνŽΈν•¨μ„ 느꼈던 ν•΄μ™Έ νŒ¬λ“€μ˜ κ²½ν—˜μ„ 크게 κ°œμ„ ν•  수 μžˆμ„ κ²ƒμ΄λΌλŠ” κ°€λŠ₯성을 ν™•μΈν–ˆμŠ΅λ‹ˆλ‹€.

image1


SFSpeechRecognizer: μŒμ„± 인식 μ„œλΉ„μŠ€μ˜ κ°€μš©μ„±μ„ ν™•μΈν•˜κ³  μŒμ„± 인식 ν”„λ‘œμ„ΈμŠ€λ₯Ό μ‹œμž‘ν•˜λŠ”λ° μ‚¬μš©ν•˜λŠ” 개체 SFSpeechRecognitionTask: μŒμ„± 인식 μ§„ν–‰ 상황을 λͺ¨λ‹ˆν„°λ§ν•˜κΈ° μœ„ν•œ μž‘μ—… 개체

λ¨Όμ € SFSpeechRecognizerλ₯Ό ν•œκ΅­μ–΄(ko-KR)둜 μ΄ˆκΈ°ν™”ν•©λ‹ˆλ‹€. transcribeLocalFile ν•¨μˆ˜κ°€ 호좜되면, 파일이 μ‹€μ œλ‘œ μ‘΄μž¬ν•˜κ³  μ§€μ›λ˜λŠ” μ˜€λ””μ˜€ ν˜•μ‹(m4a, mp3 λ“±)인지 λ¨Όμ € 검증을 μ§„ν–‰ν•˜κ³ , μœ νš¨ν•œ νŒŒμΌμž„μ΄ ν™•μΈλ˜λ©΄, SFSpeechURLRecognitionRequestλ₯Ό μƒμ„±ν•˜μ—¬ λ³€ν™˜μ„ μš”μ²­ν•©λ‹ˆλ‹€.

μ΄λ•Œ shouldReportPartialResultsλ₯Ό false둜 μ„€μ •ν–ˆκΈ° λ•Œλ¬Έμ—, λ³€ν™˜ μž‘μ—…μ€ 쀑간 κ²°κ³Ό 없이 μ΅œμ’… ν…μŠ€νŠΈλ§Œ λ°˜ν™˜ν•˜κ²Œ λ©λ‹ˆλ‹€. recognitionTaskλ₯Ό 톡해 λΉ„λ™κΈ°μ μœΌλ‘œ λ³€ν™˜μ΄ μ‹œμž‘λ˜λ©°, μž‘μ—…μ΄ μ„±κ³΅μ μœΌλ‘œ μ™„λ£Œλ˜λ©΄ result.bestTranscription.formattedString을 톡해 κ°€μž₯ μ •ν™•ν•œ ν•œκ΅­μ–΄ ν…μŠ€νŠΈλ₯Ό μΆ”μΆœν•©λ‹ˆλ‹€.

    private let speechRecognizer = SFSpeechRecognizer(locale: Locale(identifier: "ko-KR"))
    private var recognitionTask: SFSpeechRecognitionTask?
    
    private func transcribeLocalFile(at url: URL) {
        guard let speechRecognizer = speechRecognizer else { return }

        // 파일 쑴재 및 μ ‘κ·Ό κ°€λŠ₯μ„± 확인
        guard FileManager.default.fileExists(atPath: url.path) else {
            showTranscriptionResult("μ˜€λ””μ˜€ νŒŒμΌμ„ 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.")
            return
        }

        // μ§€μ›λ˜λŠ” μ˜€λ””μ˜€ ν˜•μ‹ 확인
        let supportedExtensions = ["wav", "m4a", "mp3", "aac", "caf"]
        let fileExtension = url.pathExtension.lowercased()
        guard supportedExtensions.contains(fileExtension) else {
            showTranscriptionResult("μ§€μ›λ˜μ§€ μ•ŠλŠ” μ˜€λ””μ˜€ ν˜•μ‹μž…λ‹ˆλ‹€. (지원 ν˜•μ‹: wav, m4a, mp3, aac, caf)")
            return
        }

        let request = SFSpeechURLRecognitionRequest(url: url)
        request.shouldReportPartialResults = false
        
        recognitionTask = speechRecognizer.recognitionTask(with: request) { [weak self] result, error in
            DispatchQueue.main.async {
                if let result = result {
                    if result.isFinal {
                        let koreanText = result.bestTranscription.formattedString
                        
                        if koreanText.isEmpty {
                            self?.showTranscriptionResult("μŒμ„±μ„ 인식할 수 μ—†μŠ΅λ‹ˆλ‹€.")
                        } else {
                            self?.showTranscriptionResult(koreanText)
                        }
                    }
                }
            }
        }
    }

SpeechAnalyzerλŠ” ν–₯μƒλœ 정확도와 속도λ₯Ό λ³΄μ—¬μ£Όμ—ˆμœΌλ©°, κΈ€λ‘œλ²Œ νŒ¬λ“€μ΄ μŒμ„± λ©”μ‹œμ§€ λ‚΄μš©μ„ 더 μ‰½κ²Œ μ΄ν•΄ν•˜λŠ” 데 큰 도움이 될 κ²ƒμœΌλ‘œ κΈ°λŒ€λ˜μ—ˆμŠ΅λ‹ˆλ‹€.

Live Activity

ν”„λ‘¬μ•±μ—μ„œ μ•„ν‹°μŠ€νŠΈκ°€ νŒ¬λ“€μ„ μœ„ν•œ μƒˆλ‘œμš΄ 이벀트λ₯Ό μƒμ„±ν–ˆμ„ λ•Œ(예: 깜짝 라이브 방솑 예고, μŠ€νŽ˜μ…œ 이벀트 μ‹œμž‘), νŒ¬λ“€μ΄ 이 μ€‘μš”ν•œ μˆœκ°„μ„ λ†“μΉ˜μ§€ μ•Šκ³  μ‹€μ‹œκ°„μœΌλ‘œ ν™•μΈν•˜λŠ” κΈ°λŠ₯이 ν•„μš”ν–ˆμŠ΅λ‹ˆλ‹€.

1) ActivityAttributes μ •μ˜

public struct EventCountdownAttributes: ActivityAttributes {
    public struct ContentState: Codable, Hashable {
        public var remainingTime: TimeInterval
        
        public init(remainingTime: TimeInterval) {
            self.remainingTime = remainingTime
        }
    }
    
    public var eventTitle: String
    public var eventContent: String
    public var eventDate: Date
    public var artiName: String
    public var totalDuration: TimeInterval
    public var startDate: Date
}

κ³ μ • 데이터(Attributes)와 μ‹€μ‹œκ°„ 데이터(ContentState)λ₯Ό λΆ„λ¦¬ν•˜λŠ” 것이 μ€‘μš”!

2) Activity μ‹œμž‘ν•˜κΈ°

func startActivity(
    title: String,
    content: String,
    artiName: String,
    eventDate: Date
) async {
    guard ActivityAuthorizationInfo().areActivitiesEnabled else {
        return
    }
    
    let attributes = EventCountdownAttributes(
        eventTitle: title,
        eventContent: content,
        eventDate: eventDate,
        artiName: artiName
    )
    
    let initialState = EventCountdownAttributes.ContentState(
        remainingTime: eventDate.timeIntervalSinceNow
    )
    
    let activity = try Activity.request(
        attributes: attributes,
        content: ActivityContent(state: initialState, staleDate: nil),
        pushType: nil
    )
}

Activity.request()둜 Live Activity μ‹œμž‘!

3) Activity μ—…λ°μ΄νŠΈν•˜κΈ°

// 1μ΄ˆλ§ˆλ‹€ μžλ™ μ—…λ°μ΄νŠΈ
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { _ in
    Task {
        let remaining = eventDate.timeIntervalSinceNow
        
        let newState = EventCountdownAttributes.ContentState(
            remainingTime: floor(remaining)
        )
        
        await activity.update(
            ActivityContent(state: newState, staleDate: Date())
        )
    }
}

μ‹œκ°„μ„ 초 λ‹¨μœ„λ‘œ ν‘œμ‹œν•˜κΈ° μœ„ν•΄ Timerλ₯Ό μ΄μš©ν•΄ 1초 κ°„κ²©μœΌλ‘œ μ—…λ°μ΄νŠΈ μ§„ν–‰! (μ°Έκ³ : Apple은 배터리 효율 문제λ₯Ό κ³ λ €ν•˜μ—¬ 60초 간격을 ꢌμž₯ν•©λ‹ˆλ‹€.)

image2

μ €ν¬λŠ” Live Activity와 Dynamic Islandλ₯Ό ν™œμš©ν•˜μ—¬, μ•„ν‹°μŠ€νŠΈκ°€ 이벀트λ₯Ό μ‹œμž‘ν•˜λ©΄ νŒ¬λ“€μ˜ μž κΈˆν™”λ©΄μ΄λ‚˜ λ‹€μ΄λ‚˜λ―Ή μ•„μΌλžœλ“œμ— κ΄€λ ¨ 정보가 μ‹€μ‹œκ°„ μ•Œλ¦ΌμœΌλ‘œ λœ¨λ„λ‘ κ΅¬ν˜„ν–ˆμŠ΅λ‹ˆλ‹€. 이λ₯Ό 톡해 νŒ¬λ“€μ€ 이벀트 μ‹œμž‘κΉŒμ§€ 남은 μ‹œκ°„μ„ ν™•μΈν•˜κ±°λ‚˜ λ°”λ‘œ μ•±μœΌλ‘œ μ§„μž…ν•˜λŠ” λ“±, μ•„ν‹°μŠ€νŠΈμ™€ 더 κ°€κΉκ²Œ μ†Œν†΅ν•  수 μžˆλŠ” κ²½ν—˜μ„ μ‹€ν—˜ν•΄ λ³΄μ•˜μŠ΅λ‹ˆλ‹€.

마치며

이번 μŠ€ν„°λ””μ˜ 핡심은 λ‹¨μˆœνžˆ 지식을 μŒ“λŠ” ν•™μŠ΅μ΄ μ•„λ‹Œ, μ‹€ν—˜κ³Ό μ μš©μ΄μ—ˆμŠ΅λ‹ˆλ‹€. μ €ν¬λŠ” State of the UnionλΆ€ν„° Swift의 μƒˆλ‘œμš΄ κΈ°λŠ₯κΉŒμ§€ 핡심적인 λ³€ν™”λ₯Ό ν•¨κ»˜ ν•™μŠ΅ν•˜κ³ , κ³§λ°”λ‘œ β€˜μ΄κ²ƒμ„ 프둬앱에 μ–΄λ–»κ²Œ μ“Έ 수 μžˆμ„κΉŒ?β€˜λΌλŠ” ν˜„μ‹€μ μΈ μ§ˆλ¬Έμ„ λ˜μ‘ŒμŠ΅λ‹ˆλ‹€.

SpeechAnalyzerλ₯Ό μ΄μš©ν•œ μŒμ„± λ©”μ‹œμ§€ λ³€ν™˜, Live Activityλ₯Ό ν™œμš©ν•œ λ§€λ‹ˆμ € μ•Œλ¦Ό κΈ°λŠ₯ 등은 κ·Έ μ§ˆλ¬Έμ— λŒ€ν•œ μ €ν¬μ˜ 첫 번째 λŒ€λ‹΅μ΄μ—ˆμŠ΅λ‹ˆλ‹€. 비둝 짧은 해컀톀을 ν†΅ν•œ μ‹€ν—˜μ μΈ μ μš©μ΄μ—ˆμ§€λ§Œ, 이 과정을 톡해 νŒ€ 전원이 μ΅œμ‹  κΈ°μˆ μ— λŒ€ν•œ κ³΅ν†΅μ˜ 이해λ₯Ό λ‹€μ§€κ³ , μ„œλΉ„μŠ€ κ΄€μ μ˜ μƒˆλ‘œμš΄ μΈμ‚¬μ΄νŠΈλ₯Ό μ–»λŠ” κ°’μ§„ μ„±κ³Όλ₯Ό κ±°λ‘μ—ˆμŠ΅λ‹ˆλ‹€.

무엇보닀 이번 μŠ€ν„°λ””λŠ” μ €ν¬μ—κ²Œ κΈ°μˆ μ„ ν•¨κ»˜ νƒκ΅¬ν•˜λŠ” μž¬λ―Έμ™€ 단기간에 μž‘μ€ μ„±κ³Όλ₯Ό λ§Œλ“€μ–΄λ³΄λŠ” 성취감을 μ•ˆκ²¨μ£Όμ—ˆμŠ΅λ‹ˆλ‹€. 프둬앱 μ‚¬μš©μžλ“€μ—κ²Œ 더 κ°€μΉ˜ μžˆλŠ” κΈ°λŠ₯을 μ œκ³΅ν•˜κΈ° μœ„ν•΄ 저희 iOS νŒ€μ€ μ•žμœΌλ‘œλ„ κ³„μ†ν•΄μ„œ μ‹€ν—˜ν•˜κ³  λ„μ „ν•˜κ² μŠ΅λ‹ˆλ‹€.

κ°μ‚¬ν•©λ‹ˆλ‹€!

← λͺ©λ‘μœΌλ‘œ λŒμ•„κ°€κΈ°

Art Changes Life

λ…Έλ¨ΈμŠ€μ™€ ν•¨κ»˜ μ—”ν„°ν…Œν¬ 산업을 ν˜μ‹ ν•΄λ‚˜κ°ˆ 멀버λ₯Ό μ°ΎμŠ΅λ‹ˆλ‹€.

μ±„μš© 쀑인 곡고 보기