[Swift5] 문제해결 : AVPlayer에서 Temp폴더 내 영상이 재생되지 않는 문제


몇 일전 개발 중 이런 문제가 생긴적이 있었습니다.

영상이 Temp폴더에 저장이 된 상태고, 이 Temp 폴더에 저장된 영상을 사진갤러리로 등록하고,

AVPlayer에 Temp폴더에 저장된 Path를 넣어줬는데도 재생이 되지 않는 문제(아무 반응이 없는 문제)가 있었습니다.

오늘은 이 문제를 어떻게 해결했는지 적어볼까 합니다.


원인

사람마다 조금씩 차이는 있을지도 모르겠는데, 저의 경우 사진갤러리로 영상을 등록하고 Temp성 파일을 삭제하는(ㅡㅡ)문제 였습니다. (사진갤러리로 영상 등록 후 바로 Temp 파일을 삭제하는 로직이 동작하는 문제)

뭐.. 조금만 분석해보면 나오는거긴했는데, 처음엔 AVPlayer에서 에러도 안뱉어내고 무슨문젠지도 모르는상태로 삽질만 죽어라고 했네요.. (AVPlayer에 이상한 Path넣어도 에러 안나오더라구요. 저는 나올줄 알았습니다;;)

혹시라도 영상이 재생이 안된다 싶으시다면 우선 지정된 영상 Path가 제대로 된 Path인지를 확인하시는걸 추천드립니다. 그리고 Path에 해당하는 파일이 있는지를 확인해보시는걸 추천드려요. 보통 exists 함수 사용하면 true/false로 떨어지니..

 

해결

언제나 원인만 알면 해결은 쉽습니다.

저의 경우 일단 임시방편으로 Temp성 파일을 삭제하는 로직을 주석처리 해두었는데요,

해당 부분은 나중에 Directory를 좀 더 세분화해서 어떻게 쓸건지 프로세스 등을 정해놓고 대대적인 공사를 하는걸로 하고 일단은 문제가 없도록 로직의 주석처리로써 해결을 해두었습니다.

 


어쩌다 한번씩 별거아닌거가지고 크게 삽질하는 경우가 있는데, 이번이 그 경우였네요 ㅋㅋㅋㅋㅋㅋㅋ

 

java와 차이가 있다보니 자꾸 헷갈..ㅋㅋㅋ

 

 

버전정보 (v1.0)

 - v1.0 2020.07.21 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] TableView 만들기 (custom cell을 만들어 보기)


저의 경우 아이폰 개발을 하면서 TableView를 많이 사용하게 되었는데, 덕분에 많은 부분 깨닳음(??)이 있었습니다.

오늘은 간단하게(?) TableView를 만들고 입맛에 맞춰 Custom Cell을 만드는 방법을 알아보도록 하겠습니다. 


Storyboard 작업

자, 우선 프로젝트를 생성해주시고, Main.storyboard를 선택합니다.

 

그리고 Component 중 Table View를 화면에 드래그해서 추가해줍니다. 

화면에 Table View Component 추가

 

다음으로 Table View에 보일 Cell(Table View Cell)을 앞서 만든 Table View 내에 추가해줍니다.

Table View에 Table View Cell 추가

 

Table View Cell 내 Content View 내부의 원하시는 Component를 추가해줍니다.

(여기서는 예시로 Image View, Label, Button을 추가했습니다.(왼쪽부터 순서대로))

Table View Cell 내 Content View에 원하시는 Component를 추가합니다.

 

이제 View Controller에 연결된 Class(Source 단)로 이동합니다.

(연결된 Class 정보를 잘 모르시겠다면, 처음 기본적으로 생성된 Controller의 Class는 보통 ViewController.swift입니다. 좌측에서 ViewController.swift 파일을 선택하시거나, 하단의 이미지처럼 ViewController의 Class를 확인 후 이동해 주세요.)

 

여기까지 따라오셨다면, Storyboard에서 초기작업이 끝났습니다.

단, 완벽히 끝난건 아니고, 이후부터는 Class(Source)와 Storyboard(View)를 왔다갔다하시면서 작업을 해야합니다.

 

ViewController Class 작업

처음 생성된 ViewController

 

Table View를 이용하기 위해서는 이동하신 Controller에 Table View를 동작하기 위한 Class를 상속받아야 합니다.

여기서는 Table View의 기능을 처리할 delegate(대리자) - UITableViewDelegate와 Tablew View Cell등을 제어하여 데이터를 처리할 datasource(데이터 소스) - UITableViewDataSource를 상속해줘야 합니다.

(저는 extension(확장)하는 방식으로 진행했습니다.)

 - UITableViewDelegate : Table View에서 Cell을 선택하거나, 어떠한 기능을 처리

 - UITableViewDataSource : Table View에서 Cell을 보여주기 위해 Table View의 Row나 Section은 어떻게 구현을 할것이며, Cell은 어떻게 만들어줄 것인지를 제어

   -> UITableViewDataSource 내에는 필수(Required) 함수들이 있습니다.

   -> func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int

   -> func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell

   -> 위 두 함수가 그것이며, 각각 section내에 몇개의 row가 있는지, 각 index별 cell의 정보를 어떻게 담고 있는지를 알려주기 위한 함수입니다.(하단 그림 참조)

 

ViewController를 extension(확장)하여 UITableViewDataSource, UITableViewDelegate를 상속시켜줍니다.

 

UITableViewCell Class 작업

이제 위에서 선언한 필수 함수 내부에 code를 구현을 해야겠죠!

하지만, 그 전에 우리는 UITableViewCell을 Return해줄 Class의 생성이 필요합니다.

그래서 우선은 code의 구현은 잠시 미루고 Class를 생성해주기로 합시다!

Cocoa Touch Class를 선택한 상태로 Next

Cocoa Touch Class 선택 -> Next

 

Class의 이름을 지어주고, 상속받을 Class를 선택해줍니다.

(편의상 Class의 이름은 CustomCell로 지었으며, Return할 UITableViewCell의 Class를 생성하고 있으니 상속받을 Class는 UITableViewCell을 선택해줍니다. - 하단 이미지 참조)

UITableViewCell을 상속하는 CustomCell을 만들어줍니다.

 

생성된 CustomCell Class.

UITableViewCell을 상속받는 CustomCell의 생성이 완료되었습니다.

 

이제 다시 Main.storyboard로 이동하셔서 Cell과 위에서 만드신 CustomCell을 연결해주는 작업을 합니다.

CustomCell의 Class 연결

그리고 Table View Cell의 Identifier를 지정해줍니다.

(여기서는 편의상 customCell로 지정했습니다.)

Tablew View Cell의 Identifier 지정

 

마지막으로 Main.storyboard와 앞에서 생성한 CustomCell.swift 파일을 나란히 열어두고,

기존에 만든 Component(ImageView, Label, Button)을 CustomCell Class에 선언해줍니다.

선언 방식은 Component를 마우스 우클릭하신 상태로 CustomCell Class(.swift)파일로 옮기시면 됩니다. - 하단 이미지 참조

화살표처럼 Componet를 마우스 우클릭한 상태로 소스단으로 드래그

 

자! 여기까지 오셨다면 Table View에서 Return해줄 Table View Cell Class는 다 만들어준겁니다!

 

ViewController Class 작업

이제 기존에 열어두신 화면 그대로에서 CustomCell Class 쪽만 ViewController Class로 변경해줍니다.

이 후 미리 Main.storyboard에 생성한 Table View를 제어하기 위해 위 Componet 선언한 방식처럼 Class(ViewController.swift)쪽에 선언합니다.(마우스 우클릭 한 상태로 드래그)

Table View를 제어하기위해 ViewController에 선언해줍니다.

 

마지막으로 CustomCell에 보여줄 Data와 code 생성합니다.

(하단 이미지의 소스코드는 게시글 아래쪽으로 더 내려보시면 설명과 함께 다시 정리되어있습니다.)

이제 code를 추가합니다.

 

cellName = String 형식으로, 위에서 정의한 Table View Cell의 Identifier 입니다. 저는 편의상 "customCell"로 지정하였으므로 cellName에는 "customCell" 대입해주고 있습니다.

cellTitle = Array 타입으로, ImageView의 iamge 정보를 나타냅니다. 더불어 Label의 text에 image값을 String 형식으로 넣어주기 위한 변수입니다.

 

viewDidLoad 함수의 [tableView_custom.delegate = self]

 - 기존에 선언해둔 TableView - tableView_custom에 delegate를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDelegate의 정보를 대입합니다.)

viewDidLoad 함수의 [tableView_custom.dataSource = self]

 - 기존에 선언해둔 TableView - tableView_custom에 dataSource를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDataSource의 정보를 대입합니다.)

 

extension ViewController class의 [func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int] 함수

 - 화면에 보여줄 row의 갯수를 나타냅니다. 여기서는 cellTitle.count 이므로 선언된 cellTitle 변수에는 3개의 값이 들어 있으므로 3을 return하게 됩니다.

extionsion ViewController class의 [func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell] 함수

 - 화면에 보여줄 cell을 지정합니다. function내에는 cellName("customCell")의 customCell을 선언했고, 이 customCell에 있는 Component imageView_custom과 label_custom의 정보(이미지, 텍스트)를 변경해주고 있습니다. (즉, Cell 내부 이미지와 텍스트는 짝이 되어 보일겁니다.)

 

완성된 프로젝트 Run

이제 완성된 프로젝트를 실행해 봅시다!

아이폰 11 Simulator


ViewController.swift

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var tableView_custom: UITableView!
    let cellName:String = "customCell"
    let cellTitle : Array<String> = ["pencil.circle", "doc.circle", "bolt.circle"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.

        tableView_custom.delegate = self
        tableView_custom.dataSource = self
    }

}

 

extension ViewController: UITableViewDataSource, UITableViewDelegate {

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return cellTitle.count
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let customCell = tableView_custom.dequeueReusableCell(withIdentifier: cellName, for: indexPath) as! CustomCell

        customCell.imageView_custom.image = UIImage(systemName: cellTitle[indexPath.row])
        customCell.label_custom.text = cellTitle[indexPath.row]

        return customCell
    }
    
}

cellName = String 형식으로, 위에서 정의한 Table View Cell의 Identifier 입니다. 저는 편의상 "customCell"로 지정하였으므로 cellName에는 "customCell" 대입해주고 있습니다.

cellTitle = Array 타입으로, ImageView의 iamge 정보를 나타냅니다. 더불어 Label의 text에 image값을 String 형식으로 넣어주기 위한 변수입니다.

 

viewDidLoad 함수의 [tableView_custom.delegate = self]

 - 기존에 선언해둔 TableView - tableView_custom에 delegate를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDelegate의 정보를 대입합니다.)

viewDidLoad 함수의 [tableView_custom.dataSource = self]

 - 기존에 선언해둔 TableView - tableView_custom에 dataSource를 지정합니다.(self 즉, 소스 하단에 extension(확장)한 UITableViewDataSource의 정보를 대입합니다.)

 

extension ViewController class의 [func tableView(func tableView(UITableView, numberOfRowsInSection: Int) -> Int] 함수

 - 화면에 보여줄 row의 갯수를 나타냅니다. 여기서는 cellTitle.count 이므로 선언된 cellTitle 변수에는 3개의 값이 들어 있으므로 3을 return하게 됩니다.

extionsion ViewController class의 [func tableView(UITableView, cellForRowAt: IndexPath) -> UITableViewCell] 함수

 - 화면에 보여줄 cell을 지정합니다. function내에는 cellName("customCell")의 customCell을 선언했고, 이 customCell에 있는 Component imageView_custom과 label_custom의 정보(이미지, 텍스트)를 변경해주고 있습니다. (즉, Cell 내부 이미지와 텍스트는 짝이 되어 보일겁니다.)

 

 

CustomCell.swift

import UIKit

class CustomCell: UITableViewCell {

    @IBOutlet weak var imageView_custom: UIImageView!
    @IBOutlet weak var label_custom: UILabel!
    @IBOutlet weak var button_custom: UIButton!

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
        
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
        // Configure the view for the selected state
        
    }

}

앞서 마우스 우클릭 드래그를 통해 선언해준 Componet 정보들이 담겨있습니다.

Cell 내부 ImageView -> imageView_custom

Cell 내부 Label -> label_custom

Cell 내부 Button -> button_custom


간단(?)하게 설명만 하려했더니 생각보다 길어져버렸네요;;;

스터디 하는 김에 겸사겸사 하긴했는데.. 내용이 너무 길어져버려서..;;;

혹시 이해안가시면 댓글 작성해주세요. 최대한 다시 설명드리겠습니다 ㅠㅠ

 

 

버전정보 (v1.0)

 - v1.0 2020.07.22 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com


[Swift5] 버튼에 라운드 주기 (버튼 둥글게)


개발을 하다보면 버튼에 간단한 디자인을 입혀야하는 경우가 있습니다.

 

그중 버튼의 꼭짓점부분을 둥글게 해달라는 (라운드처리) 이야기가 간혹 있는데, 이럴때 사용하는 방법입니다.

 

기본 버튼에 라운드를 주는 방법은 쉽습니다.

UIButton.layer.cornerRadius = 8

 

일반적으로 생성한 버튼의 모습

 

아래는 소스입니다.

@IBOutlet weak var btn_info: UIButton!

override func viewDidLoad() {
	super.viewDidLoad()

	//버튼의 라운드 처리
	btn_info.layer.cornerRadius = 8

}

 

UIButton은 UIControl을 상속받으며, UIControl은 UIView를 상속받고 있습니다. (https://developer.apple.com/documentation/uikit/uibutton)

 

Apple Developer Documentation

 

developer.apple.com

특히 상속을 받는 UIView에는 멤버변수로 layer:CALayer를 가지고 있습니다. (https://developer.apple.com/documentation/uikit/uiview)

 

Apple Developer Documentation

 

developer.apple.com

이 layer변수에는 뷰에 그림을 그려줄때 필요한 핵심 애니메이션 정보를 가지고 있는데, 이 layer의 정보를 수정해줌으로 라운드 처리가 가능해지는겁니다.

 

소스를 통해 라운드가 적용된 버튼의 모습

 

위에서 설명한 layer변수를 이용하면 버튼의 색상, 타입지정, 이미지 등록 등 다양한 컨트롤이 가능한데, 이는 본 게시글의 제목의 성격이 달라지므로 다음에 설명하는 시간을 갖도록 하겠습니다.

 

 

버전정보 (v1.0)

 - v1.0 2020.07.02 배포

 

* 저작권에 위반될 수 있는 컨텐츠(이미지, 동영상 등)나 게시글은 삭제되거나 수정될 수 있습니다.

* 문제의 여지가 될 수 있는 컨텐츠의 경우 댓글 달아 주시면 빠른 시일 내에 조치하도록 하겠습니다.

* Karzin은 항상 공부중입니다. 설명이 틀리거나 잘못된 부분이 있다면 의견내주시는대로 수정하도록 하겠습니다.

 

Karzin

abbeea@naver.com

+ Recent posts