728x90
반응형

iOS 8 이상의 앱에서는 UIWebView 사용보단


WKWebView를 사용하라고 문서에 나와있습니다.






장단점이 있겠지만 WKWebView를 사용하는 방법을 정리 하려고 합니다.


기존과 비슷하게 Storyboard의 Library 에서 WebKit View 로 구성하면 됩니다.







    import WebKit
cs


Swift 에서는 위와 같이 import작업이 필요합니다.


Storyboard의 WebKit View를 @IBOutLet 변수로 정의 합니다.



    let url = URL(string: "URL주소")
    let request = URLRequest(url: url)
    webView.load(request)
cs


URL에 원하는 URL주소를 넣고 URLRequest로 변환해준다음


webView.load() 함수를 사용하면 끝입니다.


정말 간단하게 웹뷰를 활용한 앱을 만들수 있습니다.


728x90
반응형
728x90
반응형


테이블 뷰 메모이제이션(memoization) 도 문제점이 있습니다.


데이터가 수십건, 수백건 이라면 화면 로딩이 지연(Blocking) 되는 문제가 생깁니다.






목록을 보여주는 앱이라면 첫 화면부터 대량의 정보를 보여줘야 하기때문에


처음 실행한 부분부터 화면이 보이지 않는다면 오류인줄 알고 앱을 종료해버리고 말것입니다.


거기에 텍스트보다 용량이 높은 이미지를 메모리에 저장까지 해야 하는 부담도 있습니다.






이를 해결하기위해 iOS에서 제공하는 법용 비동기 함수를 이용하는 것입니다.


DispathchQueue.main.async() 라는 비동기 실행 함수를 Swift에서 제공하고 있기 때문에 


내부적으로 스레드에 직접 접근없이 비동기 처리를 할 수 있도록 지원합니다.






이 함수는 블록(Block) 과 GCD(Global Centeral Dispath) 를 이용하여 글로벌 범위에서 사용할 수 있고,


GCD는 애플의 기술로서 병렬처리와 스레드 풀의 기반인 비동기 방식을 구현함으로


멀티코어 프로세서에 적합한 앱을 개발할 수 있도록 지원합니다.







    // 이미지 객체가 존재하면 리턴, 존재하지 않으면 새로 내려받아 저장 후 리턴
    func getImage(_ index: Int-> UIImage {
        
        let model = list[index]
        
        if let imageData = model.imageData {
            return imageData
        } else {
            let url: URL! = URL(string: model.imageUrl!)
            let data = try! Data(contentsOf: url)
            model.imageData = UIImage(data: data)
            return model.imageData!
        }
    }
cs


override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
 
    // 비동기 처리    
    DispatchQueue.main.async {
        cell.imgView.image = self.getImage(indexPath.row)
    }
 
    return cell
}
 
cs



이전 메모이제이션 기법과 비동기 처리를 하여 로딩 지연을 방지하도록 수정하였습니다,


이로써 지연에 대한 고민도 해결하고 부드러운 UI를 유지할 수 있습니다.


728x90
반응형

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

Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
Swift 4 WKWebView  (0) 2019.02.20
Swift 4 TableView 이미지 메모이제이션 기법  (0) 2019.02.20
Swift 4 TableView 동적 높이 설정  (0) 2019.02.19
728x90
반응형

IOS 개발을 하면서 테이블 뷰를 정말 많이 사용합니다.


애플도 문자 목록, 메일, 통화 목록 등 집합 데이터를 표현하는 필수 뷰이기 때문입니다.






AOS의 리사이클러 뷰 와 iOS 테이블 뷰는 동일한 구조입니다.


재사용 매커니즘(Reuse Mechanism) 원리를 통해 동작 한다는 것입니다.


데이터가 30가 있어도 화면에 보여질 셀 만큼만 만들어 지기 때문에 7개만 셀이 생성될 수도 있고 5개만 생성될 수도 있습니다.


스크롤 할때 마다 보여지지 않는 셀을 가져오거나 새로 생성해서 다시 데이터를 보여주는 방식이기 때문입니다.






인스타그램 처럼 레이아웃을 만들어보고 싶어서 API Server 만들고


네트워크 통신을 해서 이미지를 불러오는 방식을 쓰려고 url을 그대로 사용하는데. 


tableView(_:cellForRowAt:) 함수에서 매번 url 이미지 정보를 


네트워크 통신으로 가져온다면 스크롤 할 때마다 네트워크 통신을 하는것과 같습니다.






메모이제이션(memoization) 기법


네트워크 통신을 통해 읽은 데이터는 재사용할 수 있도록 캐싱(Caching) 처리하여 네트워크 통신 횟수를 줄이는 것이 좋습니다.



import UIKit
 
 
class Model {
 
   ...
 
   var imageData: UIImage?    
   
   ...
 
}
cs

UIImage 객체를 담을 변수를 Model에 선언해 줍니다.




    // 웹 이미지를 읽어와 UIImage 객체로 생성
    let url: URL! = URL(string: model.imageUrl!)
    let imageData = try! Data(contentsOf: url)
    model.imageData = UIImage(data: imageData)
cs

네트워크 통신을 최초로 하는 처리 메소드에서 


이미지 url을 UIImage 객체화 해서 Model에 넣어줍니다.




override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    ...
 
    // 매번 이미지를 웹으로 읽는 방식
    // let url = URL(string: row.imageUrl!)!
    // let data = try! Data(contentsOf: url)
    // cell.imgView.image = UIImage(data: data) // 이미지 캐싱
 
    // 이미지 객체를 대입 메모이제이션 (memoization) 기업
    cell.imgView.image = row.imageData
 
    return cell
}
cs

REST 통신을 통해 가져온 데이터를 객체로 받은 url로 네트워크 통신하는게 아닌


이미지 객체화 하여 변수에 담아 스크롤 할때 매번 통신을 방지하는 기법입니다.


이렇게 객체에 저장한다면 테이블 뷰의 셀을 재사용 하더라도 매번 네트워크 통신을 하지 않아 스크롤이 부드러운 UI를 유지할 수 있습니다.







728x90
반응형

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

Swift 4 TextView PlaceHolder  (0) 2019.02.21
Swift 4 WKWebView 로딩(Indicator)  (0) 2019.02.20
Swift 4 WKWebView  (0) 2019.02.20
Swift 4 TableView 이미지 비동기 처리  (0) 2019.02.20
Swift 4 TableView 동적 높이 설정  (0) 2019.02.19
728x90
반응형

테이블 뷰를 사용할때 고정된 정적 높이가 아닌 동적 높이로 구현하고 싶을때가 있습니다.


카카오톡의 장문 내용처럼 개행을 했을때 일정하게 늘어나야 하지만


조금씩 뒤틀립니다.






기존에는 아래와 같은 방식으로 대략 높이를 맞추었습니다.


 
    // 높이 설정
    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        let row = list[indexPath.row]
 
        // Default 50 + 글이 30자를 넘어갈 때마다 20만큼 높이를 증가
        let height = CGFloat(50 + (row.count / 30* 20)
        return height
    }
cs







하지만 IOS 8.0 버전 부터 동적으로 셀 높이를 정하는 방식을 도입했습니다.


이전과 달리 높이에 신경쓰지도 않고 깔끔하게 콘텐츠 높이가 조절됩니다.


이를 셀프 사이징 셀(Self-Sizing Cell) 방식이라고 합니다.







    tableView.estimatedRowHeight = 50
    tableView.rowHeight = UITableView.automaticDimension
cs



셀프 사이징 셀을 사용하려면 위의 2가지를 이해하면 됩니다.





1. extimatedRowHeight


임시 셀의 높이를 정할때 사용합니다.


셀 높이가 결정되기 전의 높이를 정해주면 됩니다.





2. UITableView.automaticDimension


테이블 뷰의 rowheight 속성에 대입되어 동적 높이가 설정되는 것을 테이블 뷰에 알려줍니다.


테이블 뷰의 rowHeight 속성이 UITableView.automaticDimension으로 설정되면


목록이 모두 만들어지고 레아아웃을 계산한다음 셀의 높이값을 재설정 합니다.








위와 같이 속성을 정하면 더 이상 직접 높이값을 처리 할 필요가 없습니다.


728x90
반응형

+ Recent posts