본문 바로가기

iOS 프로그래밍

iOS 프로그래밍_11주차

 

Xcode에서 삭제시, Move to Trash로 삭제하기

 

identity inspector에서 class 연결하기

 

Alt + 클릭  : optional string 형 확인

 

 

import UIKit
import AVKit

class VideoViewController: UIViewController {

    @IBAction func playVideo(_ sender: UIButton) {
        let videoPath : String? = Bundle.main.path(forResource: "APT", ofType: "mp4")
        let videoURL = URL(filePath: videoPath!)
        let player = AVPlayer(url: videoURL)
        let playerController = AVPlayerViewController()
        playerController.player = player
        present(playerController, animated: true)
        player.play()
    }

이 소스의 문제점

 

1. 강제 언래핑

guard let videoPath = Bundle.main.path(forResource: "APT", ofType: "mp4") else{
    return
}

→ 해결) 옵셔널 대신 guard let 사용

 

2. URL 초기화 방식

 

3. 비디오 재생 시점

해결) 

Enter키 누름 ↓

4. 에러 처리 부족

 

present 함수란?

present 함수는 iOS 앱에서 한 뷰 컨트롤러를 다른 뷰 컨트롤러 위에 모달 방식으로 표시하는 데 사용하는 메소드입니다. 이 메소드는 UIViewController 클래스의 인스턴스에서 호출됩니다. 

 

1. 기본 정의 

func present(_ viewControllerToPresent: UIViewController, animated flag: Bool, completion: (() -> Void)?)


2. 매개변수 설명
viewControllerToPresent: 표시할 뷰 컨트롤러의 인스턴스입니다. 이 뷰 컨트롤러가 현재 뷰 컨트롤러 위에 모달로 표시됩니다.

animated: 뷰 컨트롤러가 나타나는 애니메이션을 적용할지 여부를 결정하는 부울 값입니다. true로 설정하면 애니메이션 효과가 적용되고, false로 설정하면 즉시 표시됩니다.

completion: 모달 뷰 컨트롤러가 화면에 완전히 표시된 후 호출될 클로저입니다. 이 클로저는 선택사항이며, 추가적인 작업을 수행하고 싶을 때 사용할 수 있습니다.

 

3. 사용 예시

let secondViewController = SecondViewController()
present(secondViewController, animated: true) {
    print("SecondViewController가 표시되었습니다.")
}

 

4. 동작 방식
모달 표시: present 메소드를 호출하면, 지정한 뷰 컨트롤러가 현재 뷰 컨트롤러 위에 모달로 표시됩니다. 모달 방식은 일반적으로 전체 화면 또는 반쯤 표시되는 형식으로 나타납니다.

종료: 모달로 표시된 뷰 컨트롤러는 dismiss 메소드를 통해 종료할 수 있습니다. dismiss는 현재 뷰 컨트롤러를 닫고, 이전 뷰 컨트롤러로 돌아갑니다.

5. 애니메이션
animated 매개변수를 true로 설정하면, 뷰 컨트롤러가 부드럽게 나타나고 사라지는 애니메이션 효과를 볼 수 있습니다. 기본적으로 iOS는 이 애니메이션을 제공합니다.


6. 예외 상황
모달 뷰 컨트롤러는 일반적으로 한 번에 하나만 표시할 수 있습니다. 이미 모달 뷰 컨트롤러가 표시되고 있을 때 또 다른 모달 뷰 컨트롤러를 표시하려고 하면, 충돌이 발생할 수 있습니다.


7. 참고 사항
모달 방식 vs. 네비게이션 방식: present 메소드는 모달 방식으로 뷰를 표시하는 데 사용되며, 이는 사용자 흐름을 변경할 때 유용합니다. 반면, 네비게이션 컨트롤러는 스택 기반의 흐름을 관리하는 데 사용됩니다.

 

present 함수

// <세개 소스의 차이점>
present(playerViewController, animated: true)
player.play()
self.present(playerViewController, animated: true)
player.play()
self.present(playerViewController, animated: true) {
player.play()
} //후행 클로저(trailing closure)

 

# 첫번째 소스

동작 방식: playerViewController를 모달로 표시한 후, 즉시 player.play()를 호출합니다.
문제점: present 메소드는 비동기적으로 동작합니다. 즉, playerViewController가 화면에 표시되기 전에 player.play()가 호출될 수 있습니다. 이 경우, 플레이어가 화면에 표시되지 않은 상태에서 비디오가 재생될 수 있습니다. 사용자 경험에 혼란을 줄 수 있습니다.

 

# 두번째 소스

동작 방식: 첫 번째 코드와 동일합니다. self를 명시적으로 사용했지만, 실제 동작에는 변화가 없습니다.
문제점: 여전히 present가 완료되기 전에 player.play()가 호출되므로, 비디오가 화면에 나타나기 전에 재생될 수 있습니다.

 

# 세번째 소스

동작 방식: present 메소드의 후행 클로저를 사용하여 player.play()를 호출합니다. 이 클로저는 playerViewController가 화면에 완전히 표시된 후에 실행됩니다.
장점: player.play()가 playerViewController가 화면에 표시된 후에 호출되므로, 비디오가 사용자에게 보이는 상태에서 재생됩니다. 사용자 경험이 향상됩니다.


# 요약
첫 번째 및 두 번째 코드: 두 코드는 동일하게 동작하며, present가 완료되기 전에 player.play()가 호출될 수 있어 비디오가 화면에 표시되지 않은 상태에서 재생될 수 있습니다.
세 번째 코드: 후행 클로저를 사용하여 player.play()를 호출하면, 비디오가 playerViewController가 화면에 표시된 후에 재생됩니다. 이는 사용자에게 더 나은 경험을 제공합니다.
결론적으로, 비디오 플레이어와 같은 UI 요소를 다룰 때는 후행 클로저를 사용하여 뷰가 화면에 표시된 후에 비디오 재생을 시작하는 것이 좋습니다.

 

 

//
//  WebViewController.swift
//  BMI_kej
//
//  Created by 소프트웨어컴퓨터 on 2024/11/27.
//

import UIKit
import WebKit


class WebViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    
    @IBAction func goNaver(_ sender: UIButton) {
        guard let url = URL(string: "https://m.naver.com") else { return }
        let request = URLRequest(url: url)
        webView.load(request)
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        guard let url = URL(string: "https://m.youtube.com") else { return }
        let request = URLRequest(url: url)
        webView.load(request)
        

        // Do any additional setup after loading the view.
    }
    


}

 

리팩토링 하기 

import UIKit
import WebKit

class WebViewController: UIViewController {
    @IBOutlet weak var webView: WKWebView!
    
    // 상수 정의
    private let naverURLString = "https://m.naver.com"
    private let youtubeURLString = "https://m.youtube.com"
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadWebPage(urlString: youtubeURLString) // 초기 로드할 웹 페이지
    }

    @IBAction func goNaver(_ sender: UIButton) {
        loadWebPage(urlString: naverURLString) // 네이버 웹 페이지 로드
    }
    
    // 웹 페이지 로드 메소드
    private func loadWebPage(urlString: String) {
        guard let url = URL(string: urlString) else { 
            print("유효하지 않은 URL: \(urlString)")
            return 
        }
        let request = URLRequest(url: url)
        webView.load(request)
    }
}

 

문서화된 소스

//
//  WebViewController.swift
//  BMI_kej
//
//  Created by 소프트웨어컴퓨터 on 2024/11/27.
//

import UIKit
import WebKit

/// WebViewController는 웹 페이지를 로드하고 표시하는 UIViewController입니다.
class WebViewController: UIViewController {
    
    // MARK: - IBOutlet
    
    /// WKWebView 인스턴스, 웹 페이지를 표시하는 뷰입니다.
    @IBOutlet weak var webView: WKWebView!
    
    // MARK: - Actions
    
    /// 네이버 웹 페이지로 이동하기 위한 버튼 클릭 액션입니다.
    /// - Parameter sender: 버튼의 인스턴스
    @IBAction func goNaver(_ sender: UIButton) {
        // 네이버 웹 페이지의 URL을 생성합니다.
        guard let url = URL(string: "https://m.naver.com") else { return }
        // URLRequest를 생성합니다.
        let request = URLRequest(url: url)
        // 웹 뷰에서 요청을 로드합니다.
        webView.load(request)
    }

    // MARK: - Lifecycle
    
    /// 뷰가 메모리에 로드될 때 호출됩니다.
    override func viewDidLoad() {
        super.viewDidLoad()
        // 유튜브 웹 페이지의 URL을 생성합니다.
        guard let url = URL(string: "https://m.youtube.com") else { return }
        // URLRequest를 생성합니다.
        let request = URLRequest(url: url)
        // 웹 뷰에서 요청을 로드합니다.
        webView.load(request)
        
        // 추가적인 설정을 여기에 구현할 수 있습니다.
    }
}

'iOS 프로그래밍' 카테고리의 다른 글

[25.05.14_11주차] iOS 프로그래밍 실무  (0) 2025.05.14
iOS 프로그래밍_13주차  (0) 2024.12.11
iOS 프로그래밍_10주차  (0) 2024.11.20
iOS 프로그래밍_9주차  (0) 2024.11.13
iOS 프로그래밍_8주차  (0) 2024.11.06