Daehoon Lee
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    ![](https://hackmd.io/_uploads/r1MNQyh9n.png) ![](https://hackmd.io/_uploads/BJmDtsin3.png) ## Ground Rules ### 규칙 - TIL, 일일 회고 작성 시간(매일 22시부터 1시간 작성 진행) - 페어프로그래밍 시간 제한 최대 30분 - 공식문서 읽기 - 컨디션 안 좋을 때 말하기!!! ### 스크럼 - 오전 10시 디스코드에서 진행 - 금일 진행 사항 공유하기(오늘의 할일) ### 프로젝트 규칙 - 네이밍 준수하기(가이드 라인) - 커밋 메시지 규칙 진행 - 코드에 대한 기록 그때그때 하기 - 캡쳐 많이 하기 찰칵찰칵📸 ## 일일 스크럼 ### 🙌 07/24 월 - 오늘의 컨디션 - hoon🐝: 졸려요🤣 - MINT😈: 약간 졸린? 여름엔 망고를 먹어야죠! - 특이사항 - hoon🐝: 밈, 솜과 데이트 ㅎㅎ(with. 호섭이, 보름이) - MINT😈: 미라클 모닝 장렬하게 실패! 온 세상이 행복하답니다 이제 도망쳐야짛ㅎㅎㅎ - 오늘 할 일 - [x] 레드망고가 제철이에요~ - [x] 활동학습 예습 - [ ] STEP 1 구현 - [ ] STEP 1 PR ### 🙌 07/25 화 - 오늘의 컨디션 - hoon🐝: 나쁘지 않아요😊 - MINT😈: 흠 - 특이사항 - hoon🐝: 여행 계획하기 ㅋㅋㅋㅋ - MINT😈: 훈 여수 납치 계획 - 오늘 할 일 - [x] STEP 1 구현 - [x] STEP 1 PR - [x] 공식문서 스터디 - [ ] URL 공식문서 읽기 - [ ] 여수 계획 ### 🙌 07/26 수 - 오늘의 컨디션 - hoon🐝: 몸이 무거워요오....😢 - MINT😈: 케챱이 없어요오....😢 - 특이사항 - hoon🐝: 스트레칭이 필요해요 ㅋㅋㅋㅋ, 1시 반부터 노가리 데이 - MINT😈: 2시부터 1시간 반 정도 토요 스터디 보충 - 오늘 할 일 - [ ] 네트워크 필요한 개체 공부 - [x] 클로저 공식문서 - [x] 활동학습 예습 - [ ] URL ### 🙌 07/27 목 - 오늘의 컨디션 - hoon🐝: 더워요🥵 - MINT😈: 낮잠 예정 후후 - 특이사항 - hoon🐝: 더워서 아무것도 하기가 싫어요 ㅋㅋㅋㅋㅋㅋㅋ 운동도 빼먹을 예정... <-더위 먹는것보다는 포동포동을 선택! - MINT😈: 오뉴가 제 위에서 자고 이써요 ㅋㅅㅋ <- 오뉴 귀요미 - 오늘 할 일 - [x] URL Session - [x] 하비께 디엠 - [ ] Github 예시 코드 찾기 ### 🙌 07/28 금 (늦잠 꾸러기들~ 언제 일어나시는지 감시 중😏 어라?) - 오늘의 컨디션 - hoon🐝: 피곤치 MAX!!🥱 <--아침 일찍 왔다가 낭패본 그 - MINT😈: 꽤나 좋아요~ 늦잠 최고 <--좀처럼 일어나지 않는 그녀 - 특이사항 - hoon🐝: 로웬 멘토링 4시 <--멘토링 하시는 동안 자고 올 예정 - MINT😈: 로데 멘토링 4시 <--멘토링 하시는 동안 자고 올 예정 - 오늘 할 일 - [x] README 작성 - [x] 멘토링 4시 - [ ] TCP 강의 영상 <--이거 언제보시나 기다리는 중(밤 10시에 작성!!히히) - [ ] osi 7계층 - [x] 하비 답변 공부 - [ ] GitHub 예시 코드 찾기 - [ ] 망고쥬스 마시기 <--- ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ 스파이망고 ㅋㅋㅋ ### 🙌 07/31 월 (왜 오늘 스크럼 안하시죵?? 저 기대하고 있는뎅!!) - 오늘의 컨디션 - hoon🐝: 주말에 푹 쉬어서 상태가 좋습니다.😆 <- 꿀피부 그 - MINT😈: 엄청 많이 자서 기뻐요~ 😆 <- 푹자서 기쁜 그녀 - 특이사항 - hoon🐝: 오늘 열심히 책을 볼거에요.🔥🔥🔥 - MINT😈: 저도 책에 집중을 해보겠어요!🌊🌊🌊 - 오늘 할 일 - [x] HTTP 영상 보기 - [x] 책 읽기 ### 🙌 08/01 화 (오늘은 무엇을 하실 예정이신가요??) - 오늘의 컨디션 - hoon🐝: 푹 잤습니다.👍 <--오 푹 주무셨군요?? - MINT😈: 많이 먹었습니닿ㅎㅎㅎ <--맛있게 드셨어요??뭘 드셨을까용?🤩 - 특이사항 - hoon🐝: 오후에 치과! <--오호 오후에 치과가시는군요? - MINT😈: 민트 점심 먹고 서울 올라가는-! <--응??오늘 서울 올라오세요?? - 오늘 할 일 - [x] HTTP 강의 끝까지 - [x] 책 읽기 ### 🙌 08/02 수: (오늘 두 분은 쉬시나요?? 저 실시간 옵저빙하는것 같네요 😏) <-- ㅋㅋㅋㅋㅋ책만 읽은 하루~ - 오늘의 컨디션 - hoon🐝: 해피 해피😊 - MINT😈: 해피 민트!! - 특이사항 - hoon🐝: 책 완독!!! 내용은 몰라요...🤣🤣🤣 <-- 우와 결국 완독하셨군요!!! - MINT😈: 쏘오오오오오 해피 민트!!!!!! - 오늘 할 일 - [x] 책 읽기 - [x] 5,6기 초청 취업 설명회 듣기 ### 🙌 08/03 목 - 오늘의 컨디션 - hoon🐝: 몸이 무거워요. ㅋㅋㅋㅋㅋㅋㅋ <--훈 씻으셨나요? - MINT😈: 꼬질 민트 <-- 킁킁(어디서 꼬수분내가..근데 꼬질민트 귀욤) - 특이사항 - hoon🐝: 이따가 낮잠을... ㅎㅎ <-- 낮잠 필수! - MINT😈: 저는 잠시 작은엄마 직장! <--오옷?견학가신건가요? - 오늘 할 일 - [x] 활동 학습 예습 - [x] osi 7계층 정리 - [x] 오후 8시 멘토링 훈민트 둘 다 - [ ] TCP/IP 정리 ### 🙌 08/04 금 (오늘은 무엇을 하실 예정이신가용? 불금인데~🥳) - 오늘의 컨디션 - hoon🐝: 괜찮아요.🙂 <-- 어디가 어떻게 괜찮은거지요? 상세하게 알려주세요 - MINT😈: 민트 사망 <--민트 어디갔어요?!! 민트를 찾아주세요! - 특이사항 - hoon🐝: 토요스터디 준비😂 <--화이팅입니다. - MINT😈: 민트 패스 <--민트는 스크럼 패스인가요? - 오늘 할 일 - [x] 하비와의 만남 <-- 만나셨나요?(두근두근🤩) 실패! - [ ] ### 🙌 08/07 월 - 오늘의 컨디션 - hoon🐝: 주말이 행복했습니다😊 - MINT😈: 잠이 부족해서 보충해써요오 - 특이사항 - hoon🐝: 활동 학습 예습~!! - MINT😈: 히히 기절 한 번 했습니다~ - 오늘 할 일 - [x] 활동 학습 예습 - [x] TLS/SSL 정리 - [ ] HTTP 버전별 정리 - [ ] Cache/cookie 정리 ### 🙌 08/08 화 (오늘 스텝2 진행하시나요?!! 두분 화이팅입니다!) - 오늘의 컨디션 - hoon🐝: 낫배드🙂 - MINT😈: 히히 열심히 걸은 민트😈 - 특이사항 - hoon🐝: 여권 찾기😢 - MINT😈: 훈민트 뽀에버😈 - 오늘 할 일 - [ ] Cache 정리 - [x] HTTPS 정리 ### 🙌 08/09 수 (오늘 엄청 바쁘신 두 분~) - 오늘의 컨디션 - hoon🐝: 아주아주아주 힘듭니다😩 훈 오늘은 낮잠 주무시죠 ㅋㅋㅋㅋ😈 <-- 여권 신청하고 오셨나요? - MINT😈: 기절트.. 여독...<-- 민트의 행방을 찾습니다~ - 특이사항 - hoon🐝: 여권을 만들기 <-- 외식 예정아니십니까?..아니다 배달인가? - MINT😈: 저녁은...외식.. <-- 두분 같이 드세요? (같이 먹고 싶다요) - 오늘 할 일 - [X] URL cache 코드 짜기 - [ ] cache 발표자료 만들기 - [ ] TCP 및 HTTP 버전 별 정리 ### 🙌 08/10 목 (훈, 민트 모두 건강 잘 챙기세요ㅠ_ㅠ) - 오늘의 컨디션 - hoon🐝: 어제 푹쉬어서 좋습니다.😊 <--훈 괜찮으신가요? 네 (다행이네요) - MINT😈: 집인데 집에 가고 싶은 기분 <--민트도 더위 안 먹게 조심하세요~, 저 그 기분 너무 잘알아요.. - 특이사항 - hoon🐝: 밀린 공부를 호다닥~ - MINT😈: 낮잠 잘래욥😴 <-낮잠 꿀잠 - 오늘 할 일 - [x] cache 발표자료 완성하기, 대본 작성하기 - [x] TCP 및 HTTP 버전 별 정리 - [x] 활동 학습 예습 ### 🙌 08/11 금 (아싸!! 불금입니다!!) - 오늘의 컨디션 - hoon🐝: 이상해요😕 <-이가 아프신건가요? - MINT😈: 허리 아포요🥲 <-어랏??허리가..허리가 왜?.. - 특이사항 - hoon🐝: 병원을 다녀오겠습니다🏥 <--어랏? 허리는 민트가 아프신대 병원은 왜 훈이 가시죠?😲 - MINT😈: 스트레칭과 산책 필수~😈 <--맞아요 건강지켜야해요 - 오늘 할 일 - [ ] HTTP 버전 별 정리 - [x] 노션에 발표 정리 ### 🙌 08/14 월 - 오늘의 컨디션 - hoon🐝: 점점 회복중입니다.😊 - MINT😈: 해피민트~! - 특이사항 - hoon🐝: 활동 학습 예습 - MINT😈: 즐거운 활동학습! 내일 아부지 생신🎂 - 오늘 할 일 - [x] STEP 2 코드 샘플 찾기 - [x] 공식 문서 - [X] Core Data 활동학습 복습 ### 🙌 08/15 화 - 오늘의 컨디션 - hoon🐝: 잘 잤습니다.😆 - MINT😈: 허리 아파서 의자를 정적인 걸로 바꿨어요ㅜㅜ 스트레칭과 자세교정이 시급합니다ㅜ - 특이사항 - hoon🐝: 오후에 친구들과 여행 계획을 세웁니다.🛫 - MINT😈: 꿈에 훈이 나왔어요!😈 - 오늘 할 일 - [x] STEP 2 코드 샘플 탐색 - [ ] STEP 2 코드 작성 - [ ] STEP 2 PR - [ ] 공식 문서 ### 🙌 08/16 수 - 오늘의 컨디션 - hoon🐝: 푹 잤어요 ㅋㅋㅋㅋㅋㅋ🙂 - MINT😈: 굿~ 엄청 잤어요~ - 특이사항 - hoon🐝: 오후에 잠시 외출하고 오겠습니다.☺️ - MINT😈: 샤인머스캣이 맛있어요!🍇 - 오늘 할 일 - [x] STEP 2 코드 작성 - [x] STEP 2 PR - [ ] 공식 문서 - [X] 활동 학습 예습 ### 🙌 08/17 목 - 오늘의 컨디션 - hoon🐝: 조금 피곤합니다. - MINT😈: 현재는 졸립니다ㅜ - 특이사항 - hoon🐝: 활동학습 + 특강 예습 - MINT😈: 오늘 하루가 사라졌어요~ - 오늘 할 일 - [x] 활동학습 예습 - [x] 특강 ### 🙌 08/18 금 - 오늘의 컨디션 - hoon🐝: 조금 피곤해요. 그래도 마지막 날!!!🥰 - MINT😈: 캬캬 - 특이사항 - hoon🐝: 아침에 병원을 다녀왔어요 ㅎㅎ. 저녁에는 저도 인천으로~✈️ - MINT😈: 저녁 약속 후후😆 - Mango: 어디가요! 나도 데려가요!! - 오늘 할 일 - [ ] 리뷰 수정 - [ ] 공식 문서 - [ ] README 작성 - [ ] 망고 데리고 놀기 # 팀 회고 ## 우리팀이 잘한 점 - ## 우리팀 개선할 점 - ## 서로에게 좋았던 점 피드백 ## 서로에게 하고싶은 말 # PR: STEP 1 ## 고민되었던 점 ### `Unit Test`에서 `json` 파일 사용 - STEP 1에서는 `API` 서버와 실제 통신을 하지 않고 테스트하기 위해 `box_office_sample.json` 파일을 제공합니다. 제공된 `box_office_sample.json` 파일은 `Unit Test`의 목적으로만 사용될 거라는 예상 때문에 [`BoxOfficeTests`에 `json` 파일을 추가](https://stackoverflow.com/questions/46726498/add-test-assets-for-xctest)하였습니다. 새로운 `Asset Catalog`를 생성하고 `json` 파일을 추가 후 다음과 같이 사용하려고 하였습니다. ```swift guard let json = NSDataAsset(name: "box_office_sample") else { return } ``` 위와 같이 사용하면 파일을 불러오지 못하여 `json` 상수에 `nil`이 할당되는 문제가 있었습니다. 확인해 보니 사용하는 `Bundle`이 현재 `BoxOfficeTests` 번들이 아닌 점이 문제였습니다. 문제를 해결하기 위해 사용하는 번들을 지정해 주었습니다. ```swift let bundle = Bundle(for: JsonDecodeTests.self) guard let json = NSDataAsset(name: "box_office_sample", bundle: bundle) else { return } ``` `Bundle(for:)` 메서드를 사용하여 현재 지정된 클래스가 연결된 `NSBundle` 객체를 반환받고 이를 다시 넣어줌으로써 `box_office_sample`의 파일 위치를 특정하여 사용할 수 있었습니다. ## 해결이 되지 않은 점 ### `Equatable protocol`을 외부 파일에서 `extension`으로 구현 - `Unit Test`를 진행하던 도중 `BoxOfficeItemInformation`을 구조체끼리 비교해 주고 싶었습니다. 특별한 타입을 구현한 게 아니라서 단순히 `Equatable`을 채택하면 테스트를 진행할 수 있었습니다. 그런데 저희는 해당 `Equatable protocol`이 단순히 `Unit Test`에서 확인해 보기 위한 것일 뿐이기에 `test file`로 빼주고 싶었습니다. 때문에 `extension`으로 옮겨서 `Equatable`을 채택해 주었는데 다음과 같은 에러가 발생하였습니다. ![](https://hackmd.io/_uploads/r14OUJaqh.png) 찾아보니 `Equatable`안에 구현되어 있는 `==` 메서드는 접근 권한이 `public`이 아니라서 다시 `public`으로 만들어주어야 하는 것이었습니다. 프로퍼티가 굉장히 많은데 이를 하나하나 작성해서 비교하는 것은 비효율적일 것 같아 내부의 프로퍼티들을 전부 다 반복으로 돌릴 수 있는 방법을 찾아보다가 결국 `BoxOfficeItemInformation`에서 가장 정체성을 나타내는 유일한 값인 `movieCode`를 비교하는 것으로 `extension`을 작성하였습니다. ```swift extension BoxOfficeItemInformation: Equatable { public static func == (lhs: BoxOfficeItemInformation, rhs: BoxOfficeItemInformation) -> Bool { return lhs.movieCode == rhs.movieCode } } ``` # PR: STEP2 ## 고민했던 점 ### `URLSession shared` 사용 - URLSession 클래스가 task 생성을 위해 기본으로 제공하는 싱글톤 객체입니다. `shared`를 사용하는 경우 다음과 같은 제한이 있었습니다. - 데이터가 서버에서 도착할 때 점진적으로 데이터를 얻을 수 없다. - 기본 연결 동작을 사용자 지정할 수 없다. - 인증 기능에 제한이 있다. - 앱이 실행 중이지 않은 상태에서 다운로드나 업로드를 실행할 수 없다. 위와 같은 제한 사항이 존재하기 때문에 `shared`를 사용하여는 경우 일반적으로 `cache`, `cookie storage` 또는 `credential storage`를 커스텀 하여 사용하는 것을 피해야 합니다. 현재 프로젝트를 진행하며 위와 같은 제한 사항과 관련한 내용이 없기 때문에 `shared`를 사용하였습니다. ```swift let task = URLSession.shared.dataTask(with: request) { data, response, error in if error != nil { completion(.failure(.dataTaskFail)) return } guard let httpResponse = response as? HTTPURLResponse else { completion(.failure(.responseCasting)) return } guard (200...299).contains(httpResponse.statusCode) else { completion(.failure(.invalidStatus)) return } guard let data = data else { completion(.failure(.noData)) return } completion(.success(data)) } task.resume() ``` 추가적으로 찾은 자료에서는 `shared`를 사용하는 경우 configuration을 사용하여 설정하는 부분에 대한 오버헤드가 없기 때문에 더 빠른 속도를 보인다는 내용이었습니다. - 참고 자료 : [URLSession: shared vs default](https://stackoverflow.com/questions/57971904/shared-urlsession-vs-urlsession-with-default-configuration) ## 해결하지 못한 점 ### `handler` 중복 합치기 - `fetchData` 메서드에 `escaping closure`를 사용해 `completion handler`를 구현하였습니다. `Result` 타입을 사용해 실패하면 `error`를 반환하고 성공하면 `data`를 반환하는데 그때 해당 `json data`를 `decode`해 사용할 수 있는 모델을 만들고 싶었습니다. 이때 `Decodable`을 채택한 2개의 서로 다른 모델 타입을 제외하고는 `completion handler`의 내용이 같기에 하나의 프로퍼티로 선언해 전달해주고 싶었습니다. ```swift private let boxOfficeDataCompletion: (Result<Data, NetworkError>) -> Void = { result in switch result { case .success(let data): guard let decodedData = BoxOfficeData.decode(data: data) else { return } case .failure(let error): print(error.localizedDescription) } } ``` 위의 코드에서 guard let 안의 BoxOfficeData만 MovieInformation과 옵션을 줘서 번갈아가며 사용할 수 있게 해주고 싶었습니다. - 위와 같은 이유로 다음과 같이 2가지 방법을 생각해 보았지만 두 방법 모두 성공하진 못했습니다. 1. closure로 타입 전달 ```swift private let boxOfficeDataCompletion: (Decodable, (Result<Data, NetworkError>)) -> Void = { type, result in switch result { case .success(let data): guard let decodedData = type.decode(data: data) else { return } case .failure(let error): print(error.localizedDescription) } } ``` 클로저로 타입을 전달해주는 방법입니다. 다만 이 경우 fetchData 함수에서도 성공한 경우 completion(.success((`type`, data)))로 fetchData에서부터 type을 전달해주어야 합니다. 그러나 이때 type을 전달해 줄 수가 없었습니다. 2. fetchData 함수를 부르는 함수에 타입 전달 ```swift func prepareData<T: Decodable>(request: URLRequest, type: T) { let handler: (Result<Data, NetworkError>) -> Void = { result in switch result { case .success(let data): guard let decodedData = type.decode(data: data) else { return } print(decodedData) case .failure(let error): print(error.localizedDescription) } } fetchData(request: request, completion: handler) } ``` 그러나 이렇게 한 후 사용이 가능한지 실험해보는 과정에서 다음과 같은 에러가 발생하며 Decodable 타입을 사용할 수가 없었습니다. ![](https://hackmd.io/_uploads/SyDJvLq32.png) - 결국 합치지는 못하고 각각 다른 completion handler를 만들어 enum을 통해 전해줄 수 있게 구현하였습니다. ```swift enum completion { case boxOfficeData case movieInformation var handler: (Result<Data, NetworkError>) -> Void { switch self { case .boxOfficeData: return NetworkManager().boxOfficeDataCompletion case .movieInformation: return NetworkManager().movieInformationCompletion } } } ``` ## 조언을 얻고 싶은 점 ### `URLSession shared` 사용 예시 - 어떤 예시에서 `shared`를 사용하는 것이 좋은지를 찾지 못하였습니다. 기본적으로 `URLSession.init(configuration: .default)`를 바탕으로 `shared`가 만들어졌다고 하는데 어떤 경우에 `shared`를 사용할 수 있을까요? `default`와 `shared`를 사용하는 기준점이 위의 제한 사항 외에도 다른 이유가 있을까요?

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully