메일: https://mail.worksmobile.com

주소록: https://contact.worksmobile.com

 

LINE WORKS를 이용하기 위한 접속 URL이 어떻게 되나요?

LINE WORKS 브랜드사이트 우측상단의 ‘My 서비스’를 클릭하면  로그인을 거쳐 Lite 상품 이용자는 홈 서비스로, Basic 또는 Premium 상품 이용자는 메일 서비스로 접속할 수 있습니다.

그 외 이용 중인 상품에 따라 아래의 각 서비스 페이지로 로그인해서 직접 접속할 수 있습니다.

Lite 상품

Basic 또는 Premium 상품

 

help.worksmobile.com/kr/topic/common/support-environment/urls-to-access-line-works/

 

LINE WORKS를 이용하기 위한 접속 URL이 어떻게 되나요? – 주제별 질문 – LINE WORKS 헬프센터

LINE WORKS 브랜드사이트 우측상단의 ‘My 서비스’를 클릭하면  로그인을 거쳐 Lite 상품 이용자는 홈 서비스로, Basic 또는 Premium 상품 이용자는 메일 서비스로 접속할 수 있습니다. 그 외 이용 중인

help.worksmobile.com

참... 오래 간다. 이 버그 ㅠㅠ 그냥 포스팅 해 두는게 낫겠다.

'블로그 항해 일지 > Tips' 카테고리의 다른 글

어제 오늘 방문자 수  (0) 2019.02.08
powergrep exclude  (0) 2019.01.22
포스트맨 정말 좋다.  (0) 2019.01.11
github에서 repo 미리 만들고 커맨드로 머지하기  (0) 2019.01.07
파이썬 관련 주요 인물  (0) 2019.01.06

<!-- 방문자수 -->

<div class="section">

<div class="tx">

<p class="today">today : </p>

<p class="yesterday">yesterday : </p>

</div>

</div>

today :

yesterday :

*.bin;*.bmp;*.buildinfo;*.bz2;*.cnf;*.conf;*.conv;*.csm;*.cs??s;*.csv;*.da;*.dat;*??.de;*.dic;*.dist;*.d??octree;*.dtd;*.en;*.??ent;*.eot;*.err;*.es??;*.euc-kr;*.exp;*.fi??le;*.fr;*.frm;*.gif;??*.gitignore;*.gz;*.h??;*.hhvm;*.htaccess;*??.html;*.icc;*.ico;*.??inc;*.ini;*.ini-deve??lopment;*.ini-produc??tion;*.inv;*.jpg;*.j??s;*.jshintrc;??*.koi8-;*.lang;*.lib??;*.log;*.map;*.md;*.??mediawiki;*.mo;*.myd??;*.myi;*.new;*.nocov??erage;*.ods;*.opt;*.??pdb;*.phar;*.php;*.p??html;*.pickle;*.pid;??*.pl;*.png;*.propert??ies;*.pt-br;*.py;*.r??st;*.sh;*.so;*.sql;*??.sty;*.svg;*.sys;*.t??pl;*.trg;*.trn;*.ttf??;*.txt;*.types;*.utf??8;*.var;*.woff;*.exe;*.obj;*.dll




json 은 제외했다.



그런, 크롬 플러그인 때가 더 그립긴 하다.


구글에서 하나 만들어서 넣어줘도 좋을 듯.


'블로그 항해 일지 > Tips' 카테고리의 다른 글

어제 오늘 방문자 수  (0) 2019.02.08
powergrep exclude  (0) 2019.01.22
github에서 repo 미리 만들고 커맨드로 머지하기  (0) 2019.01.07
파이썬 관련 주요 인물  (0) 2019.01.06
Android 개발자 iOS전환 - 2  (0) 2019.01.03

git init

git add .

killall gpg-agent //제껀 좀 꼬여서...

git remote add original git@github.com:hajunho/iOS_project_pad.git

git fetch

git remote -v //original 이름 확인

git remote set-branches original

git pull original master --allow-unrelated-histories

git push --set-upstream original master



------------------


echo "# Myproject" >> README.md

git init

git add README.md

git commit -m "first commit"

git remote add origin git@github.com:hajunho/myProject.git

git push -u origin master

'블로그 항해 일지 > Tips' 카테고리의 다른 글

powergrep exclude  (0) 2019.01.22
포스트맨 정말 좋다.  (0) 2019.01.11
파이썬 관련 주요 인물  (0) 2019.01.06
Android 개발자 iOS전환 - 2  (0) 2019.01.03
Android 개발자 iOS전환 - 1  (0) 2019.01.03
  1. 귀도 반 로섬 (Guido van Rossum): 파이썬의 창시자로, 그의 기여와 이 언어에 대한 지속적인 관심으로 커뮤니티에서 가장 높은 존경을 받습니다.
  2. 레이몬드 헤팅거 (Raymond Hettinger): 파이썬 코어 개발자이자, 파이썬의 내장 기능과 라이브러리 개발에 중요한 기여를 한 인물입니다. 그는 또한 탁월한 강연자로도 유명합니다.
  3. 데이비드 비즐리 (David Beazley): 파이썬 교육자이자 저자로, 'Python Essential Reference'와 같은 중요한 파이썬 책들을 저술했습니다. 그는 또한 파이썬의 고급 기능과 내부 작동 원리에 대한 심층적인 이해를 공유합니다.
  4. 트레비스 올리판트 (Travis Oliphant): 과학 계산을 위한 파이썬의 주요 라이브러리인 NumPy의 주요 개발자 중 한 명이며, SciPy와 Anaconda의 공동 창시자입니다.
  5. 캐롤 윌링 (Carol Willing): 파이썬 소프트웨어 재단 이사회 멤버이자, 교육과 다양성 증진을 위한 활동으로 존경받습니다.

 

 

2편이다.


각 언어의 특징으로만 보라는 이상한 말


내가 좋아하는 책이라 여러 권을 산 책이 있다. Objective-C라는 책인데 난 2권 다 있다. 물론, 내가 책을 쓸 때도 이 책의 영향을 많이 받았다.(2.0버전) 마크 달림플(Mark Dalrymple), 스콧 내스 터(Scott Knaster), 와카르 말릭(Waqar Malik). 실무 개발자 3인방의 내공을 책으로도 크게 느낄 수가 있다. 사실, 실무를 오래 한 프로그래머가 깊게 파보면 다른 프로그래밍 언어 책과 큰 내용 차이는 없다. 작은 두 가지의 의견을 새롭게 낼 뿐이었다. 그러나 그 작은 의견은 아는 사람이 보면, 프로그래밍의 정수를 담은 것이라 하겠다. indirection layer와 이 세상의 문제를 완벽하게 해결해 줄 수 있는 단일 프로그래밍 언어는 존재하지 않는다는 것이다. 그래서 각 언어의 특징은 그 언어로 이해하라는 식의 글귀가 있었다.(책 뽑아서 보면 되지만 너무 아래 깔려 있다 ㅠ)


그중 후자는 시중의 책에서 가장 많이 인용되어 잘못 생각하는 사람이 많이 생겨나는 것 같아서 몇 글자 적어 본다. 다른 책이 원조일 수도 있겠지만, 그들의 프로그래밍 역사로 봤을 때 벤치마킹이 분명하다. 후자는 프로그래밍 언어는 바로 그 언어의 특징으로만 봐야 한다는 말이다. 어느 책이나 이 말을 돌려서 하던지, 직접적으로 적던지... 비슷하게 쓴다.


미국에서 사는 사람들의 문화, 한국 사람의 문화. 다르고 언어도 그 문화의 다름과 같이 1:1로 완벽하게 대치될 수 없는 부분이 있다. 그러나 뿌리가 판이하게 다르고 역사도 너무도 깊다. 그에 반해 컴퓨터의 역사를 깊지도 않고 그 뿌리는 결국 인텔 프로세서다. 혹은, ARM Instruction Set이다.


3인방이 말한 것도 한 가지 언어를 배울 때 집중해서 깊게 이해라 하는 뜻이지. 이기종의 언어에서 말하는 똑같은 개념까지도 다르게 표현하라는 뜻은 아니다. 한국말에 있는 부모님 마음속의 한, 인연 등 문화적 관점에서 이해해야 할 부분도 있거니와. 영어 사전에서 쉽게 찾을 수 있는 한국말은 같다고 봐도 무방하듯이 각 프로그래밍 언어의 비슷한 부분은 비슷하게 이해하면 된다.


상속, 다형성, 캡슐화, interface, delegate, abstract, protocol


요즘 코딩 교육을 일반 교사가 직접 배워서 하기 때문에 가끔 지인을 만나 비 전공자 교사의 고충을 듣는다. 사실 나도 코딩 교사가 따로 있을 줄 알았는데 말이다. 어차피 모든 지식은 학교로 다시 돌려보내야 하는 것이 맞으니 몇 가지 적어 본다. 교사는 워낙 똑똑한 사람들이라 이미 지식은 꽉 차 있다. 두리뭉실한 개념을 이 분야의 묵은지가 연결만 시켜주면 되겠다. 비공개로 출판한 책에서 밝힌 적이 있는데, 글로 쓰는건 제대로 전달되지 않지만 끄적여 본다.(장자 윤편으로 검색해서 관련 글을 보시길)


어려운 개념들은 쉽게 말해도 관계없고, 또 그게 많다.


상속은

복사/붙여 넣기.


내가 프로그래밍 수업에서 상속을 가르칠 때도 이렇게 간단히 말한다.


썰을 더 풀면,

다형성은 배열 돌려서 동시 다발적으로 실행하게 만들기 위함이라고 했는데, 사실 실무에서는 그게 다다. 

void pointer가 java에서 object type이다. 그래서 모든 객체를 가리킬 수 있고 그것을 다형성이라 부른다. 


간단한 이론이지만 이것으로 메시지 큐를 구현하고, 또 애플이나 안드로이드 앱 프레임워크를 만든다. 어떤 알림이 오면 각 앱을 list 에 등록하고 for문을 돌면서 브로드 캐스팅 메시지를 날리게 되는 것이다. 


Xcode에서 싱글뷰 어플 test 하나 만들고 Viewcontroller에 넣으면 된다.


우선 해당 글에 있던 델이게이터 예제.

//

//  ViewController.swift

//  test

//

//  Created by Junho HA on 2018. 10. 5..

//  Copyright © 2018년 hajunho.com. All rights reserved.

//


import UIKit


class ViewController: UIViewController {


    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        let a : implementMe = 지나가던사람()

        a.날사랑하니()

    }

}


protocol implementMe {

    func 날사랑하니() -> Void

}


class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


에서 implementMe 를 상속받는 친구는 implementMe type으로 생성가능하다. 추상화된 포인터로 보면 되겠다.


행인을 하나 추가하고 배열로 선언하면 다음과 같다.


//

//  ViewController.swift

//  test

//

//  Created by Junho HA on 2018. 10. 5..

//  Copyright © 2018년 hajunho.com. All rights reserved.

//


import UIKit


class ViewController: UIViewController {


    override func viewDidLoad() {

        super.viewDidLoad()

        // Do any additional setup after loading the view, typically from a nib.

        let a : [implementMe] = [ 지나가던사람() , 행인1() ]


        a[0].날사랑하니()

        a[1].날사랑하니()

    }

}


protocol implementMe {

    func 날사랑하니() -> Void

}


class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


class 지나가던사람 : 관심있던남자, implementMe {

}


class 행인1 : implementMe {

    func 날사랑하니() {

        print("누구슈")

    }

}


a[0], a[1] 은


   for x in a {

            x.날사랑하니()

        }


로 치환 가능하다.


결국, 인터페이스 하나 던져주고 아래에서 다 구현하라고 하고 어떻게 구현했던 상위 포인터(Object  던 Void Pointer던 상위 포인터든)로 하위 구현부의 메소드를 for 문 돌려서 실행시켜 주면,


모든 앱의 이름도 반환 받을 수 있고,

모든 앱을 실행시킬수도,

모두 지울 수도,

모든 앱의 메시지 수신부에 메세지를 보낼 수도 있다.


다형성은 간단한 개념이지만 매우 강력한 아키텍쳐 패턴의 주요 개념이다. 참고로 우리가 패턴이라고 하는 것들은 대부분 모듈 패턴이다.


캡슐화는

변수 마음대로 못 바꾸게 하기.

가령 속도라는 변수가 있어서 자동차를 제어한다면 그 속도가 0보다 크고 200보다 크게 세팅되어야 한다는 조건을 걸어 주는 게 좋다. 그래서 변수를 직접 제어하지 안혹, getter/setter를 쓴다.


인터페이스는 상속자(상속받은 무언가)가 구현해야 할 껍데기다.

앱스트랙트는 껍데기에 살을 좀 붙인 것이다.


껍데기는 다중 상속이 가능하다.

살이 붙은 것(내용이 있는 것)은 다중 상속이 불가능하다.


다중 상속(복사/붙여 넣기) 해봤자. 껍데기는 껍데기일 뿐이다. 구현해야 할 것만 많아진다.

제약 사항이 많다는 것은 누가 편하게 쓰라고 만들어 놓으면서 제약을 걸어 놓은 것이다.


가령 허허벌판 일 때는 규칙이 없지만, 놀이터를 만들어 줄 테니 아이들만 뛰어놀게 하라는 제약처럼.


프로토콜은 인터페이스와 같다. 다만, 다른 애들이 대신 구현해 줄 수 있다.


protocol implementMe {

    func 날사랑하니() -> Void

}


라는 프로토콜이 있다. 프로토콜은 껍데기다.

Protocol methods must not have bodies


그럼 이 프로토콜(인터페이스, abstract class)를 상속하는 클래스는 무조건 구현을 해 줘야 한다.

class 남자 : implementMe {

    func 날사랑하니() {

        print("...")

    }

}

안하면,

Type '남자' does not conform to protocol 'implementMe'

맞지 않는다고 한다.


만약 구현하고 싶지 않은 누군가가 있다고 하자

class 지나가던사람 : implementMe {

}

이 경우엔 다른 클래스가 구현해도 된다.


class 관심있던남자 {

    func 날사랑하니() {

        print("어")

    }

}


class 지나가던사람 : 관심있던남자, implementMe {

}


관심있던 남자가 날사랑하니()를 구현해 놓았었으니 복/붙하면 implementMe의 요구사항을 충족시켜준다는 뜻. UITableViewDelegate, UIScrollViewDelegate 같이 복잡한 녀석들로 이런 개념으로 쉽게 분석이 가능하다. 다른 복/붙(상속)없이 해당 델리게이트만 상속하면 구현해야할 수많은 stub이 있다.



위에서 말한 모든 개념은 사실 아래의 요구사항으로 생겼다.


1. 잘 만들어 놓으니(framework, library, api,...)

2. 네가 맘대로 복/붙해서 가져다 써(상속)

3. 그런데 몇 가지는 네가 알아서 넣어야 하니까 구현을 해야 할 거야 내가 정해놓은 규칙대로 (인터페이스, 프로토콜, 앱스 트렉트 클래스/매소드)

4. 모두 구현하기 싫으면 다른 애들이 구현한 거 그대로 상속(복사)해서 써(델리게이트)

5. 내가 만든 것의 값은 마음대로 못 바꿔(접근 제한자, 캡슐화) 수치가 0이 되면 사람이 죽을 수도 있으니 0이 들어오면 에러를 발생시켜버릴 때(setter, assert)


그래서 사실 따지고 보면 다 같은 개념은 아니다.


그러나 실무에서는 비슷하다.


모듈을 보는 단계에서는 완전히 다르고,

아키텍처를 보는 단계 해서는 부분 부분 다르고,

시스템을 보는 관점에서는 완전히 같다.


프로그래밍은 어차피 메모리와 CPU의 장난.


lambda, 함수형 프로그래밍, 클로저

 

셋 다 같은 말이다.


모든 함수는 y=f(x) 에서 나왔다.


세상 간단.


함수형 프로그래밍은 람다 대수에서 나왔다.


람다 대수의 핵심은 무언가를 추상화하는 방법과 구체화 하는 방법에 대한 철학이고.

특징은 익명 함수라는 것.


클로저는 기본적으로 함수 포인터다.


    func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }


swift 에 이런 함수를 만들었다면 C의 함수포인터로


String (*v)();

v = 주문받기


이렇게 만들 수 있을 것이다.


그러나 swift 는 문법이 쉽다.


let v = 주문받기

var v = 주문받기


쉽게 만들 수 있다. 배가 고프니 중국집을 하나 만들어 본다. 배가 고파 자장면이 아닌 입에 촥 감기는 짜장면을 불러 본다.


class 중국집 {

    func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }

}


프로그래밍은 많은 사람들이 작업을 하기 때문에 수많은 클래스에 수많은 함수가 있다. 클래스는 메모리에 없으니 생성해서 만들어 줘야 함수를 쓸 수 있다.


let a : 중국집 =  중국집()

let b = a.주문받기()


자바였다면,

중국집  a = new 중국집();

이었겠지.


클래스 생성없이 메모리에 바로 생성시키는 방법도 있다. primitive type, new, malloc, static

static 은 swift에도 있으니


  static func 주문받기() -> [String] {

        let 주문목록 : [String] = ["짜장면", "짬뽕"]

        return 주문목록

    }

로 선언하면


print(중국집.주문받기())

가 가능하다.


내가 주문하려면, 파라미터를 넣고

  func 주문받기(s : [String]) -> [String] {

        let 주문목록 : [String] = s

        return 주문목록

    }


 let c : [String] = ["짜장면", "짬뽕"]

 print(a.주문받기(s: c))


혹은


  print(a.주문받기(s: ["짜장면2", "짬뽕2"]))

로 하면 된다.


위의 위키피디아 링크 "람다대수"를 보면 함수가 반드시 이름을 가질 필요는 없다. 는 구절이 있다.

b가 그렇다. print(b) 도 되지만, a.주문받기() 혹은 print(a.주문받기(s: ["짜장면2", "짬뽕2"])) 처럼 b를 안 써도 된다. b가 생긴다는 것은 상태 변수 혹은 속성 혹은 멤버변수 혹은 프로퍼티(다 같은 말이다)가 생긴다는 말인데 b 를 안쓰니 함수형 프로그래밍의 특징이 하나는 상태값을 저장하지 않는 것으로 귀결된다. C/C++, Objective-C, C#, JAVA, SWIFT 모두 함수형 프로그래밍 언어의 특징을 구현할 수 있다. 그러나 하나의 프로그래밍 패러다임만 구현하지 않는다.


이 상황에서 주문하는 쪽은 상태를 가질 필요가 없다(중국집 전화번호만 있으면 된다) 그러나 중국집은 주문 목록은 있어야 한다.



한타임 쉬고. <밥먹음 ㅋㅋ> 배부르니 중국집이 하기 싫어진다.


자, 여기까지 하고 문법 짚고 가보자.

보면, 클로저는

(parameters) -> return type in

statements

}

이렇게 선언한다고 한다.


swift 에서 함수 선언은


func #name(parameters) -> return type {

        function body

}


이랬다. func와 이름이 사라지고 {} 가 바깥으로 나와버려서 function body 시작점을 몰라 in 이 들어갔다.

별거 없다.


이제 중국집을 다시 만들고, 고객의 소리를 받아보자.


class 중국집 {

    private var 주문목록 : [String] = []

    static func 고객소리(x : ()->Void) {

        x() //고객의 소리는 x, 실행 명령어는 ()

    }

}


고객의 소리는 이렇게 만드는데,

    func name() -> Void {

            print("짜장면 더 맛있게 해주삼")

        }

        중국집.고객소리(x: name)


앞 서 말했 듯이 내가 func를 가질 필요는 없겠다.


중국집.고객소리(x: {})

중국집.고객소리(x: { () -> Void })

중국집.고객소리(x: { () -> Void in print("짜장면 더 맛있게 해주삼")})


그런데 () -> Void 이거 왠지 결국엔 C의 함수포인터랑 같다. 안돼! 난 최신 언어라구.


중국집.고객소리(x: { print("짜장면 더 맛있게 해주삼")})


이렇게도 가능하겠다.


        중국집.고객소리(x: { print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

        })


결국 실행은 사장이 하는 거고 구현을 클라이언트(함수를 호출하는 사람)이 하게 되었다. 그리하여 파라미터도 사장이 넣을 수 있다. 사장의 성깔이 좋은지 아닌지 중국집 사장이 직접 넣어보자.


class 중국집 {

    private var 주문목록 : [String] = []

    static func 고객소리(x : (Bool)->Void) {

        x(true)

    }

}


성격이 좋다고 넣었다. 그러면 고객은 한마디 더 할 수 있다.


        중국집.고객소리(x: { (사장성깔좋아) in

            print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

            if(사장성깔좋아) { print("진짜 맛없어요")}

        })


이렇게 클로저가 탄생하게 되었다. UI 기초 2편을 써야 하는데 스냅킷 내용이 반 이상이라. 클로저를 먼저 짚고 넘어가야할 것 같아서. 물론, 축약 안하고 써도 된다.


        중국집.고객소리(x: { (사장성깔좋아) -> Void in

            print("짜장면 더 맛있게 해주삼")

            print("짬뽕은 더 맵게")

            if(사장성깔좋아) { print("진짜 맛없어요")}

        })


그리고 사실 프로그래밍 할 때 이런 프로그래밍 언어적 특성이나 모듈 패턴을 몰라도 아키텍처만 잘 짜면 굳이 축약 코드로 도배 안해도 충분히 재 사용성이나 메모리 사용량은 감소한다.


결국 임베디드, C/C++을 해야 언어를 제대로 이해할 수 있다. 기초 서적은 외서를 보지만 가끔 국내 서적도 여러권 가서 내가 이해한 것이랑 비교해 보는데 생략된 부분이 너무도 많다. 물론, 나 역시도 써봐서 싣고자 했는데 까먹고 못 실었던 내용이 많으니... 비슷한 경우일 수도 있겠다.


그러나 람다 대수의 위키 페이지를 참고하는 게 함수형 프로그래밍을 더 확실히 이해할 수 있는 지름길이라 하겠다. fxJAVA 도 함수형 프로그래밍인데,...


사실 수학을 떠나, 프로그래밍 언어에서 완전히 함수형으로 된다는 것은 메모리 관리가 완전히 순차적으로 되어야 한다는 말이다. 메모리 청크 찾는 거야 운영체제 단에서 어쩔 수 없다고 해도 그 상위에서는 정말 순차적으로 들어가야 한다. 그래야 데이터 무결성도 지켜지고 액세스 속도도 빠르다.


뭐, 응용 프로그래머야 함수형 프로그래밍 흉내만 잘 내어도 쓸데없는 상태 변수를 만들지는 않겠지만, 결국 언어를 만든 사람이 적절한 타이밍에 메모리 관리를 효율적으로 하는 게 중요하다고 생각한다.



최근 코틀린이 아닌 자바를 사용하는 안드로이드 개발자가 iOS 개발을 하고 싶다고 하여 이야기 한 내용을 적어 둔다. 글은 2개로 쪼갠다.



1. MAC을 안 사도 된다.


이전에 포스팅 올렸다가 지워서 캡처 화면은 없지만 인터넷 뒤지니 자료가 많았다. 삼성 시리즈 9 노트북, VMWARE 위에 시에라 버전 올리고 XCode로 해 보았다. 전혀 문제없다. 맥의 커맨드 키는 컨트롤키 기능의 일부를 가져갔다고 생각하면 되고(cmd+C, cmd+V처럼) 맥의 옵션 키는 알트키(Alt, @)로 생각하면 금방 적응될 것이다. 맥이 있었지만 3개월가량 삼성 노트북으로 iOS 앱 개발했다.


2. 적응


맥의 프로그램 실행은 대부분 cmd+space bar를 눌러서 실행한다. 윈도에서 윈도키를 누르고 앱 이름을 실행하는 것과 같다. 윈도에서 Ctrl+Shift+ESC를 눌러 실행하는 프로세스 모니터는 Activity monitor란 이름이니 커맨드+스패이스 바를 통하여 실행하면 된다. 나머지는 우분투 리눅스 배포판과 창 모양, 창 닫기 위치, bash shell(맥에서는 terminal)이므로 사용하기 쉬울 것이다. 바꾸자. 맥으로. 오버워치 때문에 윈도우는 무조건 써야하니 하나 더 사자는 말


윈도우의 익스플로러는 finder 이며, 윈도우처럼 쉬프트 우클릭으로 쉘을 바로 열 수 있는게 아니라 몇가지 작업을 좀 해줘야 한다. 그리고 윈도에서 cmd 말고 powershell을 쓰듯이 맥은 기본 터미널 말고 iterm2를 쓴다. 거기에 zsh를 더해주면 더 좋다. 화면이 좁으니 모니터를 더 구입하는 것보다 bettersnap tool 같은 앱을 연결해서 창을 다룬다. 윈도 유저는 많은 모니터를, 맥 유저는 그냥 맥북 프로에 창 관리를 잘 하는 차이라고 보면 되겠다.



3. SWIFT


우선, ARM Firmware를 하는 내 입장에서는 JAVA나 C/C++, SWIFT가 모두 똑같은 언어로 보인다. PYTHON 은 perl이나 bash shell script 정도로 보이고 ^^;; 인터넷 서핑 공부법으로 편하게 공부하면 되지만 몇 가지 팁을 적어 본다.


(1) module, framework


module은 application 이나 framwork 을 말한다. Andoird에서 Project 와 같은(비슷하다는 말을 "같은"으로 표현하여 더욱 접근 장벽을 더 낮추겠다.) 개념이다. Eclipse에서 여러 Project를 하나의 workspace에 띄우는 것과 같다. Visual Studio 의 Project 개념. 더 큰 개념은 Solution이고 XCode에서는 그것을 workspace라고 부르니 결국 Eclipse의 workspace랑 같다. Android studio 에서는 gradle로 다양한 라이브러리를 import 한다. gradle의 그 한줄이 module, 또는 framework 이라고 보면 되겠다. 즉, framwork은 라이브러리다.



(2) cocoa Pods


cocoa는 STL이나 GLIBC처럼 표준 라이브러리 집합이다. swift 하는 분은 서버 개발자나 iOS 개발자, 특히 모바일 개발자가 많다고 생각된다. iOS는 UIKit을 쓴다. UI 프레임웍은 다음을 참고!


https://developer.apple.com/videos/frameworks/ui-frameworks

Frameworks - UI Frameworks - Videos - Apple Developer


developer.apple.com 



그리고 node.js에 npm이 있고, react에 yarn이 있고, fedora의 yum, ubuntu의 apt 가 있듯이 맥에는 brew 라는 패키지 관리자가 있다. brew를 이용해서 cocoapods를 설치할 수 있는데 pod은 라이브러리 관리 프로그램이다. pod 설치 후 pod init 하면 Podfile이 생성되고 해당 파일에 pod 'SwiftyJSON', '~> 4.0' 와 같이 패키지명을 적어주고 pod install 하면 라이브러리를 설치해 준다. 지우는 명령어는 따로 없고, Podfile에서 삭제하고 pod install 로 지운다. 현재 설치된 버전은 Podfile.lock에 저장된다. 설정파일 2개로만 관리하니 많이 편리하다. workspace 파일(각 project를 관리하는)이 없는 경우 자동 생성해 준다.




(3) 접근 제한자


2 때는 public, private, internal 만 있어서 비슷했는데 3버전 부터 open, fileprivate이 늘어났다. 자바에서의 public 은 swift의 open과 같다. 


https://docs.swift.org/swift-book/LanguageGuide/AccessControl.html

Access Control — The Swift Programming Language (Swift 4.2)


docs.swift.org 




(4) 함수 선언



void 리턴값은 아예 적지 않는다.

func stringMetohd(source : [String]){

for a in source {

print(a)

}

}


var weekdays : [String] = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]


stringMetohd(source: weekdays)






모든 프로그래밍 언어에 y=f(x) 개념이 있듯이 스위프트도 함수가 기본이다.


func square(n:Int) -> Int {…}


로 함수 선언을 한다.


자바에서 public int square(int n) {...} 겠다.


C에서 함수포인터가 JAVA에서 인스턴스 변수로 편하게 객체를 대입하듯이


swift에서는 더 쉽게 할 수 있다.


let a=square


변수 선언은 var나 let을 쓸 수 있는데, let은 C에서 const, java에서 final과 같다.


물론, 자동 자료형 casting이 되지만 중급 이상 프로그래머는 알 것이다. 결국 자료형을 컨트롤해줘야 한다는 것을(뭐 frontUI만 짜면 별 상관 없겠지만 통신 기능만 들어가도 객체 직렬화 때문에 고려할 수 밖에)






믓튼, 이걸 더 쉽게 쓸 수 있다.


var b={(n:Int) -> Int in return n*n}


b(3) 하면 9가 나온다.






더 쉽게 쓸 수도 있다.


var c:(Int) -> Int


c={$0 * $0}


c(3)






bash shell programming을 많이 했던 사람에게는 별 이상할 게 없다.






Activity = ViewController


List View = Table View


Function Pointer, Instance = closer + new programming rules라고 보면 된다.


등 용어가 바뀌는 게 있지만 사실 안드로이드에게 바뀐 건 API 네임뿐.


애플이 삼성 베끼고, 삼성이 애플 베끼듯이 정책이 결국 requirement인데 requirements가 같아지다 보니 그걸 구성하는 system, architecture, module도 같아질 수밖에 없다. 즉, 메커니즘도 별반 차이 없다는 이야기. 애플이 파워칩을 계속 생산했으면 모르겠으나 어차피 Intel base고 각 회사 엔지니어들이 서로 이직을 하는 이상 바뀌는 것은 이름뿐일 거라는.






(5) Array


선언 방법은 다양하다.


var a = [Bool]()


var b : [Int] = []


a = [true, false, (3==3)]


var c = Array(repeating : true, count : 5)


var d : [Int ] = [1, 2, 3, 4]






이와 같이 선언을 먼저하고, 값을 넣는 방법도 있다.


개인적으로 변수가 nil을 포함한다는 개념인 Optional(?)이 있으니


C/C++과 비슷하게


var e : [Character]? = nil 을 선호한다.






배열을 JAVA의 ArrayList 처럼


var chart : [Character] = ["A", "�"]


chart.append("d")


chart += ["4", "5"]


chart.insert("h", at: 1)


chart.remove(at: 2)


편하게 넣었다 뺐다 할 수 있으니 자주 쓴다.






(6) for loop


()가 없는 점이 다르다. 


var weekdays : [String] = ["SUN", "MON", "TUE", "WED", "THU", "FRI", "SAT"]






for index in 0...6 { //for index in 0..< 7 { 요렇게 해도 된다.


print(weekdays[index])


}






for index in 0...(weekdays.count-1) { //이렇게도


print(weekdays[index])


}






for day in weekdays {


print(day)


}






이런 식으로 쓴다. JAVA에도 for(String a : Iteratores), C++에서 for each(String a in ...) 하고 쓰는 것과 같기 때문에 편하게 볼 수 있다. 다만 ... , ..< 문법이 좀 생소할테지만 쓰다보면 더 직관적라는 것을 알게 된다.






(7) enum


enum integers : Int {


case one


case two


case three


}






print(integers.one.rawValue)


0


보통 enum 은 rawValue를 뽑아내기 위해 쓰는 개념이 아니긴하지만 이렇게 값을 뽑아낼 수 있는 방법이 있다는 뜻.






(8) casting


자바에서는 (String)을 했지만 as를 쓴다.


value as! Int


같이.






4. 조금 더...


struct 는 메소드 없이 멤버변수만 있는 자료형, 


struct myStruct {


var a : String?


var b : Int?


}






var c = myStruct()


c.a = "hello"


print(c.a!)






class의 경우 메소드 포함. Swift 용어로는 프로퍼티, 펑션이 둘 다 있는 class, 프로퍼티만 있으면 struct . 이 정도 개념이면, 맥으로 개발하는데 별 무리 없이 금방 적응하리라 생각된다. JAVA 던, 코틀 린이던, Swift 던 base 코드는 어셈블리랑 C일 수밖에 없어서... 다만 그들이 쌓아 올린 개념이 거대한 프로그램(프레임웍)인 경우 안 무너지기를 바라지만. 내 경험상 칩 단까지 디버깅을 해야 하는 상황도 오기 때문에 결국 안 무너지지는 않는다.






그냥 프런트 UI에 집중하고, 아키텍처나 모듈 단위를 벗어나지 않는 범위에서 디자인 패턴으로 개발자들끼리 싸우게끔 해서 시스템을 못 보게 하는 게 공룡 기업이 하는 방식이다. 






끝으로 대부분의 상황에서 폴링 방식보다 인터럽트 방식이 좋듯. 함수 포인터로 콜백을 구현하듯이 인터페이스를 잘 뽑으면 된다. 그 콜백이 옵서버가 되고 그런 옵서버를 편하게 만들어 주는 API 라이브러리를 사용하면 그게 곧 반응형 프로그래밍이다.






내 책에서도 밝혔지만 사실 더 편한 건 그런 개발을 알아서 다 해주는 개발자 API를 쓰는 기업 사장이 최고의 프로그래머!





sudo /usr/libexec/locate.updatedb


updatedb는 linux랑 이름이 같다.


sudo launchctl load -w /System/Library/LaunchDaemons/com.apple.locate.plist


이렇게 로딩 후 

locate 가 동작한다.


#if DEBUG

        txtID.text = "itsme"

        txtPASSWD.text = "goodToSeeU#123"

#endif


//  Copyright © 2018 hajunho.com All rights reserved.



import UIKit


//Where am I, exactly  ex) "".pwd(self)

//I recommend the codes below to a base view controller


extension String {

    func pwd(_ x: Any)  {

        debugPrint("🍭pwd_"String(describing: x.self))

    }

}


+ Recent posts