[Swift5] 에러해결 : unable to dequeue a cell with identifier ~


iOS 어플 개발 테스트 중 화면이 뜨지 않고 이러한 에러를 만날때가 있습니다.

unable to dequeue a cell with identifier ~

저의 경우 TableView를 건들다가 일어난 문제였는데요, 어렵지 않게 해결할 수 있으니 당황하지 않으셔도 됩니다.


원인

해당 에러가 발생한 경우 원인은 보통 Storyboard 혹은 nib에서 identifier을 지정해주지 않았거나,

identifier에 지정된 명칭이 코드와 Storyboard단에서 서로 상이해서 발생하는 문제입니다.

 

해결

해결 방법으로는 Storyboard에서 코드와 연결될 identifier을 지정해주거나 혹은 변경해주는(코드단과 동일하게 해주는)겁니다.

 

Storyboard Identifier 지정 위치 : 

Storyboard - Show the Attributes inspector 아이콘클릭 후 나오는 항목들 중 Identifier input box에서 지정

 

Storyboard에서 Identifier 지정해주기

저의 경우 TableView의 Cell을 지정할때 Storyboard와 코드단에서 사용할때의 Identifier이 서로 상이하여 찾지 못해 일어난 문제였습니다.

 

버전정보 (v1.0)

 - v1.0 2020.07.16 배포

 

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

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

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

 

Karzin

abbeea@naver.com


[Swift5] 특정 View만 화면 회전 (UINavigationController)


아까 공부하러 간다고 말씀을 드렸습니다만.. 오늘의 공부는 바로 iOS(Xcode-Swift)공부였습니다. ㅋㅋㅋ

 

iOS개발을 하다보면 가끔 특정 View에서만 화면을 회전해야하는 경우가 있습니다.

예를들어 가로->세로->가로로 하나의 화면을 세로로 보여야한다던가,

세로->가로->세로 등의 화면으로 보여줘야한다는 등 특정한 요구가 있는 경우가 있습니다.

 

그런 경우 코드로 어떻게 처리를 하는지를 알아보겠습니다.

 

특히 제가 사용하는 소스의 경우 UINavigationController가 적용된 UIViewController에서 강제적으로 화면을 회전시키는 소스입니다.

뭐, 다른 방법이 있을 수 있으나..(supportedInterfaceOrientations를 이용해 변경을 해보려했는데 잘 되지 않더군요. 저의 방법이 잘못된거일지도 모르겠지만, 대략적인 느낌은 전역으로 지정된 UINavigationController 혹은 제가 커스텀한 CustomUIViewController가 override된 supportedInterfaceOrientations를 무시하는 것 같았습니다.)

한동안 삽질을 하던 저는 이 방법을 통해 해결하였습니다.

(더 좋은 방법이 있다면 알려주시면 감사하겠습니다! 감사히 배우겠습니다!!)


 

우선 이 코드를 이해하기 위해서는 viewWillAppear 함수와 viewWillDisappear 함수에 대해 대강 이해하고 계셔야합니다.

이 함수들을 이해하기 위해서는 View Controller의 생명주기에 대해서 알고 계셔야 이해가 쉬운데요.

이 부분은 나중에 다시한번 다루도록 하겠습니다. (... 시간관계상)

 

간단히 말하면 viewWillAppear 함수와 viewWillDisappear 함수는 뷰의 생명주기에 있어 뷰가 나타날때, 뷰가 사라질때 사용(Override)하는 함수입니다. (짤막..)

네.. 지금은 뷰의 생명주기를 알려드리는 시간은 아니니 대강 그렇다는것만 이해하시면 그나마 이해하시는데 큰 문제는 없을겁니다.

 

바로 소스를 보시죠

화면을 시작할 때 회전시키기 (가로 회전 혹은 세로 회전)

override func viewWillAppear(_ animated: Bool) {

  // 화면 회전하기 (가로 회전)
  let orientation = UIInterfaceOrientation.landscapeRight.rawValue
  
  // 세로로 회전 (주석제거)
  // let orientation = UIInterfaceOrientation.portrait.rawValue

  UIDevice.current.setValue(orientation, forKey: "orientation")

  UINavigationController.attemptRotationToDeviceOrientation()

}

 

화면이 종료될 때 원상복귀시키기 (세로->가로->세로 혹은 가로->세로->가로)

override func viewWillDisappear(_ animated: Bool) {
  // 기존 세로에서 가로로 변경했었다면 다시 세로로 원상복구
  let orientation = UIInterfaceOrientation.portrait.rawValue

  // 기존 가로에서 세로로 변경했었다면 다시 가로로 원상복구 (주석제거)
  // let orientation = UIInterfaceOrientation.landscapeRight.rawValue
  
  UIDevice.current.setValue(orientation, forKey: "orientation")

  UINavigationController.attemptRotationToDeviceOrientation()

}

 

보시면 크게 어려운 건 없습니다.

세로모드 혹은 가로모드의 값을 orientation 변수에 담아서

UIDevice 클래스에 접근하여 Value, Key 형태로 저장해줍니다.

 

그리고 attemptRotationToDeviceOrientation함수에서 새로운 인터페이스 방향을 수동으로 적용해줍니다.

 

 

UIDevice - Use a UIDevice object to get information about the device such as assigned name, device model, and operating-system name and version.

대충 UIDevice 객체는 디바이스의 정보를 가져오는 용도로 사용할 수 있다는 모양입니다.

=> 그 정보로는 이름, 모델명, os 이름, 버전 등

출처 : developer.apple.com (https://developer.apple.com/documentation/uikit/uidevice)

 

Apple Developer Documentation

 

developer.apple.com

다들 아시다시피 UINavigationController 클래스도 UIViewController를 상속하여 만들어진 클래스입니다.

그러다보니 UINavgiationController만의 함수가 아닌 상속되어진 UIViewController에도 있는것으로 보입니다.

단지 제 생각이지만, 제가 supportedInterfaceOrientations 함수를 사용함에 있어서 계속해서 실패한 까닭은 이러한 상속여부에 따라 UIViewController에서는 Override가 적용이 불가하지 않았나 싶네요. (쉽게말해 무시)

 

UINavigationController.attemptRotationToDeviceOrientation - If your view controller does this, when those conditions change, your app should call this class method. The system immediately attempts to rotate to the new orientation.

대충 ViewController에서 상태의 변경이 필요한 경우 해당 메소드를 부르면 사용자가 원하는 새로운 방향으로 즉각적으로 회전을 시도한다는 모양입니다.

출처 : developer.apple.com (https://developer.apple.com/documentation/uikit/uiviewcontroller/1621400-attemptrotationtodeviceorientati)

 

Apple Developer Documentation

 

developer.apple.com


버전정보 (v1.0)

 - v1.0 2020.07.14 배포

 

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

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

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

 

Karzin

abbeea@naver.com


프로젝트 개발 모형 : 폭포수 모델, 애자일 방법(XP방법론)


제가 작업하고 있는 개인 프로젝트(Project.다원 ERP) 개발모형은 거의 폭포수 모델을 베이스로 두고있다고 보셔도 될 것 같습니다.

흠.. 거의 반절 재미삼아 취미(???)로 만드는 프로젝트라서 다른분들이 보시기에는 많이 부족하겠지만, 시간이 괜찮으시다면 한번쯤 쭉 읽어보시는것도 괜찮을겁니다! (아마...?ㅠㅠ)

 

Project.다원ERP_개발 정보(개발언어, 장비, 예정내역)

다원ERP_개발 정보 (개발언어, 장비, 예정내역) Project Infomation Project Name : 다원ERP 기획 : Karzin 분석 : Karzin 설계 : Karzin 개발 : Karzin 디자인 : Karzin 유지보수 : Karzin 개발 정보 Develop Lan..

karzin.tistory.com

사실 고객도 저이고, 개발자도 저인 이상 어느정도 제 머릿속에 정립된 시스템은 바뀔일이 없다보니 거의 빠꾸는 없겠지요.. 다만, 개발하다가 막히는 부분이라던가, 문제가 생겨 바뀔수밖에 없는 부분에 대해서는 로직이 바뀔뿐이지 보이는 UX/UI상에는 크게 바뀌는 부분은 없을겁니다.

 

그렇다면 제가 베이스로 두는 개발모형 폭포수 모델은 무엇일까요?

 

제가 느끼는 특징은 이렇습니다.

 * 확고하게 정립된 프로젝트(계획, 분석, 설계가 고객에게는 확고하게 정리가 된 상태 - 이렇게 만들 것이다!) 

 - 앞에서부터 차례대로 나아가는 모델

 - 노빠꾸 모델

 - 프로젝트의 철저한 문서화 (앞으로 철저하게 하겠습니다..ㅠㅠ)

 

사실 이는 확고하게 정립된 프로젝트 즉, 제 자신이 생각하는 틀에서 벗어나지 않기 때문에 폭포수모델을 사용할 수 있었습니다.

뭐.. 확고하게 정립된 프로젝트라고해서 보통의 프로젝트에서 사용하지 않는건 아닙니다.

기본적으로 일반적인 프로젝트에서도 폭포수 모델은 많이 사용되기는 합니다.

고객과의 커뮤니케이션을 통해 미리 분석을 하고, 분석된 자료들을 토대로 설계를 확정지어버리는 것이죠.

설계까지 확정만 되었다면, 다음으로는 개발을 진행합니다. 개발이 마무리되면 이제 테스트를 하고 배포가 끝나고나면 유지보수가 마지막 단계이겠지요.

 

이걸 머릿속에 기억하시고 아래 이미지를 보시면 이해하기가 편합니다.

아래는 폭포수 모델의 구조입니다.

폭포수 모델은 위에서 아래로 흐르는 듯한 구조를 가지고 있습니다.

 

여기서 한가지! 개발자에게 있어 가장 행복한건 역시 잘 짜여진 설계 문서이겠죠. 확고한 프로젝트의 설계자료는 개발자에게 있어서 굉장한 도움입니다.

그도 그럴게 버튼에 입혀질 디자인이 바뀌더라도 그 디자인의 원본 Structure인 Button은 바뀌지 않으니까요!

 

이 부분을 설명하기 위해서는 당연하게도 설계가 되어 있겠지만, Wireframe이나 화면설계단에서는 이미 이것은 Button이라는게 확고하게 잡혀 있을 것입니다.

그렇기에 개발자 입장에서는 Button을 만들어놓고 그 위에 어떤 디자인을 입히든 문제가 되지 않는 다는거죠.

Button의 위치, 글자 혹은 이미지는 그대로지만, 그 아래 디자인을 입히는건 어쩌면 개발자에겐 어렵지 않은 일이 될겁니다. (물론 상황에 따라 이미지를 바꾸는게 어려운 상황이 있기도 합니다.)

 

하지만 문제는 여기서 일어납니다. 바로 설계문서가 바뀌어버리는 경우가 있습니다.

물론 이 설계문서가 바뀌는건 계획단계-분석단계-설계단계까지는 그나마 문제가 적을 수 있으나,

문제는 개발에 들어가서부터 문제가 하나 둘 터지기 시작됩니다.

예를 들어 개발자는 디자인(버튼의 스킨)을 바꾸는건 쉬울지는 몰라도, 설계문서의 UX나 화면설계서가 크게 바뀌는 경우 그 구조 차체를 새로 만들어야하는 문제가 생길 수 있습니다.

이는 결코 작은 문제가 아닙니다. 개발자는 변경된 설계로 인해 지금까지 쌓아 올린 모든걸 새로 쌓아올려야하는 위험한 도박이 될 수 있습니다.

 

이런 경우에는 폭포수모델과 조금 방식이 다른 애자일 방법론을 사용해야하는 경우가 있습니다.

애자일 방식의 하나인 XP(익스트림 프로그래밍)방법론처럼 개발자 개개인의 역량에 맡긴채로 고객과 계속 소통을 해가면서 진행을 해가는 방법입니다.

수시로 변경이 되어가는 고객의 요구사항을 맞춰가며 팀원과의 대화를 통해 문서보다는 어느정도 개발이 진행된 시스템을 먼저 보여주는 형식입니다. 여기서 개발이 진행된 시스템은 프로토타입이라고 봐도 문제가 없을정도의 퀄리티가 있는(높은) 시스템입니다.

쉽게 말하면 프로토타입을 마구 찍어내면서 고객에게 모두 보여고 또 고객이 원하는 요구사항에 맞추어 프로토타입을 변경해가며 완료되어가는 시스템을 보여주는 것이죠.

아래는 애자일 방식의 구조입니다.

애자일은 계속된 반복을 통해 결과물을 만들어갑니다.

그만큼 고객과 개발자간 서로의 커뮤니케이션이 가장 중요한 개발론이기도 합니다.

애자일 방식의 특징으로는

 - 중요한 커뮤니케이션

 - 요구사항의 변동에 유연하고 그만큼 빠른 대처가 가능

 

여기서 잠시 한가지! 애자일에 대한 예시를 생각해보다보니 좋은 예시가 떠올랐습니다.

그 좋은 예시로 설명을 든다면! 개인적으로는 가장 적합한 프로젝트로는 R&D가 적합하지 않나 싶습니다.

사실 R&D는 요구사항이 계속해서 바뀌는 프로젝트 중 하나입니다. 

진행을 하다보니 시스템의 구조가 틀어져버린다거나, 아무래도 새로운 요구가 들어가야한다던가 여러가지 이유로 계속해서 변동에 유연해져야하는 경우가 많이 발생하죠. 특히 연구가 진행이 되고 있는 상태라면 그 연구에 맞춰지기 위해 요구도 계속해서 변동하는게 R&D라고 생각하고 있습니다.

그렇기에 애자일방법론(XP방법론)을 사용해서 고객과의 끊임없는 커뮤니케이션을 통해 Prototype을 만들어내고 테스트함을 반복함으로써 고객에게 만족도가 높은 시스템에 가까워지는 방법이라고 생각합니다.

 

폭포수 모델 이야기를 꺼내다가 잠시동안 애자일 방법론을 이야기해봤지만, 저는 보통 두가지를 다 경험해가면서 진행을 하고 있습니다.

어떤때는 개발보다 분석과 설계를 통한 문서화를, 어떤때는 문서보다는 개발이 앞서서 진행이 되어 PM과 PL과 소통해가며 프로토타입을 최단시간으로 또 최상의 퀄리티를 내기위해 노력하기도 하죠.

 

다만 이런 방식을 택하기 위해서는 위에서 말한것처럼 계획을 철저히 지켜나가는 '노빠꾸' 폭포수 모델이 굉장히 좋아보일 수 있으나.. 제 생각으로는 어느정도 규모가 있는 프로젝트에서는 폭포수 모델이, 규모가 적고 투입되는 인원이 적어지는 프로젝트에서는 애자일 모델이 가장 적합하다고 생각합니다. (위에서 말했던 R&D와 같은 타입)

이유는 규모가 있는 프로젝트(투입인력이 많고 프로젝트가 큰 경우)의 경우 어느정도 규모가 있는 만큼 고객의 요구사항이 어느정도 정립이 되어 있다고 보여집니다. 그런 경우 철저한 계획을 수립하고 수립된 계획대로 요구에 맞춘 분석, 설계를 진행하여 알맞은 결과를 내어주는게 필요하다고 생각을 하고 있습니다.

반면 규모가 적은 프로젝트(투입인력이 적고 프로젝트가 상대적으로 작다 싶을때)의 경우 고객과 팀원간의 커뮤니케이션을 통해 정립이 덜 된 프로젝트를 눈치껏(?) 빠르게 만들어주는게 중요하다고 보여지기 때문입니다.

그만큼 애자일의 경우 (여기서는 XP방법론을 예시로 들어보겠지만), 고객 - (PM, PL) - 팀원들간의 커뮤니케이션이 제일 중요하게 부각이 되는게 그 이유중 하나입니다.

 

실제로 프로젝트 진행시에도 상황에 따라서(규모 혹은 요구사항 등) 폭포수나 XP방법론을 사용하고 있습니다.

 

위에서 적은 내용은 저의 생각일 뿐이고 어느 하나가 더 좋다고도 할 수 없는 방법론들이지만, 현재 자신의 팀원이 처한 상황에서 가장 효율좋은 방법을 찾아내는게 중요하지 않을까 싶습니다.

 

PM, PL분들 모두 고생많으시고 멋지십니다! 화이팅입니다! (갑자기???)

물론 개발자들도 말이죠!ㅎㅎㅎ


 

흠흠.. 그냥 제가 만드는 프로젝트는 폭포수 모델을 베이스로 두고 있고, 폭포수 모델은 이런겁니다! 라는걸 적으려했는데.. 또 길어졌네요. 항상 이럽니다ㅠㅠㅠ 뭔 말이 이렇게 많냐 싶으시겠네요.. ㅎㅎ... 그래서 그냥 적당히 끊었습니다. ( 사실 더 주저리주저리 적어 나갈순 있는데.. 다들 졸리실겁니다.. 그 마음 다 압니다ㅠㅠ 밥먹을시간만 되면 꼭 잠 다 깨다가도 교장선생님의 말씀이 이어지면 졸리는 그... 뭔가모를 그런 분위기.. 저도 다 경험해봤거든요 ㅋㅋㅋㅋㅋㅋㅋ)

 

오늘은 그냥 제가 사용중인 프로젝트의 개발 모형에 대해서 잠깐이나마(???) 설명하는 시간을 가졌습니다. 

물론 제가 틀린부분도 있을 겁니다. (아직 많이많이 부족해서..ㅠㅠ) 이런부분들은 지적해주시면 바로바로 공부해서 수정하도록 하겠습니다!

이제 슬슬 샤워하고 Class Diagram이나 작성해봐야겠네요 ㅋㅋㅋ

는 샤워하면서 아 일단 쓴거 그냥 다 쓸껄 아쉬워하면서 생각만하다가 나오자마자 에자일방식 구조랑 내용을 좀 추가해뒀습니다 ㅋㅋㅋㅋㅋㅋㅋㅋㅋ

이빨닦으면서도 이런거 생각하고 있는 나는....(절래절래)ㅋㅋㅋㅋㅋㅋㅋㅋ

 

+ 음.. 생각해보니 내일 오전부터 중요한 회의가 있었네요. 오늘은 Class Diagram보다는 내일 오전에 있을 회의에 졸지 않기 위해 일찍 공부하고 마무리해서 조금 일찍 취침을 해야겠군요! (변명이지만 이래서 프로젝트 WBS(일정관리)를 작성하지 않았습니다 ㅠㅠ 워낙 스케쥴에 변동이 많다보니...)

 

 

 

버전정보 (v1.2)

 - v1.0 2020.07.13 배포

 - v1.1 2020.07.13 애자일 방식 구조 및 내용 추가, 오타 수정

 - v1.2 2020.07.13 내용 수정

 

* 본 게시글의 이미지에 들어간 글씨체는 네이버 나눔 글씨체인 나눔스퀘어 Bold를 사용했습니다.

* 본 게시글의 이미지는 전부 (이미지 내의 픽토그램 등) 직접 제작했음을 명시합니다.

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

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

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

 

Project.다원은 개인(karzin)이 기획, 분석, 설계, 디자인, 개발, 유지보수 등

모든 부분을 혼자 맡아 진행하는 개인 프로젝트입니다.

Project.다원 Ensemble

Karzin

abbeea@naver.com

 

 

 

 


Sidecar 지원 맥 및 아이패드


회사에서 사용중인 아이패드 5세대는 iPadOS 13을 지원함에도 불구하고 Sidecar를 지원하지 않았습니다.

제가 사용중인 맥북프로 2012와 맥북에어 2013도 지원하지 않구요..ㅠㅠ

그래서 준비했습니다! Sidecar를 지원하는 요구사항이 무엇인지 알아보도록 하죠! 


 - 맥 : macOS Catalina가 설치된 Mac

MacBook Pro 2016 및 이후 모델
MacBook 2016 및 이후 모델
MacBook Air 2018 및 이후 모델
iMac 2017 및 이후 모델
iMacPro 전체
Mac mini 2018 및 이후 모델
Mac Pro 2019 및 이후 모델

 

 - 아이패드 : iPadOS 13이 설치된 iPad

iPad Pro 전체
iPad 6세대 및 이후 모델
iPad mini 5세대
iPad Air 3세대

 


대강 봤을때 mac은 cpu 최소 6세대 이상 iPad는 ap 최소 a9x 이상부터 지원을 하는 것 같습니다.

macOS쪽은 4세대부터 지원이 되었다면 제가 가진 맥북에어 2013도 지원했을텐데 ㅠㅠ 아쉽네요.

 

 

버전정보 (v1.0)

 - v1.0 2020.07.10 배포

 

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

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

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

 

Karzin

abbeea@naver.com

 


Persona - 효율적인 UX디자인을 위한 시작


저는 학부시절 소프트웨어 공학을 굉장히 좋아했었습니다.

뭐.. 이전부터 멍때리는 시간이 있으면 무언갈 분석하거나 그려가면서 설계하는게 취미(??)이긴 했는데

그런시간을 많이 주어주는 소프트웨어 공학은 저에게 있어 즐거움 중 하나였지요.

 

오늘은 분석/설계 단계에서 사용할 수 있는 Persona(퍼소나 혹은 페르소나)에 대해서 적어볼까 합니다.

어쩌면 가장 즐거운 시간이 되겠네요.


Persona?

우선 Persona가 무엇인지에 대한 궁금증이 있을겁니다.

Persona는 쉽게 말해 나의 시스템을 사용해 줄 가상의 사용자라고 생각하시면 될 것 같습니다.

우리는 개발을 하다보면 분석/설계 단계에서 실 사용자가 될 고객들과 인터뷰를 하게됩니다.

이 인터뷰를 토대로 고객이 원하는 정보를 모아 새로운 요구사항 분석서(기술서)를 작성하기도 합니다.

하지만, 실 사용자와 인터뷰가 어렵거나, 인터뷰를 해야할 사용자가 너무 많거나 하는 경우와

실 사용자와 인터뷰를 하기 전 사전 정보 조사로 Persona를 사용하면 효과적입니다.

사전 정보조사를 통해 Persona를 생성을 하면 인터뷰시 조율이 더 편리할 수 있다는 점을 노리는겁니다.

가상의 사용자를 통해 미리 만나본 고객은 이러한 요구를 가지고 있으며, 이런 요구를 어떠한식으로 답을 해줄 수 있는지를 미리 예측을 해보다보면 실제 인터뷰시에도 많은 부분 도움이 된다는 것입니다.


효과적인 Persona

그렇다면 효과적으로 Persona의 구축방법은 무엇일까요?

위에서 말했다시피 Persona는 분석/설계단계에서 고객과의 조율이나, 수 많은 사용자를 상대로 인터뷰를 할 수 없는 경우에 사용한다고 말했습니다.

자, 우리는 위 문장에서 답을 찾을 수 있습니다.

쉽게 생각하면 실 인터뷰를 진행할 고객과 비슷한 Persona를 만드는 것입니다!

또는 수 많은 사용자들 중 많이 사용을 할 사용자분들을 타겟팅하거나, 특정 사용자(시스템을 사용할 신규 유입자나, 사용이 불편하실 수 있는 사용자분들)분들을 만들어 인터뷰하는것입니다.


Persona를 이루는 항목들

그렇다면 Persona가 만들어지기 위한 항목들은 무엇이 있을까요?

예를 들어 실사용자와 인터뷰를 한다고 합시다.

우리는 실사용자와의 인터뷰에서 다음과 같은 항목을 얻을 수 있습니다.

 - 사용자의 프로필 (외형, 이름, 연령대, 성별, 직장, 직급, 성격 등)

 - 사용자가 시스템을 사용할 이유

 - 시스템에 바라는 점 (신규)

 - 기존 시스템과 비교해 현 시스템에 바라는 점 (업그레이드 시)

 - 시스템의 장단점

위는 실사용자와의 인터뷰를 통해 얻을 수 있는 항목들입니다.

그럼 Persona는? 맞습니다. 실사용자처럼 생각을 하고 가상의 사용자를 만드는거기 때문에 위와 동일한 항목들을 가집니다.

다만 우리가 저기서 얻지 못한다면 외형이 있을 수 있으나, 이 외형은 가상의 인물을 토대로 하는 것 이기 때문에 저작권이 없는 사진을 가져다가 작성을 하면 됩니다.

 


Persona의 예시

우선 인터뷰를 위한 시작입니다.

자, 우리가 여기 사용자를 위한 ERP를 만들었다고 칩시다.

사용자는 이 신규 ERP를 사용하면서 나오는 피드백을 줄것입니다.

(이미지는 저작권 등의 문제로 제가 만든 픽토그램으로 대체하였습니다.)

 

 

Persona1

 

 - 이름 : 전하윤

 - 나이 : 26

 - 성별 : 여성

 - 직급 : 사원

 - 부서 : 인사과

 - 성격 : 꼼꼼하고 매사에 정직하게 임함, 다만 가끔씩 빼먹는게 있음.

 - 사용자는 회사에서 인사담당을 하고 있어 ERP의 인사관리 시스템을 사용해야함

 - 시스템에 바라는점 : 

  -> UI가 깔끔했으면 좋겠고, 사용시 많은 부분 편리했으면 좋겠습니다.

  -> 가끔씩 인사등록시에 필요한 정보를 빼먹는 경우가 있는데 이런 부분들을 조금 정리해서 빼먹지 않게 해주세요.

 - 사용 후 장점 : 

  -> UI가 너무 깔끔해 보는 즐거움이 있었습니다.

  -> 인사 등록 시 꼭 필요한 필드를 다르게 보여줌으로써 저도 편리하지만, 신규 직원이 들어와도 알기 편해서 너무나 좋습니다.

 - 사용 후 단점 :

  -> 여전히 프로세스의 어려움이 있습니다.

 

 

Persona2

 - 이름 : 김수현

 - 나이 : 48

 - 성별 : 남성

 - 부서 : 홍보부

 - 직급 : 부장

 - 성격 : 무엇이든 문서를 남겨야 편하다는 생각을 가짐, 항상 직원들을 생각함

 - 사용자는 회사에서 출장을 자주 다니며, 출장정보의 등록등을 위해 ERP 시스템을 사용해야함.

 - 시스템에 바라는 점 : 

  -> 나의 권한이 미치는 직원들의 출장정보를 수시로 볼 수 있으면 좋겠습니다.

  -> 결재된 문서들을 워드형태의 문서로 다운받을 수 있으면 좋을 것 같습니다.

  -> 단순히 이쁜 디자인보다 사용의 편리성을 원합니다.

  -> 요즘 트랜드에 맞춰 핸드폰이나 태블릿에서도 사용할 수 있었으면 좋겠습니다.

 - 사용 후 장점 : 

  -> 결재된 문서를 워드형태의 문서로 다운받을 수 있어 너무나 좋습니다.

 - 사용 후 단점 :

  -> 이쁘지만 편리한지 모르겠습니다.

 


Persona Worst Case

모든 Persona가 유효한 것만은 아닙니다.

간혹 시스템을 사용하지도 않거나 전혀 상관없을 법한 가상의 인물을 만들어 인터뷰를 하는 경우가 있습니다.

우리는 이런 경우를 피해야만 합니다.

왜일까요? 물어볼 필요도 없이 의미없는 행위이기 때문입니다.

시스템을 사용하지도 않을 사람의 인터뷰를 받아 어떠한 의미가 있을까요?

예시로 다음은 Worst Case에 대한 Persona를 보여드리겠습니다.

 

Persona3

 - 이름 : 박중헌

 - 나이 : 900살

 - 성별 : 남성

 - 부서 : 국자감

 - 직급 : 간신

 - 성격 : 집착이 강함, 죠스바를 좋아함.

 - 사용자는 도망을 자주 다니며, 요령있게 보기싫은 자들을 피해다님.

 - 시스템에 바라는 점 : 

  -> 내 손으로 시스템을 만들고 키워 이 세상을 내 시스템의 발 아래, 그 시스템을 발 아래, 그리하여 천하를 내 시스템 아래 둘 것이다. (?!?!!!)

  -> 테마 색상은 보라색으로 하거라

 - 사용 후 장점 :

  -> 그게 딱 그 시스템의 가치이다. (대략 만족하셨다고..)

 - 사용 후 단점 : 

  -> 파국이다. (버그가 많다고..)

 

뭐, 위는 엄청 극단적인 예이긴 하지만, 조금 와닿으면 좋겠다는 생각으로 예시를 들어봤습니다.

 


학부시절에 배웠고, 그걸 활용하고 있는 지금으로써는 한번쯤 정리하자는 생각을 가지고는 있었으나,

바쁘다는 핑계만 들이대고 많이 늦어져버린건아닌가 싶습니다. (누가 늦었다 생각했을때가 빠른법이라고 말했습...)

후..

그래도 박중헌은 조금 극단적인 예시는 아닌가 싶기는 한데..ㅋㅋㅋ

한번쯤 웃고가세요. 긴 글 읽으면 졸리기도 하고.

 

 

버전정보 (v1.1)

 - v1.0 2020.07.07 배포

 - v1.1 2020.07.08 오타 수정

 

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

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

* 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


에러해결 : Windows SDK 버전 10.0을(를) 찾을 수 없습니다.

(MSB8036)


간만에 git에서 프로젝트를 가져와 빌드를 하니 다음과 같은 에러가 뜨고 있습니다.

 

에러가 엄청 잡힐겁니다. 아마도...

 

심각도 코드 설명
오류 MSB8036 Windows SDK 버전 10.0.xxxxx.x을(를) 찾을 수 없습니다. 필요한 버전의 Windows SDK를 설치하거나, 솔루션을 마우스 오른쪽 단추로 클릭하고 [솔루션 대상 변경]을 선택하거나 프로젝트 속성 페이지에서 SDK 버전을 변경하세요.

 

원인

에러 그대로 Windows SDK 버전 10.0.xxxxx.x를 찾을 수 없어 일어나는 문제입니다.

 

해결

 - 프로젝트에 세팅된 Windows SDK 버전을 변경해줍니다.

  -> 방법은 속성 -> 일반 -> Windows sdk 버전 : 10.0(최근 설치된 버전)으로 변경하시면 됩니다.

   1. 프로젝트 속성에 들어갑니다.

    - 방법은 3가지 있습니다.

      1) Alt + Enter

      2) 상단 메뉴에서 [프로젝트] -> 맨 아래 [속성]

      3) 솔루션 탐색기에 속성 버튼 클릭하기 (하단 이미지 참조)

 

빨간 박스안에 있는 속성 버튼을 클릭!

   2. 일반 속성의 Windows SDK 버전을 변경합니다. : 10.0(최근 설치된 버전)

 

Windows SDK 버전을 변경합니다.

   3. 하단의 적용 -> 확인 그리고 빌드

 

빌드 성공!

 

 * 만일 위 방법으로 해결이 안된다면, Windows SDK의 버전이 맞지 않아 생기는 문제일 수 있습니다.

  이 경우 우선 developer.microsoft.com/ko-kr/windows/downloads/windows-10-sdk/ 로 이동합니다

 

Windows 10 SDK - Windows 앱 개발

Windows 10 SDK Windows 10, 버전 2004용 Windows 10 SDK(10.0.19041.0)는 Windows 10 앱을 빌드하는 데 필요한 최신 헤더, 라이브러리, 메타데이터 및 도구를 제공합니다. 이 SDK를 사용하여 Windows 10, 버전 2004 및 이�

developer.microsoft.com

 -> 설치 관리자 다운로드 버튼 클릭합니다.

페이지로 이동 후 설치 관리자 다운로드 클릭

 

  -> 다운로드 된 파일을 실행 및 설치를 해주세요. (작성 시 Windows SDK 버전 : 10.0.19041.0)

  -> 설치가 완료되면 PC 재시작을 요청합니다.

  -> 재시작을 하시고 프로젝트를 실행시켜보세요!

 

버전정보 (v1.0)

 - v1.0 2020.07.03 배포

 

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

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

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

 

Karzin

abbeea@naver.com

 


[Swift5] 화면 전환하기

(storyboard와 show함수 사용)


Android에서 화면전환을 할때에는 Intent를 생성하여 startActivityForResult 함수를 사용하여 다른 액티비티로 전환을 했습니다. (Manifest도 적용을 해줘야 에러가 안난다는건 잊지말아야 하구요!)

 

하지만 iOS에서는 화면전환시 어떠한형식으로 전환을 하면 좋을까요?

사실 화면전환 방법은 다양한 방법이 있지만, 오늘은 storyboard에 id를 입력해주고, controller클래스에서 show 함수를 사용하여 화면을 전환하는 형식을 배워보도록 하겠습니다.

사실 storyboard의 경우 저는 Android의 xml에 대응한다고 생각을 하고 있습니다. (조금 다른면이 많이 있지만)

때문에 Android에서의 Intent 형식과 비슷한 형식을 취하는 방법을 알려드릴까 합니다.

 

요약해서 보기

프로젝트를 생성하시고,

Main.storyboard에서 기본생성된 ViewController에는 버튼을 생성하고(다음화면으로 이동할 이벤트 발생용),

이동할 ViewController를 추가로 생성합니다.

이동할 ViewController를 선택하시고 Identity의 Storyboard ID input 상자를 입력해줍니다.

입력된 Storyboard Id를 잘 기억하고 계시고,

초기 생성된 ViewController의 class로 이동합니다.

class에서 Button의 멤버생성 및 action이벤트를 생성합니다.

생성된 action이벤트에 아래와 같은 코드를 생성합니다.

//생성된 Main.storyboard와 연동작업 (변수에 담는 작업)
let myStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
//aController에 이동할 storyBoard의 ID를 지정합니다. (다음화면의 ID)
let aController = myStoryBoard.instantiateViewController(widthIdentifier: "여기에 기억하고 계신 StoryBoard ID를 입력")
//show함수에 생성한 aController 변수를 매개변수로 넘겨줌으로써 클릭이벤트가 발생하면 이동할 storyBaord ID와 매칭되어 화면이 전환됩니다.
self.show(aController, sender: self)

 

따라해보기

0. 프로젝트를 생성하시고,

1. Main.storyboard로 이동하여 기본 생성된 ViewController와 별개로 두개의 ViewController를 생성하겠습니다.

  -> 기호에 따라 저처럼 NavigationController를 붙이셔도 됩니다!

ViewController를 추가합니다.

 

2. View를 이동하기 위한 이벤트를 걸어줄 Button을 생성합니다.

Button을 생성하고 Title를 지정합니다. (저의 경우 A Controller, B Controller라고 지었습니다.)

 

 2.1. Button에 Title을 지정하는 방법입니다.

버튼을 더블클릭해도 쉽게 변경이 가능합니다.

 - 생성된 버튼 클릭

 - 우측 상단의 Show the Attributes inspector 아이콘을 선택합니다. (선택되어있는지 확인)

 - 하단의 Title input 상자에 버튼에 보여질 Title을 입력하시면 됩니다.

 

3. 알아보기 쉽게 생성된 Controller에 각각 Label을 추가합니다.

저의 경우 A와 B로 입력했습니다. (Label의 추가 및 Title변경도 위 Button 추가하시는것처럼 진행하시면 됩니다.)

4. A를 입력한 Controller를 선택하시고,

    우측 상단의 Show the Identity Inspector 아이콘을 클릭하신 후,

    Storyboard ID input 상자를 입력해줍니다. (입력한 Storyboard ID는 잘 기억해둡니다.)

왼쪽 상자부터 클릭해가면서 차근히 따라해봅니다.

 

5. B를 입력한 Controller도 4번과 동일하게 만들어줍니다.

   단, Storyboard ID는 고유해야하므로 B는 BController등의 형식으로 입력해줍니다.

Label에 B를 입력한 Controller도 A와 동일한 작업을 해줍니다. (Storyboard ID는 다르게)

 

 -> 여기까지 Storyboard ID를 지정해 줌으로써 Android에서 xml의 android:id="@+id/~~~"와 동일한 작업을 했다고 생각하시면 되겠습니다.

 

6. 기본 생성되었던 View에 연결된 ViewController class를 storyboard와 함께 보이게 합니다.

   - 함께 보이는 방법은 우측 상단의 Add Editor on Right 버튼을 찾아 클릭하신 후, 하나는 class를 선택하시고, 하나는 storyboard를 선택하시면 됩니다.

Add Editor on Right 버튼은 이미지에 표시된 상자입니다.

7. 버튼을 우클릭한 상태로 클래스로 드래그하여 변수로 연결시켜줍니다.

여기서는 편리상 btn_a, btn_b로 생성하였습니다.

8. 7번처럼 동일한 방식으로 Action(onClick) 이벤트 함수도 생성시켜줍니다.

여기서도 편리상 onClick_a, onClick_b로 생성하였습니다.

 

9. 아래와 같이 myStoryBoard 변수의 추가와, onClick 이벤트 내 코드를 추가합니다.

여기까지 따라오셨다면 끝!

10. 실행을 해보시면 A와 B button을 누름에 따라 다른 화면(A, B)이 나옴을 확인할 수 있습니다.

 

기본 Main View
A Controller 버튼을 클릭했을때 나오는 A View

 

B Controller 버튼을 클릭했을때 나오는 B View

 

완성된 코드

class ViewController: UIViewController {


    @IBOutlet weak var btn_a: UIButton!
    @IBOutlet weak var btn_b: UIButton!
    
    //추가
    let myStoryBoard : UIStoryboard = UIStoryboard(name: "Main", bundle: nil)
    
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view.
    }
    
    
    @IBAction func onClick_a(_ sender: Any) {
        //추가
        let aController = myStoryBoard.instantiateViewController(withIdentifier: "AController")
        
        self.show(aController, sender: self)
    }
    
    @IBAction func onClick_b(_ sender: Any) {
        //추가
        let bController = myStoryBoard.instantiateViewController(withIdentifier: "BController")
        
        self.show(bController, sender: self)
    }
    
}

 

금방 정리할 줄 알았더니 시간이 좀 걸려버렸네요.ㅠㅠㅠ

 

테스트 장비 : 맥미니(2020)

 

버전정보 (v1.0)

 - v1.0 2020.07.02 배포

 

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

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

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

 

Karzin

abbeea@naver.com

+ Recent posts