Skip to content

boostcamp-2020/Project01-A-User-Event-Collector

Folders and files

NameName
Last commit message
Last commit date

Latest commit

ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 
ย 

Repository files navigation

Team DIVE introduction

J124 J153 J190 S002 S015
์œ ์„ ๊ทœ(sunkest) ์ด์œ ํƒ(lcpnine) ์กฐ๋ณ‘๊ฑด(marulloc) ๊ฐ•๋ณ‘๋ฏผ(mike123789-dev) ๋ฅ˜์—ฐ์ˆ˜(yeonduing)

Link to Web Dev Logs
Link to iOS Dev Logs

[Web ์‹คํ–‰ํ™”๋ฉด]

iOS ์‹คํ–‰ํ™”๋ฉด





Project introduction

๋‹ค์–‘ํ•œ ํ”„๋กœ์ ํŠธ์—์„œ ๋…๋ฆฝ์ ์œผ๋กœ ์ ์šฉ ๊ฐ€๋Šฅํ•œ User Event Collector ์ œ์ž‘

User Event ? UI/UX ๊ฐœ์„  ๋“ฑ์„ ์œ„ํ•ด ์ˆ˜์ง‘ํ•˜๋Š” Event


์šฐ๋ฆฌ์˜ ์ด๋ฒคํŠธ ์ˆ˜์ง‘๊ธฐ "DIVE"

ํ”„๋กœ์ ํŠธ ๋งˆ๋‹ค **์˜๋ฏธ ์žˆ๋Š” ์ด๋ฒคํŠธ**๋Š” ๋‹ค๋ฅผ ๊ฒƒ ์ž…๋‹ˆ๋‹ค. **DIVE**๋Š” ์ž์œ ๋„ ๋†’๊ฒŒ ์„ค๊ณ„๋˜์–ด, **์˜๋ฏธ ์žˆ๋Š” ์ด๋ฒคํŠธ**์˜ ๋ฒ”์ฃผ๋ฅผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฆ‰, ๊ฐœ๋ฐœ์ž๊ฐ€ ์›ํ•œ๋‹ค๋ฉด, ๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ์ด๋ฒคํŠธ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์›น์˜ ๊ฒฝ์šฐ, ๋‹จ์ผ ์ด๋ฒคํŠธ ์—ฌ๋Ÿฌ๊ฐœ๋กœ ์ด๋ฃจ์–ด์ง„ ๋ณตํ•ฉ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ฑฐ๋‚˜, ์•ฑ์˜ ๊ฒฝ์šฐ, ์•ฑ์„ ์ข…๋ฃŒํ•˜๊ฑฐ๋‚˜ ๋…ธ๋ž˜๋ฅผ ์žฌ์ƒํ•˜๋Š” ์ด๋ฒคํŠธ๋“ค์„ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

**DIVE**๋ฅผ ์ด์šฉํ•˜์—ฌ, ์›ํ•˜๋Š” ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์ง‘ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ˆ˜์ง‘ํ•œ ๋ฐ์ดํ„ฐ๋Š” UI/UX ๊ฐœ์„ ์— ์ค‘์š”ํ•œ ๋ฐ์ดํ„ฐ๊ฐ€ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.


DIVE์˜ ๋™์ž‘์„ ๋ณด์ด๊ธฐ ์œ„ํ•˜์—ฌ, Naver ์ŠคํŠธ๋ฆฌ๋ฐ ์„œ๋น„์Šค VIBE๋ฅผ Cloneํ•˜์—ฌ ์ด๋ฒคํŠธ๋ฅผ ์ˆ˜์ง‘ํ–ˆ์Šต๋‹ˆ๋‹ค. Clone scope์—์„œ VIBE์˜ ์ถ”์ฒœ ๊ธฐ๋Šฅ๊ณผ ์Œ์› ์žฌ์ƒ ๊ธฐ๋Šฅ์€ ์ œ์™ธ

Link to Web DIVE ReadMe

Link to iOS DIVE ReadMe





Technology Stack

์Šคํฌ๋ฆฐ์ƒท(163)





DIVE ReadME

Web Event Collector

React ํ”„๋กœ์ ํŠธ๋ผ๋ฉด, ์–ด๋””์„œ๋“  ์‚ฌ์šฉ์ด ๊ฐ€๋Šฅํ•œ Event ์ˆ˜์ง‘๊ธฐ์ž…๋‹ˆ๋‹ค.

Config Object ๋ฅผ ์ž‘์„ฑํ•˜๊ณ , ์ด๋ฒคํŠธ ๋กœ๊น…์„ ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ๋ฅผ Emitter ๋กœ ๊ฐ์‹ธ๊ณ , ๋ถ€๋ชจ ์ปดํฌ๋„ŒํŠธ ์–ด๋”˜๊ฐ€์—์„œ Collector ๋กœ ๊ฐ์‹ธ์ค€๋‹ค๋ฉด ๋์ž…๋‹ˆ๋‹ค.

๊ฐ„๋‹จํ•œ Native Event์— ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ event๋กœ ๊ตฌ์„ฑ๋œ ๋ณตํ•ฉ ์ด๋ฒคํŠธ์—๋„ ์˜๋ฏธ๋ฅผ ๋ถ€์—ฌํ•˜์—ฌ ๋กœ๊น…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ตฌ์„ฑ์š”์†Œ

1. Event Config Object

โ€ƒ ์‚ฌ์šฉ์ž๊ฐ€ ์›ํ•˜๋Š” Event๋“ค์ด ๋‚˜์—ด๋˜์–ด ์žˆ๋‹ค.

โ€ƒ ์กฐ๊ฑด์ด ์ถฉ์กฑ๋˜๋ฉด, ์‚ฌ์šฉ์ž์—๊ฒŒ ์ฃผ์–ด์งˆ Event๋“ค์„ ์ •์˜

โ€ƒ Event์˜ ์˜ต์…˜๋“ค์„ ์ •์˜

โ€ƒ ์—ฌ๋Ÿฌ๊ฐœ์˜ Config Object๊ฐ€ ์กด์žฌ ํ•  ์ˆ˜ ์žˆ๋‹ค.

โ€ƒ ์›ํ•˜๋Š” Collector์—๊ฒŒ ์›ํ•˜๋Š” Config Object๋ฅผ ๋„˜๊ธธ ์ˆ˜ ์žˆ๋‹ค.

2. Collector

โ€ƒ config object์—์„œ ์ •์˜๋œ ์ด๋ฒคํŠธ๋“ค์„ ํ•ด์„

โ€ƒ Emiiter๋กœ๋ถ€ํ„ฐ ์ „ํŒŒ๋˜๋Š” ์ด๋ฒคํŠธ๋“ค์„ ๊ฐ์ง€ ๋ฐ ํ•„ํ„ฐ๋ง

โ€ƒ ๊ฐ์ง€๋œ ์ด๋ฒคํŠธ์— ๋Œ€ํ•ด dispatch๋กœ ์ „๋‹ฌ

โ€ƒ dispatch: ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•  ์ˆ˜ ์žˆ๋Š” ์ด๋ฒคํŠธ ํ•ธ๋“ค๋Ÿฌ.

3. Emitter

โ€ƒ ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ Event๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” Wrapping Component

โ€ƒ Event๊ฐ€ Bubbling๋˜๊ธฐ ์ „, Event ๊ฐ์ฒด์— props์™€ Event ID๋ฅผ ์‚ฝ์ž…ํ•œ๋‹ค.

โ€ƒ Native Event๊ฐ€ ์•„๋‹ˆ๋ผ, ์ปดํฌ๋„ŒํŠธ์˜ ์ƒํƒœ ๊ฐ’์„ ์กฐ๊ฑด์œผ๋กœ Event๋ฅผ ๋ฐœ์ƒ์‹œํ‚ฌ ์ˆ˜ ์žˆ๋‹ค.

4. Dispatch

โ€ƒ Collector์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์•ผ ํ•˜๋Š” ํ•จ์ˆ˜๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

โ€ƒ ๋กœ๊น…๋˜๋Š” ์ด๋ฒคํŠธ์˜ getterํ•จ์ˆ˜๋กœ ์ƒ๊ฐํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

โ€ƒ Collector๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ •์˜ํ•œ ์ด๋ฒคํŠธ ๋ฐœ์ƒ ์กฐ๊ฑด์„ ๋งŒ์กฑํ•˜๋ฉด dispatch๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.

โ€ƒ ๋”ฐ๋ผ์„œ, dispatch ํ•จ์ˆ˜๋Š”, ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์ฒ˜๋ฆฌํ•˜๋Š” ๋กœ์ง์„ ๋‹ด๊ณ  ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.


Event Config Object

Simple events

const example1: EventObject = {
  simple: {
    identifier_1: {
      event_id: 1,
      event_type: "click",
      description: "ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฐœ์ƒ",
    },
    identifier_2: {
      event_id: 2,
      event_type: "mouseover",
      description: "๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ ๋ฐœ์ƒ",
    },
  }
}
  • Simple ์—๋Š” ๋‹จ์ผ Event๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. line [2]
  • DIVE (our event collector)๋Š” "identifier_1"๊ณผ ๊ฐ™์ด string์œผ๋กœ event๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ identifier_1๊ณผ ๊ฐ™์ด ๊ฐ์ฒด์˜ key๊ฐ’์€ Uniqueํ•ด์•ผ ๋ฉ๋‹ˆ๋‹ค. line [3][9]
  • DIVE ๋Š” ์‚ฌ์šฉ์ž๊ฐ€ event_type์— ์ž…๋ ฅํ•œ event์— ๋”ฐ๋ผ, event log๋ฅผ ๋‚ด๋ณด๋ƒ…๋‹ˆ๋‹ค. DIVE ๋Š” Native Event๋ฅผ ๋Œ€๋ถ€๋ถ„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.line [5][11]
  • ๋˜ํ•œ ["click","mouseover"]์™€ ๊ฐ™์ด ์ž…๋ ฅ์„ ํ•œ๋‹ค๋ฉด, Emitter ๊ฐ€ ๊ฐ์‹ธ๋Š” ์ปดํฌ๋„ŒํŠธ์—์„œ click, mouseover์— ๋Œ€ํ•ด DIVE๊ฐ€ Event log๋ฅผ ๋‚จ๊น๋‹ˆ๋‹ค.
  • description ๋Š” optional์ž…๋‹ˆ๋‹ค. description์„ ์ž…๋ ฅํ•œ๋‹ค๋ฉด, event log์— description์ด ๋‹ด๊ธธ ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Complex events

import { EventObject } from "./collector";

const example1: EventObject = {
  simple: {
    identifier_1: {
      event_id: 1,
      event_type: ["click"],
      once: true,
      description: "ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฐœ์ƒ",
    },
    identifier_2: {
      event_id: 2,
      event_type: ["mouseover"],
      once: true,
      description: "๋งˆ์šฐ์Šค ์˜ค๋ฒ„ ์ด๋ฒคํŠธ ๋ฐœ์ƒ",
    },
    identifier_3: {
      event_id: 4,
      event_type: ["click"],
      once: false,
      description: "๋‹ค์‹œ ํด๋ฆญ ์ด๋ฒคํŠธ ๋ฐœ์ƒ",
    },
  },
  complex: {
    {
      timer: 3000,
      sequence: ["identifier_1", "identifier_2", "identifier_1"],
      event_id: 3,
      once: false,
      description: "์ƒ๋‹จ์˜ 3๊ฐ€์ง€ ์ด๋ฒคํŠธ๊ฐ€ ๋ชจ๋‘ ๋ฐœ์ƒํ•˜๋ฉด ํ•ด๋‹น ์ด๋ฒคํŠธ๊ฐ€ ์ˆ˜์ง‘๋ฉ๋‹ˆ๋‹ค",
    },
  },
};
export default example1;

  • complex ์—๋Š” ๋ณตํ•ฉ ์ด๋ฒคํŠธ๋ฅผ ์ •์˜ํ•ฉ๋‹ˆ๋‹ค.
  • sequence ์—๋Š”, simple์—์„œ ์ •์˜ํ•œ ๋‹จ์ผ ์ด๋ฒคํŠธ์˜ ์‹๋ณ„์ž๊ฐ€ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
  • sequence์— ๋‚˜์—ดํ•œ ์ด๋ฒคํŠธ๋“ค์ด, timer ์— ์ž‘์„ฑํ•œ ms๊ฐ€ ๋๋‚  ๋•Œ ๊นŒ์ง€ ๋ชจ๋‘ ๋ฐœ์ƒํ•œ๋‹ค๋ฉด, ์ด๋ฒคํŠธ๋ฅผ ๋กœ๊น…ํ•ฉ๋‹ˆ๋‹ค. ์—ฌ๊ธฐ์„ , 3์ดˆ ์•ˆ์—, identifier1, identifier2, identifier1์ด ๋ฐœ์ƒํ•  ๋•Œ, ์ด๋ฒคํŠธ๋ฅผ ๋กœ๊น…ํ•ฉ๋‹ˆ๋‹ค.

Note: ์ด๋ฒคํŠธ์˜ ๋กœ๊น…์€ Collector์—์„œ ์ด๋ค„์ง‘๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๋กœ๊น…์ด ๋ฐœ์ƒํ•˜๋ฉด, Collector๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ๋„˜๊ธด dispatchํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฒคํŠธ ๊ฐ์ฒด๋ฅผ dispatch ํ•จ์ˆ˜์˜ ์ธ์ž๋กœ ๋„˜๊ธฐ๋ฉด์„œ, ์‚ฌ์šฉ์ž๊ฐ€ dispatch๋ฅผ ์ •์˜ํ•œ๋Œ€๋กœ event๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.



Collector & Emitter

Example Code

const IndexPage = () => {
  return (
    <Collector eventConfig={example1} dispatch={(e) => {console.log(e)}}>
      <div>
        <Emitter identifier="testH1Event" eventType={["click"]}>
          <h1>Click Event Tester</h1>
        </Emitter>
        <div>Nothing Div</div>
        <Emitter identifier="testComponentEvent" eventType={["mouseover"]}>
          <TestComponent />
        </Emitter>
      </div>
    </Collector>
  );
};

Collector

  • Collector ๋Š” ํ•˜๋‚˜์˜ React Component๋กœ, ์œ„ ์ฝ”๋“œ์—์„œ์™€ ๊ฐ™์ด ์›ํ•˜๋Š” ์ปดํฌ๋„ŒํŠธ ๋ฐ”๊นฅ์ชฝ์— ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  • ํ•˜๋‚˜์˜ Collector ์•ˆ์ชฝ์— ์žˆ๋Š” ์—ฌ๋Ÿฌ ๊ฐœ์˜ Emitter ๋“ค๋กœ ๋ถ€ํ„ฐ ๋ฐœ์ƒ๋œ ๋ชจ๋“  ์ด๋ฒคํŠธ๋Š” ๋ชจ๋‘ ๊ฐ™์€ Collector์—์„œ ์ˆ˜์ง‘๋ฉ๋‹ˆ๋‹ค.
  • ํ•˜๋‚˜์˜ Complex Event์— ํฌํ•จ๋˜๋Š” Simple Event ๋“ค์€ ํ•˜๋‚˜์˜ Collector์•ˆ์— ์ž‘์„ฑ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ์–ด์ง€๋Š” props๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • eventConfig: ์•ž์„œ ์„ค๋ช…๋œ ์ด๋ฒคํŠธ ์ •์˜ object
    • dispatch: ํ•ด๋‹น Collector์—์„œ ์ด๋ฒคํŠธ ๊ฐ์ง€์‹œ ํ˜ธ์ถœ๋  ์ฝœ๋ฐฑ ๋ฉ”์„œ๋“œ. dispatch์˜ ์ž‘์„ฑ์— ๋Œ€ํ•ด์„œ๋Š” ํ›„์ˆ ๋ฉ๋‹ˆ๋‹ค.

      Note: Collector๋ฅผ ์–ด๋–ค ์ปดํฌ๋„ŒํŠธ์— ๋ž˜ํ•‘ํ•  ๊ฒƒ์ธ์ง€ ์ •ํ•˜๋Š” ๊ฒƒ์€ ๊ฐœ๋ฐœ์ž์˜ ๋ชซ์ž…๋‹ˆ๋‹ค. ๋‹ค๋งŒ, ์ „์—ญ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜, ๋„ˆ๋ฌด ํฐ ํŽ˜์ด์ง€์™€ ๊ฐ™์€ ์ปดํฌ๋„ŒํŠธ์— ์‚ฌ์šฉ๋œ๋‹ค๋ฉด ํ•˜๋‚˜์˜ Collector์— ๋ฒ„๋ธ”๋ง๋˜๋Š” ์ด๋ฒคํŠธ๊ฐ€ ๊ณผ๋„ํ•˜๊ฒŒ ๋งŽ์•„์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ€๋Šฅํ•˜๋‹ค๋ฉด, ์ ์ ˆํžˆ Collector๋ฅผ ๋ถ„๋ฆฌํ•˜๋Š” ๊ฒƒ์„ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค.


Emitter

  • Emitter ๋˜ํ•œ ํ•˜๋‚˜์˜ React Component๋กœ, ๊ธฐ๋ณธ ์ด๋ฒคํŠธ ์ˆ˜์ง‘ ๋Œ€์ƒ ์ปดํฌ๋„ŒํŠธ ๋ฐ”๋กœ ๋ฐ”๊นฅ์ชฝ์— ๋ž˜ํ•‘ํ•ฉ๋‹ˆ๋‹ค.
  • ์ฃผ์–ด์ง€๋Š” props๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    • identifier: ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•  ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ตฌ๋ถ„ํ•  ์‹๋ณ„์ž๋กœ, ๋ฌธ์ž์—ด ํ˜•ํƒœ์ž…๋‹ˆ๋‹ค. config object์— ์ •์˜ํ•œ ์‹๋ณ„์ž๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.
    • eventType: ๋ฐœ์ƒ๋  ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ •์˜๊ฐ€ ๋“ค์–ด๊ฐ€๋ฉฐ, ๋ฌธ์ž์—ด ๋˜๋Š” object ์˜ ๋ฐฐ์—ด ํ˜•ํƒœ๋กœ ์ž…๋ ฅ๋ฐ›์œผ๋ฉฐ ์—ฌ๋Ÿฌ ๊ฐœ๋ฅผ ์ž…๋ ฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
      • eventType์— ๋“ค์–ด๊ฐˆ Object ์˜ˆ์‹œ :
      • {
          eventType: "click",
          restrictFire: {
            method: "throttle",
            time: 3,
        }
        
      • ๋ณ„๋„ option๋“ค์ด ํ•„์š”ํ•˜์ง€ ์•Š์€ ๊ฒฝ์šฐ string ํ˜•ํƒœ๋กœ eventType๋งŒ ์ž…๋ ฅํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • Emitter๋กœ ๊ฐ์‹ผ ์ปดํฌ๋„ŒํŠธ์—์„œ eventType์œผ๋กœ ์ง€์ •ํ•œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒ๋œ ๊ฒฝ์šฐ, identifier, ๋ธŒ๋ผ์šฐ์ €์˜ nativeEvent์ •๋ณด, children์˜ props ๋“ฑ ๋ช‡๊ฐ€์ง€ ์ •๋ณด๋ฅผ ๋‹ด์€ ๊ฐ์ฒด๋ฅผ ๋ถ€๋ชจ ์š”์†Œ๋กœ ๋ฒ„๋ธ”๋งํ•ฉ๋‹ˆ๋‹ค.
    • children์ด ๋ฐ˜๋“œ์‹œ single React element์ผ ํ•„์š”๋Š” ์—†์ง€๋งŒ single React element๊ฐ€ ์•„๋‹ˆ๋ผ๋ฉด children props๋Š” undefined๋กœ ๋ฒ„๋ธ”๋ง ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์ด๋ ‡์— ๋ฒ„๋ธ”๋ง ๋˜๋Š” ์ด๋ฒคํŠธ๋Š” Collector๋ฅผ ๋งŒ๋‚  ๋•Œ ๊นŒ์ง€ ๋ฒ„๋ธ”๋ง๋˜๋ฉฐ, Collector๋ฅผ ๋งŒ๋‚˜๋ฉด config object ์ •๋ณด์™€, identifier, eventType์„ ๋น„๊ตํ•˜์—ฌ ํ•„ํ„ฐ๋ง๋˜๊ณ , ์ˆ˜์ง‘ ๋Œ€์ƒ์ธ ์ด๋ฒคํŠธ์˜ ๊ฒฝ์šฐ dispatch์— ์ „๋‹ฌ๋ฉ๋‹ˆ๋‹ค.

Dispatch

  • Collector ์˜ ์ธ์ž๋กœ ๋„˜๊ฒจ์ง€๋Š” ํ•จ์ˆ˜๋กœ, ์‚ฌ์šฉ์ž๊ฐ€ ์ง์ ‘ ์ •์˜ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • dispatch={console.log}์™€ ๊ฐ™์ด ๋„˜๊ฒจ์ง‘๋‹ˆ๋‹ค. ์ •์˜๋œ ์ด๋ฒคํŠธ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด, Collector ๋Š” ๋ฐ”๋กœ dispatch ๋ฅผ ํ˜ธ์ถœํ•ฉ๋‹ˆ๋‹ค.
  • dispatch์— ๋„˜๊ฒจ์ง€๋Š” ์ธ์ž๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.
    dispatch({
      userEvent : {user๊ฐ€ config object์— ์ •์˜ํ•œ ๊ฐ์ฒด},
      data : {Emitter๊ฐ€ ๋ž˜ํ•‘ํ•˜๊ณ  ์žˆ๋Š” ์ปดํฌ๋„ŒํŠธ์˜ props},
      nativeEvent : {๋ธŒ๋ผ์šฐ์ €์˜ native ์ด๋ฒคํŠธ ๊ฐ์ฒด}
    })
    
  • data ๋ฅผ ํ†ตํ•ด, map์„ ํ†ตํ•ด ์ƒ์„ฑ๋œ ์ปดํฌ๋„ŒํŠธ๋ผ๋„, ์–ด๋Š ์š”์†Œ๋ฅผ ํด๋ฆญํ–ˆ๋Š”์ง€ ์‚ฌ์šฉ์ž๊ฐ€ dispatch ํ•จ์ˆ˜๋ฅผ ํ†ตํ•ด ํŒ๋‹จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • nativeEvent ์™€ userEvent ๊ฐ์ฒด๋ฅผ ๋ฐ›์•„ ์‚ฌ์šฉ์ž๊ฐ€ ์ž์œ ๋กญ๊ฒŒ ์ด์šฉํ•  ์ˆ˜ ์žˆ๊ฒŒ ํ–ˆ์Šต๋‹ˆ๋‹ค.


iOS Event Collector


๊ตฌ์„ฑ์š”์†Œ

  1. Event
    • Event Collector์—์„œ ์ œ๊ณตํ•˜๋Š” ๋ชจ๋“  ์ด๋ฒคํŠธ.
    • Event ํ”„๋กœํ† ์ฝœ ์ฑ„ํƒ
  2. EventManager
    • ์ด๋ฒคํŠธ๋ฅผ ๋กœ๊น…ํ•˜๊ธฐ ์œ„ํ•œ ์ตœ์ƒ๋‹จ API, ์‹ค์ œ๋กœ ๋กœ๊น…์„ํ•˜์ง€๋Š” ์•Š๊ณ ,
    • EventEngine์„ ์ด์šฉํ•˜์—ฌ ๋ณด๋ƒ„.
  3. EventEngine
    • ์ง์ ‘์ ์œผ๋กœ ๋กœ๊น… ์ „์†ก/์ €์žฅ์„ ๋‹ด๋‹น.
    • EventSendable, EventFetchable ํ”„๋กœํ† ์ฝœ ์ฑ„ํƒ

Event

public protocol Event: Codable {
    var name: String { get }
    var createdAt: String? { get }
    var metadata: [String: String]? { get }
}

๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” ์ด๋ฒคํŠธ

class BaseEvent: Event {
    var name: String
    var createdAt: String?
    var metadata: [String: String]?

    public init(name: String, createdAt: String?, metadata: [String: String]?) {
        self.name = name
        self.createdAt = createdAt
        self.metadata = metadata
    }
}

Event ํ”„๋กœํ† ์ฝœ์„ ์ฑ„ํƒํ•˜๋Š” Custom Event์˜ ์˜ˆ์‹œ

struct ScreenEvent: Event {
    var name: String
    var metadata: [String: String]?

    private init(name: String, metadata: [String: String]? = nil) {
        self.name = name
        self.metadata = metadata
    }

    static let playerPushed = ScreenEvent(name: "playerPushed")

    static let playerPopped = ScreenEvent(name: "playerPopped")

}

Event Engine

public protocol EventSendable: class {
    func send<T: Event>(_ event: T)
}

public protocol EventFetchable: class {
    func fetch() -> [BaseEvent]
}
public protocol EventSendableAndFetchable: EventSendable, EventFetchable {
}

๊ธฐ๋ณธ์ ์œผ๋กœ ์ œ๊ณต๋˜๋Š” Engine

public final class MockServerEngine: EventSendable {
    public init() {

    }
    public func send<T: Event>(_ event: T) {
        print("MockServer - \(event.name)")
        event.metadata?.forEach { key, value in
            print("ใ„ด \(key) : \(value)")
        }
    }
}

์ด๋ฒคํŠธ์˜ ํ๋ฆ„

์ด๋ฒคํŠธ์˜ ๊ฐ„ํŽธํ•œ ํ™•์žฅ์„ฑ

Event protocol๋กœ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ, ์ƒˆ๋กœ์šด ์ด๋ฒคํŠธ๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š”๊ฒƒ์€ ๋งค์šฐ ๊ฐ„ํŽธํ•ด์ง‘๋‹ˆ๋‹ค.

New Model Version

์ด๋ฒคํŠธ type checking

Event protocol์„ ์ฑ„ํƒํ•˜๋Š” custom type์˜ ์ด๋ฒคํŠธ๋ฅผ ๊ตฌํ˜„ํ•จ์œผ๋กœ์จ, ์›ํ•˜๋Š” ์ด๋ฒคํŠธ์— ๋Œ€ํ•œ ์ž๋™์™„์„ฑ ๊ฒฐ๊ณผ๋ฅผ ๋ณผ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์—”์ง„์˜ ๋‹ค์–‘ํ•œ ๊ตฌํ˜„

EventSendable, EventFetchableprotocol์„ ์ฑ„ํƒํ•˜๋Š” ์—”์ง„์„ ๋‹ค์–‘ํ•˜๊ฒŒ ๊ตฌํ˜„ํ• ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ์ƒํ™ฉ์— ๋งž๊ฒŒ ํ•„์š”ํ•œ ์—”์ง„์„ ๊ฐˆ์•„ ๋ผ์šฐ๋Š”๊ฒƒ๋„ ๋งค์šฐ ์‰ฝ์Šต๋‹ˆ๋‹ค.

New Model Version

๋˜ํ•œ, EventManager๋Š” ๋‹ค์ˆ˜์˜ ์—”์ง„์„ ๊ฐ€์งˆ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ์ €ํฌ ์•ฑ์—์„œ๋Š” back end server๋ฅผ ์œ„ํ•œ engine๊ณผ core data๋ฅผ ์œ„ํ•œ engine ๋‘๊ฐœ๋ฅผ ๊ตฌํ˜„ํ•˜๊ณ  ์ฃผ์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

์„ค์น˜

์–ด๋Š ํ”„๋กœ์ ํŠธ์—์„œ๋„ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•˜๋„๋ก Swift package manager๋ฅผ ์ด์šฉํ•œ ์„ค์น˜๊ฐ€ ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

  1. Xcode ๋ฉ”๋‰ด์—์„œ File > Swift Packages > Add Package Dependency๋ฅผ ์„ ํƒํ›„
  2. https://github.com/mike123789-dev/DiveEventCollector ๋ฅผ ์ž…๋ ฅํ•ฉ๋‹ˆ๋‹ค

Web Dev Logs

Web Dev Logs Author
Next.js ์กฐ๋ณ‘๊ฑด
Sequelize ๋– ๋‚˜๋ณด๋‚ด๊ธฐ ์ด์œ ํƒ
Prisma ๋„์ž…๊ณผ ์‚ฌ์šฉ๋ฒ• ์ด์œ ํƒ
Vercel๋กœ Next app ๋ฐฐํฌํ•˜๊ธฐ ์ด์œ ํƒ
Jenkins๋กœ CI ๊ตฌํ˜„ํ•˜๊ธฐ ์กฐ๋ณ‘๊ฑด
Naver OAuth2.0 ์—ฐ๋™ํ•˜๊ธฐ ์œ ์„ ๊ทœ
์šฐ๋ฆฌ๋งŒ์˜ Storybook ํ™œ์šฉ๋ฒ•...
Spread Operator(...)๋กœ props๋ฅผ ์ „๋‹ฌํ•˜๋Š” ๊ฒƒ์€ ์ •๋ง anti-pattern์ธ๊ฐ€?
์กฐ๋ณ‘๊ฑด,์ด์œ ํƒ,์œ ์„ ๊ทœ

iOS Dev Logs

iOS Dev Logs Author
๋…ธ๋ž˜ track list๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž! (part1: SwiftUI๋ฅผ ์ด์šฉํ•˜์—ฌ Cell ๋””์ž์ธํ•˜๊ธฐ) ๊ฐ•๋ณ‘๋ฏผ
๋…ธ๋ž˜ track list๋ฅผ ๋งŒ๋“ค์–ด๋ณด์ž! (part2: List๋กœ ๋ณด์—ฌ์ฃผ๊ธฐ ๋ฐ ViewModel์ ์šฉํ•˜๊ธฐ) ๊ฐ•๋ณ‘๋ฏผ
SwiftUI์—์„œ View์™€ Model Binding (part1: @State์™€ @Binding) ๊ฐ•๋ณ‘๋ฏผ
SwiftUI์—์„œ View์™€ Model Binding (part2: @StateObject, @ObservedObject, @Published) ๊ฐ•๋ณ‘๋ฏผ
SwiftUI์—์„œ View์™€ Model Binding (part3: @EnvironmentObject) ๊ฐ•๋ณ‘๋ฏผ
Combine์„ ์ด์šฉํžŒ chaining ๊ฐ•๋ณ‘๋ฏผ
Protocol ๊ธฐ๋ฐ˜์˜ Analytics System์„ ๋งŒ๋“ค์–ด๋ณด์ž ๊ฐ•๋ณ‘๋ฏผ
SwiftUI) ์‚ฌ์šฉ์ž ์ด๋ฒคํŠธ ์ˆ˜์ง‘ ๋ฐ Alert๋กœ ํ™•์ธ ๋ฅ˜์—ฐ์ˆ˜
์„œ๋ฒ„๋กœ postํ•  ๋•Œ json ํ˜•์‹์œผ๋กœ ๋ณด๋‚ด๊ธฐ ๋ฅ˜์—ฐ์ˆ˜
์ฝ”์–ด๋ฐ์ดํ„ฐ ๋งˆ์ด๊ทธ๋ ˆ์ด์…˜ ๋ฅ˜์—ฐ์ˆ˜
CoreData๋กœ ์˜คํ”„๋ผ์ธ์—์„œ๋„ ์ด์šฉ ๊ฐ€๋Šฅํ•œ ์•ฑ ๋งŒ๋“ค๊ธฐ ๋ฅ˜์—ฐ์ˆ˜
SwiftUI) NavigationLink์™€ Memory Leak ๋ฅ˜์—ฐ์ˆ˜
URL๋กœ ๋น„๋™๊ธฐ ์ด๋ฏธ์ง€ ์ƒ์„ฑํ•˜๊ธฐ - Combine๊ณผ Network ๋ฅ˜์—ฐ์ˆ˜
SwiftUI) ViewBuilder ์™€ guard let ๋ฅ˜์—ฐ์ˆ˜
SwiftUI) ObservableObject์™€ ์ƒ์† ๋ฅ˜์—ฐ์ˆ˜
SwiftUI) MVVM๊ณผ Combine ๋ฅ˜์—ฐ์ˆ˜
SwiftUI) ๋‹ค์ด๋‚˜๋ฏน ๋ฆฌ์ŠคํŠธ ๋ฅ˜์—ฐ์ˆ˜