2019년 10월 30일 수요일

Swift's Sequence Inside The Compiler: How for loops work internally 를 읽고

https://swiftrocks.com/swift-sequence-inside-the-compiler-how-for-loops-work.html

Swift 에서 for loop는 어떻게 동작하는 것일까?
초기 버전에서는 c-style for loop 형태였지만 현재는 protocol을 사용하는 syntactic sugar의 형태로 되어 있다.

IteratorProtocol : associatedtype으로 동작할 타입을 지정하고 next() 함수로 값을 가져올 수 있게 한다.
Sequence : Iterator를 지정하고 makeIterator()로 사용할 iterator를 만든다.
Collection : Sequence를 상속. Sequence에 다양한 기능을 추가

for loop를 컴파일하면 어떻게 되는지 살펴보면 makeIterator() -> while -> next() 의 형태로 변경되어 구성되는 것을 볼 수 있다.


2019년 10월 27일 일요일

SwiftUI layout system 을 읽고

https://kean.github.io/post/swiftui-layout-system

1. Layout Basics

safearea

Layout Process

parent가 child에게 '너의 크기 이렇게 할까'라고 제안 -> child는 자신의 크기를 지정 -> parent는 child가 지정한 크기로 child를 자신의 coordinate space 안에서 위치시킨다.

Frame

2.Stack

HStack, VStack, ZStack

Stack Process

stack은 내부의 spacing을 계산하고 자신의 size에서 이 값을 제외 -> child들을 균등하게 나눌 경우의 size를 계산. 이 값은 우선 least flexible child에게 제안. 이 child로부터 지정된 size를 자신의 size에서 제외. 남은 size를 남은 child들을 가지고 size 제안 반복  -> 모든 child는 size를 가지고, stack은 spacing과 align에 따라 child들을 위치시킨다.

3. Environment

libp2p - Protocols 를 읽고

https://docs.libp2p.io/concepts/protocols/

libp2p는 특정한 하나의 프로토콜을 지원하는 형태가 아니라 여러 프로토콜을 지원하고 이 중 원하는 프로토콜을 선택해서 사용할 수 있도록 하고 있습니다.

libp2p는 원하는 프로토콜을 선택하기 위해 크게 다음의 세가지 특징을 사용합니다.

- Protocol Ids

protocol negotiation에 사용하는 unique한 id(예: /my-app/amazing-protocol/1.0.0).
맨 마지막에 버전 정보가 따라옵니다.

- Handler functions

지정된 protocol id를 통한 연결 요청이 들어오는 경우 실행되는 함수
연결을 맺을 때 꼭 버전이 정확하게 맞아야만 handler function이 호출되도록 하지 않아도 됩니다. 이를 위해 match function을 사용합니다. match function이 true를 리턴하면 이에 연결된 handler function이 호출되도록 합니다.

- Binary streams

Bidirectional, reliable delivery of binary data
Supports backpressure

* Protocol Negotiation

연결을 맺고자 하는 peer는 자신이 사용하고자 하는 protocol id를 연결하고자 하는 peer에게 보냅니다. 요청을 받은 peer는 이에 대한 응답으로 연결이 가능한지 아닌지를 표현합니다.
연결을 위해 protocol id를 보낼 때 하나가 아닌 여러개를 보낼 수도 있습니다. 이 경우 요청을 받은 peer는 여러개 중 하나를 선택해서 응답하면 됩니다.

* libp2p가 사용하는 프로토콜

아래의 프로토콜들 모두 protocol buffer를 사용합니다.

- Ping

상대방이 살아있는지 아닌지를 체크합니다.
32 byte의 랜덤 데이터를 보내고 응답을 받습니다.
응답을 받으면 stream을 닫습니다.

/ipfs/ping/1.0.0

- Identify

서로서로에 대한 정보를 교환합니다.(public key, observedAddr)
(public key는 PeerId를 만들어 내는데 사용할 수 있고, observedAddr은 NAT 정보를 알아내기 위해 필요한 정보입니다.)

/ipfs/id/1.0.0

identify/push

Identify에서 약간 변형된 프로토콜로서 request가 와야만 response를 주는 Identify와는 다르게 상대 peer에게 Identify message를 보낼 수 있는 프로토콜입니다.
(relay peer인 경우 연결된 peer의 정보를 다른 peer들에 알려줄 수 있습니다.)
 
/ipfs/id/push/1.0.0

- secio

secure input/output 로서 TLS1.2에 유사한 프로토콜입니다. 현재 TLS1.3으로 변경이 작업중입니다.

/secio/1.0.0

- kad-dht

peer routing와 content routing에 사용하는 프로토콜
/ipfs/kad/1.0.0

- Circuit-Relay

peer들 사이를 relay해주는 프로토콜
/libp2p/circuit/relay/1.0.0

2019년 10월 26일 토요일

Bezier Curve 공부

Drawing Bezier Curves like in Google Material Rally

How I drew custom shapes in bottom bar

How I make CustomBottomSheet

Drawing bezier curves

Cubic Bezier curve : start point와 end point 그리고 두개의 control point로 구성된다.

Bezier curve를 그리기 위해 아래의 세단계를 취한다.

1. data point 지정
2. connection point 지정
3. point들을 연결하는 path를 정하고 canvas에 그린다. 이때 사용하는 함수는 cubicTo이다.

2019년 10월 25일 금요일

uCrop, the Image Cropping Library for Android: Look under the Hood of Our Masterpiece 를 읽고

https://yalantis.com/blog/how-we-created-ucrop-our-own-image-cropping-library-for-android/

[세 파트로 나누어서 구현]

- TransformImageView

ImageView를 상속
소스로부터 이미지 로드
matrix transform(translate, scale, rotate)하기

- CropImageView

crop boundary와 grid 그리기
이미지 이동시 crop boundary에 빈 영역이 생기지 않도록 이미지 위치시키기
지정한 룰(minimum scale, maximum scale 등)에 따라 matrix transform하는 함수 추가
zoom in/out
이미지 crop 하기

- GestureImageView

사용자 제스쳐(zoom, scroll, rotate gestures)

1. TransformImageView

크기가 큰 이미지의 경우 그대로 폰에 로드하면 메모리 문제가 발생할 수 있으므로 이미지를 샘플링해서 로드하는 것이 필요하다. 샘플링에 필요한 값은 screen diagonal로 정한다.
(BitmapFactory.options의 inJustDecodeBounds 를 사용해서 이미지를 메모리로 로드하지 않고 이미지의 정보만을 가져올 수 있다.)

2. CropImageView

이미지가 crop boundary를 전부 채우고 있는지 아닌지 확인 : crop bound의 네 코너가 이미지 안에 들어오는지 아닌지 확인
이미지가 crop boundary 안에 들어오도록 transform 하기 : 이미지의 센터와 crop bound의 센터 사이의 거리 계산. 그리고 이미지가 crop boundary 를 채우고 있지 못하면 scale을 한다.
이미지 crop 하기 :

3. GestureImageView

Android SDK에서 제공하는 GestureDetector와 ScaleGestureDetector를 사용하여 제스쳐 구현.
Rotation Gesture는 제공하지 않기 때문에 직접 구현




2019년 10월 23일 수요일

Testing Camera and Gallery Intents with Espresso 를 읽고

https://proandroiddev.com/testing-camera-and-galley-intents-with-espresso-218eb9f59da9

사진을 찍거나 갤러리에 접근하려면 권한이 필요하기 때문에 관련 작업을 하기전에 안드로이드에 권한을 요청해야 합니다. 앱의 코드에서는 권한을 요청하면 권한이 없는 경우 다이얼로그가 뜨고 여기서 OK를 하면 다음으로 진행이 되게 됩니다.
그러면, 테스트 코드에서는 어떻게 하면 될까요? 아래와 같은 코드를 테스트쪽에 넣어주면 테스트시 권한을 자동으로 부여합니다.

@get:Rule
var mRuntimePermissionRule = GrantPermissionRule.grant(android.Manifest.permission.WRITE_EXTERNAL_STORAGE)

Activity parameter는 다음의 코드로 가져올 수 있습니다.

@get:Rule
var mActivityTestRule = IntentsTestRule(MyActivity::class.java)

- 갤러리로부터 이미지 가져와서 ImageView에 넣는 코드 테스트하기

a. 가장 먼저 image를 로컬에 저장합니다.

b. 그리고 Intent.ACTION_CHOOSER action이 발생하면 응답으로 줄 ActivityResult를 등록해 줍니다.

intending(hasAction(Intent.ACTION_CHOOSER)).respondWith(imgGalleryResult)

c. ActivityResult는 아래와 같은 코드로 만들 수 있습니다.

Instrumentation.ActivityResult(Activity.RESULT_OK, resultData)

d. View에서의 동작을 지정해줍니다.

onView(withId(R.id.gallery)).perform(click())

onView(withId(R.id.image_viewer)).check(matches(hasImageSet()))

R.id.gallery에 click 이벤트가 발생하면 image_viewer에 hasImageSet에 일치하는지 확인하는 코드입니다.

hasImageSet은 BoundedMatcher를 상속해서 matchesSafely에 확인하고 싶은 것을 체크합니다.

관련 구글 코드 : https://github.com/android/testing-samples/blob/master/ui/espresso/IntentsAdvancedSample/app/src/androidTest/java/com/example/android/testing/espresso/intents/AdvancedSample/ImageViewerActivityTest.java

2019년 10월 20일 일요일

libp2p - Circuit Relay 를 읽고

https://docs.libp2p.io/concepts/circuit-relay/

Circuit Relay : 별도의 peer를 통해 통신하고자 하는 두 peer를 연결하는 transport protocol

보통 NAT 내부에 있는 peer의 경우 다른 peer와 쉽게 통신 할 수 없다. 이러한 경우 통신이 가능하도록 하기 위해 libp2p는 p2p-circuit이라는 프로토콜을 사용한다.

중간에 relay해주는 peer에게 연결은 어떻게 할 수 있을까? 기본적으로는 내가 연결이 가능한 relay peer의 주소를 peer에게 알려주면 될 것이다. 주소는 multiaddr을 사용한다.
또는 libp2p의 content routing interface를 사용해서 연결이 가능한 relay peer를 찾고 연결을 한 다음에 peer routing을 사용해서 연결한 relay peer의 주소를 다른 peer에게 알린다.(Autorelay)

Generic interfaces 요점

 https://go.dev/blog/generic-interfaces  Generic interface를 정의할 때 최소한의 제약만을 정의하고 실제 구현체들이 자신만의 필요한 제약을 추가할 수 있도록 하는 것이 좋다. pointer receiver를...