종달랩 종다리 이야기

Docker run 옵션 및 활용

Computer Science/클라우드-대용량 아키텍처
반응형

Docker run 명령어를 정리합니다.

 

일반적으로 docker 이미지를 만들었다면 다음과 같이 실행하게 됩니다.

 

docker run <옵션> <이미지> <명령> <매개변수>

 

다음과 같은 형태로 만들어지게 됩니다.

docker run -it -p 8080:80 --nmae mydockerimg

여기서 사용되는 다양한 옵션들에 대해서 정리해보면 다음과 같습니다.

 

  • -i, --interactive
    • 표준 입력(stdin)을 활성화하며, 컨테이너와 연결(attach)되어 있지 않더라도 표준 입력을 유지합니다.
    • 보통 이 옵션을 사용하여 Bash 에 명령을 입력합니다.
  • -t, --tty
    • TTY 모드(pseudo-TTY)를 사용합니다.
    • Bash를 사용하려면 이 옵션을 설정해야 합니다.
    • 이 옵션을 설정하지 않으면 명령을 입력할 수는 있지만, 셸이 표시되지 않습니다.
  • --name
    • 컨테이너 이름을 설정합니다. 사용할 이름과 표시할 이름을 설정할 수 있습니다.
  • -d, --detach
    • Detached 모드입니다.
    • 보통 데몬 모드라고 부르며, 컨테이너가 백그라운드로 실행됩니다.
  • -p, --publish
    • 호스트와 컨테이너의 포트를 연결합니다. (포트포워딩)
    • <호스트 포트>:<컨테이너 포트>
      • -p 80:80
  • --privileged
    • 컨테이너 안에서 호스트의 리눅스 커널 기능(Capability)을 모두 사용합니다.
    • 호스트의 주요 자원에 접근할 수 있습니다.
  • --rm
    • 프로세스 종료시 컨테이너 자동 제거
  • --restart
    • 컨테이너 종료 시, 재시작 정책을 설정합니다.
      • --restart="always"
  • -v, --volume
    • 데이터 볼륨을 설정입니다.
    • 호스트와 컨테이너의 디렉토리를 연결하여, 파일을 컨테이너에 저장하지 않고 호스트에 바로 저장합니다. (마운트)
  • -u, --user
    • 컨테이너가 실행될 리눅스 사용자 계정 이름 또는 UID를 설정합니다.
      • --user root
  • -e, --env
    • 컨테이너 내에서 사용할 환경 변수를 설정합니다.
    • 보통 설정 값이나 비밀번호를 전달할 때 사용합니다.
      • -e GRANT_SUDO=yes
  • --link
    • 컨테이너끼리 연결합니다.
    • [컨테이너명 : 별칭]
      • --link="db:db"
  • -h, --hostname
    • 컨테이너의 호스트 이름을 설정합니다.
  • -w, --workdir
    • 컨테이너 안의 프로세스가 실행될 디렉터리를 설정합니다.
  • -a, --attach
    • 컨테이너에 표준 입력(stdin), 표준 출력(stdout), 표준 에러(stderr) 를 연결합니다.
  • -c, --cpu-shares
    • CPU 자원 분배 설정입니다.
    • 기본 값은 1024이며, 각 값은 상대적으로 적용됩니다.
  • -m, --memory
    • 메모리 한계를 설정합니다.
    • <숫자><단위> 형식이며 단위는 b, k, m, g 를 사용할 수 있습니다
      • --memory=”100000b”
  • --gpus
    • 컨테이너에서 호스트의 NVIDIA GPU 를 사용할 수 있도록 설정합니다.
      • 호스트는 NVIDIA GPU 가 장착 된 Linux 서버여야하며,
      • NVIDIA driver 가 설치되어 있어야하고,
      • docker 19.03.5 버전 이상이어야합니다.
    • GPU 모두 사용하기
      • --gpus all
    • GPU 지정해서 사용하기
      • --gpus ‘”device=0,1”’
  • --security-opt
    • SELinux, AppArmor 옵션을 설정합니다.
      • --security-opt=”label:level:TopSecret”

참조한 사이트는 다음과 같습니다.

도커의 동작 시각화 자료

 

반응형

Free NAS : 남아도는 컴퓨터리소스 응용 - OS 선정

Computer Science/클라우드-대용량 아키텍처
반응형

회사를 운영하다 보면 회사의 남는 리소스, 그중에 가장 아까운것들이 컴퓨터와 HDD/SSD등이다.

누군가 퇴사를 하게 되면, 그 컴퓨터를 다른 신입에게 주기에는 이미 시기가 많이 지나서 할당해주기도 그렇고,

그렇다고 이게 못쓸만큼 오래되지도 않았고..

 

재고에서 없애버리기에도 아깝고, 그렇다고 안버리기에는 쓸사람도 없고..

 

컴터에 환장한 친구들이 있으면 그들을 위한 장난감으로 던져주면 좋아라 할텐데,

딱히 그런 오타쿠스러운 친구들도 별로 없을때는 정말 아깝다.

 

당근마켓에 던지기에도 안타까운 이것들을 어떻게 하면 효율적으로 활용할까 생각하던 과정에,

일부 컴퓨터들의 리소스를 모아서 NAS를 만들면 어떨까 생각이 들었다.

 

일반 NAS를 구매하기에는 매우 가격이 비싸지만, 케이스만 대충 그럴싸한걸 구매하던지, 

아니면 기존 케이스에서 HDD/SDD들만 잘 고정시킬 수 있으면 가능할 것 같았다.

 

이것 저것 자료를 조사해본 결과 다음과 같은 순서대로 만들어 보기로 하였다.

 

1. NAS OS 및 환경 설정

2. 회사의 리소스 수집

3. 설치하고, 회사내트워크에서 운영

4. 외부에서 접속할 수 있도록 설정 및 운영

5. 업무의 효율성 득실계산

 

우선은, OS는 여러가지를 선택할 수 있었다.

 

TrueNAS : FreeNAS에서 시작하여 가장 많이 쓰는것으로 파악되는 NAS OS

헤놀로지 : 시놀로지 정품에서 파생된 정식은 아닌것으로 확인되는 NAS OS

XigmaNAS : Open Source기반의 Storage NAS로 FreeBSD기반이 특징이다.

OpenMediaVault : Debian Linux에 기반한 NAS 이다. 다양한 네트워크 서비스를 제공하는것이 특징이다. 

OpenFiler : x86_64시스템을 완전한 NAS로 바꿔주는 기능을 제공한다고 한다. 리눅스 커널기반 서비스이다.

Rockstor : Linux 및 BTRFS기반 NAS OS. SMB(Small and Midsize Business)클라우드 서버를 구축할 수 있다.

PetaSAN : Open Source Scale-Out SAN 솔루션으로 대규모 스케일관리와 높은 성능을 제공한다. 노드관리를 통해서 확장성과 운영성을 제공하는것이 특징이다. 

ESOS (Enterprise Storage OS) : SCST프로젝트에 기반한 기업용 Storage OS로 분산리눅스를 기초하고 있다. 

CryptoNAS : CryptoNAS 프로젝트는 데이터 암호화를 대중화하기 위해 시작되었다. CryptoNAS live-CD는 복잡한 없이 데이터를 암호화하기 위해 만들어졌다고 보면 될것 같다. 단, 해당 프로젝트는 비트코인화되면서 맛이 좀 간듯 하다.(일본어로 비트코인관련 정보만 뜨네요)

 

일부 자료들을 찾아보면 USB에 OS를 설치하고 USB로 부팅하는것도 볼 수 있다. 

개인적으로 USB로 부팅하고, 나머지 스토리지를 모두 NAS에 할당하는것도 나쁘지는 않을 것 같다.

 

위 자료들을 통한 조사 결과는 TrueNAS로 설치, OpenMediaVault를 통한 설치를 가장 유력하게 생각한다.

그래도 자료를 가장 많이 찾을 수 있고, 리눅스 기반이라는 것이 운영관리에 최적화될것 같다.

 

다음에는 회사의 어떤 리소스들을 긁어모을 것인지를 사진과 함께 정리해보자.

 

반응형

카카오톡, 페이스북, 구글 간편로그인 오류문제중 인증서부분

Computer Science/Android&iOS
반응형

디버그 모드에서는 대부분 SSO 로그인의 구현과 테스트가 쉽다.

 

하지만, 릴리즈로 바꾸는 과정에서는 새로이 인증키도 만들어야 되고, 이것으로 인증도 해야 하고, SSO 사이트에 들어가서 등록 및 키해쉬, SHA-1을 등록도 해야 한다.

 

이렇게 개발PC에서 등록한 것으로 완벽하게 테스트 마치고 앱스토어에 올렸는데, SSO오류가 나거나 앱이 그냥 뻗어버리는 경우가 발생할 수 있다.

 

카카오톡, 구글에서의 오류메시지를 실시간으로 출력해본 결과 인증이 잘못되었다고 나오는 것이다.

 

분명히 나는 제대로된 인증서로 제대로 키해쉬, SHA-1을 입력했는데...

 

만일 내가 구글플레이스토어에서 앱무결성관련 설정을 건드린적이 있다면, 이부분을 의심해야 한다.

 

구글에서는 내가 만든 앱이라도 이 인증서를 이용해서 다시 인증을 하는 작업을 하게 되는것이다. 

그로인해서 인증에 따른 MD5, SHA-1, SHA-256의 값이 변경이 되어버린채 등록이 된다.

 

그래서 내가 PC에 생성한 인증서관련 값들이 먹히지 않게 된다.

 

내가 설정한 앱에서 대충 여기까지 따라오시고, 앱서명탭을 누르면 오호라.. 구글이 비밀스럽게 사용하는 인증서 정보가 있다.

우리는 여기서 값들을 이용하기면 하면 된다.

 

만일 키해쉬를 추출해야 한다면, 

 

echo <SHA-1 인증서 지문> | xxd -r -p | openssl base64

이렇게 해서 해쉬값을 변환할 수 있다.

반응형

iOS 화면전환 및 데이터 전송방식(동기 방식)

Computer Science/Android&iOS
반응형

동기방식에서 데이터를 주고 받는 방식은 생각보다 직관적입니다.

 

Android나 일반적인 프로그램에서는 데이터를 함수를 통해서 전달하는 경우가 많습니다. 이동하려는 개체를 생성하고, 이곳에 전달할 데이터개체를 생성해서 초기값으로 넣어주고, 이동하려는 개체를 호출하는 그런 방식이 조금 일반적입니다.

 

하지만, iOS는 이부분에서 조금 더 직관적인 부분이 있습니다.

 

이제 아래 예를 통해서 해당 방식을 고민해봅시다.

 

왼쪽 ViewController는 오른쪽 ViewController에 값을 전달할거고, 오른쪽에 ViewController는 값을 전달받아서 표시하고, 수정할것입니다. 수정된 내용은 다시 왼쪽의 ViewController로 보내는 그런 순환방식입니다.

왼쪽에서 오른쪽으로 데이터를 보내고, 역시 오른쪽에서 왼쪽으로 보내는걸 상상합시다.

일단, 왼쪽에 VC를 보면 "입력되지 않았습니다."라고 표시된 3개의 값들이 있는데, 처음에는 아무런 값도 없다고 가정해봅시다.

 

먼저 중요하게 봐야 할 부분이 어느시점에 화면에 데이터값을 표시할것인가 입니다. 우선 코드를 먼저 봅시다.

 

class RegisterController: UIViewController {
  @IBOutlet var resultEmail: UILabel!
  @IBOutlet var resultUpdate: UILabel!
  @IBOutlet var resultInterval: UILabel!
  
  var paramEmail: String? = ""
  var paramUpdate: Bool? = true
  var paramInterval: Double? = 0
  
  override func viewWillAppear(_ animated: Bool){
    if let email = paramEmail{
      resultEmail.text = email
    }
    
    if let update = paramUpdate{
      resultUpdate.text = update == true ? "AutoUpdate":"No Auto"
    }
    
    if let interval = paramInterval{
      resultInterval.text = "\(Int(interval))"
    }
  }
  
  @IBAction func close(_ sender: Any){
    self.presentingViewController?.dismiss(animated: true)
  }
  
  @IBAction func showRegister(_ sender: Any){
    let uvc = self.storyboard!.instantiateViewController(withIdentifier: "FormVC")
    
    guard let vc = uvc as? FormController else {
      return
    }
    
    vc.paramEmail = self.paramEmail!
    vc.paramUpdate = self.paramUpdate!
    vc.paramInterval = self.paramInterval!
    
    uvc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
    uvc.modalPresentationStyle = .fullScreen
    self.presnet(uvc, animated: true)
  }

코드를 보면 화면전환을 present형태로 하는 것을 확인할 수 있습니다. 만일 우리가 화면전환을 NavigationController로 한다면 마지막 코드를 다음과 같이 전환하면 됩니다.

 

 //self.present(rvc, animate: true)
 self.navigationController?.pushViewController(rvc, animated: true)

 

중요한 것은 3가지 입니다.

 

- 변수의 정의

- viewWillAppear()에서 화면갱신시 이전 ViewController로부터 전달받은 값으로 화면 갱신

- showRegister() 함수에서 이동할 개체를 확인한 후 해당 개체안에 정의된 변수에 직접 값을 입력

 

내용이 그렇게 어렵지 않으므로 설명은 생략하고, 나머지 ViewController의 코드를 살펴보겠습니다.

 

class FormController : UIViewController{
  @IBOutlet weak var email: UITextField!
  @IBOutlet weak var update: UILabel!
  @IBOutlet weak var interval: UILabel!
  
  @IBOutlet weak var isUpdate: UIswitch!
  @IBOutlet weak var ControlInterval: UIStepper!
  
  var paramEmail: String = ""
  var paramUpdate: Bool = false
  var paramInterval: Double = 0
  
  override func viewDidLoad(){
    self.email.text = paramEmail
    self.update.text = paramUpdate == true ? "Auto Update":"No Auto"
    self.isUpdate.setOn(paramUpdate, animated: true)
    self.interval.text = "\(Int(paramInterfal))"
  }
  
  @IBAction func onSwitch(_ sender: UISwitch){
    if sender.isOn == true{
      self.update.text = "Auto Update"
    } else {
      self.update.text = "No Auto"
    }
  }
  
  @IBAction func onStepper(_ sender: UIStepper){
    let value = Int(sender.value)
    self.interval.text = "\(value)"
  }
  
  @IBAction func onSubmit(_ sender: Any){
    let preVC = self.presentingViewController
    
    guard let vc = preVC as? RegisterController else {
      return
    }
    
    vc.paramEmail = self.email.text
    vc.paramUpdate = self.isUpdate.isOn
    vc.paramInterval = self.ControlInterval.value
    
    self.presentingViewController?.dismiss(animated: true)
  }
}

여기서도 주의깊게 볼 부분은 다음과 같습니다.

 

- 변수의 정의

- viewDidLoad()에서 외부로부터 전달받은 값으로 화면을 구성

- onSubmit() 함수에서 되돌아갈 ViewController를 그에 맞는 class로 형변환후 변수를 저장

 

여기서도 present에 대응하는 코드로 작성되었지만, NavigationController를 이용했다면 다음 함수만 변경해주면 됩니다.

 //self.presentingViewController?.dismiss(animated: true)
 self.navigationController?.popViewController(animated: true)

 

마지막으로 Segue를 통한 화면전환시의 데이터전달만 마지막으로 정리해봅시다.

 

모든 코드에서는 이동할 또는 돌아갈 ViewController를 미리 인지하고 그에 맞게 class를 변환해서 데이터를 넣어주었습니다. 그런데, Segue는 그런 과정이 없습니다. Segue를 통한 이동시에는 해당 Segue를 identifier를 통해서 호출하기만 했습니다. 그러면 데이터를 넣어주는 시점이 언제일까? 

 

- prepare()를 통해서 segue를 통한 이동/반환시에 해당 목적지를 구분해서 데이터를 넣어줍니다.

 

@IBAction func onPerformSegue(_ sender: Any){
  self.performSegue(withIdentifier: "ManualSubmit", sender:self)
}

override func prepare(for segue: UIStoryboardSegue, sender: Any?){
  let dest = segue.destination
  guard let vc = dest as? ResultViewController else {
    return
  }
  
  rvc.paramEmail = self.email.text!
  rvc.paramUpdate = self.isUpdate.isOn
  rvc.paramInterval = self.interval.value
}

prepare함수를 오버라이드해서 그 시점에 이동할 ViewController를 확인하고 데이터를 넣어주면 됩니다. Action Segue일때도 해당 함수를 통해서 데이터를 넣어주면 됩니다.

 

 

반응형

iOS 화면전환 및 데이터 전송방식(비동기 방식)

Computer Science/Android&iOS
반응형

화면전환시 데이터를 주고받는 방식은 동기식, 비동기식으로 나눌 수 있습니다.

 

비동기식은 별도의 저장소를 두고 그곳에 데이터를 저장하고, 상호 데이터를 조회하는 방식입니다.

 

갑을 주고받는다기 보다는 글로벌한 곳에 데이터를 두고 상호참조하는 방식으로 이해하면 됩니다.

 

그러면 어디에 데이터를 저장하고 읽고, 쓰기를 진행하면 될까요.

 

1. AppDelegate를 이용한 접근

 

Swift의 모든 개체가 다 접근할 수 있는 AppDelegate class가 적합합니다.

 

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  var window: UIWindow?
  
  var paramEmail: String?
  var paramUpdate: Bool?
  var param.....

여기에 변수를 정의합니다.

 

그러면 해당 데이터는 어떻게 접근할까요?

@IBAction func onSubmit(_ sender: Any){
  let ad = UIApplication.shared.delegate as? AppDelegate
  
  ad?.paramEmail = self.email.text
  ..

다음과 같이 UIAppliation에 접근해서 데이터를 바로 읽고, 쓰면 됩니다.

 

2. UserDefaults 객체를 이용한 방법

iOS에는 코코아 터치 프레임워크가 있습니다. iOS의 전통적인 프레임워크이고 swift에서도 사용이 가능합니다. 이 개체의 장점은 앱을 삭제하기 전까지는 반영구적으로 사용이 가능하다는 것입니다.

 

내부적으로 plist파일을 이용하여 값을 저장관리합니다. 기존에는 UserDefaults객체에 NSData, NSString, NSNumber와 같이 코코아 프레임워크에서 사용하는 데이타타입만 저장이 가능하지만, Swift에서는 기본 데이터타입도 저장관리가 가능해진 부분이 있습니다.

 

데이터에 읽고 쓰는 코드만으로 설명은 줄여도 될것 같습니다.

 

@IBAction func onSubmit(_ sender: Any){
  let ud = UserDefaults.standard
  
  ud.set(self.email.text, forKey: "email")
  ud.set(self.isUpdate.isOn, forKey: "isUpdate")
  ud.set(self.interval.value, forKey: "interval")
  
  self.presentingViewController?.dismiss(animated: true)
}

이 코드는 UserDefault에 데이터를 저장하게 됩니다.

 

overide func viewWillAppear(_ animated: Boole){
  let ud = UserDefaults.standard
  
  if let email = ud.string(forKey: "email") {
    resultEmail.text = email
  }
  
  let update = ud.bool(forKey: "isUpdate")
  resultUpdate.text = (update == true ? "Auto Update":"No Auto")
  
  let interval = ud.double(forKey: "interval")
  resultInterval.text = "\(Int(interval))"
}
반응형

iOS 화면전환 및 데이터 전송정리(Segue를 이용한 전환)

Computer Science/Android&iOS
반응형

4. Segue

 

Segue는 화면간의 연결을 표시하는 링크와 같다고 저는 이해했습니다. 그것의 이름이 Segue고요.

No Coding환경에서 Segue는 굳이 이름이 없어도 되는 경우가 많습니다. 하지만, 이건 기존 개발자들에게는 매우 불안한 요소입니다. 왜 불안하냐면.. 그냥 이름이 없으니까요.

 

코딩없이 우리가 Segue를 이용한것을 "Action Segue"라고 합니다. 버튼, 테이블 셀의 이벤트 트리거에 자동으로 연결이 되기 때문입니다.

Action Seguq라고 이름이 나옵니다. 오른쪽 마우스버튼으로 호출되는 메뉴입니다.

이건 굳이 우리가 프로그래밍 하지 않아도 되고, Storyboard를 통해서 직관적(?)으로 알 수 있습니다. 

사실 직관적이지는 않죠. 화면이 많으면 더더욱.. 하지만 코딩을 하지 않는것이 어디입니까.

 

이것말고 우리는 프로그램으로 제어하는 방법을 알려드리고자 합니다. 이걸 "Manual Segue"라고 합니다.

 

Action Segue는 버튼과 같은 컨트롤과 ViewController간의 관계입니다. 그렇기 때문에 해당 버튼의 동작과 연결시킬 수 있었습니다. 하지만, Manual Segue는 ViewController간의 관계를 정의해주고 이름을 명명해줘야 합니다. 역시 그림으로 설명합니다.

Manual Segue는 다음과 같이 생성합니다.

 

Action Segue는 다음과 같이 컨트롤과 Segue를 하일라이트 합니다.
Manual Segue는 ViewController를 전체로 표시합니다.

이제 우리는 Segue의 이름을 정해줘야 합니다.

Seguq의 이름은 Identifier에 넣으면 됩니다.

이제 버튼을 누르면 Segue를 통해서 화면전환하는 코드를 작성합니다. 이때 사용하는 함수와 예제 코드는 다음과 같습니다.

@IBAction func wind(_ send: Any){
  self.performSegue(withIdentifier:"ManualWind", sender:self)
}

여기서 함수 이름을 왜 wind라고 졌을까요. 지금까지 작명과는 다른데 말이죠.

 

화면전환하는 것을 iOS에서는 wind된다고 합니다. 그럼 그 반대는 unwind이겠죠.. 

 

여기서 재미있는것은 unwind되는 시점을 각각의 ViewController안에 작성해야 한다는 것입니다. 그래야 우리는 unwind되는 곳의 함수를 불러서 그쪽으로 이동하게 됩니다.

 

@IBAction func wind(_ send: Any){
  self.performSegue(withIdentifier:"ManualWind", sender:self)
}

@IBAction func unwindToVC(_ segue: UIStoryboardSegue){}

위 코드뭉치를 보면 wind를 통해서 해당 segue와 연결된 ViewController로 이동을 하게 됩니다. 그런데 복귀되는 함수도 같이 있습니다. 즉, 이 함수를 통해서 우리는 현재의 ViewController로 돌아오게 됩니다.

 

unwindToVC는 오른쪽 ViewController의 상단 "Exit"버튼과 연결됩니다.

ViewController에는 항상 위에 3개의 버튼이 있습니다. 그중에 가장 마지막에 "Exit"가 이런 unwind함수들과 연결이 됩니다.

 

unwind함수를 만드는것은 간단합니다. 함수 parameter에 (_ segue: UIStoryboardSegue) 만 정의하면됩니다. 그러면 swift가 전체 코드에서 다음과같은 parameter가 있는 함수들 리스트를 보여주고, 우리는 돌아갈 ViewController의 unwind함수만 선택하면 됩니다.

위에 그림을 보면 왼쪽에 Exit 바로 밑에 unwind가 있는것을 볼 수 있습니다.

 

버튼을 Exit와 연결시킵니다.
unwind함수들 즉 함수 parameter가 (_ segue: UIStorygoardSeguq) 인 함수리스트를 보여줍니다.

물론 전에 unwind함수를 표시하므로 내가 가야할 곳의 ViewController의 함수를 잘 선택해야 합니다.

 

휴.. 지금까지 속성으로 화면전환을 정리했습니다.

 

기존 개발자는 화면 컨트롤만으로 동작하는게 너무 힘들었습니다. 하지만, 익숙해지면 되는문제였습니다. 다만, 한번에 코드안에서 파악이 안된다는것은 아직도 생소합니다.

 

화면전환은 총 3가지 입니다.

- present(_, animated:) <-> presentingViewController.dismiss()

- navigationController.pushViewController() <-> navigationController.popViewController()

- performSegue(withIdentifier:,sender:) <-> unwind 함수

 

다음에는 화면전환시 데이터를 어떻게 주고 받는지를 정리합니다.

 

반응형

iOS 화면전환 및 데이터 전송정리(Navigation controller)

Computer Science/Android&iOS
반응형

3. 네비게이션 컨트롤러 (Navigation Controller)

 

네비게이션 컨트롤러는 다양한 페이지들이 서로 연관이 있다면 호출하고 다시 되돌아오는데 기본적인 편리성을 제공하는 View Controller입니다.

기존에 present는 화면전화 및 복귀를 내가 직접 코딩해야 했고, 복귀할때 적어도 1개의 버튼을 만들어야 했지만, Navigation Controller는 이러한 부분을 자동화 해준다고 보면됩니다.

 

기존 오래된 개발자 입장에서는 이 부분을 어떻게 이해해야 하나 고민했지만, 역시 오래보면 익숙해진다고, 그냥 익숙해지면 됩니다.

 

Navigation Controller를 만들기 위해서는 처음부터 Navigation Controller를 화면에 추가하거나, 기존의 ViewController에 Navigation Controller를 embed시키면 됩니다. 말로 풀어쓰면 어렵고, 화면을 보고 설명합시다.

 

Library입니다.

Library에서 Navigation Controller를 추가합니다. 이러면 다음과 같이

Library에서 Navigation Controller를 선택
화면에 2개의 View Controller가 표시가 됩니다.

표시가 됩니다. 기본적으로 Table View Controller가 추가가 됩니다. 여기서 Table View Controller안에 컨트롤을 삭제하고 마치 새것처럼 작업해도 됩니다. 

 

저는 이 방법보다는 기존에 사용하던 View Controller가 있다면, 거기에 Navigation Controller를 추가하는게 더 맘에 편합니다. 이 방법은

ViewController를 선택하고 메뉴에서 다음과 같은 기능을 선택합니다.

그림에 자세히 설명이 되어있습니다. View Controller를 선택하고, Editor/Embed In/Navigation Controller를 선택하면 됩니다.

 

Navigation Controller 와 연결된 View Controller들은 Navigation Item이 자동으로 생성되고, 뒤로가기가 자동으로 생성됩니다.

그렇습니다. 이렇게 자동으로 뒤로가기가 생성이 됩니다. 물론 Navigation Controller와 연결을 시켜야 하지만요.

 

연결시키는 방법은 오른쪽 마우스 버튼으로 연결시키면 됩니다.

연결여부는 여기를 통해서 확인됩니다. Show 형태로 되었습니다. 이건 뭘 의미할까요.

사실 이러한 연결은 No coding형태입니다. Present에서도 이야기 드렸듯이 코딩으로 또는 No coding으로 구현이 가능합니다.

 

위에 마우스가 아닌 버튼에 함수를 설정하면 다음과 같을 것입니다. 

 

@IBAction func moveByNavy(_ sender: Any){
  guard let uvc = self.storyboard?.instantiaterViewController(withIdentifier: "SecondVC") else{
    return
  }
  
  self.navigationController?.pushViewController(uvc, animated: true)
}

navigationController의 pushViewController(_, animated:)를 이용한것입니다. 그래서 Show(e.g. Push)로 표시가 되는 것입니다.

 

뒤로가기 위해서는 자동으로 뒤로가는 버튼이 생성이 됩니다. 물론 이것도 우리는 코딩으로 처리할 수 있습니다.

 

@IBAction func back(_ sender: Any){
  self.navigationController?.popViewController(animated: true)
}

여기서 조심해야 할것은 NavigationController를 이용하게 되면 우리 의지와는 상관없이 NavigationItem이 추가로 생성되고, 왼쪽에 뒤로가기 버튼이 자동으로 생성된다는 것입니다. UI충돌을 막기 위해서는 View Controller의 왼쪽상단에 Navigation Item이 생성되는것을 고려한 UI디자인이 필요합니다.

반응형

iOS 화면전환 및 데이터 전송정리(present without coding)

Computer Science/Android&iOS
반응형

2. present를 이용하되 화면디자인만으로 처리하는 방법

 

기존 전통적인 개발자 입장에서 이 방법은 오히려 이해가 어려웠던 부분입니다. 마우스 오퍼레이팅만으로 코딩없이 화면을 호출한다는 개념이 말입니다.

익숙해지면 쓸만하지만, 생각보다 어려웠습니다. 

"만일 코드를 수정해야 하는데, 이걸 화면에서 뒤져서 찾아내야 하나.."

물론, 익숙해지기까지 적잖은 시간이 걸렸지만, 우선은 외우는거죠.

 

우선 ViewController를 만들고 버튼을 하나 만듭니다. 그리고, 이동할 ViewController도 하나 만들어야 합니다. 뭐, 화면을 그리듯이 만들면 됩니다. 

 

 

첫번째 ViewController이고, 위 하일라이트된 버튼에 대한 동작을 정의할것입니다.
두번째 ViewController 입니다. 여기로 이동합니다.

그러면 코디없이 어떻게 이 두개의 페이지를 버튼으로 연결시킬까요?

 

버튼을 선택하고 오른쪽 마우스버튼을 누르고 두번째 ViewController를 선택하고 나면 다음과 같은 팝업메뉴가 뜹니다.

여기서 저는 "Present Modally"를 선택했습니다. 각각의 멘뉴는 시간내서 한번씩 선택해보면 도움이 됩니다. 이렇게 선택하면

Segue의 도형모양이 어떤 동작을 선택했는지 알려줍니다.

이렇게 연결이 생기는데 이걸 "Segue"라고 합니다. "세그"라고 읽어버립시다. 이렇게 하면 코딩없이 해당 페이지가 보여지게 됩니다. 만일 페이지가 팝업처럼 보인다면 위 Segue를 선택하고

Presentation을 선택합니다.

Presentation을 "Full Screen"으로 선택하면 화면을 꽉 채워줍니다.

@IBAction func moveToBlueTest(_ sender: Any){
  let uvc = self.storyboard!.instantiateViewController(withIdentifier: "BluetoothTestVC")
  uvc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
  self.present(uvc, animated: true)
}

 

이러함 코드를 직접 작성하지 않아도 되는 것입니다. 

 

이제.. 화면을 복귀해야겠지요. 

 

present를 이용한것과 똑같다고 이야기 한것 기억하시고, 두번째 ViewController에서 "Close"버튼에 다음과 같은 코드를 작성합니다.

 

@IBAction func close(_ sender: Any){
  self.presentingViewController?.dismiss(animated: true)
}

예.. 이 버튼을 클릭하면 이제 화면을 dismiss하게 됩니다.

 

그런데, 화면표시를 아무 코딩없이 했는데, 화면닫기는 왜 코딩을 해야 하나 궁금할 수 있습니다. 이건 다음다음편에.. Unwind기법으로 소개합니다.

반응형

iOS 화면전환 및 데이터 전송정리(present)

Computer Science/Android&iOS
반응형

1. present 메소드 활용

 

ViewController를 생성하고 버튼도 하나 만드어 본다 (BlueTest)
두번째 ViewController를 만든다. 이때 해당 ViewController의 이름을 설정한다. "BluetoothTestVC"로 명명한다.
두번째 ViewController의 이름을 설정한다.

"BlueTest" 버튼을 클릭하면 동작할 함수를 다음과 같이 정의한다. 화면이동을 위한 첫번째 코드입니다. 물론 첫번째 ViewController를 위한 클래스는 정의해야 합니다.

 

@IBAction func moveToBlueTest(_ sender: Any){
  let uvc = self.storyboard!.instantiateViewController(withIdentifier: "BluetoothTestVC")
  uvc.modalTransitionStyle = UIModalTransitionStyle.coverVertical
  self.present(uvc, animated: true)
}

첫번째 ViewController에서 다음과 같은 코드를 통해서 두번째 ViewController로 이동하게 됩니다.

 

두번째 ViewController에서 화면을 종료하기 위해서는 다음과 같은 코드를 작성합니다.

 

@IBAction func Close(_ sender: Any){
  self.presentingViewController?.dismiss(animated: true)
}

해당 코드에서는 자체적으로 종료하는 것이 아니라, presentingViewController(즉, 현재 이 페이지를 호출하게 해준 ViewController를 통해서 화면을 닫도록 요청해야 함)를 통해서 현재 ViewController를 종료하도록 합니다.

 

여기서 만일 다시 self.presnet() 함수를 사용하게 되면, 화면을 닫는 것이 아니라 새로운 화면을 하나 더 만들어서 쌓게 됩니다. 메모리가 불필요하게 낭비가 되겠죠. 반드시 화면을 종료한다고 생각하고 화면을 닫아(dismiss) 해야 합니다.

반응형

섬유 산업의 인공지능 - 현재와 미래의 응용분야

Computer Science/인공지능
반응형

자세한 내용은 아래 링크를 참조하십시오.

https://emerj.com/ai-sector-overviews/artificial-intelligence-in-the-textile-industry-current-and-future-applications/

 

Artificial Intelligence in the Textile Industry – Current and Future Applications | Emerj

This article explores AI use-cases in the textile industry, including machine vision for fabric and weave error detection, inventory management, and...

emerj.com

섬유 산업의 인공 지능 - 현재와 미래의 응용 분야

2019 년 2 월 13 일 최종 업데이트, Raghav Bharadwaj 발행

Raghav는 Emerj에서 컨텐트 리드로 일하고 있으며, 주요 산업 분야를 다루고 연구를 수행합니다. Raghav는 로봇 공학에 개인적인 관심을 가지고 있으며 Frost & Sullivan 및 Infiniti Research와 같은 연구 회사에서 근무했습니다.

공유 대상 :

링크드 인 지저귀다 페이스 북 이메일

의류 및 섬유 제조는 역사적으로 노동 집약적 산업왔다 , 세계 최대 규모의 패션, 의류 및 의류 브랜드의 몇에서 본  자사 제품의 상당 부분은 등 중국, 인도, 방글라데시, 베트남 등 아시아 국가에서 제조 가지고 .

동쪽으로의 섬유 제조업의 이주는 아시아 국가들 (특히 중국 ) 에서 노동 비용이 상승하기 시작한 지난 수십 년 동안 일어났습니다 . 업계에서 산업 자동화의 보급률  증가함에 따라 과거 및 실시간 운영 데이터에 액세스 할 수있는 섬유 제조업체는 AI를 활용하여 효율성을 높이고 직원들의 능력을 향상시킬 수 있습니다.

독자는 섬유 제조 산업에서 인공 지능 응용 프로그램의 채택이 아직 이르다는 것을 알아야하며, 몇 가지 유스 케이스가 있지만 (많은 부분을 아래 섹션에서 살펴 보았 음), 널리 보급 된 것으로 보이지 않습니다 인공 지능은 선진국에서도 마찬가지입니다.

대신, 우리는 오늘날 섬유 산업 분야에서 인공 지능을 적용 할 가능성과 향후 2 ~ 5 년 동안 산업 분야에서 AI가 수행 할 수있는 가능성을 탐구합니다.

아래의 기사를 현재 및 미래의 응용 프로그램으로 나누어 기업 및 사례를 개별적으로 검토하여 비즈니스 가치를 탐구했습니다.

(이 기사는 섬유 및 직물 응용 분야에 대해서만 다루며 패션에 대해서는 다루지 않을 것입니다. 유행에 관심이있는 독자 는 Fashion에서 AI 기사 전체 기사를 읽을 수 있습니다 .)

현재 응용 프로그램

Cognex - 패브릭 패턴 검사

1981 년 Boston에 설립되어 현재 1000 명 이상의 직원이 근무하고있는 Cognex Corp.은 머신 비전 시스템, 소프트웨어 및 센서의 미국 제조업체입니다. 이 회사는 직물 업계에서 패브릭 패턴 인식을 위해 맞춤 제작 된 머신 비전 기반의 Cognex ViDi 플랫폼을 제공합니다.

Cognex는 Cognex ViDi 플랫폼이 직조, 편직, 편조, 마무리 및 인쇄와 같은 패브릭 패턴의 측면을 자동으로 검사 할 수 있다고 주장합니다. 이 회사는 또한 플랫폼을 제조 시스템에 통합하기위한 개발 기간이 필요하지 않으며, 훌륭한 원단 샘플을 미리 정의 된 이미지를 사용하여 교육 할 수 있다고 제안합니다.

출처 - vision-systems.com

서면 작성 당시 Cognex의 ViDi 기술의 성공적인 사용 사례 목록을 찾을 수 없었습니다. 기술이 연구 개발 단계 또는 파일럿 단계에 있거나 현재 고객이 이름으로 식별 할 수있는 권한을 부여하지 않았을 수 있습니다.

반응형