네트워크

Similar documents
Microsoft PowerPoint - 04-UDP Programming.ppt

Analytics > Log & Crash Search > Unity ios SDK [Deprecated] Log & Crash Unity ios SDK. TOAST SDK. Log & Crash Unity SDK Log & Crash Search. Log & Cras

iOS4_13

API STORE 키발급및 API 사용가이드 Document Information 문서명 : API STORE 언어별 Client 사용가이드작성자 : 작성일 : 업무영역 : 버전 : 1 st Draft. 서브시스템 : 문서번호 : 단계 : Docum

Microsoft PowerPoint - Supplement-03-TCP Programming.ppt [호환 모드]

어댑터뷰


Microsoft PowerPoint - ch09 - 연결형리스트, Stack, Queue와 응용 pm0100

Microsoft PowerPoint - 03-TCP Programming.ppt

Microsoft PowerPoint 웹 연동 기술.pptx

자바-11장N'1-502

PowerPoint Presentation

<4D F736F F F696E74202D20C1A63235C0E520B3D7C6AEBFF6C5A920C7C1B7CEB1D7B7A1B9D628B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

JAVA 프로그래밍실습 실습 1) 실습목표 - 메소드개념이해하기 - 매개변수이해하기 - 새메소드만들기 - Math 클래스의기존메소드이용하기 ( ) 문제 - 직사각형모양의땅이있다. 이땅의둘레, 면적과대각

PowerPoint Presentation

PowerPoint Template

JAVA PROGRAMMING 실습 08.다형성

쉽게 풀어쓴 C 프로그래밊

제11장 프로세스와 쓰레드

2) 활동하기 활동개요 활동과정 [ 예제 10-1]main.xml 1 <LinearLayout xmlns:android=" 2 xmlns:tools="

- 목차 - - ios 개발환경및유의사항. - 플랫폼 ios Project. - Native Controller와플랫폼화면연동. - 플랫폼 Web(js)-Native 간데이터공유. - 플랫폼확장 WN Interface 함수개발. - Network Manager clas

PowerPoint Presentation

rmi_박준용_final.PDF

Design Issues

Secure Programming Lecture1 : Introduction

PowerPoint 프레젠테이션

Cluster management software

PowerPoint Presentation

게시판 스팸 실시간 차단 시스템

05-06( )_¾ÆÀÌÆù_ÃÖÁ¾

PowerPoint 프레젠테이션

<4D F736F F F696E74202D20C1A63038C0E520C5ACB7A1BDBABFCD20B0B4C3BC4928B0ADC0C729205BC8A3C8AF20B8F0B5E55D>

안드로이드기본 11 차시어댑터뷰 1 학습목표 어댑터뷰가무엇인지알수있다. 리스트뷰와스피너를사용하여데이터를출력할수있다. 2 확인해볼까? 3 어댑터뷰 1) 학습하기 어댑터뷰 - 1 -

JAVA PROGRAMMING 실습 09. 예외처리

Network Programming

Network seminar.key

다른 JSP 페이지호출 forward() 메서드 - 하나의 JSP 페이지실행이끝나고다른 JSP 페이지를호출할때사용한다. 예 ) <% RequestDispatcher dispatcher = request.getrequestdispatcher(" 실행할페이지.jsp");

슬라이드 1

목차 BUG offline replicator 에서유효하지않은로그를읽을경우비정상종료할수있다... 3 BUG 각 partition 이서로다른 tablespace 를가지고, column type 이 CLOB 이며, 해당 table 을 truncate

chap 5: Trees

JUNIT 실습및발표

목차 INDEX JSON? - JSON 개요 - JSONObject - JSONArray 서울시공공데이터 API 살펴보기 - 요청인자살펴보기 - Result Code - 출력값 HttpClient - HttpHelper 클래스작성 - JSONParser 클래스작성 공공

gnu-lee-oop-kor-lec06-3-chap7

Microsoft PowerPoint - java1-lab5-ImageProcessorTestOOP.pptx

<4D F736F F F696E74202D E20B3D7C6AEBFF6C5A920C7C1B7CEB1D7B7A1B9D62E >

17장 클래스와 메소드

q 이장에서다룰내용 1 객체지향프로그래밍의이해 2 객체지향언어 : 자바 2

PowerPoint Presentation

교육자료

9 차시고급위젯다루기 1 학습목표 날짜 / 시간과관련된위젯을배운다. 웹뷰를사용하여간단한웹브라우저기능을구현한다. 매니패스트파일의설정법을배운다. 2 확인해볼까? 3 날짜 / 시간위젯 1) 활동하기 활동개요

Eclipse 와 Firefox 를이용한 Javascript 개발 발표자 : 문경대 11 년 10 월 26 일수요일

mytalk

Microsoft PowerPoint 자바-기본문법(Ch2).pptx

I T C o t e n s P r o v i d e r h t t p : / / w w w. h a n b i t b o o k. c o. k r

캐빈의iOS프로그램팁01

hd1300_k_v1r2_Final_.PDF

PowerPoint Presentation

The Pocket Guide to TCP/IP Sockets: C Version

02 C h a p t e r Java

ibmdw_rest_v1.0.ppt

학습목차 2.1 다차원배열이란 차원배열의주소와값의참조

Modern Javascript

<C0CCBCBCBFB52DC1A4B4EBBFF82DBCAEBBE7B3EDB9AE2D D382E687770>

0. 들어가기 전

12-file.key

쉽게 풀어쓴 C 프로그래밍

PowerPoint Presentation

untitled

Interstage5 SOAP서비스 설정 가이드

3ÆÄÆ®-11

PowerPoint Presentation

PowerPoint 프레젠테이션

2ndWeek_Introduction to iPhone OS.key

[ 그림 8-1] XML 을이용한옵션메뉴설정방법 <menu> <item 항목ID" android:title=" 항목제목 "/> </menu> public boolean oncreateoptionsmenu(menu menu) { getme

목차 BUG DEQUEUE 의 WAIT TIME 이 1 초미만인경우, 설정한시간만큼대기하지않는문제가있습니다... 3 BUG [qp-select-pvo] group by 표현식에있는컬럼을참조하는집합연산이존재하지않으면결괏값오류가발생할수있습니다... 4

PowerPoint Presentation

매력적인 맥/iOS 개발 환경 그림 A-1 변경 사항 확인창 Validate Setting... 항목을 고르면 된다. 프로젝트 편집기를 선택했을 때 화면 아 래쪽에 있는 동일한 Validate Settings... 버튼을 클릭해도 된다. 이슈 내비게이터 목록에서 변경할

오늘날의 기업들은 24시간 365일 멈추지 않고 돌아간다. 그리고 이러한 기업들을 위해서 업무와 관련 된 중요한 문서들은 언제 어디서라도 항상 접근하여 활용이 가능해야 한다. 끊임없이 변화하는 기업들 의 경쟁 속에서 기업내의 중요 문서의 효율적인 관리와 활용 방안은 이

PowerPoint 프레젠테이션

The Pocket Guide to TCP/IP Sockets: C Version

The Pocket Guide to TCP/IP Sockets: C Version

Spring Boot/JDBC JdbcTemplate/CRUD 예제

Microsoft PowerPoint - 11주차_Android_GoogleMap.ppt [호환 모드]

제8장 자바 GUI 프로그래밍 II


Microsoft PowerPoint - web-part03-ch20-XMLHttpRequest기본.pptx

PowerPoint 프레젠테이션

Mobile Service > IAP > Android SDK [ ] IAP SDK TOAST SDK. IAP SDK. Android Studio IDE Android SDK Version (API Level 10). Name Reference V

신림프로그래머_클린코드.key

Microsoft PowerPoint - web-part03-ch19-node.js기본.pptx

슬라이드 1

(8) getpi() 함수는정적함수이므로 main() 에서호출할수있다. (9) class Circle private double radius; static final double PI= ; // PI 이름으로 로초기화된정적상수 public

[ 마이크로프로세서 1] 2 주차 3 차시. 포인터와구조체 2 주차 3 차시포인터와구조체 학습목표 1. C 언어에서가장어려운포인터와구조체를설명할수있다. 2. Call By Value 와 Call By Reference 를구분할수있다. 학습내용 1 : 함수 (Functi

untitled

PowerPoint Presentation

Microsoft PowerPoint - Java7.pptx

PowerPoint 프레젠테이션

서현수

Remote UI Guide

adfasdfasfdasfasfadf

Transcription:

네트워크

네트워크통신의종류 v 애플리케이션과서버간의네트워크통신을하는방법으로는직접소켓을만들어서통신을하는 Low-Level 통신이있고 HTTP, HTTPS 등의프로토콜을이용하는 High-Level 통신이있음 v Low-Level 통신은성능은우수하지만구현이어려워서메신저나화상통화, RPG 게임등트래픽이많은분야에사용되고 High-Level 통신은 Low-Level 통신과반대되는특징을가짐 v Low Level 통신은다시 TCP 통신과 UDP 통신으로분류 v High-Level 통신의가장대표적인서비스가 HTTP/HTTPS 프로토콜을사용하는 Web Service v Web Service 는다시아키텍쳐구조에따라 SOAP 와 RESTful 방식으로나누고데이터종류에따라서 XML 과 JSON 방식으로구분하기도함 v SOAP(Simple Object Access Protocol) 는일반적으로널리알려진 HTTP, HTTPS, SMTP 등의프로토콜을통해양쪽에서 XML 형태의메시지를주고받을수있도록구현된방식으로원격프로시저호출 (Remote Procedure Call) 이라고불리우는방식을이용하며통신구조는 Envelop/Header/Body 세가지영역으로구분 ü ü ü Header 에는메타정보를저장하고데이터는 Body 영역에저장 SOAP 방식의장점은프록시나방화벽없이쉽게통신할수있고 HTTP 이외의프로토콜을이용할수있으며플랫폼독립적이고프로그래밍언어에종속되지않으며간단하고확장이용이 단점은메시지가커지면느려짐

네트워크통신의종류 v RESTful(REpresentational State Transfer) 서비스는분산하이퍼미디어시스템을위한소프트웨어아키텍쳐의한형식으로네트워크자원을정의하고자원에대한주소를관리하는방식으로별도의전송프로토콜없이전송하기위해만들어진간단한형식의인터페이스 v 데이터를요청하는 URI 를네트워크를통해서버에전달하면서버에서는그에맞는응답데이터를전송 v 서버에데이터를요청하는정보의타입은쓰기, 읽기, 수정, 삭제의 4 가지로구분하고이 4 가지를합쳐서 CRUD(Create, Read, Update, Delete) 라고부르는데이 4 가지요청을메소드방식을이용해서구분 v 전송방식 ü ü ü ü ü ü GET: 특정리소스의요청 POST: 리소스를생성및수정 PUT: 리소스를생성및수정 DELETE: 리소스를삭제 HEAD: GET 방식의요청이지만메타정보만요청하고자하는경우 OPTIONS: 특정 URL 에대한보조메소드역할

소켓통신 v TCP Socket Server : TCPServer.Java import java.io.bufferedreader; import java.io.ioexception; import java.io.inputstreamreader; import java.io.nslogwriter; import java.net.serversocket; import java.net.socket; public class TCPServer { public static void main(string[] args) { ServerSocket ss = null; Socket sock = null; try { ss = new ServerSocket(9999); System.out.NSLogln(" 서버대기중..."); while (true) { sock = ss.accept(); System.out.NSLogln(" 접속자정보 : " + sock.tostring()); BufferedReader in = new BufferedReader(new InputStreamReader(sock.getInputStream())); String str = in.readline(); System.out.NSLogln(" 전송된내용 : " + str); NSLogWriter pw = new NSLogWriter(sock.getOutputStream()); pw.nslogln(" 서버가보내는메시지 "); pw.flush();

소켓통신 v TCP Socket Server : TCPServer.Java in.close(); pw.close(); sock.close(); catch (IOException e) { System.out.NSLogln(" 해당포트사용중!!!"); try { ss.close(); catch (Exception ex) {

소켓통신 v ios App 프로젝트생성 v 다운로드받은소켓관련파일들을추가 : https://github.com/swiftsocket/swiftsocket v 화면디자인 TextField, Button, TextView v TextField 에는 tfmsg, TextView에는 textview 라는변수를연결 v Button에는 touchupinside 이벤트에 send 라는메소드를연결 v ViewController.swift 파일에인스턴스변수선언 let host = "192.168.1.95" let port = 9999 var client: TCPClient? v ViewController.swift 파일의 viewdidload 메소드에연결코드작성 override func viewdidload() { super.viewdidload() client = TCPClient(address: host, port: Int32(port))

소켓통신 v ViewController.swift 파일에사용자정의메소드작성 private func sendrequest(string: String, using client: TCPClient) -> String? { appendtotextfield(string: "Sending data... ") switch client.send(string: string) { case.success: return readresponse(from: client) case.failure(let error): appendtotextfield(string: String(describing: error)) return nil

소켓통신 v ViewController.swift 파일에사용자정의메소드작성 private func readresponse(from client: TCPClient) -> String? { sleep(3) guard let response = client.read(1024*10) else { return nil return String(bytes: response, encoding:.utf8) private func appendtotextfield(string: String) { NSLog(string) textview.text = textview.text.appending("\n\(string)")

소켓통신 v ViewController.swift 파일에 send 메소드작성 @IBAction func send(_ sender: Any) { guard let client = client else { return switch client.connect(timeout: 60) { case.success: appendtotextfield(string: "Connected to host \(client.address)") if let response = sendrequest(string: "\(tfmsg.text!)\n\n", using: client) { appendtotextfield(string: "Response: \(response)") case.failure(let error): appendtotextfield(string: String(describing: error))

웹에서가져오기 v Data 클래스를이용해서다양한종류의데이터를변환과정없이가져올수있음 v 초기화메소드를이용해서데이터를가져올수있는데 URL 이잘못되서데이터를제대로가져오지못하면 nil 이저장될수있기때문에이클래스의초기화메소드로만들어진데이터는 Optional 타입 v URL 인코딩 let urlstr = https://www.google.com/search?q= 아이폰 let encoded = urlstr.addingpercentencoding(withallowedcharacters:.urlqueryallowed) v 웹의자원을동기적으로가져오기 Data(contentsOf:URL) v Data 타입의데이터를 String 타입으로변환 String(data:Data 객체, encoding: 인코딩방식 ) v Data 타입의데이터를 Image 타입으로변환 UIImage(data: Data)

웹의이미지와텍스트다운로드

웹의이미지와텍스트다운로드 1.Single View Application 프로젝트생성 (DataDownload) 2.ViewController.swift 파일에변수추가 var imgview : UIImageView! var tv:uitextview! var filemgr:filemanager = FileManager.default

웹의이미지와텍스트다운로드 3.ViewController.swift 파일의 viewdidload 재정의 override func viewdidload() { super.viewdidload() tv = UITextView(frame:CGRect(x:0,y:220,width:320,height:350)) let naver = URL(string:"https://www.naver.com") let naverdata = try! Data(contentsOf:naver!) let naverstring = String.init(data: naverdata, encoding:.utf8) tv!.text = naverstring tv!.iseditable = false view.addsubview(tv!) imgview = UIImageView(frame: CGRect(x:0,y:0,width:320,height:200)) // 이미지파일의내용을다운로드받기 let addr = "http://img.hani.co.kr/imgdb/resize/2018/0518/00502318_20180518.jpg" let imageurl = URL(string: addr) let imagedata = try! Data(contentsOf: imageurl!) // 이미지데이터로변환 let image = UIImage(data: imagedata) // 화면에출력 imgview.image = image view.addsubview(imgview!)

웹에서가져오기 v ATS ü ü ü ü ATS : App Trapsport Security 앱과백엔드서버와의보안연결강제 ios9, mac OS 10.11 부터 TLS v1.2 이상, SHA256, 2048bit RSA 등보안요건강화보안연결이아닌경우 : info.plist에등록 ü 설정 l l l l l Info.plist 에작성 루트키 : App Transport Security Settings(NSAppTransportSecurity) ATS 끄기 : NSAllowsArbitraryLoads(NSAllowsArbitraryLoads) 웹뷰만허용 : Allow Arbitary Loads in Web Content(NSAllowsArbitraryLoadsInWebContent) ATS 예외서버설정 : NSExceptionDomains(NSExceptionDomains)

웹에서가져오기 v ATS ü 모든도메인해제 ü 특정네트워크만예외로설정

웹에서가져오기 4.info.plist 파일에아래내용추가 =>SSL 보안프로토콜이적용된서버라면 ATS 보안설정없이접속이가능하지만 SSL 프로토콜이적용되어있지않으면아래설정을추가해서 ATS 설정을사용하지않도록해주어야합니다. <key>nsapptransportsecurity</key> <dict> <key>nsallowsarbitraryloads</key> <true/> </dict>

XML Parsing v iphone 에서는 XMLParser 클래스를이용해서 XML 데이터를파싱할수있음 ü ü ü ü XMLParser 의 init?(contentsof url: URL) 이나 init(data: Data) 로생성 XMLParser 의 parse 메소드를호출해서파싱하기시작 parse 메소드의수행결과가 true 이면유효한주소나데이터이고 false 이면유효하지않은주소나데이터 XMLParser 클래스의 delegate 속성에파싱에사용될메소드가있는인스턴스를지정

XML Parsing v XMLDelegate ü optional func parserdidstartdocument(_ parser: NSXMLParser) ü optional func parserdidenddocument(_ parser: NSXMLParser) ü 에러가발생하는경우호출되는메소드 o optional func parser(_ parser: NSXMLParser, validationerroroccurred parseerror: NSError) o optional func parser(_ parser: NSXMLParser, parseerroroccurred parseerror: NSError) ü 여는태그를만났을때호출되는메소드 optional func parser(_ parser: NSXMLParser, didstartelement elementname: String, namespaceuri namespaceuri: String?, qualifiedname qualifiedname: String?, attributes attributedict: [NSObject : AnyObject]) o parser는파싱을시작한객체이고 elementname은태그문자열 o namespaceuri는이름공간으로 http://www.w3.org/1999/xsl/transform o qualifiedname 역시이름공간에대한인자 o AttributeDict는각태그의속성값을 Dictionary 형태로반환 ü element를만나면호출되는메소드 optional func parser(_ parser: NSXMLParser, foundcharacters string: String?) o string이 element v 닫는태그를만나면호출되는메소드 optional func parser(_ parser: NSXMLParser, didendelement elementname: String, namespaceuri namespaceuri: String?, qualifiedname qname: String?)

XML Parsing http://sites.google.com/site/iphonesdktutorials/xml/books.xml <?xml version="1.0" encoding="utf-8"?> <Books> <Book id="1"> <title>circumference</title> <author>nicholas Nicastro</author> <summary>eratosthenes and the Ancient Quest to Measure the Globe.</summary> </Book> <Book id="2"> <title>copernicus Secret</title> <author>jack Repcheck</author> <summary>how the scientific revolution began</summary> </Book> <Book id="3"> <title>angels and Demons</title> <author>dan Brown</author> <summary>robert Langdon is summoned to a Swiss research facility to analyze a cryptic symbol seared into the chest of a murdered physicist.</summary> </Book> <Book id="4"><title>keep the Aspidistra Flying</title><author>George Orwell</author><summary>A poignant and ultimately hopeful look at class and society, Keep the Aspidistra Flying pays tribute to the stubborn virtues of ordinary people who keep the aspidistra flying.</summary></book></books>

XML Parsing

XML Parsing 1.Single View Application 프로젝트생성 (XMLParsing) 2. 프로젝트에서 ViewController.swift 를제거 3. 프로젝트에 UITableViewController 로부터상속받는 RootViewController 클래스생성 4.Main.storyboard 에서 ViewController 를제거하고 TableViewController 를추가한후 3 번에서만든클래스를 Class 로설정하고첫번째뷰컨트롤러로설정 5.Navigation Controller 추가 6. 하나의데이터를저장할 Book 클래스생성 import Foundation class Book{ var bookid:string? var title:string? var author:string? var summary:string?

7.RootViewController 클래스에멤버변수선언 var book : Book! var currentelementvalue : String! var books = [Book]() XML Parsing

XML Parsing 8.RootViewController 클래스의 viewdidload 메소드수정 override func viewdidload() { super.viewdidload() let url = URL(string:"http://sites.google.com/site/iphonesdktutorials/xml/Books.xml") let xmlparser = XMLParser(contentsOf: url!) xmlparser?.delegate = self let success = xmlparser?.parse() NSLog(success! as Bool) if success == true { let alert = UIAlertController(title:"XML 파싱 ", message: " 파싱완료.", preferredstyle:.alert) let ok = UIAlertAction(title: " 확인 ", style:.cancel) alert.addaction(ok) // 메시지창실행 self.present(alert, animated: true, completion: nil) self.title = " 파싱성공 " else { let alert = UIAlertController(title:"XML 파싱 ", message: " 파싱실패 ", preferredstyle:.alert) let ok = UIAlertAction(title: " 확인 ", style:.cancel) alert.addaction(ok) // 메시지창실행 self.present(alert, animated: false) self.title = " 파싱실패 "

XML Parsing 9.RootViewController 클래스에 extension 을생성하고 XML 파싱을수행해줄메소드생성 extension RootViewController:XMLParserDelegate{ func parser(_ parser: XMLParser, didstartelement elementname: String, namespaceuri: String?, qualifiedname qname: String?, attributes attributedict: [String : String] = [:]) { if elementname == "Book" { book = Book() let dic = attributedict as Dictionary book?.bookid = dic["id"]

XML Parsing func parser(_ parser: XMLParser, didendelement elementname: String, namespaceuri: String?, qualifiedname qname: String?) { if elementname == "Books"{ return if elementname == "Book" { books.append(book!) book = nil else{ if elementname == "title"{ book?.title = currentelementvalue else if elementname == "author"{ book?.author = currentelementvalue else if elementname == "summary"{ book?.summary = currentelementvalue currentelementvalue = nil

XML Parsing func parser(_ parser: XMLParser, foundcharacters string: String) { // 처음호출되는것이라면 currentelementvalue 에메모리할당하고 string 대입 if currentelementvalue == nil{ currentelementvalue = string // 처음호출되는경우가아니라면이전데이터에이어붙이기 else{ currentelementvalue = "\(currentelementvalue!)\(string)"

XML Parsing 10.RootViewController 클래스에테이블뷰출력메소드작성 override func numberofsections(in tableview: UITableView) -> Int { // #warning Potentially incomplete method implementation. // Return the number of sections. return 1 override func tableview(_ tableview: UITableView, numberofrowsinsection section: Int) -> Int { // #warning Incomplete implementation, return the number of rows return books.count override func tableview(_ tableview: UITableView, cellforrowat indexpath: IndexPath) -> UITableViewCell { let cell:uitableviewcell = UITableViewCell.init(style:.subtitle, reuseidentifier: "cell") cell.textlabel?.text = books[indexpath.row].title cell.accessorytype =.disclosureindicator return cell

XML Parsing 11. 하위데이터를출력할 UIViewController 로부터상속받은 DetailViewController 클래스생성 12.Main.stroyboard 파일에 ViewController 를 1 개배치하고클래스를이전에만든클래스로변경하고 storyboard ID 도이전에만든클래스이름을변경하고화면디자인

XML Parsing 13. DetailViewController 의 View 에레이블 5 개와 TextView1 개배치하고 2 개의레이블과텍스트뷰에변수연결하고 Book 타입의변수추가 @IBOutlet weak var lbltitle: UILabel! @IBOutlet weak var lblauthor: UILabel! @IBOutlet weak var tvsummary: UITextView! var book : Book? 14. DetailViewController 의 ViewDidLoad 메소드재정의 override func viewdidload() { super.viewdidload() lbltitle.text = book!.title lblauthor.text = book!.author tvsummary.text = book!.summary self.title = book!.title // Do any additional setup after loading the view.

XML Parsing 15. RootViewController.swift 파일에테이블뷰의셀을선택했을때호출되는메소드를재정의 override func tableview(_ tableview: UITableView, didselectrowat indexpath: IndexPath){ let detailviewcontroller = self.storyboard?.instantiateviewcontroller(withidentifier: "DetailViewController") as! DetailViewController detailviewcontroller.book = books[indexpath.row] self.navigationcontroller?.pushviewcontroller(detailviewcontroller, animated: true)

JSON Parsing v JSON 파싱 ü JSONSerialization.JSONObject(with data: Data, options opt: JSONSerialization.ReadingOptions = []) throws -> Any ü 파싱결과 : Array, Dictionary, String 등 v JSON 생성 ü JSONSerialization.data(withJSONObject obj: Any, options opt: JSONSerialization.WritingOptions = []) throws -> Data v http://cyberadam.cafe24.com/movie/list {"count":4266,"list":[{"movieid":"p00000530014","title":" 매기 ","genre":" 드라마, 스릴러 ","participant":0,"ratinga verage":10.0,"thumnailimage":"rep_02310042581_1_1_0314.jpg","linkurl":"https://search.daum.net/search? w=tot&da=s43&q=%eb%a7%a4%ea%b8%b0",{"movieid":"p00000530006","title":" 바이러스격리구역 ","genre":" 공포 ","participant":0,"ratingaverage":10.0,"thumnailimage":"rep_02310042540_1_1_0138.j pg","linkurl":"https://search.daum.net/search?w=tot&da=s43&q=%eb%b0%94%ec%9d%b4%eb%9f%ac% EC%8A%A4+%EA%B2%A9%EB%A6%AC%EA%B5%AC%EC%97%AD",{"movieId":"P00000529992","title":" 데몬킹스

JSON Parsing

JSON Parsing 1.Single View Application 프로젝트생성 - JsonParsing 2.Main.storyboard 의 ViewController 의 View 에 UITableView 를배치하고 datasource 와 delegate 를 ViewContrroller 로설정하고 NavigationController 추가

JSON Parsing 3.ViewController 클래스에데이터를저장할배열변수를선언 var titles:[string]=[] var images:[string]=[]

JSON Parsing 4.ViewController 클래스의 viewdidload 메소드수정 override func viewdidload() { super.viewdidload() self.title = " 영화목록 " // 주소만들기 let url = URL(string: "http://cyberadam.cafe24.com/movie/list") // 다운로드받기 let data = try! Data(contentsOf: url!) // 다운로드받은데이터를 NSDictionary 로만들기 let jsonresult = try! JSONSerialization.jsonObject(with:data, options:[]) as! NSDictionary //channel 키의값을디셔너리로가져오기 let ar = jsonresult["list"] as! NSArray // 반복문을이용해서배열의데이터를꺼낸후 titles 에추가 for index in 0...(ar.count-1){ let item = ar[index] as! NSDictionary titles.append(item["title"] as! String) images.append(item["thumnailimage"] as! String)

JSON Parsing 5.ViewController 의 extension 을생성하고테이블뷰출력메소드작성 extension ViewController : UITableViewDelegate, UITableViewDataSource{ func numberofsections(in tableview: UITableView) -> Int { return 1 func tableview(_ tableview: UITableView, numberofrowsinsection section: Int) -> Int { return titles.count func tableview(_ tableview: UITableView, cellforrowat indexpath: IndexPath) -> UITableViewCell { let cell:uitableviewcell = UITableViewCell(style:UITableViewCell.CellStyle.subtitle, reuseidentifier:"cell") cell.textlabel?.text = titles[indexpath.row] let addr = images[indexpath.row] let imageurl = URL(string: "http://cyberadam.cafe24.com/movieimage/\(addr)") let imagedata = try! Data(contentsOf:imageUrl!) let image = UIImage(data: imagedata) cell.imageview?.image = image return cell

6. info.plist 파일에보안설정해제설정추가 <key>nsapptransportsecurity</key> <dict> <key>nsallowsarbitraryloads</key> <true/> </dict> JSON Parsing

동기식 & 비동기식 v 동기식 ü 코드를실행하면결과를얻을때까지대기 ü 실행결과는반환값으로전달 ü 다른코드의실행을멈춤 ü 코드작성쉬움 v 비동기식 ü 코드실행후결과를얻을때까지대기하지않으며실행결과는델리게이트 / 클로저등을사용 ü 다른코드실행을멈추지않음 ü 코드작성어려움 ( 멀티스레드의이해필요 ) ü 처리방법 l Thread 클래스이용 l URLSession 과 URLConnection 과 API 이용 l 비동기라이브러리를사용

스레드 v Swift의스레드 ü Thread 클래스로부터상속받는클래스를생성 ü main 메소드에스레드로동작할코드를작성 ü 인스턴스를생성하고 start 메소드호출 ü 주의할점 : main 스레드이외의스레드에서 UI를변경하려고하는것은안됨

스레드

스레드 v Single View App 프로젝트생성 - iosthread v ViewController 클래스에변수선언 var imageview : UIImageView! var imagename : UILabel!

스레드 v ViewController 클래스의 viewdidload 메소드작성 override func viewdidload() { super.viewdidload() // 화면전체크기가져오기 let frame = UIScreen.main.bounds imageview = UIImageView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) imageview.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2) let addr = "http://img.hani.co.kr/imgdb/resize/2018/0518/00502318_20180518.jpg" let imageurl = URL(string: addr) let imagedata = try! Data(contentsOf: imageurl!) let image = UIImage(data: imagedata) imageview.image = image self.view.addsubview(imageview) imagename = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50)) imagename.center = CGPoint(x: imageview.center.x, y:imageview.center.y + 200) imagename.textalignment =.center imagename.text = " 수지 " self.view.addsubview(imagename)

스레드 v Info.plist 파일에 ATS 설정옵션설정 <key>nsapptransportsecurity</key> <dict> <key>nsexceptiondomains</key> <dict> <key>img.hani.co.kr</key> <dict> <key>nsincludessubdomains</key> <true/> <key>nstemporaryexceptionallowsinsecurehttploads</key> <true/> </dict> </dict> </dict>

스레드 v 이미지를다운로드받아이미지뷰에출력하는스레드클래스를생성하고 main 메소드구현 class ImageDownloader : Thread { var imageview : UIImageView! var url : URL! override func main() { let imagedata = try! Data(contentsOf: url) let image = UIImage(data: imagedata) imageview.image = image

스레드 v ViewController 클래스의 viewdidload 메소드수정 override func viewdidload() { super.viewdidload() // 화면전체크기가져오기 let frame = UIScreen.main.bounds imageview = UIImageView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) imageview.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2) self.view.addsubview(imageview) let addr = "http://img.hani.co.kr/imgdb/resize/2018/0518/00502318_20180518.jpg" let imageurl = URL(string: addr) let downloader = ImageDownloader() downloader.imageview = imageview downloader.url = imageurl downloader.start() imagename = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50)) imagename.center = CGPoint(x: imageview.center.x, y:imageview.center.y + 200) imagename.textalignment =.center imagename.text = " 수지 " self.view.addsubview(imagename)

스레드

스레드 v Main Thread 동작 API ü NSObject와셀렉터이용 func performselector(onmainthread aselector: Selector, with arg: Any?, waituntildone wait: Bool) ü OperationQueue 이용 OperationQueue.main.addOperation { self.imageview.image = UIImage(data: imagedata)

스레드 v 이미지를다운로드받는스레드클래스를수정 class ImageDownloader : Thread { var imageview : UIImageView! var url : URL! override func main() { let queue = OperationQueue() queue.addoperation { let imagedata = try! Data(contentsOf: self.url) let image = UIImage(data: imagedata) OperationQueue.main.addOperation { self.imageview.image = image

스레드 v 이미지를다운로드받는스레드클래스를수정 class ImageDownloader : Thread { var imageview : UIImageView! var url : URL! override func main() { self.performselector(onmainthread: #selector(download), with: nil, waituntildone: false) @objc func download(){ let imagedata = try! Data(contentsOf: self.url) let image = UIImage(data: imagedata) self.imageview.image = image

비동기 API v ios 앱에서서버와통신하기위해 Apple 은 URLSession 이라는 API 를제공 v URLSession 의 Request 와 Response ü ü URLSession 은다른 HTTP 통신과마찬가지로 Request 와 Response 를기본구조로가지고있으며 Request 는 URL 객체를통해직접통신하는형태와 URLRequest 객체를만들어서옵션을설정하여통신하는형태가있음 Response 는설정된 Task 의 Completion Handler 형태로 response 를받거나 URLSessionDelegate 를통해지정된메소드를호출하는형태로 response 를받는형태가있는데일반적으로간단한 response 를작성할때에는 Completion Handler 를사용하지만앱이 background 상태로들어갈때에도파일다운로드를지원하도록설정하거나인증과캐싱을 default 옵션으로사용하지않는상황과같은경우에는 Delegate 패턴을사용

비동기 API v URLSession은크게 3가지종류의 Session을지원 ü Default Session: 기본적인 Session으로디스크기반캐싱을지원 ü Ephemeral Session: 어떠한데이터도저장하지않는형태의세션 ü Background Session: 앱이종료된이후에도통신이이뤄지는것을지원 v Session 생성 ü 공용세션얻기 let session = URLSession.shared ü 커스텀세션생성 : 세션설정 (URLSessionConfiguration) let config = URLSessionConfiguration.default let session = URLSession(configuration: config)

비동기 API v URLSessionTask ü Task 객체는일반적으로 Session 객체가서버로요청을보낸후응답을받을때 URL 기반의내용들을받는 (retrieve) 역할을수행 ü 3가지종류의 Task가지원됨 l Data Task - Data 객체를통해데이터주고받는 Task l Download Task - data를파일의형태로전환후다운받는 Task로백그라운드다운로드지원 l Upload Task - data를파일의형태로전환후업로드하는 Task ü 메소드 l func suspend() l func resume() l func cancel() l 태스크생성후 resume 호출해야동작 l 태스크상태 var state: URLSessionTask.State {get

비동기 API v 세션 (URLSession) 에서태스크생성 ü func datatask(with url: URL, completionhandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask ü func datatask(with request: URLRequest, completionhandler: @escaping (Data?, URLResponse?, Error?) -> Swift.Void) -> URLSessionDataTask ü func downloadtask(with url: URL, completionhandler: @escaping (URL?, URLResponse?, Error?) - > Swift.Void) -> URLSessionDownloadTask ü func uploadtask(with request: URLRequest, fromfile fileurl: URL) -> URLSessionUploadTask

비동기 API v URLSessionTask ü 태스크완료 l 태스크완료시 completionhandler 클로저동작 l 태스크결과전달 : Data, URLResponse, Error l 에러처리필요 l 클로저는멀티쓰레드로동작 l UI 업데이트하려면메인스레드로동작하도록작성

비동기 API 를이용한다운로드 v ViewController 클래스의 viewdidload 메소드수정 override func viewdidload() { super.viewdidload() // 화면전체크기가져오기 let frame = UIScreen.main.bounds imageview = UIImageView(frame: CGRect(x: 0, y: 0, width: 300, height: 300)) imageview.center = CGPoint(x: frame.size.width/2, y: frame.size.height/2) self.view.addsubview(imageview) let addr = "http://img.hani.co.kr/imgdb/resize/2018/0518/00502318_20180518.jpg" let imageurl = URL(string: addr) let session = URLSession.shared let task = session.datatask(with: imageurl!, completionhandler: { (data : Data?, response : URLResponse?, error : Error?) in if error!= nil{ NSLog(" 다운로드에러 :\(error!.localizeddescription)") return // 메인쓰레드에서이미지를이미지뷰에반영 OperationQueue.main.addOperation { self.imageview.image = UIImage(data: data!) ) task.resume()

비동기 API 를이용한다운로드 imagename = UILabel(frame: CGRect(x: 0, y: 0, width: 300, height: 50)) imagename.center = CGPoint(x: imageview.center.x, y:imageview.center.y + 200) imagename.textalignment =.center imagename.text = " 수지 " self.view.addsubview(imagename)

비동기 API 를이용한다운로드 v URLSession 을이용한 post 방식요청 // Prepare URL let url = URL(string: "http://cyberadam.cafe24.com/member/login") guard let requesturl = url else { fatalerror() // Prepare URL Request Object var request = URLRequest(url: requesturl) request.httpmethod = "POST" // HTTP Request Parameters which will be sent in HTTP Request Body let poststring = "email=email&pw=password"; // Set HTTP Request Body request.httpbody = poststring.data(using: String.Encoding.utf8); // Perform HTTP Request let task1 = URLSession.shared.dataTask(with: request) { (data, response, error) in if let error = error { NSLog("Error took place \(error)") return if let data = data, let datastring = String(data: data, encoding:.utf8) { NSLog("Response data string:\n \(datastring)") task1.resume()

영화정보목록보기

목록화면 v v v v v 프로젝트생성 (MovieList) 기존 ViewController 대신새로운뷰컨트롤러로사용할 UITableViewController 로부터상속받는클래스를생성 (MovieListViewController) Main.storyboard 파일에테이블뷰컨트롤러를추가하고 class 속성을설정하고시작뷰컨트롤러로설정 NavigationController 를추가 CustomCell 을사용하기위해서 UITableViewCell 클래스로부터상속받는클래스를생성 (MovieCell)

CustomCell 만들기 v 셀의높이조정 : storyboard 에서 TableView 를선택하고 size inspector 에서높이를조정

CustomCell 만들기 v v storyboard에서 prototype cell을선택하고 class 와 Identifier를생성한클래스이름으로변경화면디자인 ImageView 1개와 Label 3개배치

CustomCell 만들기 v ImageView 1 개와 Label 4 개를 MovieCell 클래스에변수로연결 @IBOutlet weak var thumbnail: UIImageView! @IBOutlet weak var lbltitle: UILabel! @IBOutlet weak var lblgenre: UILabel! @IBOutlet weak var lblrating: UILabel!

OpenAPI 가져오기 v v http://cyberadam.cafe24.com/movie/list 요청파라미터 ü 파라미터 :searchtype, keyword, page, pagecnt ü searchtype: title, genre, both ü keyword는검색어 ü page는페이지번호 ü count는페이지당데이터개수 ü 전부생략이가능

OpenAPI 가져오기 v 응답결과 {"count":4262,"list":[{"movieid":4264,"title":" 바이러스격리구역 ","subtitle":"infected","pubdate":"2013","director":" 필립매시즈위츠 ","actor":" 딜라란마틴 보린튼 유지니아쿠즈미나 아드리안부 아디아딘 니나케이트 ","genre":" 공포 ","rating":10.0,"thumbnail":"rep_02310042540_1_1_0138.jpg","link":"https://movi e.naver.com/movie/bi/mi/basic.nhn?code=104605",{"movieid":4263,"title":" 쥬라기공원 : 다이노어택 ","subtitle":"jurassic Attack","pubdate":"2013","director":" 안소니팽크하우저 ","actor":" 조던로슨 코린네멕 베론웰스 게리스트레치 ","genre":"sf/ 판타지, 공포, 액션 / 모험 ","rating":10.0,"thumbnail":"rep_02310042015_1_1_0235.j pg","link":"https://movie.naver.com/movie/bi/mi/basic.nhn?code=103735",{"movieid":4262,"title":" 영웅본색 2 HD","subtitle":null,"pubdate":null,"director":null,"actor":null,"genre":" 드라마, 액션 / 모험 ","rating":10.0,"thu mbnail":"rep_02310042053_1_1_0219.jpg","link":"http://swiftapi.rubypaper.co.kr:2029/hoppin/detailvie w?movieid=p00000529234",{"movieid":4261,"title":" 페인킬러엑스 ","subtitle":"painkiller","pubdate":"2012","director":" 베레니카매시즈위츠 ","actor":" 마이크파프 엘로디하라 론푸실로 딜라란마틴 ","genre":" 액션 / 모험, 스릴러 ","rating":0.0,"thumbnail":"rep_02310041823_1_1_0240.jpg","link":"http s://movie.naver.com/movie/bi/mi/basic.nhn?code=104607"

OpenAPI 가져오기 v MovieListViewController.swift 파일의 viewdidload 메소드에코드를추가하고테스트 override func viewdidload() { super.viewdidload() // 다운로드받을 URL 만들기 let url = "http://cyberadam.cafe24.com/movie/list" let apiuri : URL! = URL(string: url) //REST API 를호출 let apidata = try! Data(contentsOf: apiuri) // 데이터전송결과를로그로출력 let log = NSString(data: apidata, encoding: String.Encoding.utf8.rawValue)?? "" NSLog("API Result=\( log )")

OpenAPI 가져오기 v 다운로드가안되면인터넷접속여부를확인하고 info.plist 파일에아래코드를추가 <key>nsapptransportsecurity</key> <dict> <key>nsallowsarbitraryloads</key> <true/> </dict>

OpenAPI 가져오기 v 영화정보하나를저장할구조체를생성 MovieVO.swift import Foundation import UIKit struct MovieVO { var title: String? // 영화제목 var genre: String? // 영화장르 var link:string? // 영화상세정보링크 var rating: Double? // 평점 var thumbnail: String? // 영화섬네일이미지주소 var image:uiimage? // 이미지

OpenAPI 가져오기 v 데이터를파싱해서저장하기 1.MovieListViewController.swift 파일에데이터를저장할프로퍼티생성 // 테이블뷰를구성할리스트데이터 lazy var list: [MovieVO] = { var datalist = [MovieVO]() return datalist ()

OpenAPI 가져오기 v 데이터를파싱해서저장하기 2.MovieListViewController.swift 파일의 viewdidload 메소드하단에파싱해서저장하는코드추가 do { //JSON 객체를파싱하여 NSDictionary 객체로받음 let apidictionary = try JSONSerialization.jsonObject(with: apidata, options: []) as! NSDictionary // 데이터구조에따라차례대로캐스팅하며읽어온다. let movies = apidictionary["list"] as! NSArray //Iterator 처리를하면서 API 데이터를 MovieVO 객체에저장한다. for row in movies { // 데이터를 NSDictionary 타입으로캐스팅 let r = row as! NSDictionary // 테이블뷰리스트를구성할데이터형식 var movie = MovieVO( ) // movie 배열의각데이터를 mvo 상수의속성에대입 movie.title = r["title"] as? String movie.genre = r["genre"] as? String movie.thumbnail = r["thumbnail"] as? String movie.link = r["link"] as? String movie.rating = ((r["rating"] as! NSNumber).doubleValue)

OpenAPI 가져오기 // 웹상에있는이미지를읽어와 UIImage 객체로생성 let url: URL! = URL(string: "http://cyberadam.cafe24.com/movieimage/\(movie.thumbnail!)") let imagedata = try! Data(contentsOf: url) movie.image = UIImage(data:imageData) // list 배열에추가 self.list.append(movie) NSLog(self.list.description) // 데이터를다시읽어오도록테이블뷰를갱신한다. self.tableview.reloaddata() catch { NSLog("Parse Error!!")

데이터출력하기

데이터출력하기 v 테이블뷰출력메소드재정의 // 섹션의개수를설정하는메소드 override func numberofsections(in tableview: UITableView) -> Int { return 1 // 섹션별행의개수를설정하는메소드 override func tableview(_ tableview: UITableView, numberofrowsinsection section: Int) -> Int { return self.list.count

데이터출력하기 // 셀을만들어서출력하는메소드 override func tableview(_ tableview: UITableView, cellforrowat indexpath: IndexPath) -> UITableViewCell { // 주어진행에맞는데이터소스를읽어온다. let row = self.list[indexpath.row] let cell = tableview.dequeuereusablecell(withidentifier: "MovieCell") as! MovieCell // 데이터소스에저장된값을각아울렛변수에할당 cell.lbltitle?.text = row.title cell.lblgenre?.text = row.genre cell.lblrating?.text = "\(row.rating!)" cell.thumbnail?.image = row.image return cell

데이터출력하기 // 셀을선택했을때호출되는메소드 override func tableview(_ tableview: UITableView, didselectrowat indexpath: IndexPath) { NSLog(" 선택된행은 \(indexpath.row) 번째행입니다 ") // 셀의높이를설정하는메소드 override func tableview(_ tableview: UITableView, heightforrowat indexpath: IndexPath) -> CGFloat { return 80

업데이트기능 v MovieListViewController.swift 파일에페이지번호를저장할변수선언 var page = 1

업데이트기능 v MovieListViewController.swift 파일에데이터를다운로드받는메소드생성 // 데이터를다운로드받는메소드 func downloaddata(){ // 다운로드받을 URL 만들기 let url = "http://cyberadam.cafe24.com/movie/list?page=\(page)" let apiuri : URL! = URL(string: url) //REST API 를호출 let apidata = try! Data(contentsOf: apiuri) // 데이터전송결과를로그로출력 let log = NSString(data: apidata, encoding: String.Encoding.utf8.rawValue)?? "" NSLog("API Result=\( log )")

업데이트기능 do { //JSON 객체를파싱하여 NSDictionary 객체로받음 let apidictionary = try JSONSerialization.jsonObject(with: apidata, options: []) as! NSDictionary // 데이터구조에따라차례대로캐스팅하며읽어온다. let movies = apidictionary["list"] as! NSArray //Iterator 처리를하면서 API 데이터를 MovieVO 객체에저장한다. for row in movies { // 데이터를 NSDictionary 타입으로캐스팅 let r = row as! NSDictionary // 테이블뷰리스트를구성할데이터형식 var movie = MovieVO( ) // movie 배열의각데이터를 mvo 상수의속성에대입 movie.title = r["title"] as? String movie.genre = r["genre"] as? String movie.thumbnail = r["thumbnail"] as? String movie.link = r["link"] as? String movie.rating = ((r["rating"] as! NSNumber).doubleValue)

업데이트기능 // 웹상에있는이미지를읽어와 UIImage 객체로생성 let url: URL! = URL(string: "http://cyberadam.cafe24.com/movieimage/\(movie.thumbnail!)") let imagedata = try! Data(contentsOf: url) movie.image = UIImage(data:imageData) // list 배열에추가 self.list.append(movie) NSLog(self.list.description) // 데이터를다시읽어오도록테이블뷰를갱신한다. self.tableview.reloaddata()

업데이트기능 // 전체데이터카운트를얻는다. let totalcount = (apidictionary["count"] as? NSNumber)!.intValue // totalcount 가읽어온데이터크기와같거나클경우리프레시컨트롤을숨김 if (self.list.count >= totalcount) { self.refreshcontrol?.ishidden = true catch { NSLog("Parse Error!!")

업데이트기능 v MovieListViewController.swift 파일에 refreshcontrol 이호출할메소드생성 @objc func handlerefresh(_ refreshcontrol: UIRefreshControl) { // O 현재페이지값에 1 을추가한다. self.page += self.page + 1 self.downloaddata() // 데이터를다시읽어오도록테이블뷰를갱신한다. self.tableview.reloaddata() refreshcontrol.endrefreshing()

업데이트기능 v MovieListViewController.swift 파일의 viewdidload 메소드수정 override func viewdidload() { super.viewdidload() self.title = " 영화정보 " self.refreshcontrol = UIRefreshControl() self.refreshcontrol!.addtarget(self, action: #selector(movielistviewcontroller.handlerefresh(_:)), for:.valuechanged) self.refreshcontrol!.tintcolor = UIColor.red self.downloaddata()

비동기처리 v MovieListViewController.swift 파일에이미지를다운로드받아오는메소드를생성 func getthumbnailimage(_ index: Int) -> UIImage { // 인자값으로받은인덱스를기반으로해당하는배열에서데이터를읽어옴 var movie = self.list[index] // 저장된이미지가있으면그것을반환하고, 없을경우내려받아저장한후반환 if let savedimage = movie.image { return savedimage else { let url: URL! = URL(string: movie.thumbnail!) let imagedata = try! Data(contentsOf: url) movie.image = UIImage(data:imageData) // UIImage를 MovieVO 객체에우선저장 return movie.image! // 저장된이미지를반환

비동기처리 v MovieListViewController.swift 파일의셀출력메소드수정 // 셀을만들어서출력하는메소드 override func tableview(_ tableview: UITableView, cellforrowat indexpath: IndexPath) -> UITableViewCell { // 주어진행에맞는데이터소스를읽어온다. let row = self.list[indexpath.row] let cell = tableview.dequeuereusablecell(withidentifier: "MovieCell") as! MovieCell // 데이터소스에저장된값을각아울렛변수에할당 cell.lbltitle?.text = row.title cell.lbldescription?.text = row.genrenames cell.lblrating?.text = "\(row.ratingaverage!)" DispatchQueue.main.async(execute: { cell.thumbnail.image = self.getthumbnailimage(indexpath.row) ) return cell