Swift 문법 간단 정리 #1

2015. 5. 9. 17:16
  • Optional
    • 값이 존재할 수도 있는 상황에서 optional를 사용한다.
    • optional의 의미
      • 값이 있고 그 값이 x와 같다.
      • 값이 없다.
    • optional가 값이 있다는 것을 확신하면 마지막에 느낌표를 붙여서 값에 접근할 수 있다.
      • !: 값이 존재함을 확신할 수 있다는 의미
      • forced unwrapping
    • optional binding
      • if let abc = possible.toInt()
      • possible.toInt가 리턴한 optional int값이 값을 가지고 있다면 새로운 상수 abc의 값을 그 값으로 한다.
      • forced unwrapping이 불필요 = ! 쓸 필요 없음
    • Implicitly Unwrapped Optionals
      • 프로그램 구조적으로 항상 값을 가질 때 수시로 !로 unwrapping해줄 필요 없이 값 지정 후 선언해주는 것
      • Q. 그럼 일반 상수와의 차이는 뭘까?
        • nil을 지정할 수 있는지 여부
      • String! 사용
      • 클래스 초기화 과정에서 사용
        • 클래스의 initialize 과정에서 property를 선언할 때는 값을 지정할 수 없으니까 (외부에서 받으므로..)
        • @see Unowned References and Implicitly Unwrapped Optional Properties
      • 사용하면서 forced unwrapping을 해줄 필요가 없다.
  • Assertion
    • 조건이 false가 될 수 있지만 코드 실행을 위해서는 반드시 true여야 하는 곳에서 사용
      • An integer subscript index is passed to a custom subscript implementation, but the subscript index value could be too low or too high.
      • A value is passed to a function, but an invalid value means that the function cannot fulfill its task.
      • An optional value is currently nil, but a non-nil value is essential for subsequent code to execute successfully.
      • 다음에서 발췌: Apple Inc. ‘The Swift Programming Language.’ iBooks. https://itun.es/kr/jEUH0.l
  • Operator
    • 할당 연산자 = 는 그 값을 반환하지 않음. 따라서 if a = 5 {} 는 유효하지 않음
    • 산술 연산자는 값이 오버플로우 되는 것을 허락하지 않음
    • 오버플로우 시에 사용할 수 있는 overflow operator가 존재
      • &+, &-, &*
    • %는 나머지를 의미
    • i++ 보다는 ++i를 추천. i를 변경하고 결과를 반환한다는 일반적으로 예상되는 동작을 수행하기 때문
    • a…b : b 포함
    • a..b : b 제외
  • String
    • value type: 함수나 메소드에 전달될 때 복사됨
    • count() : 글자수 세기
    • extended grapheme cluster로 인해 e위에 `가 있는 글자거나 한글이 초,중,종성의 각각의 코드로 이루어져 있어도 한 글자로 센다. (ㄱ,ㅏ,ㄴ 코드를 합친 것을 한 글자로. 물론 '간'에 대한 코드도 존재)
      • 이런 이유로 긴 문자열에서 count를 실행하면 모든 글자를 돌게 된다.
      • 마찬가지 이유로 NSString.length의 값과 count의 결과가 달라질 수 있다.
    • String은 integer를 바로 index로 사용할 수 없다.
      • String.startIndex, String.endIndex
        • 빈 경우 두 값은 같다.
        • endIndex는 마지막 문자의 index가 아니라 그 다음 index를 나타냄
      • advance(start: n:): 시작 지점부터 n번째의 index
    • 함수들
      • indicies(_:): range 생성
      • insert(_:atIndex:): index에 글자 삽입
      • splice(_:atIndex:): 특정 index에 문자열 삽입
      • removeAtIndex(_:): 특정 index의 글자 제거
      • removeRange(_:): 특정 범위의 문자열 제거
    • 비교
      • extended grapheme cluster로 구성된 글자든 한 코드로 된 글자든 표현하는 모습이 같으면 글자를 구성하는 코드가 달라도 같은 글자(문자열)이다. (canonical equivalent)
      • 비교시에는 locale에 따라 달라지지 않는다. (not locale-sensitive)
  • Collection
    • Array
      • Array<Type>, Type[]: 후자를 추천
      • count property로 배열에 포함된 값의 갯수를 확인
      • 함수들
        • isEmpty로 count가 0 여부 확인
        • append: 배열 마지막에 추가
        • += [ ]: 배열 마지막에 추가
        • insert(atIndex:): 특정 index에 값 추가
        • removeAtIndex(_:): 특정 index의 값 제거
        • removeLast()
        • for-in
        • enumerate
    • Set
      • Set<Type>
      • count property로 갯수 확인
      • 함수들
        • insert(_:)
        • remove(_:)
        • removeAll()
        • contains(_:)
        • for-in
        • 순서가 없으므로 특정한 순서에 따라 탐색하려면 sorted 사용
      • set 함수들
        • union(_:): 합집합
        • subtract(_:): 공통된거 빼기
        • intersect(_:): 교집합
        • exclusiveOr(_:): 두 set중 공통만 제외
        • ==: 동일한지
        • isSubsetOf(_:)
        • isSupersetOf(_:)
        • isStrictSubsetOf(_:), isStrictSupersetOf(_:) : superset이거나 subset인데 같지는 않은
        • isDisjointWith(_:): 공통 값 있는지
      • set에 저장되는 타입은 hashable 해야 함
    • Dictionaries
      • Dictionary<Key, Value>
      • [Key: Value]
        • Key는 hashable 해야 함
      • count property로 갯수 확인
      • 함수들
        • updateValue(_:forKey:): 옛날 값 반환 (optional)
        • removeValueForKey(_:)
        • for-in
        • 순서를 지정해서 탐색하려면 sorted 사용
  • control flow
    • for-in
      • for index in 1…5
        • index는 상수, 루프 돌 때마다 초반에 자동으로 값이 지정, let 불필요
    • switch
      • fallthrough
      • 여러 case에 매치할 경우 첫 번째 매치만 실행됨
      • case에 let, var를 사용하여 임시 변수로 만들 수 있음
      • where: case let (x, y) where x == y :
        • case내에서 또 조건을 세분화할 수 있음




nundefined ETC IOS, SWIFT, 스위프트

DOM에서 특정 element를 제거하는 크롬 확장 프로그램

2015. 2. 28. 12:48

아주 간단한 확장 프로그램을 하나 만들었다. 웹 페이지를 로딩할 때 특정한 dom element를 문서에서 제거하는 것이다. 설정 페이지 등 일반적인 형태로 사용할 수 있는 기능들을 빼고 dom element를 제거하는 기능 구현에 집중했더니 개발 시간은 길지 않았다. 소스 코드는 다음과 같다.


// manifest.json

{

  "manifest_version": 2,


  "name": "Dom Element Remover",

  "description": "This extension removes pre-specific elements from HTML document.",

  "version": "1.0",


  "content_scripts": [

    {

      "matches": ["http://*.daum.net/*"],

      "js": ["jquery.js", "bg.js"],

      "run_at": "document_end"

    }

  ],

  "permissions": ["http://*.daum.net/"]

}


// bg.js

var $target = $('#banner');


if ($target.length) {

$target.remove();

}


두 개의 파일이면 충분하다. manifest.json에서 선언한 것과 같이 사용자가 다음 사이트에 접근하면(matches) dom의 구성이 끝난 시점에(run_at) 파일(js)을 삽입한다. 그러면 bg.js 파일이 실행되고 문서에서 id가 banner인 엘리먼트를 찾아 해당 엘리먼트가 존재할 때 엘리먼트를 제거한다.


다음 사이트 이외의 곳에서는 확장 프로그램의 기능이 실행되지 않기를 원하므로 permissions에도 도메인을 추가했다.


이 프로그램을 더 개선한다면 사용자에게 지울 엘리먼트를 선택하는 방법을 제공할 수 있을 것이다. 지금은 bg.js 파일에 직접 선택자를 지정했지만 사용자가 변경할 수 있게 한다면 더 편리한 프로그램이 될 것이다. 그리고 다음 사이트에만 적용되는 기능을 다른 사이트 혹은 임의의 사이트에서도 동작하도록 변경할 수 있을 것이다.

nundefined ETC Chrome, extensions, 크롬, 확장프로그램

Google Hangouts manifest.json 정리

2013. 8. 6. 01:30

개인적으로 크롬 확장 프로그램(또는 크롬 익스텐션)에 관심이 있는 편이다. 그래서 이전에 간단한 확장 프로그램을 만들어보기도 했고. 크롬 확장 프로그램을 실행시키기 위해 필요한 파일 중에 하나가 manifest.json인데 Google Hangouts의 manifest.json을 예제로 삼아 간단히 정리해봤다. Hangouts가 manifest.json의  모든 항목을 사용하는 것은 아니므로 manifest.json의 전체 내용을 파악하긴 어렵지만 시작점으로는 충분히 의미있으리라 생각한다.


{

   // background 페이지는 익스텐션의 프로세스를 실행한다.

   // extensions의 기본 lifecycle에 대한 이해가 필요함

   // html이 필요 없는 경우 'scripts'를 name으로 하고 javascript 파일의 배열을 value로 설정 가능

   // 브라우저가 빨리 시작되어야 하는 경우에는 permission에 background를 설정한다.

   "background": {

      "page": "background.html"

      // 여기에 persistent를 설정할 수 있는데 특별한 설정이 없다면 true로 설정된 것

   },


   // 브라우저 액션을 위한 설정. 툴바 우측에 아이콘이 생긴다.

   "browser_action": {

      "default_icon": {

         "19": "images_2/presence/offline_19.png",

         "38": "images_2/presence/offline_38.png"

      },

      // 아이콘에 마우스를 올렸을 때 나타나는 툴팁

      "default_title": "__MSG_CHROME_EXT_SHORT_NAME__"

   },


   // 웹페이지의 컨텍스트에서 실행되는 자바스크립트 파일

   // DOM을 사용하여 브라우저의 내용에 접근, 변경이 가능

   "content_scripts": [ {

      // 아래 matches로 선택한 페이지에서 모든 프레임에 삽입할지, top 프레임에만 삽입할지 여부

      "all_frames": true,

      // 대상 페이지에 삽입할 javascript. 배열에 표시된 순서대로 삽입됨

      "js": [ "scripts/ace-contentscript.js" ],

      // 필수. js를 삽입할 대상 페이지를 결정하는 규칙

      "matches": [ "*://*.google.com/mail/*" ],

      // js가 삽입될 때를 지정.

      // document_start: css 다음에 삽입

      // document_end: DOM이 완료되면 삽입. (DomContentLoaded)

      // document_idle: 기본값. document_end와 window.onload 이벤트 사이에서 브라우저가 적절히 삽입

      "run_at": "document_start"

   }, {

      "all_frames": true,

      // 조건에 맞는 URL은 대상에서 제외.

      "exclude_globs": [ "*prop=docs*" ],

      "js": [ "scripts/ace-contentscript.js" ],

      "matches": [ "*://*.google.com/talkgadget/notifierclient*" ],

      "run_at": "document_end"

   }, {

      "all_frames": true,

      "exclude_globs": [ "*prop=docs*" ],

      "js": [ "scripts/ace-contentscript.js" ],

      "matches": [ "*://*.google.com/talkgadget/_/chat*" ],

      "run_at": "document_end"

   }, {

      "all_frames": true,

      "exclude_globs": [ "*prop=docs*" ],

      "js": [ "scripts/ace-contentscript.js" ],

      "matches": [ "*://*.google.com/u/*/talkgadget/_/chat*" ],

      "run_at": "document_end"

   } ],


   // 기본 보안 제약

   // 1. eval 및 동일한 기능을 사용하여 문자열로 된 스크립트 실행 불가

   // 2. inline 스크립트 실행 불가

   // 3. local script와 객체 리소스만 로드 가능

   //

   // inline script 보안 해제: unsafe-inline

   // remote script/object 보안 해제: 필요한 origin 등록

   // eval 보안 해제: unsafe-eval

   "content_security_policy": "script-src 'self' https://*.google.com https://feedback.googleusercontent.com ; object-src 'self'",


   // _locales의 서브디렉토리를 지정한다. _locales 디렉토리가 있는 경우에는 필수

   // _locales 디렉토리가 없다면 빠져야 한다.

   "default_locale": "en",


   // 132자 이내의 설명. management ui와 스토어에 모두 노출됨

   "description": "__MSG_CHROME_EXT_DESCRIPTION__",


   // 아이콘

   // extensions의 경우 128x128과 48x48이 필수

   // 16x16의 경우 favicon용

   "icons": {

      "128": "images_2/icon-128x128.png",

      "48": "images_2/icon-48x48.png"

   },


   // 개발 과정에서 extension의 유일한 Id를 만들기 위해 사용.

   // crx로 패키징한 후 manifest.json 파일을 보면 확인 가능

   "key": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDsDApubb73tPfYlNIFxDu3K3/EHgV6/YOJXJkld1OZ20jW/cOht1j0NggnXhQYuu1mXFUufud4I2N7b5ydyg09gcM9Va3Zk17RhNV9smbPHOd4XlzJeXifX/9MgHPu4FzCen3CiSXsOeAELJIXEuT28xICriuUko/rNPwGeIB9VwIDAQAB",


   // 항상 2

   "manifest_version": 2,


   // 최소 실행 가능한 크롬 버전

   "minimum_chrome_version": "26.0.0.0",


   // extension 이름. 45자 이하. install dialog, management ui, store에 노출

   // i18n을 사용하기 위해 아래와 같이 설정하고 프로그램에서 변경 가능

   "name": "__MSG_CHROME_EXT_SHORT_NAME__",


   // extension의 동작을 결정하는 옵션을 수정할 수 있는 페이지

   "options_page": "settingsdialog.html",


   // extensions에서 사용할 권한, API, 접근할 도메인 등등

   // 패턴: 접근 가능한 호스트. cross-origin XHR, cookie, 프로그램적으로 삽입되는 컨텐트 스크립트 등

   // background: 크롬이 빨리 뜨고 늦게 종료되도록하여 extension이 더 오래 살아있도록 함 (크롬 실행되지 않아도 extension 실행)

   // cookies: chrome.cookie 모듈 사용시

   // idle: chrome.idle 모듈 사용시

   // notifications: 권한 확인(checkPermission()) 없이 notification API 사용

   // tabs: chrome.tabs 또는 chrome.windows 모듈 사용시

   "permissions": [ "*://*.google.com/*", "*://*.orkut.com/*", "background", "cookies", "idle", "notifications", "tabs" ],


   // NPAPI plugins 설정

   "plugins": [ {

      // plugin 위치. manifest 파일로부터의 상대적 경로

      "path": "plugin/ace.dll",

      // 웹 페이지에서 접근 가능 여부

      // true: 일반 웹 페이지에서 로드 가능

      // false: extensions에서만 로드 가능

      "public": false

   }, {

      "path": "plugin/ace.bundle",

      "public": false

   }, {

      "path": "plugin/libace.so",

      "public": false

   } ],

   "requirements": {

      "plugins": {

         "npapi": false

      }

   },


   // 자동 업데이트를 위한 경로 설정

   "update_url": "https://clients2.google.com/service/update2/crx",


   // .으로 구분하는 4개의 숫자. 0 ~ 65535에서 사용. 0으로 시작할 수 없음.

   // 자동 업데이트시 이 숫자를 기준으로 삼는다.

   // 앞 자리의 숫자가 크면 뒷 자리의 숫자와 관계 없이 새로운 버전 (ex. 1.2.0 > 1.1.9.999)

   "version": "2013.717.433.1",


   // 웹에서 직접 접근 가능한 extensions의 리소스

   "web_accessible_resources": [ "*" ]

}


manifest.json 파일의 전체 내용을 알고 싶다면 크롬 개발자 사이트의 manifest 파일에 대한 페이지를 방문해보기 바란다.




nundefined ETC Chrome, chrome extensions, extensions, Google, google hangouts, hangouts, manifest, manifest.json, 구글, 크롬, 크롬 익스텐션, 크롬 확장 프로그램

  1. Blog Icon

    비밀댓글입니다

맥 sourcetree에서 git에 push할 때 osxkeychain이 git 명령어가 아니라고 나오는 경우

2013. 7. 30. 01:18

Mac에서 Source Tree를 이용하여 Github을 사용하고 있다. 

이미 계정 하나가 있고 새로 계정을 만들어 checkout을 받았다. 이 때 SSH 대신 HTTPS를 사용하였다.


그런데 수정한 내용을 push하려고 하니 credential-osxkeychain이 git 명령어가 아니라는 오류가 자꾸 발생한다. GitHub에서 이런 오류가 발생할 경우 다음 주소에서 프로그램을 설치해야 한다고 안내하고 있다.


https://help.github.com/articles/set-up-git#password-caching


그러나 위 프로그램이 이미 설치되어 있는 상황인 것을 확인하였고 설정(git config --global -l)으로도 제대로 설정된 것을 확인 가능했다. 한참을 고민하다가 키체인 접근을 실행시켜 Github과 관련된 설정을 모두 지웠다.


키체인 접근에 등록된 정보는 최초에 만든 계정만 등록되어 있었고 이 정보를 지워주니 정상적으로 push가 가능했다. source tree나 키체인 접근 중 어느 한 곳(전자일 것으로 추측)에서 계정 여러 개를 동시에 사용할 것이라고 가정하지 않고 프로그램을 작성한 것 같다. 


정리하면...

1. Source Tree에서 Github를 연결해 사용할 때 사용할 수 있는 계정은 하나이다.

2. 만약 다른 계정을 사용하고 싶다면 키체인 접근을 실행시켜 기존 계정 정보를 삭제해야 한다.



nundefined ETC credential-osxkeychain, git, Github, Mac, source tree

Mac에서 프로그램에 옵션 지정해서 실행시키기

2013. 7. 23. 01:04

크롬 브라우저를 띄우면서 특정한 옵션을 지정하여 실행시켜야 하는 상황이 생겼다. 처음에는 'Mac도 unix의 일종이니까'라는 생각으로 shell script를 만들었다. 그런데 의도한대로 실행되지 않는다. 프로그램을 정상적으로 못찾았던가.. 지금은 기억이 좀 가물가물.


언젠가 애플스크립트를 본 기억이 있어 애플스크립트 편집기를 실행시켰다. 이리저리 명령어를 입력해봤지만 제대로 실행되지 않고 계속해서 오류를 일으키기에 결국 구글에서 검색. 역시나 검색해서 결과를 보니 너무 간단하다.


do shell script "open -a '/Applications/Google Chrome.app/' -options"


이렇게 스크립트를 만들고 컴파일하면 계속 애플스크립트 편집기를 띄우지 않고도 옵션을 지정하여 크롬 브라우저를 띄울 수 있다. 만약 이렇게 만들지 않았다면 매번 터미널을 열어 위의 명령어를 계속 입력하는 노가다를 하고 있었을 듯.

nundefined ETC Apple Script, Chrome