{"id":2929,"date":"2017-03-09T23:13:48","date_gmt":"2017-03-10T07:13:48","guid":{"rendered":"https:\/\/www.couchbase.com\/blog\/?p=2929"},"modified":"2025-06-13T19:58:39","modified_gmt":"2025-06-14T02:58:39","slug":"couchbase-mobile-changes-explorer-part-2","status":"publish","type":"post","link":"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-2\/","title":{"rendered":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ubaa8\ubc14\uc77c, \ud0d0\uc0c9\uae30\ub97c \ubc14\uafbc\ub2e4 - \ud30c\ud2b8. 2"},"content":{"rendered":"<h2>\uc18c\uac1c<\/h2>\n<p>\uadf8\ub9ac\uace0 <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/developers\/mobile\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ubaa8\ubc14\uc77c<\/a> <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/guides\/sync-gateway\/index.html?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">\ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774<\/a> \ubcc0\uacbd\uc0ac\ud56d \ud53c\ub4dc\ub294 \ubaa8\ubc14\uc77c \ubc30\ud3ec\uc5d0\uc11c \uc774\ubca4\ud2b8\ub97c \ubaa8\ub2c8\ud130\ub9c1\ud560 \uc218 \uc788\ub294 \ubc29\ubc95\uc744 \uc81c\uacf5\ud569\ub2c8\ub2e4. \uc774 \ud53c\ub4dc\ub97c \uc0ac\uc6a9\ud558\uba74 \uc815\uad50\ud55c \ube44\uc988\ub2c8\uc2a4 \ub85c\uc9c1\uc744 \uc791\uc131\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ud53c\ub4dc\ub97c \uac80\ud1a0\ud558\uace0 \uc774\ud574\ud558\ub294 \ub370 \ub3c4\uc6c0\uc774 \ub418\ub294 \ub3c4\uad6c\ub97c \ub9cc\ub4e4\uc5c8\uc2b5\ub2c8\ub2e4. \ub2e4\uc74c\uc5d0\uc11c \uc18c\uac1c\uc640 \uc124\uba85\uc744 \uc77d\uc744 \uc218 \uc788\uc2b5\ub2c8\ub2e4. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-1\/\">\ud30c\ud2b8 1<\/a> \uc758 \ub450 \ubd80\ubd84\uc73c\ub85c \uad6c\uc131\ub41c \uc2dc\ub9ac\uc988\uc785\ub2c8\ub2e4. \uc774 \ucf54\ub4dc\ub294 \ud53c\ub4dc \uccad\ucde8\uc758 \uc608\uc2dc\uc774\uae30\ub3c4 \ud569\ub2c8\ub2e4.<\/p>\n<h2>\ucf54\ub4dc<\/h2>\n<p>\uc571 \ucf54\ub4dc\uc758 \uc8fc\uc694 \ud074\ub798\uc2a4\ub97c \uc5ec\uae30\uc5d0 \ud3ec\ud568\uc2dc\ucf30\uc2b5\ub2c8\ub2e4. \uc774\uac83\uc740 \uccab \ubc88\uc9f8 \ubc84\uc804\uc774\ubbc0\ub85c \ub9ce\uc740 \uac1c\uc120 \uc0ac\ud56d\uc744 \uc0ac\uc6a9\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. \ub9e4\uac1c\ubcc0\uc218\ub294 \ubaa8\ub450 \ud558\ub4dc \uc640\uc774\uc5b4\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4. \ud504\ub85c\uc81d\ud2b8 \ud655\uc778 <a href=\"https:\/\/github.com\/couchbaselabs\/CBM-Changes-Explorer\">\uc5ec\uae30 \uae43\ud5c8\ube0c\uc5d0\uc11c<\/a> \uc5d0\uc11c \uc5c5\ub370\uc774\ud2b8\ub97c \ud655\uc778\ud558\uc138\uc694.  \uc571 \ube4c\ub4dc, \uc2e4\ud589 \ubc0f \ud328\ud0a4\uc9d5\uc5d0 \ub300\ud55c \uc9c0\uce68\ub3c4 \uc5ec\uae30\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<h3>JavaFX: \ucee8\ud2b8\ub864\ub7ec \ud074\ub798\uc2a4<\/h3>\n<p>JavaFX\ub294 \uac04\ub2e8\ud55c \uc571\uc744 \ucee8\ud2b8\ub864\ub7ec \ud074\ub798\uc2a4\uc640 \uc120\uc5b8\uc801 UI\ub85c \ub098\ub215\ub2c8\ub2e4. \ucee8\ud2b8\ub864\ub7ec\ub97c \uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">com.couchbase.mobile\uc744 \ud328\ud0a4\uc9c0\ud654\ud569\ub2c8\ub2e4;\r\n\r\nimport com.couchbase.lite.*;\r\ncom.fasterxml.jackson.core.JsonProcessingException\uc744 \uac00\uc838\uc635\ub2c8\ub2e4;\r\njavafx.application.Platform\uc744 \uac00\uc838\uc635\ub2c8\ub2e4;\r\njavafx.beans.value.ChangeListener\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\nimport javafx.beans.value.ObservableValue;\r\njavafx.collections.FXCollections;\r\njavafx.collections.ObservableList\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\njavafx.event.ActionEvent\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\nimport javafx.fxml.FXML;\r\nimport javafx.scene.control.*;\r\njavafx.scene.control.TextField\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\n\r\nimport java.io.IOException;\r\nimport java.net.MalformedURLException;\r\nimport java.net.URL;\r\nimport java.util.Map;\r\n\r\n\uc815\uc801 com.couchbase.mobile.Runtime.mapper\ub97c \uc784\ud3ec\ud2b8\ud569\ub2c8\ub2e4;\r\n\r\n\uacf5\uc6a9 \ud074\ub798\uc2a4 \ucee8\ud2b8\ub864\ub7ec\ub294 LiveQuery.ChangeListener, \ubcc0\uacbd \ub9ac\uc2a4\ub108\ub97c \uad6c\ud604\ud569\ub2c8\ub2e4,\r\n    SGMonitor.ChangesFeedListener, DBService.ReplicationStateListener { {\r\n  private static final String SYNC_GATEWAY_HOST = \"https:\/\/localhost\";\r\n  private static final String SG_PUBLIC_URL = SYNC_GATEWAY_HOST + \":4984\/\" + DBService.DATABASE;\r\n  private static final String SG_ADMIN_URL = SYNC_GATEWAY_HOST + \":4985\/\" + DBService.DATABASE;\r\n\r\n  private static final String TOGGLE_INACTIVE = \"-fx-background-color: #e6555d;\";\r\n  private static final String TOGGLE_ACTIVE = \"-fx-background-color: #ade6a6;\";\r\n  private static final String TOGGLE_DISABLED = \"-fx-background-color: #555555;\";\r\n\r\n  @FXML private ListView documentList;\r\n  private ObservableList documents = FXCollections.observableArrayList();\r\n  @FXML private TextArea contentsText;\r\n  @FXML private TextArea changesFeed;\r\n  @FXML private TextField usernameText;\r\n  @FXML private TextField passwordText;\r\n  @FXML private ToggleButton applyCredentialsBtn;\r\n  @FXML \ube44\uacf5\uac1c \ud1a0\uae00 \ubc84\ud2bc syncBtn;\r\n\r\n  private DBService service = DBService.getInstance();\r\n  private \ub370\uc774\ud130\ubca0\uc774\uc2a4 db = service.getDatabase();\r\n  private SGMonitor changesMonitor;\r\n  private LiveQuery liveQuery;\r\n<\/pre>\n<p>\uc774 \uccab \ubc88\uc9f8 \ubaa9\ub85d\uc5d0\ub294 \ubcf4\uc77c\ub7ec \ud50c\ub808\uc774\ud2b8 \ucf54\ub4dc\uac00 \ub9ce\uc774 \ub098\uc640 \uc788\uc2b5\ub2c8\ub2e4. \ud074\ub798\uc2a4 \uc790\uccb4 \ub0b4\uc5d0\uc11c UI\ub97c \uc704\ud55c \uc5ec\ub7ec \ub9ac\uc2a4\ub108\ub97c \uad6c\ud604\ud558\uc5ec \ud30c\uc77c \uc218\ub97c \uc904\uc600\uc2b5\ub2c8\ub2e4. \uc774\uac83\uc740 \uc608\uc2dc\ub97c \uc704\ud55c \uac83\uc785\ub2c8\ub2e4.<\/p>\n<p>\uadf8\ub9ac\uace0 <code>@FXML<\/code> \uc5b4\ub178\ud14c\uc774\uc158\uc740 \ud504\ub808\uc784\uc6cc\ud06c\uac00 UI\uc758 \uc77c\ubd80\uc5d0 \uc790\ub3d9\uc73c\ub85c \ubc14\uc778\ub529\ud558\ub294 \ubaa8\ub4e0 \ud544\ub4dc\ub97c \ud45c\uc2dc\ud569\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c\uc740 \ucd08\uae30\ud654\uc785\ub2c8\ub2e4. JavaFX\ub294 \ud45c\uc900 \ub77c\uc774\ud504\uc0ac\uc774\ud074\uc758 \uc77c\ubd80\ub85c \uc774 \uba54\uc11c\ub4dc\ub97c \ud638\ucd9c\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  @FXML private void initialize() {\r\n    documentListInitialize();\r\n    documentList.setItems(documents);\r\n\r\n    setState(applyCredentialsBtn, false);\r\n    setState(syncBtn, false);\r\n\r\n    service.addReplicationStateListener(this);\r\n\r\n    changesMonitor = new SGMonitor(SG_ADMIN_URL, \"false\", \"true\", \"0\", \"all_docs\", this);\r\n    changesMonitor.start();\r\n  }\r\n\r\n  private void documentListInitialize() {\r\n    \ucffc\ub9ac \ucffc\ub9ac = db.createAllDocumentsQuery();\r\n    query.setAllDocsMode(Query.AllDocsMode.INCLUDE_DELETED);\r\n    liveQuery = query.toLiveQuery();\r\n    liveQuery.addChangeListener(this);\r\n    liveQuery.start();\r\n\r\n    documentList.getSelectionModel().selectedItemProperty().addListener(this);\r\n  }<\/pre>\n<p>\ubb38\uc11c \ubaa9\ub85d \ucd08\uae30\ud654\ub97c \uc790\uccb4 \ub8e8\ud2f4\uc73c\ub85c \ubd84\ub9ac\ud588\uc2b5\ub2c8\ub2e4. \ubb38\uc11c \ubaa9\ub85d\uc740 <code>\ubb38\uc11c \ubaa9\ub85d<\/code> \ubcc0\uc218\ub97c \uc124\uc815\ud569\ub2c8\ub2e4. \ucc28\ub840\ub85c <code>\ubb38\uc11c \ubaa9\ub85d<\/code> \ub294 \uc804\ub2ec\ud55c \ud56d\ubaa9 \ubaa9\ub85d\uc774 \ubcc0\uacbd\ub420 \ub54c\ub9c8\ub2e4 UI\ub97c \uc5c5\ub370\uc774\ud2b8\ud569\ub2c8\ub2e4.<\/p>\n<p>\ud074\ub77c\uc774\uc5b8\ud2b8 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \ubcc0\uacbd \uc0ac\ud56d\uc774 \uc788\ub294\uc9c0 \ubaa8\ub2c8\ud130\ub9c1\ud558\uae30 \uc704\ud574 \uc2e4\uc2dc\uac04 \ucffc\ub9ac\ub97c \uc124\uc815\ud588\uc2b5\ub2c8\ub2e4. \uc774\ub294 '\ubaa8\ub4e0 \ubb38\uc11c' \ucffc\ub9ac\ub97c \ud1b5\ud574 \uc774\ub8e8\uc5b4\uc9d1\ub2c8\ub2e4. \ubaa8\ub4e0 \ubb38\uc11c \ucffc\ub9ac\uc5d0\ub294 \uc5f0\uacb0\ub41c \ubcf4\uae30\uac00 \ud544\uc694\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uc800\ub294 <code>\ud3ec\ud568_\uc0ad\uc81c\ub428<\/code> \ub97c \uc124\uc815\ud558\uba74 \ub3c4\uad6c\uac00 \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc0ad\uc81c\ub41c \ubb38\uc11c\uac00 \uc5b4\ub5bb\uac8c \ubcf4\uc774\ub294\uc9c0 \ubcf4\uc5ec\uc904 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\ub978 \ubc14\uc778\ub529\uc774 \uc81c\uc790\ub9ac\uc5d0 \uc788\uc73c\uba74, \uc6b0\ub9ac\ub294 \ub2e8\uc9c0 <code>\ubb38\uc11c<\/code> \ubaa9\ub85d\uc5d0 \ucd94\uac00\ud569\ub2c8\ub2e4. \uc774 \uc791\uc5c5\uc744 \uc218\ud589\ud558\ub294 \ub77c\uc774\ube0c \ucffc\ub9ac \ub9ac\uc2a4\ub108\ub294 \ub098\uc911\uc5d0 \uc790\uc138\ud788 \uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c \uba87 \uc904\uc740 \uba87 \uac1c\uc758 \ud1a0\uae00 \ubc84\ud2bc\uc758 \ucd08\uae30 \uc0c1\ud0dc\ub97c \uc124\uc815\ud569\ub2c8\ub2e4. \ucd94\uac00 \ub9ac\uc2a4\ub108\uac00 \uc788\uc5b4\uc57c <code>\ub3d9\uae30\ud654<\/code> \ubc84\ud2bc\uc774 \ubcf5\uc81c\ubcf8\uc758 \uc2e4\uc81c \uc0c1\ud0dc\uc640 \uc77c\uce58\ud558\ub3c4\ub85d \uc124\uc815\ud569\ub2c8\ub2e4. \uc774\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \uc774 \uae00\uc758 \ub4b7\ubd80\ubd84\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774\ub97c \ubaa8\ub2c8\ud130\ub9c1\ud558\uae30 \uc704\ud574 \ubcc4\ub3c4\uc758 \ud074\ub798\uc2a4\ub97c \uc791\uc131\ud588\uc2b5\ub2c8\ub2e4. \ucd08\uae30\ud654 \ucf54\ub4dc\ub294 \uc0c8 \ubaa8\ub2c8\ud130 \uc778\uc2a4\ud134\uc2a4\ub97c \uc0dd\uc131\ud558\uace0 \uc2dc\uc791\ud558\uc5ec \uc644\ub8cc\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c \uc139\uc158\uc5d0\ub294 \uc5ec\ub7ec \ub9ac\uc2a4\ub108\uac00 \ud3ec\ud568\ub418\uc5b4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  \/\/ LiveQuery.ChangeListener\r\n  @Override\r\n  public void changed(LiveQuery.ChangeEvent event) {\r\n    if (event.getSource().equals(liveQuery)) {{\r\n      Platform.runLater(() -&gt; {\r\n        \ucffc\ub9ac \uc5f4\uac70\uc790 rows = event.getRows();\r\n\r\n        documents.clear();\r\n\r\n        rows.forEach(queryRow -&gt; documents.add(queryRow.getDocumentId()));\r\n      });\r\n    }\r\n  }<\/pre>\n<p>\ub2e4\uc74c\uc740 \ub85c\uceec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uac00 \ubcc0\uacbd\ub420 \ub54c\ub9c8\ub2e4 \ud638\ucd9c\ub418\ub294 \ub77c\uc774\ube0c \ucffc\ub9ac \ub9ac\uc2a4\ub108\uc785\ub2c8\ub2e4. \uc800\ub294 \uc774 \ub3c4\uad6c\ub97c \ub300\uaddc\ubaa8 \ub370\uc774\ud130\ubca0\uc774\uc2a4 \uc791\uc5c5\uc6a9\uc73c\ub85c \uc124\uacc4\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4. \uadf8\ub798\uc11c \ub370\uc774\ud130\uac00 \ubcc0\uacbd\ub420 \ub54c\ub9c8\ub2e4 \ubaa8\ub4e0 \ubb38\uc11c\ub97c \ub2e4\uc2dc \uc77d\ub294 \ubb34\ucc28\ubcc4 \ub300\uc785 \ubc29\uc2dd\uc744 \ud0dd\ud588\uc2b5\ub2c8\ub2e4. \uadf8\ub798\uc11c <code>getRows<\/code> \uba54\uc11c\ub4dc\ub294 \uc778\ub371\uc2f1\uc744 \uc218\ud589\ud558\ub294 \uc5f4\uac70\uc790\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4. JavaFX\ub294 \ub2e4\uc74c\uacfc \uac19\uc740 \uacbd\uc6b0 UI \uc5c5\ub370\uc774\ud2b8\ub97c \ucc98\ub9ac\ud569\ub2c8\ub2e4. <code>\ubb38\uc11c<\/code> \ubcc0\uacbd\ub429\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  \/\/ ListView \ubcc0\uacbd \ub9ac\uc2a4\ub108\r\n  @Override\r\n  public void changed(ObservableValue observable, String oldId, String newId) {\r\n    if (null == newId) return;\r\n\r\n    \ub9f5 \uc18d\uc131 = db.getDocument(newId).getProperties();\r\n\r\n    try {\r\n      String json = mapper.writeValueAsString(properties);\r\n\r\n      contentsText.setText(prettyText(json));\r\n    } catch (JsonProcessingException ex) {\r\n      ex.printStackTrace();\r\n      Dialog.display(ex);\r\n    }\r\n  }<\/pre>\n<p>\uc774 \ub9ac\uc2a4\ub108\ub294 \uc0ac\uc6a9\uc790\uac00 \ubb38\uc11c \ubaa9\ub85d\uc5d0\uc11c \ud56d\ubaa9\uc744 \ud074\ub9ad\ud560 \ub54c \ucd94\uc801\uc744 \ucc98\ub9ac\ud569\ub2c8\ub2e4. \ud56d\ubaa9\uc740 \ubb38\uc11c ID\uc774\ubbc0\ub85c \uc120\ud0dd \ud56d\ubaa9\uc744 \uc0ac\uc6a9\ud558\uc5ec \ub370\uc774\ud130\ubca0\uc774\uc2a4\uc5d0\uc11c \uc9c1\uc811 \ubb38\uc11c\ub97c \uac00\uc838\uc62c \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  \/\/ SGMonitor.ChangesFeedListener\r\n  @Override\r\n  public void onResponse(String body) {\r\n    changesFeed.appendText(prettyText((String) body));\r\n  }<\/pre>\n<p>\ubcc0\uacbd \ud53c\ub4dc \uacb0\uacfc\ub97c \uac00\uc838\uc624\uae30 \uc704\ud574 \ucf5c\ubc31 \ubc29\uc2dd\uc744 \uc0ac\uc6a9\ud588\uc2b5\ub2c8\ub2e4. \uc778\ud130\ud398\uc774\uc2a4\ub294 <code>SGMonitor<\/code> \ud074\ub798\uc2a4\uc785\ub2c8\ub2e4. \uba54\uc11c\ub4dc\ub294 \ud558\ub098\ubfd0\uc785\ub2c8\ub2e4. \uc774 \uad6c\ud604\uc5d0\uc11c\ub294 \ud53c\ub4dc \uc751\ub2f5\uc758 \ubcf8\ubb38\uc744 \uac00\uc838\uc640 \ubcc0\uacbd \ud53c\ub4dc \ud14d\uc2a4\ud2b8 \ucc3d\uc5d0 \uc788\ub294 \uae30\uc874 \ud14d\uc2a4\ud2b8\uc5d0 \ubd99\uc774\uae30\ub9cc \ud558\uba74 \ub429\ub2c8\ub2e4. \uc77d\uae30 \uc27d\ub3c4\ub85d \uc57d\uac04\uc758 \uc11c\uc2dd\ub3c4 \uc801\uc6a9\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  \/\/ DBService.ReplicationStateListener\r\n  @Override\r\n  public void onChange(boolean isActive) {\r\n    setState(syncBtn, isActive);\r\n  }<\/pre>\n<p>\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ubcf5\uc81c \ud65c\ub3d9\uc5d0 \ub300\ud55c \ub9ac\uc2a4\ub108\ub97c \ucd94\uac00\ud588\uc2b5\ub2c8\ub2e4. \uc774 \uc778\ud130\ud398\uc774\uc2a4\ub294 DBService \ud5ec\ud37c \ud074\ub798\uc2a4\uc5d0\uc11c \uc81c\uacf5\ub429\ub2c8\ub2e4. \ubcf5\uc81c \uc0c1\ud0dc \uac10\uc9c0\uc5d0 \ub300\ud574 \uc870\uae08 \uc791\uc131\ud588\uc2b5\ub2c8\ub2e4. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/determining-status-replication-couchbase-lite\/\">\uc5ec\uae30<\/a>. \uc774 \uc571\uc758 \uacbd\uc6b0 \ubcf5\uc81c\uac00 \uc2e4\ud589 \uc911\uc778\uc9c0 \uc5ec\ubd80\ub9cc \uc54c\uba74 \ub429\ub2c8\ub2e4. <code>\ub3d9\uae30\ud654<\/code> \ubc84\ud2bc \uc0c1\ud0dc\ub97c \uc77c\uad00\ub418\uac8c \uc720\uc9c0\ud569\ub2c8\ub2e4. \uc774\ub807\uac8c \ud558\uba74 \uc0ac\uc6a9\uc790\uac00 \ub3d9\uae30\ud654\ub97c \uc2dc\uc791\ud558\ub824\uace0 \ud558\uc9c0\ub9cc \uc2e4\ud328\ud558\ub294 \uacbd\uc6b0\ub97c \ucc98\ub9ac\ud569\ub2c8\ub2e4. \uc608\ub97c \ub4e4\uc5b4 \uc0ac\uc6a9\uc790\uac00 \uc778\uc99d \uc790\uaca9 \uc99d\uba85\uc744 \uc81c\uacf5\ud574\uc57c \ud558\uc9c0\ub9cc \uc81c\uacf5\ud558\uc9c0 \uc54a\uc740 \uacbd\uc6b0 \uc774\ub7f0 \uc77c\uc774 \ubc1c\uc0dd\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c\uc73c\ub85c UI \uc694\uc18c\uc5d0 \ubc14\uc778\ub529\ub41c \uba87 \uac00\uc9c0 \uba54\uc11c\ub4dc\uac00 \uc788\uc2b5\ub2c8\ub2e4. JavaFX\ub294 \ub300\ubd80\ubd84\uc758 \ubc30\uc120\uc744 \ucc98\ub9ac\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  @FXML private void applyCredentialsToggled(ActionEvent event) {\r\n    String username = null;\r\n    String password = null;\r\n\r\n    if (applyCredentialsBtn.isSelected()) { {\r\n      username = usernameText.getText();\r\n      password = passwordText.getText();\r\n    }\r\n\r\n    DBService.getInstance().setCredentials(username, password);\r\n    applyCredentialsBtn.setStyle(applyCredentialsBtn.isSelected() ? toggle_active : toggle_inactive);\r\n  }<\/pre>\n<p>\uc5ec\uae30\uc11c\ub294 \ud574\ub2f9 \ubc84\ud2bc\uc774 \uc804\ud658\ub420 \ub54c\ub9c8\ub2e4 \uc778\uc99d \uc790\uaca9 \uc99d\uba85\uc744 \uc0ac\uc6a9\ud558\ub3c4\ub85d \uc124\uc815\ud588\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  @FXML private void saveContentsClicked(ActionEvent event) {\r\n    \ub9f5 \uc18d\uc131 = null;\r\n    \ubb38\uc11c\ub97c \ubb38\uc11c\ud654\ud569\ub2c8\ub2e4;\r\n\r\n    try {\r\n      properties = mapper.readValue(contentsText.getText(), Map.class);\r\n    } catch (IOException ex) {\r\n      ex.printStackTrace();\r\n      Dialog.display(ex);\r\n    }\r\n\r\n    if (properties.containsKey(\"_id\")) {\r\n      document = db.getDocument((String) properties.get(\"_id\"));\r\n    } else {\r\n      document = db.createDocument();\r\n    }\r\n\r\n    try {\r\n      document.putProperties(properties);\r\n    } catch (CouchbaseLiteException ex) {\r\n      ex.printStackTrace();\r\n      Dialog.display(ex);\r\n    }\r\n  }\r\n<\/pre>\n<p>\uc774 \ucf54\ub4dc\uc5d0\ub294 \uba87 \uac00\uc9c0 \ud765\ubbf8\ub85c\uc6b4 \ud56d\ubaa9\uc774 \uc788\uc2b5\ub2c8\ub2e4. \uc7ad\uc2a8 <code>\uc624\ube0c\uc81d\ud2b8 \ub9f5\ud37c<\/code> \uc778\uc2a4\ud134\uc2a4\ub97c \uc0ac\uc6a9\ud558\uc5ec \ucf58\ud150\uce20 \ucc3d\uc758 \ud14d\uc2a4\ud2b8\ub97c \uc18d\uc131 \ub9f5\uc73c\ub85c \ubcc0\ud658\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c\uc73c\ub85c \ud56d\ubaa9\uc744 \ud655\uc778\ud569\ub2c8\ub2e4. <code>_id<\/code>. \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ubaa8\ubc14\uc77c\uc740 \uc2dc\uc2a4\ud15c \uc0ac\uc6a9\uc744 \uc704\ud574 \"_\"\ub85c \uc2dc\uc791\ud558\ub294 \ub300\ubd80\ubd84\uc758 \uc18d\uc131\uc744 \ubcf4\uc720\ud569\ub2c8\ub2e4(\ud2b9\ubcc4\ud55c \uc608\uc678\uac00 \uc788\uc744 \uc218 \uc788\uc74c). \ubcc0\ud658\ud558\ub824\ub294 \ud14d\uc2a4\ud2b8\uc5d0 \ub2e4\uc74c\uc774 \ud3ec\ud568\ub41c \uacbd\uc6b0 <code>_id<\/code>\ub97c \ud074\ub9ad\ud558\uba74 \uae30\uc874 \ubb38\uc11c\ub97c \ud3b8\uc9d1\ud558\ub294 \uac83\uc73c\ub85c \uac04\uc8fc\ud569\ub2c8\ub2e4. \uadf8\ub807\uc9c0 \uc54a\uc73c\uba74 \uc0c8 \ubb38\uc11c\ub97c \ub9cc\ub4ed\ub2c8\ub2e4.<\/p>\n<p>\uac04\ub2e8\ud788 \ub9d0\ud574\uc11c \ubb38\uc11c\ub97c \ub9cc\ub4e4\uace0 \uc5c5\ub370\uc774\ud2b8\ud558\ub294 \ub450 \uac00\uc9c0 \uc608\uac00 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \ubc29\ubc95\uc774 \uc120\ud638\ub418\ub294 \uc5c5\ub370\uc774\ud2b8 \ubc29\ubc95\uc740 \uc544\ub2c8\uc9c0\ub9cc \ub9ce\uc740 \uacbd\uc6b0\uc5d0 \ucda9\ubd84\ud569\ub2c8\ub2e4. \uc5c5\ub370\uc774\ud2b8\uc5d0 \ub300\ud574 \uc790\uc138\ud788 \uc54c\uc544\ubcf4\uc138\uc694. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/better-updates-couchbase-lite\/\">\uc5ec\uae30<\/a>.<\/p>\n<pre><code class=\"language-java\">  @FXML private void syncToggled(ActionEvent event) {\r\n    try {\r\n      syncBtn.setDisable(true);\r\n      syncBtn.setStyle(TOGGLE_DISABLED);\r\n      service.toggleReplication(new URL(SG_PUBLIC_URL), true);\r\n    } catch (Exception ex) {\r\n      ex.printStackTrace();\r\n      Dialog.display(ex);\r\n      syncBtn.setDisable(false);\r\n    }\r\n  }<\/code><\/pre>\n<p>\uc774\uac83\uc740 \ud1a0\uae00\uc5d0 \ubc18\uc751\ud569\ub2c8\ub2e4. <code>\ub3d9\uae30\ud654<\/code> \ubc84\ud2bc\uc744 \ud074\ub9ad\ud569\ub2c8\ub2e4. \ub9ac\uc2a4\ub108\ub97c \uc0ac\uc6a9\ud558\uc5ec \ub2e4\ub978 \uacf3\uc5d0\uc11c \uc0c1\ud0dc\ub97c \ud655\uc778\ud55c\ub2e4\ub294 \uc810\uc744 \uae30\uc5b5\ud558\uc138\uc694.<\/p>\n<pre class=\"lang:java decode:true\">  @FXML private void exitClicked(ActionEvent event) {\r\n    \/\/ \ubaa8\ub4e0 \uac83\uc744 \uc6b0\uc544\ud558\uac8c \uc885\ub8cc\ud558\ub824\uace0 \uc2dc\ub3c4\ud569\ub2c8\ub2e4.\r\n    changesMonitor.stop();\r\n    liveQuery.stop();\r\n    service.stopReplication();\r\n    db.close();\r\n    db.getManager().close();\r\n\r\n    Platform.exit();\r\n  }\r\n\r\n  private void setState(ToggleButton btn, boolean active) {\r\n    btn.setSelected(active);\r\n    btn.setStyle(active ? TOGGLE_ACTIVE : TOGGLE_INACTIVE);\r\n    btn.setDisable(false);\r\n  }\r\n\r\n  private String prettyText(String json) {\r\n    String out = null;\r\n\r\n    try {\r\n      \uac1d\uccb4 object = mapper.readValue(json, Object.class);\r\n\r\n      out = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);\r\n    } catch (Exception ex) {\r\n      ex.printStackTrace();\r\n    }\r\n\r\n    \ubc18\ud658\ud569\ub2c8\ub2e4;\r\n  }\r\n}\r\n<\/pre>\n<p>\ub098\uba38\uc9c0 \ucf54\ub4dc\ub294 \ud5ec\ud37c \ube44\ud2b8\uc640 \uc885\ub8cc\ud558\uae30 \uc804\uc5d0 \ubaa8\ub4e0 \uac83\uc744 \uc885\ub8cc\ud558\ub294 \ubd80\ubd84\uc77c \ubfd0\uc785\ub2c8\ub2e4.<\/p>\n<h3>\ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub3c4\uc6b0\ubbf8 \ud074\ub798\uc2a4<\/h3>\n<p>\uc774\uac83\uc740 \uac04\ub2e8\ud55c \ub370\uc774\ud130\ubca0\uc774\uc2a4 \ud5ec\ud37c \ud074\ub798\uc2a4\uc758 \ucf54\ub4dc\ub97c \ubcf4\uc5ec\uc90d\ub2c8\ub2e4. \ub300\ubd80\ubd84\uc758 \uacbd\uc6b0 \uc774 \ud074\ub798\uc2a4\ub294 \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \uad00\ub9ac\ud558\uace0 \ud45c\uc900 \uc591\ubc29\ud5a5 \ubcf5\uc81c \uc9d1\ud569\uc744 \uc2dc\uc791\ud558\ub294 \ub370 \ud544\uc694\ud55c \uc77c\ubc18\uc801\uc778 \uc791\uc5c5\uc744 \uba4b\uc9c0\uac8c \ud328\ud0a4\uc9d5\ud55c \uac83\uc77c \ubfd0\uc785\ub2c8\ub2e4. \uc720\uc6a9\ud558\uace0 \uba85\ud655\uc131\uc744 \uc704\ud574 \uc5ec\uae30\uc5d0 \ud3ec\ud568\uc2dc\ucf30\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\uc800\ub294 <code>\ubcf5\uc81c.\ubcc0\uacbd \ub9ac\uc2a4\ub108<\/code> \uc778\ud130\ud398\uc774\uc2a4\uc785\ub2c8\ub2e4. \uc870\uae08 \ud2b9\uc774\ud560 \uc218\ub3c4 \uc788\uc2b5\ub2c8\ub2e4. \uc55e\uc11c \uadf8 \uc774\uc720\uc5d0 \ub300\ud574 \uc5b8\uae09\ud588\uc2b5\ub2c8\ub2e4. \uc774 \ub9c1\ud06c\ub97c \ud074\ub9ad\ud558\uba74 <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/determining-status-replication-couchbase-lite\/\">\ube14\ub85c\uadf8 \uac8c\uc2dc\ubb3c<\/a> \uc5d0 \ub300\ud574 \uc54c\uc544\ubcf4\uc138\uc694.<\/p>\n<pre class=\"lang:java decode:true\">com.couchbase.mobile\uc744 \ud328\ud0a4\uc9c0\ud654\ud569\ub2c8\ub2e4;\r\n\r\ncom.couchbase.lite.Database\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.JavaContext\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.Manager\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.auth.Authenticator\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.auth.AuthenticatorFactory\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.replicator.Replication\uc744 \uac00\uc838\uc635\ub2c8\ub2e4;\r\ncom.couchbase.lite.replicator.ReplicationState\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\n\r\nimport java.net.URL;\r\nimport java.util.ArrayList;\r\njava.util.List;\r\n\r\npublic class DBService implements Replication.ChangeListener { {\r\n  public static final String DATABASE = \"db\";\r\n\r\n  private static final String DB_DIRECTORY = \"data\";\r\n\r\n  private Manager manager;\r\n  private \ub370\uc774\ud130\ubca0\uc774\uc2a4 \ub370\uc774\ud130\ubca0\uc774\uc2a4\r\n  private Replication pushReplication = null;\r\n  private Replication pullReplication = null;\r\n  private boolean replicationActive = false;\r\n  private List stateListeners = new ArrayList();\r\n  private String username = null;\r\n  private String password = null;\r\n\r\n  private DBService() {\r\n    try {\r\n      manager = new Manager(new JavaContext(DB_DIRECTORY), Manager.DEFAULT_OPTIONS);\r\n      database = manager.getDatabase(DATABASE);\r\n    } catch (Exception ex) {\r\n      ex.printStackTrace();\r\n    }\r\n  }\r\n\r\n  \ube44\uacf5\uac1c \uc815\uc801 \ud074\ub798\uc2a4 \ud640\ub354 {\r\n    private static DBService INSTANCE = new DBService();\r\n  }\r\n\r\n\r\n  \uacf5\uc6a9 \uc778\ud130\ud398\uc774\uc2a4 ReplicationStateListener {\r\n    void onChange(boolean isActive);\r\n  }\r\n\r\n  public static DBService getInstance() {\r\n    return Holder.INSTANCE;\r\n  }\r\n\r\n  public Database getDatabase() {\r\n    \ub370\uc774\ud130\ubca0\uc774\uc2a4\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4;\r\n  }\r\n\r\n  public void setCredentials(String username, String password) {\r\n    this.username = username;\r\n    this.password = password;\r\n  }\r\n\r\n  public void toggleReplication(URL \uac8c\uc774\ud2b8\uc6e8\uc774, boolean continuous) {\r\n    if (replicationActive) {\r\n      stopReplication();\r\n    } else {\r\n      startReplication(\uac8c\uc774\ud2b8\uc6e8\uc774, \uc5f0\uc18d);\r\n    }\r\n  }\r\n\r\n  public void startReplication(URL \uac8c\uc774\ud2b8\uc6e8\uc774, boolean continuous) {\r\n    if (replicationActive) {\r\n      stopReplication();\r\n    }\r\n\r\n    pushReplication = database.createPushReplication(gateway);\r\n    pullReplication = database.createPullReplication(\uac8c\uc774\ud2b8\uc6e8\uc774);\r\n    pushReplication.setContinuous(\uc5f0\uc18d);\r\n    pullReplication.setContinuous(continuous);\r\n\r\n    if (username != null) {\r\n      \uc778\uc99d\uc790 auth = AuthenticatorFactory.createBasicAuthenticator(username, password);\r\n      pushReplication.setAuthenticator(auth);\r\n      pullReplication.setAuthenticator(auth);\r\n    }\r\n\r\n    pushReplication.addChangeListener(this);\r\n    pullReplication.addChangeListener(this);\r\n\r\n    pushReplication.start();\r\n    pullReplication.start();\r\n  }\r\n\r\n  public void stopReplication() {\r\n    if (!replicationActive) return;\r\n\r\n    pushReplication.stop();\r\n    pullReplication.stop();\r\n\r\n    pushReplication = null;\r\n    pullReplication = null;\r\n  }\r\n\r\n  public void addReplicationStateListener(ReplicationStateListener listener) {\r\n    stateListeners.add(listener);\r\n  }\r\n\r\n  public void removeReplicationStateListener(ReplicationStateListener listener) {\r\n    stateListeners.remove(listener);\r\n  }\r\n\r\n  \/\/ Replication.ChangeListener\r\n  @Override\r\n  public void changed(Replication.ChangeEvent changeEvent) {\r\n    if (changeEvent.getError() != null) {\r\n      Throwable lastError = changeEvent.getError();\r\n\r\n      Dialog.display(lastError.getMessage());\r\n\r\n      return;\r\n    }\r\n\r\n    if (changeEvent.getTransition() == null) return;\r\n\r\n    \ubcf5\uc81c \uc0c1\ud0dc dest = changeEvent.getTransition().getDestination();\r\n\r\n    replicationActive = ((dest == ReplicationState.STOPPING || dest == ReplicationState.STOPPED) ? false : true);\r\n\r\n    stateListeners.forEach(listener -&gt; listener.onChange(replicationActive));\r\n  }\r\n}<\/pre>\n<h3>\ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774 \ubaa8\ub2c8\ud130 \ud074\ub798\uc2a4<\/h3>\n<p>\ub9c8\uc9c0\ub9c9\uc73c\ub85c \ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774 \ubaa8\ub2c8\ud130\ub9c1\uc744 \uc704\ud55c \ud5ec\ud37c \ud074\ub798\uc2a4\uc5d0 \ub300\ud574 \uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4. \uc774\uac83\ub3c4 \uc870\uae08\uc529 \uc0b4\ud3b4\ubcf4\uaca0\uc2b5\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">com.couchbase.mobile\uc744 \ud328\ud0a4\uc9c0\ud654\ud569\ub2c8\ub2e4;\r\n\r\ncom.fasterxml.jackson.databind.JsonNode\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\nokhttp3.*\ub97c \uac00\uc838\uc635\ub2c8\ub2e4;\r\n\r\nimport java.io.IOException;\r\nimport java.net.SocketException;\r\njava.util.concurrent.TimeUnit;\r\n\r\n\uc815\uc801 com.couchbase.mobile.Runtime.mapper\ub97c \uc784\ud3ec\ud2b8\ud569\ub2c8\ub2e4;\r\n\r\npublic class SGMonitor {\r\n  private static final OkHttpClient client = new OkHttpClient.Builder()\r\n      .readTimeout(1, TimeUnit.DAYS)\r\n      .build();\r\n  \ube44\uacf5\uac1c \ubcc0\uacbd \ud53c\ub4dc \ub9ac\uc2a4\ub108 \ub9ac\uc2a4\ub108;\r\n  private HttpUrl.Builder urlBuilder;\r\n  private Thread monitorThread;\r\n  private String since = \"0\";\r\n  private Call call;\r\n\r\n  SGMonitor(String url, String activeOnly, String includeDocs, String since, String style,\r\n            ChangesFeedListener \ub9ac\uc2a4\ub108) {\r\n    this.since = \uc774\ud6c4;\r\n\r\n    urlBuilder = HttpUrl.parse(url).newBuilder()\r\n        .addPathSegment(\"_changes\")\r\n        .addQueryParameter(\"active_only\", activeOnly)\r\n        .addQueryParameter(\"include_docs\", includeDocs)\r\n        .addQueryParameter(\"style\", style)\r\n        .addQueryParameter(\"since\", since)\r\n        .addQueryParameter(\"feed\", \"longpoll\")\r\n        .addQueryParameter(\"timeout\", \"0\");\r\n\r\n    \uc774.\ub9ac\uc2a4\ub108 = \ub9ac\uc2a4\ub108;\r\n  }<\/pre>\n<p>\uc800\ub294 <a href=\"https:\/\/square.github.io\/okhttp\/\">Square\uc758 OkHttp \ub77c\uc774\ube0c\ub7ec\ub9ac<\/a>. \ud604\uc7ac \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ub77c\uc774\ud2b8\ub294 \ub0b4\ubd80\uc801\uc73c\ub85c\ub3c4 \uc774 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub97c \uc0ac\uc6a9\ud569\ub2c8\ub2e4. OkHttp\ub294 \ube4c\ub354 \ud328\ud134\uc744 \uc0ac\uc6a9\ud569\ub2c8\ub2e4. \ud074\ub798\uc2a4 \uc0dd\uc131\uc790\uc5d0\uc11c \ub098\uba38\uc9c0 \ucf54\ub4dc\ub97c \ud1b5\ud574 \uc0ac\uc6a9\ud560 \ube4c\ub354 \uc778\uc2a4\ud134\uc2a4\ub97c \uc900\ube44\ud569\ub2c8\ub2e4. \ubaa8\ub4e0 \ub9e4\uac1c \ubcc0\uc218\uc758 \uc758\ubbf8\uc5d0 \ub300\ud55c \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 <a href=\"https:\/\/developer.couchbase.com\/documentation\/mobile\/current\/references\/sync-gateway\/index.html\">\ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774 \ubb38\uc11c<\/a>.<\/p>\n<pre><code class=\"language-java\">  public interface ChangesFeedListener {\r\n    void onResponse(String body);\r\n  }\r\n\r\n  public void start() {\r\n    monitorThread = new Thread(() -&gt; {\r\n      while (!Thread.interrupted()) {\r\n        Request request = new Request.Builder()\r\n            .url(urlBuilder.build())\r\n            .build();\r\n\r\n        call = client.newCall(request);\r\n\r\n        try (Response response = call.execute()) {\r\n          if (!response.isSuccessful()) throw new IOException(\"Unexpected code \" + response);\r\n\r\n          String body = response.body().string();\r\n\r\n          JsonNode tree = mapper.readTree(body);\r\n\r\n          since = tree.get(\"last_seq\").asText();\r\n          urlBuilder.setQueryParameter(\"since\", since);\r\n\r\n          listener.onResponse(body);\r\n        } catch (SocketException ex) {\r\n          return;\r\n        } catch (IOException ex) {\r\n          ex.printStackTrace();\r\n          Dialog.display(ex);\r\n        }\r\n      }\r\n    });\r\n\r\n    monitorThread.setDaemon(true);\r\n    monitorThread.start();\r\n  }<\/code><\/pre>\n<p>\uadf8\ub9ac\uace0 <code>\uc2dc\uc791<\/code> \uba54\uc11c\ub4dc\uc5d0\ub294 \ucf54\ub4dc\uc5d0\uc11c \uac00\uc7a5 \ud765\ubbf8\ub85c\uc6b4 \ubd80\ubd84\uc774 \uc788\uc2b5\ub2c8\ub2e4. \uc774 \uba54\uc11c\ub4dc\ub294 \ubc31\uadf8\ub77c\uc6b4\ub4dc \uc2a4\ub808\ub4dc\ub97c \ud68c\uc804\uc2dc\ud0b5\ub2c8\ub2e4. \uc2a4\ub808\ub4dc \uc124\uc815 \ubc0f \uc81c\uc5b4 \ucf54\ub4dc \uc544\ub798\uc5d0\uc11c \uc5f0\uc18d \ub8e8\ud504\ub97c \uc2e4\ud589\ud569\ub2c8\ub2e4. \uc774 \ub8e8\ud504\ub294 \ub3d9\uae30\uc2dd \ub124\ud2b8\uc6cc\ud06c \ud638\ucd9c\uc744 \uc218\ud589\ud569\ub2c8\ub2e4. \uc624\ub958 \ucc98\ub9ac\ub294 \uac04\ub2e8\ud569\ub2c8\ub2e4. \ubb38\uc81c\uac00 \ubc1c\uc0dd\ud558\uba74 \uc608\uc678\ub97c \ub358\uc9c0\uae30\ub9cc \ud558\uba74 \ub429\ub2c8\ub2e4.<\/p>\n<p>\ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774\ub294 JSON \ubb38\uc790\uc5f4\ub85c \uc751\ub2f5\ud569\ub2c8\ub2e4. \ucf54\ub4dc\uc5d0\uc11c \uc751\ub2f5\uc744 \ubd84\ub9ac\ud558\uace0 JSON\uc744 \ud30c\uc2f1\ud558\uc5ec <code>JsonNode<\/code> \uac1d\uccb4\uc785\ub2c8\ub2e4. \uc774 \ubaa8\ub4e0 \uac83\uc740 <code>last_seq<\/code> \uac12\uc744 \ubc18\ud658\ud569\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c\uc5d0 \ubcf4\ub0bc \ub0b4\uc6a9\uc744 \ucd94\uc801\ud558\uae30 \uc704\ud574 \ubcc0\uacbd\uc0ac\ud56d \ud53c\ub4dc\ub294 \uac04\ub2e8\ud55c \uc2dc\ud000\uc2a4 \uba54\ucee4\ub2c8\uc998\uc5d0 \uc758\uc874\ud569\ub2c8\ub2e4. \uc774\ub97c \ubd88\ud22c\uba85\ud55c \uac1d\uccb4\ub85c \ucde8\uae09\ud574\uc57c \ud569\ub2c8\ub2e4. \ub2e4\uc74c\uacfc \uac19\uc740 \uac12\uc744 \uac00\uc838\uc635\ub2c8\ub2e4. <code>last_seq<\/code> \ub97c \uc774\uc804 \uc751\ub2f5\uc5d0\uc11c <code>\uc774\ud6c4<\/code> \ub9e4\uac1c\ubcc0\uc218\ub97c \ub2e4\uc74c \uc694\uccad\uc5d0 \ub3d9\uc77c\ud55c \uac12\uc73c\ub85c \uc124\uc815\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc81c\uacf5\ud558\uc9c0 \uc54a\ub294\ub2e4\uace0 \ud574\uc11c \uc2e4\uc81c\ub85c \ud574\uac00 \ub418\ub294 \uac83\uc740 \uc5c6\uc2b5\ub2c8\ub2e4. <code>\uc774\ud6c4<\/code> \ub9e4\uac1c\ubcc0\uc218\ub97c \ucd94\uac00\ud558\uc138\uc694. \ub3d9\uae30\ud654 \uac8c\uc774\ud2b8\uc6e8\uc774\ub294 \uc774 \ub9e4\uac1c\ubcc0\uc218\uac00 \ub204\ub77d\ub41c \uacbd\uc6b0 \ubaa8\ub4e0 \ubcc0\uacbd \uc0ac\ud56d\uc744 \ucc98\uc74c\ubd80\ud130 \ub2e4\uc2dc \uc7ac\uc0dd\ud569\ub2c8\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \uc774 \uc608\uc81c\uc5d0\uc11c\ub294 \uc57d\uac04\uc758 \uce58\ud2b8\ub97c \uc0ac\uc6a9\ud558\uc5ec \ud56d\uc0c1 \ud074\ub798\uc2a4 \uc778\uc2a4\ud134\uc2a4\ub97c <code>\uc774\ud6c4<\/code> \ubb38\uc790\uc5f4 \"0\"\uc73c\ub85c \uc124\uc815\ud569\ub2c8\ub2e4.<\/p>\n<p>\uc2e4\uc81c \uc560\ud50c\ub9ac\ucf00\uc774\uc158\uc5d0\uc11c\ub294 \ub9e4\ubc88 \ubcc0\uacbd \uae30\ub85d\uc744 \uc0b4\ud3b4\ubcf4\ub294 \ub300\uc2e0 \uc571\uc774 \ucc98\ub9ac\ud55c \ub9c8\uc9c0\ub9c9 \uc2dc\ud000\uc2a4 \ubb38\uc790\uc5f4\uc744 \uc800\uc7a5\ud558\ub294 \ubc29\ubc95\uc774 \ud544\uc694\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub098\uba38\uc9c0 \ucf54\ub4dc\ub294 \uba87 \uac00\uc9c0 \uc9e7\uc740 \uba54\uc11c\ub4dc\uc5d0 \ubd88\uacfc\ud569\ub2c8\ub2e4.<\/p>\n<pre class=\"lang:java decode:true\">  public void stop() {\r\n    monitorThread.interrupt();\r\n    call.cancel();\r\n  }\r\n\r\n  public String getSince() {\r\n    \uc774\ud6c4\ub97c \ubc18\ud658\ud569\ub2c8\ub2e4;\r\n  }\r\n}<\/pre>\n<p>\uc8fc\uc694 \uc218\uc5c5\uc740 \uc5ec\uae30\uae4c\uc9c0\uc785\ub2c8\ub2e4. \uc571\uc744 \uc644\uc131\ud558\uae30 \uc704\ud574 \ud544\uc694\ud55c \ub2e4\ub978 \uc218\uc5c5\ub3c4 \uc788\uc2b5\ub2c8\ub2e4.<\/p>\n<p>\ub2e4\uc74c \ub0b4\uc6a9\uc744 \ud655\uc778\ud558\uc138\uc694. <a href=\"https:\/\/github.com\/couchbaselabs\/CBM-Changes-Explorer\">GitHub \ub9ac\ud3ec\uc9c0\ud1a0\ub9ac<\/a> \ub97c \ud074\ub9ad\ud558\uc5ec \ubaa8\ub4e0 \ucf54\ub4dc\uc640 \ube4c\ub4dc \uc9c0\uce68\uc744 \ud655\uc778\ud558\uc138\uc694.<\/p>\n<p>\uc571\uc5d0 \ub300\ud55c \uc124\uba85\uacfc \uc0ac\uc6a9 \ubc29\ubc95\uc744 \ub2e4\uc74c\uc5d0\uc11c \uc77d\uc5b4\ubcf4\uc138\uc694. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-1\/\">\ud30c\ud2b8 1<\/a>.<\/p>\n<h2>\ud3ec\uc2a4\ud2b8 \uc2a4\ud06c\ub9bd\ud2b8<\/h2>\n<p>\ub354 \ub9ce\uc740 \ub9ac\uc18c\uc2a4\ub294 \ub2e4\uc74c\uc5d0\uc11c \ud655\uc778\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/developers\/community\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">\uac1c\ubc1c\uc790 \ud3ec\ud138<\/a> \ud2b8\uc704\ud130\uc5d0\uc11c \ud314\ub85c\uc6b0\ud558\uc138\uc694 <a href=\"https:\/\/twitter.com\/CouchbaseDev\">\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \uac1c\ubc1c<\/a>.<\/p>\n<p>\uc9c8\ubb38\uc5d0 \ub300\ud55c \ub2f5\ubcc0\uc744 \uac8c\uc2dc\ud560 \uc218 \uc788\uc2b5\ub2c8\ub2e4. <a href=\"https:\/\/www.couchbase.com\/blog\/ko\/forums\/?utm_source=blogs&amp;utm_medium=link&amp;utm_campaign=blogs\">\ud3ec\ub7fc<\/a>. \uadf8\ub9ac\uace0 \ub2e4\uc74c\uc5d0\ub3c4 \uc801\uadf9\uc801\uc73c\ub85c \ucc38\uc5ec\ud569\ub2c8\ub2e4. <a href=\"https:\/\/stackoverflow.com\/questions\/tagged\/couchbase\">\uc2a4\ud0dd \uc624\ubc84\ud50c\ub85c<\/a>.<\/p>\n<p>\uc9c8\ubb38, \uc758\uacac, \ubcf4\uace0 \uc2f6\uc740 \uc8fc\uc81c \ub4f1\uc774 \uc788\uc73c\uba74 \ud2b8\uc704\ud130\uc5d0\uc11c \uc800\uc5d0\uac8c \uc5f0\ub77d\ud574 \uc8fc\uc138\uc694. <a href=\"https:\/\/twitter.com\/HodGreeley\">\ud638\ub4dc\uadf8\ub9b4\ub9ac<\/a><\/p>","protected":false},"excerpt":{"rendered":"<p>Introduction The Couchbase Mobile Sync Gateway changes feed provides a way to monitor events in a mobile deployment. The feed makes it feasible to write sophisticated business logic. I wrote a tool to help examine and understand the feed. You [&hellip;]<\/p>","protected":false},"author":73,"featured_media":2888,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[1810,1818,2366],"tags":[1867,1868,1809],"ppma_author":[9042],"class_list":["post-2929","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-couchbase-mobile","category-java","category-sync-gateway","tag-business-logic","tag-changes-feed","tag-document"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO Premium plugin v25.7.1 (Yoast SEO v25.7) - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>Couchbase Mobile Changes Explorer \u2013 Part. 2 - The Couchbase Blog<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-2\/\" \/>\n<meta property=\"og:locale\" content=\"ko_KR\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Couchbase Mobile Changes Explorer \u2013 Part. 2\" \/>\n<meta property=\"og:description\" content=\"Introduction The Couchbase Mobile Sync Gateway changes feed provides a way to monitor events in a mobile deployment. The feed makes it feasible to write sophisticated business logic. I wrote a tool to help examine and understand the feed. You [&hellip;]\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-2\/\" \/>\n<meta property=\"og:site_name\" content=\"The Couchbase Blog\" \/>\n<meta property=\"article:published_time\" content=\"2017-03-10T07:13:48+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-06-14T02:58:39+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif\" \/>\n\t<meta property=\"og:image:width\" content=\"480\" \/>\n\t<meta property=\"og:image:height\" content=\"275\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/gif\" \/>\n<meta name=\"author\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@HodGreeley\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Hod Greeley, Developer Advocate, Couchbase\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"6\ubd84\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/\"},\"author\":{\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\"},\"headline\":\"Couchbase Mobile Changes Explorer \u2013 Part. 2\",\"datePublished\":\"2017-03-10T07:13:48+00:00\",\"dateModified\":\"2025-06-14T02:58:39+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/\"},\"wordCount\":1261,\"commentCount\":0,\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif\",\"keywords\":[\"Business Logic\",\"Changes Feed\",\"document\"],\"articleSection\":[\"Couchbase Mobile\",\"Java\",\"Sync Gateway\"],\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/\",\"name\":\"Couchbase Mobile Changes Explorer \u2013 Part. 2 - The Couchbase Blog\",\"isPartOf\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif\",\"datePublished\":\"2017-03-10T07:13:48+00:00\",\"dateModified\":\"2025-06-14T02:58:39+00:00\",\"breadcrumb\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#breadcrumb\"},\"inLanguage\":\"ko-KR\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif\",\"width\":480,\"height\":275,\"caption\":\"Couchbase Mobile Changes Explorer Animated Gif\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/www.couchbase.com\/blog\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Couchbase Mobile Changes Explorer \u2013 Part. 2\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#website\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"name\":\"The Couchbase Blog\",\"description\":\"Couchbase, the NoSQL Database\",\"publisher\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"ko-KR\"},{\"@type\":\"Organization\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#organization\",\"name\":\"The Couchbase Blog\",\"url\":\"https:\/\/www.couchbase.com\/blog\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\",\"url\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"contentUrl\":\"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png\",\"width\":218,\"height\":34,\"caption\":\"The Couchbase Blog\"},\"image\":{\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/\"}},{\"@type\":\"Person\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4\",\"name\":\"Hod Greeley, Developer Advocate, Couchbase\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"ko-KR\",\"@id\":\"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g\",\"caption\":\"Hod Greeley, Developer Advocate, Couchbase\"},\"description\":\"Hod Greeley is a Developer Advocate for Couchbase, living in Silicon Valley. He has over two decades of experience as a software engineer and engineering manager. He has worked in a variety of software fields, including computational physics and chemistry, computer and network security, finance, and mobile. Prior to joining Couchbase in 2016, Hod led developer relations for mobile at Samsung. Hod holds a Ph.D. in chemical physics from Columbia University.\",\"sameAs\":[\"https:\/\/hod.greeley.org\/blog\",\"https:\/\/x.com\/HodGreeley\"],\"url\":\"https:\/\/www.couchbase.com\/blog\/ko\/author\/hod-greeley\/\"}]}<\/script>\n<!-- \/ Yoast SEO Premium plugin. -->","yoast_head_json":{"title":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ubaa8\ubc14\uc77c, \ud0d0\uc0c9\uae30\ub97c \ubc14\uafbc\ub2e4 - \ud30c\ud2b8. 2 - \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-2\/","og_locale":"ko_KR","og_type":"article","og_title":"Couchbase Mobile Changes Explorer \u2013 Part. 2","og_description":"Introduction The Couchbase Mobile Sync Gateway changes feed provides a way to monitor events in a mobile deployment. The feed makes it feasible to write sophisticated business logic. I wrote a tool to help examine and understand the feed. You [&hellip;]","og_url":"https:\/\/www.couchbase.com\/blog\/ko\/couchbase-mobile-changes-explorer-part-2\/","og_site_name":"The Couchbase Blog","article_published_time":"2017-03-10T07:13:48+00:00","article_modified_time":"2025-06-14T02:58:39+00:00","og_image":[{"width":480,"height":275,"url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif","type":"image\/gif"}],"author":"Hod Greeley, Developer Advocate, Couchbase","twitter_card":"summary_large_image","twitter_creator":"@HodGreeley","twitter_misc":{"Written by":"Hod Greeley, Developer Advocate, Couchbase","Est. reading time":"6\ubd84"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#article","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/"},"author":{"name":"Hod Greeley, Developer Advocate, Couchbase","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4"},"headline":"Couchbase Mobile Changes Explorer \u2013 Part. 2","datePublished":"2017-03-10T07:13:48+00:00","dateModified":"2025-06-14T02:58:39+00:00","mainEntityOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/"},"wordCount":1261,"commentCount":0,"publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif","keywords":["Business Logic","Changes Feed","document"],"articleSection":["Couchbase Mobile","Java","Sync Gateway"],"inLanguage":"ko-KR","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/","url":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ubaa8\ubc14\uc77c, \ud0d0\uc0c9\uae30\ub97c \ubc14\uafbc\ub2e4 - \ud30c\ud2b8. 2 - \uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","isPartOf":{"@id":"https:\/\/www.couchbase.com\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage"},"thumbnailUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif","datePublished":"2017-03-10T07:13:48+00:00","dateModified":"2025-06-14T02:58:39+00:00","breadcrumb":{"@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#breadcrumb"},"inLanguage":"ko-KR","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/"]}]},{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#primaryimage","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/sites\/1\/2017\/02\/ChangesExplorer.gif","width":480,"height":275,"caption":"Couchbase Mobile Changes Explorer Animated Gif"},{"@type":"BreadcrumbList","@id":"https:\/\/www.couchbase.com\/blog\/couchbase-mobile-changes-explorer-part-2\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.couchbase.com\/blog\/"},{"@type":"ListItem","position":2,"name":"Couchbase Mobile Changes Explorer \u2013 Part. 2"}]},{"@type":"WebSite","@id":"https:\/\/www.couchbase.com\/blog\/#website","url":"https:\/\/www.couchbase.com\/blog\/","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","description":"NoSQL \ub370\uc774\ud130\ubca0\uc774\uc2a4, Couchbase","publisher":{"@id":"https:\/\/www.couchbase.com\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.couchbase.com\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"ko-KR"},{"@type":"Organization","@id":"https:\/\/www.couchbase.com\/blog\/#organization","name":"\uce74\uc6b0\uce58\ubca0\uc774\uc2a4 \ube14\ub85c\uadf8","url":"https:\/\/www.couchbase.com\/blog\/","logo":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","contentUrl":"https:\/\/www.couchbase.com\/blog\/wp-content\/uploads\/2023\/04\/admin-logo.png","width":218,"height":34,"caption":"The Couchbase Blog"},"image":{"@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/logo\/image\/"}},{"@type":"Person","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/9b62593c8a13531e53d52fcd5aabbca4","name":"\ud638\ub4dc \uadf8\ub9b4\ub9ac, \uac1c\ubc1c\uc790 \uc639\ud638\uc790, \uce74\uc6b0\uce58\ubca0\uc774\uc2a4","image":{"@type":"ImageObject","inLanguage":"ko-KR","@id":"https:\/\/www.couchbase.com\/blog\/#\/schema\/person\/image\/21eb69cb5d4a401fb23b149e4f4e9e87","url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","caption":"Hod Greeley, Developer Advocate, Couchbase"},"description":"\ud638\ub4dc \uadf8\ub808\uc774\ub9ac\ub294 \uc2e4\ub9ac\ucf58\ubc38\ub9ac\uc5d0 \uac70\uc8fc\ud558\ub294 \uce74\uc6b0\uce58\ubca0\uc774\uc2a4\uc758 \uac1c\ubc1c\uc790 \uc639\ud638\uc790\uc785\ub2c8\ub2e4. \uadf8\ub294 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5d4\uc9c0\ub2c8\uc5b4 \ubc0f \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \uad00\ub9ac\uc790\ub85c\uc11c 20\ub144 \uc774\uc0c1\uc758 \uacbd\ub825\uc744 \ubcf4\uc720\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uadf8\ub294 \uc804\uc0b0 \ubb3c\ub9ac\ud559 \ubc0f \ud654\ud559, \ucef4\ud4e8\ud130 \ubc0f \ub124\ud2b8\uc6cc\ud06c \ubcf4\uc548, \uae08\uc735, \ubaa8\ubc14\uc77c \ub4f1 \ub2e4\uc591\ud55c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubd84\uc57c\uc5d0\uc11c \uc77c\ud574 \uc654\uc2b5\ub2c8\ub2e4. 2016\ub144 \uce74\uc6b0\uce58\ubca0\uc774\uc2a4\uc5d0 \ud569\ub958\ud558\uae30 \uc804\uc5d0\ub294 \uc0bc\uc131\uc5d0\uc11c \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc790 \uad00\uacc4\ub97c \uc774\ub04c\uc5c8\uc2b5\ub2c8\ub2e4. \uceec\ub7fc\ube44\uc544 \ub300\ud559\uad50\uc5d0\uc11c \ud654\ud559 \ubb3c\ub9ac\ud559 \ubc15\uc0ac \ud559\uc704\ub97c \ubc1b\uc558\uc2b5\ub2c8\ub2e4.","sameAs":["https:\/\/hod.greeley.org\/blog","https:\/\/x.com\/HodGreeley"],"url":"https:\/\/www.couchbase.com\/blog\/ko\/author\/hod-greeley\/"}]}},"authors":[{"term_id":9042,"user_id":73,"is_guest":0,"slug":"hod-greeley","display_name":"Hod Greeley, Developer Advocate, Couchbase","avatar_url":"https:\/\/secure.gravatar.com\/avatar\/52d0018695c0ced0d1c68cf64a6195c81dbac03dce5983f98eb209e7c84350df?s=96&d=mm&r=g","first_name":"Hod","last_name":"Greeley","user_url":"https:\/\/hod.greeley.org\/blog","author_category":"","description":"\ud638\ub4dc \uadf8\ub808\uc774\ub9ac\ub294 \uc2e4\ub9ac\ucf58\ubc38\ub9ac\uc5d0 \uac70\uc8fc\ud558\ub294 \uce74\uc6b0\uce58\ubca0\uc774\uc2a4\uc758 \uac1c\ubc1c\uc790 \uc639\ud638\uc790\uc785\ub2c8\ub2e4. \uadf8\ub294 \uc18c\ud504\ud2b8\uc6e8\uc5b4 \uc5d4\uc9c0\ub2c8\uc5b4 \ubc0f \uc5d4\uc9c0\ub2c8\uc5b4\ub9c1 \uad00\ub9ac\uc790\ub85c\uc11c 20\ub144 \uc774\uc0c1\uc758 \uacbd\ub825\uc744 \ubcf4\uc720\ud558\uace0 \uc788\uc2b5\ub2c8\ub2e4. \uadf8\ub294 \uc804\uc0b0 \ubb3c\ub9ac\ud559 \ubc0f \ud654\ud559, \ucef4\ud4e8\ud130 \ubc0f \ub124\ud2b8\uc6cc\ud06c \ubcf4\uc548, \uae08\uc735, \ubaa8\ubc14\uc77c \ub4f1 \ub2e4\uc591\ud55c \uc18c\ud504\ud2b8\uc6e8\uc5b4 \ubd84\uc57c\uc5d0\uc11c \uc77c\ud574 \uc654\uc2b5\ub2c8\ub2e4. 2016\ub144 \uce74\uc6b0\uce58\ubca0\uc774\uc2a4\uc5d0 \ud569\ub958\ud558\uae30 \uc804\uc5d0\ub294 \uc0bc\uc131\uc5d0\uc11c \ubaa8\ubc14\uc77c \uac1c\ubc1c\uc790 \uad00\uacc4\ub97c \uc774\ub04c\uc5c8\uc2b5\ub2c8\ub2e4. \uceec\ub7fc\ube44\uc544 \ub300\ud559\uad50\uc5d0\uc11c \ud654\ud559 \ubb3c\ub9ac\ud559 \ubc15\uc0ac \ud559\uc704\ub97c \ubc1b\uc558\uc2b5\ub2c8\ub2e4."}],"_links":{"self":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/2929","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/users\/73"}],"replies":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/comments?post=2929"}],"version-history":[{"count":0,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/posts\/2929\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media\/2888"}],"wp:attachment":[{"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/media?parent=2929"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/categories?post=2929"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/tags?post=2929"},{"taxonomy":"author","embeddable":true,"href":"https:\/\/www.couchbase.com\/blog\/ko\/wp-json\/wp\/v2\/ppma_author?post=2929"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}