{"id":45255,"date":"2021-07-12T18:03:27","date_gmt":"2021-07-12T09:03:27","guid":{"rendered":"https:\/\/www.charlezz.com\/?p=45255"},"modified":"2021-07-12T19:11:07","modified_gmt":"2021-07-12T10:11:07","slug":"kapt%eb%b3%b4%eb%8b%a4-2%eb%b0%b0-%eb%8d%94-%eb%b9%a0%eb%a5%b4%ea%b2%8c-%ec%bd%94%ed%8b%80%eb%a6%b0%ec%9d%84-%ec%9c%84%ed%95%9c-ksp","status":"publish","type":"post","link":"https:\/\/charlezz.com\/?p=45255","title":{"rendered":"KAPT\ubcf4\ub2e4 2\ubc30 \ub354 \ube60\ub974\uac8c, \ucf54\ud2c0\ub9b0\uc744 \uc704\ud55c KSP"},"content":{"rendered":"<h1><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-coollogo-com-8362411.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-coollogo-com-8362411.png\" alt=\"\" width=\"663\" height=\"467\" class=\"alignnone size-full wp-image-45257\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-coollogo-com-8362411.png 663w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-coollogo-com-8362411-300x211.png 300w\" sizes=\"(max-width: 663px) 100vw, 663px\" \/><\/a><\/h1>\n<h1>KSP(Kotlin Symbol Processing)<ins><\/ins><\/h1>\n<p class=\"rich-diff-level-zero\">KSP(Kotlin Symbol Processing)\ub294 \ucf54\ud2c0\ub9b0\uc5d0\uc11c \uacbd\ub7c9\ud654 \ub41c \ucef4\ud30c\uc77c\ub7ec \ud50c\ub7ec\uadf8\uc778\uc744 \uac1c\ubc1c\ud560 \uc218 \uc788\ub294 API\ub2e4.\u00a0 \ud559\uc2b5\uace1\uc120\uc744 \ucd5c\uc18c\ud55c\uc73c\ub85c \uc904\uc774\uace0, \ucf54\ud2c0\ub9b0\uc758 \uae30\ub2a5\uc744 \ud65c\uc6a9\ud560 \uc218 \uc788\ub294 \ub2e8\uc21c\ud654\ub41c API\ub97c \uc81c\uacf5\ud55c\ub2e4. KSP\ub294 \ucf54\ud2c0\ub9b0 1.4.30 \ubc84\uc804 \uc774\uc0c1\ubd80\ud130 \ud638\ud658\ub418\uba70, KAPT\uc640 \ube44\uad50\ud588\uc744 \ub54c KSP\ub97c \uc0ac\uc6a9\ud558\ub294 <a href=\"https:\/\/www.charlezz.com\/?p=1167\">\uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c<\/a>\ub294 \ucd5c\ub300 <strong>2\ubc30<\/strong> \ub354 \ube60\ub974\uac8c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 <span>\u00a0<\/span><a href=\"https:\/\/github.com\/google\/ksp\" class=\"rich-diff-level-one\">KSP Github \ub9ac\ud3ec\uc9c0\ud1a0\ub9ac<\/a>\uc5d0\uc11c \uc624\ud508 \uc18c\uc2a4 \ucf54\ub4dc \ubc0f \ubb38\uc11c\ub97c \ud655\uc778\ud560 \uc218 \uc788\ub2e4.\u00a0<\/p>\n<h3>Annotation Processor\ub780?<\/h3>\n<p><a href=\"https:\/\/www.charlezz.com\/?p=1167\">\uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c(Annotation Processor)<\/a>\ub294 \uc560\ub178\ud14c\uc774\uc158\uc5d0 \ub300\ud55c \ucf54\ub4dc\ubca0\uc774\uc2a4\ub97c \uac80\uc0ac\ud558\uac70\ub098 \uc0c8\ub85c\uc6b4 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud558\ub294\ub370 \uc0ac\uc6a9\ub41c\ub2e4.\u00a0 \uc774 \ud504\ub85c\uc138\uc11c\ub294 \uc790\ubc14 \ucef4\ud30c\uc77c\ub7ec \ud50c\ub7ec\uadf8\uc778\uc758 \uc77c\uc885\uc73c\ub85c \uac1c\ubc1c\uc790\uc758 \ucf54\ub4dc\ub97c \ub2e8\uc21c\ud654 \ub610\ub294 \uc790\ub3d9\ud654\ud558\ub294\ub370 \uc0ac\uc6a9\ud560 \uc218 \uc788\ub2e4.<\/p>\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc \uac1c\ubc1c\uc790\ub85c\uc11c \uc790\uc8fc \uc0ac\uc6a9\ud558\ub294 Room, Dagger, Hilt, Glide \ub4f1\uc774 Annotation Processor\ub97c \ud65c\uc6a9\ud558\ub294 \ub300\ud45c\uc801\uc778 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub2e4.<\/p>\n<h3>KAPT\ub780?<\/h3>\n<p><span>\ucf54\ud2c0\ub9b0 \ud504\ub85c\uc81d\ud2b8\ub97c \ucef4\ud30c\uc77c \ud560 \ub54c\ub294 javac\uac00 \uc544\ub2cc kotlinc\ub85c \ucef4\ud30c\uc77c\uc744 \ud558\uae30 \ub54c\ubb38\uc5d0 Java\ub85c \uc791\uc131\ud55c \uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c\uac00 \ub3d9\uc791\ud558\uc9c0 \uc54a\ub294\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \ucf54\ud2c0\ub9b0\uc5d0\uc11c\ub294 \uc774\ub7ec\ud55c \uc560\ub178\ud14c\uc774\uc158 \ucc98\ub9ac\uae30\ub97c \uc704\ud574 <a href=\"https:\/\/kotlinlang.org\/docs\/kapt.html\">KAPT(Kotlin Annotation Processing Tool)<\/a>\ub97c \uc81c\uacf5\ud55c\ub2e4. <\/span><\/p>\n<p><span>\ucf54\ud2c0\ub9b0 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c KAPT\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574\uc11c build.gradle \ud30c\uc77c\uc5d0 \ub2e4\uc74c\uacfc \uac19\uc740 \ub77c\uc778\uc744 \ucd94\uac00\ud558\uba74 \ub41c\ub2e4.<\/span><\/p>\n<pre class=\"lang:null decode:true lang:\">\/\/ \ubaa8\ub4c8 \ub808\ubca8\uc758 build.gradle \ud30c\uc77c\r\n\r\n\/\/ kapt \ud50c\ub7ec\uadf8\uc778 \uc801\uc6a9\r\napply plugin: 'kotlin-kapt' \r\n\r\n... \/\/ \uae30\ud0c0 \uc0dd\ub7b5\r\n\r\ndependencies{\r\n  \/\/ \uae30\uc874 annotationProcessor \ub300\uc2e0 kapt\ub85c \uc120\uc5b8\r\n  \/\/ annotationProcessor \"com.google.dagger:hilt-android-compiler:$hilt_version\"\r\n  kapt \"com.google.dagger:hilt-android-compiler:$hilt_version\"\r\n}<\/pre>\n<h2>KAPT\uac00 \uc788\ub294\ub370 \uc65c KSP\ub97c \uc368\uc57c\ud558\ub098\uc694?<\/h2>\n<h3>1. \ube60\ub974\ub2e4<\/h3>\n<p>\uae30\uc874\uc5d0\ub294 \ucf54\ud2c0\ub9b0 \uc804\uc6a9 \uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c\uac00 \uc5c6\uc5c8\uae30 \ub54c\ubb38\uc5d0, javax.lang.model \ud328\ud0a4\uc9c0\uc5d0\uc11c \uc81c\uacf5\ud558\ub294 API\ub97c \ud1b5\ud574 \uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c\ub97c \uc791\uc131\ud588\ub2e4. \uc774 \ud504\ub85c\uc138\uc11c\ub97c \uc218\ud589\ud558\uae30 \uc704\ud574 KAPT\ub294 \ucf54\ud2c0\ub9b0 \ucf54\ub4dc\ub97c <strong>\uc790\ubc14 \uc2a4\ud141(Stub)<\/strong>\uc73c\ub85c \ucef4\ud30c\uc77c\ud558\uac8c \ub41c\ub2e4. \uc774\ub7ec\ud55c \uc2a4\ud141\uc744 \uc0dd\uc131\ud558\ub824\uba74 KAPT\uac00 \ucf54\ud2c0\ub9b0 \ud504\ub85c\uadf8\ub7a8\uc758 \ubaa8\ub4e0 \uae30\ud638(symbol)\ub4e4\uc744 \ud655\uc778\ud574\uc57c \ud55c\ub2e4. \uc2a4\ud141 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud558\ub294 \ube44\uc6a9\uc740 \ucef4\ud30c\uc77c \uc804\uccb4\uc758 1\/3\uc744 \ucc28\uc9c0\ud55c\ub2e4.\u00a0<\/p>\n<p>\uc131\ub2a5 \ud3c9\uac00\ub97c \uc704\ud574 KSP\uc5d0\uc11c Glide\uc758 \ub2e8\uc21c\ud654\ub41c \ubc84\uc804\uc744 \uad6c\ud604\ud558\uc5ec <a href=\"https:\/\/github.com\/tachiyomiorg\/tachiyomi\">Tachiyomi<\/a> \ud504\ub85c\uc81d\ud2b8\uc6a9 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud588\ub294\ub370 \ucf54\ud2c0\ub9b0 \ucef4\ud30c\uc77c \uc2dc\uac04\uc740 21.55\ucd08\uc5d0\uc11c KAPT\uac00 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud558\ub294\ub370 8.67\ucd08, KSP\uac00 \ucf54\ub4dc\ub97c \uc0dd\uc131\ud558\ub294\ub370 1.15\ucd08\uac00 \uac78\ub838\ub2e4\uace0 \ud55c\ub2e4. KSP\uc758 \ucf54\ub4dc \uc0dd\uc131 \uc2dc\uac04\uc774 \uc57d 7\ubc30 \uc774\uc0c1 \ube68\ub790\ub2e4<\/p>\n<h3>2. \uc27d\ub2e4<\/h3>\n<p>KSP\ub294 \ucf54\ud2c0\ub9b0 \uce5c\ud654\uc801\uc774\ub2e4. KSP\ub294 \ucf54\ud2c0\ub9b0\ub9cc\uc758 \uace0\uc720\ud55c \uae30\ub2a5\ub4e4\uc778 \ud655\uc7a5 \ud568\uc218(extension function), \uc120\uc5b8 \uc704\uce58 \ubcc0\ud658 (Declaration-Site Variance), \uc9c0\uc5ed \ud568\uc218(local functions) \ub4f1\uc744 \uc774\ud574\ud55c\ub2e4. \ub610\ud55c \ud0c0\uc785\uc744 \ubaa8\ub378\ub9c1\ud558\uace0 \ub3d9\ub4f1\uc131 \ubc0f \ud560\ub2f9\ud638\ud658\uc131(assign-comppatibility)\uacfc \uac19\uc740 \uae30\ubcf8\uc801\uc778 \ud0c0\uc785\uc744 \uac80\uc0ac\ud558\ub294 \uae30\ub2a5\uc744 \uc81c\uacf5\ud55c\ub2e4.<\/p>\n<p>\ub610\ud55c KSP\ub97c \uc774\uc6a9\ud558\uc5ec \uc18c\uc2a4\ucf54\ub4dc\ub97c \ucc98\ub9ac\ud560 \ub54c \ud074\ub798\uc2a4, \ud074\ub798\uc2a4 \uba64\ubc84, \ud568\uc218 \ubc0f \uad00\ub828 \ub9e4\uac1c\ubcc0\uc218\uc640 \uac19\uc740 \ub0b4\uc6a9\uc5d0 \uc27d\uac8c \uc811\uadfc\uc774 \uac00\ub2a5\ud558\ub2e4. \uac1c\ub150\uc801\uc73c\ub85c\ub294 \ucf54\ud2c0\ub9b0 \ub9ac\ud50c\ub809\uc158\uc758 KType\uacfc \uc720\uc0ac\ud558\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \ucee4\uc2a4\ud140 SymbolProcessor \uc791\uc131 \uc2dc AbstractProcessor\uc640 \ube44\uad50\ud558\uc5ec \uc791\uc131\uc774 \ud3b8\ud558\ub2e4\ub294 \ub290\ub08c\uc744 \ubc1b\uac8c \ub41c\ub2e4.<\/p>\n<h3>3. \ud638\ud658\uc131 \ubc0f \uc720\uc9c0\ubcf4\uc218<\/h3>\n<p>KSP\ub294 JVM\uc5d0 \uc885\uc18d\ub418\uc9c0 \uc54a\ub3c4\ub85d \uc124\uacc4\ub418\uc5c8\ub2e4. \uadf8\ub807\uae30 \ub54c\ubb38\uc5d0 \ud5a5\ud6c4 \ub2e4\ub978 \ud50c\ub7ab\ud3fc\uc5d0 \ubcf4\ub2e4 \uc27d\uac8c \uc801\uc6a9\ud560 \uc218 \uc788\ub2e4. \ub610\ud55c \ucef4\ud30c\uc77c\ub7ec \ubcc0\uacbd \uc0ac\ud56d\uc744 \uc228\uae30\ub3c4\ub85d \uc124\uacc4\ub418\uc5b4 \uc774\ub97c \uc0ac\uc6a9\ud558\ub294 \ud504\ub85c\uc138\uc11c\uc758 \uc720\uc9c0 \uad00\ub9ac \ub178\ub825\uc744 \ucd5c\uc18c\ud654 \ud55c\ub2e4.\u00a0<\/p>\n<h2>KSP\uc758 \ud55c\uacc4\uc810<\/h2>\n<p>KSP\ub294 \uc77c\ubc18\uc801\uc778 \uc720\uc988\ucf00\uc774\uc2a4\uc5d0 \ub300\ud55c \uac04\ub2e8\ud55c \uc194\ub8e8\uc158\uc774 \ub418\uace0\uc790 \ub4f1\uc7a5\ud588\ub2e4. \ub2e4\ub978 \ud50c\ub7ec\uadf8\uc778 \uc194\ub8e8\uc158\uc5d0 \ube44\uad50\ud588\uc744 \ub54c \uba87\uac00\uc9c0 \uc808\ucda9\uc810(trade-off)\uc774 \uc874\uc7ac\ud55c\ub2e4.<\/p>\n<p><strong> \ub2e4\uc74c\uc740 KSP\uc758 \ubaa9\ud45c\uac00 \uc544\ub2c8\ub2e4.<\/strong><\/p>\n<ol>\n<li>\uc18c\uc2a4 \ucf54\ub4dc\uc758 \ud45c\ud604 \uc218\uc900 \uc815\ubcf4\ub97c \uc870\uc0ac\ud558\uae30<\/li>\n<li>\uc18c\uc2a4 \ucf54\ub4dc \uc218\uc815\ud558\uae30<\/li>\n<li>Java Annotation Processing API\uc640 100% \ud638\ud658\ud558\uae30<\/li>\n<li>IDE\uc640 \ud1b5\ud569\ud558\uae30 (\ud604\uc7ac\ub294 IDE\uac00 \uc0dd\uc131 \ub41c \ucf54\ub4dc\ub97c \uc77d\uc9c0 \ubabb\ud568)<\/li>\n<\/ol>\n<p>\uc548\ub4dc\ub85c\uc774\ub4dc \uc2a4\ud29c\ub514\uc624(IDE)\uc5d0\uc11c\ub3c4 \ucf54\ub4dc\ub97c \uc77d\uc9c0 \ubabb\ud558\uae30 \ub54c\ubb38\uc5d0 \ub2e4\uc74c\uc758 \uacbd\ub85c\ub97c \uba85\uc2dc\ud574\uc57c \ud55c\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">build\/generated\/ksp\/debug\/kotlin<\/pre>\n<p>build.gradle.kts \uc608\uc2dc<\/p>\n<pre class=\"lang: decode:true \">android {\r\n    buildTypes {\r\n        getByName(\"debug\") {\r\n            sourceSets {\r\n                getByName(\"main\") {\r\n                    java.srcDir(File(\"build\/generated\/ksp\/debug\/kotlin\"))\r\n                }\r\n            }\r\n        }\r\n    }\r\n}\r\n<\/pre>\n<h2>KSP\ub97c \uc774\uc6a9\ud55c \uc608\uc81c \ub9cc\ub4e4\uae30 (Intent \ube4c\ub354)<\/h2>\n<p>KSP\ub97c \uc0ac\uc6a9\ud558\uc5ec \uac04\ub2e8\ud55c Intent \ube4c\ub354 \uc608\uc81c\ub97c \ub9cc\ub4e4\uace0\uc790 \ud55c\ub2e4. (<a href=\"https:\/\/github.com\/Charlezz\/IntentBuilderSample\">\uc608\uc81c\ucf54\ub4dc<\/a>)<\/p>\n<p>Intent \ube4c\ub354\ub294 \uc0ac\uc6a9\uc790 Activity\uac00 \uc694\uad6c\ud558\ub294 \ud544\uc218 \ud30c\ub77c\ubbf8\ud130\ub97c Builder \ud074\ub798\uc2a4\uc758 \uc0dd\uc131\uc790 \ub9e4\uac1c\ubcc0\uc218\ub85c \uac16\ub294 \ube4c\ub354 \ud074\ub798\uc2a4\ub97c \uc758\ubbf8\ud55c\ub2e4. \uc774 \ube4c\ub354 \ud074\ub798\uc2a4\ub97c KSP\ub97c \ud1b5\ud574 \uc790\ub3d9\uc73c\ub85c \uc0dd\uc131\ud574\ubcf4\uc790!<\/p>\n<h3>IntentBuilder \uc608\uc81c \ud504\ub85c\uc81d\ud2b8 \uc124\uc815\ud558\uae30<\/h3>\n<p>\ub2e4\uc74c\uacfc \uadf8\ub9bc\uacfc \uac19\uc774 \ubaa8\ub4c8\uc744 \ub9cc\ub4e4\uace0, \uc758\uc874\uad00\uacc4\ub97c \uc124\uc815\ud588\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project-1024x296.png\" alt=\"\" width=\"750\" height=\"217\" class=\"alignnone size-large wp-image-45258\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project-1024x296.png 1024w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project-300x87.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project-768x222.png 768w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-ksp-project.png 1182w\" sizes=\"(max-width: 750px) 100vw, 750px\" \/><\/a><\/p>\n<h4>IntentBuilder\uc5d0 \uc0ac\uc6a9\ud558\ub294 Annotation<\/h4>\n<p>IntentBuilder annotation \ubaa8\ub4c8\uc740 \ucf54\ud2c0\ub9b0\/\uc790\ubc14 \ubaa8\ub4c8\ub85c \uc0dd\uc131\ud588\ub2e4. \ub2e4\uc74c\uacfc \uac19\uc740 \uc560\ub178\ud14c\uc774\uc158\uc744 \uc815\uc758\ud55c\ub2e4.<\/p>\n<p><strong>@IntentBuilder<br \/>\n<\/strong>\ud0c0\uac9f Activity \ud074\ub798\uc2a4\uc5d0 \uc0ac\uc6a9. (Activity\uc774\ub984 + Builder) \ud074\ub798\uc2a4 \uc0dd\uc131.<\/p>\n<p><strong>@Extra<br \/>\n<\/strong>\ud0c0\uac9f Activity \uba64\ubc84 \ud544\ub4dc\uc5d0 \uc0ac\uc6a9. (\ube4c\ub354 \ud074\ub798\uc2a4\uc758 \uc0dd\uc131\uc790 \ub9e4\uac1c\ubcc0\uc218)<\/p>\n<h4>IntentBuilder KSP \ubaa8\ub4c8<\/h4>\n<p>ksp \ubaa8\ub4c8\uc740 \ucf54\ud2c0\ub9b0\/\uc790\ubc14 \ubaa8\ub4c8\ub85c \uc0dd\uc131\ud588\ub2e4. \ub2e4\uc74c\uacfc \uac19\uc774 gradle\uc744 \uc124\uc815 \ud55c\ub2e4.<\/p>\n<p><strong>build.gradle.kts (ksp \ubaa8\ub4c8\ub808\ubca8)<\/strong><\/p>\n<pre class=\"lang:null decode:true lang:\">plugins {\r\n    \/\/ \ucf54\ud2c0\ub9b0 \ud50c\ub7ec\uadf8\uc778 \uc801\uc6a9\r\n    kotlin(\"jvm\")\r\n}\r\n\r\n\r\nrepositories {\r\n    mavenCentral()\r\n    \/\/ google() \ub9ac\ud3ec\uc9c0\ud1a0\ub9ac\ub97c \ucd94\uac00\ud558\uc5ec \ud574\ub2f9 \ud50c\ub7ec\uadf8\uc778\uc744 \ucc3e\uc744 \uc218 \uc788\ub3c4\ub85d \ud55c\ub2e4.\r\n    google()\r\n}\r\n\r\ndependencies {\r\n    \/\/KSP API\ub97c \uc0ac\uc6a9\ud558\uae30 \uc704\ud574 \uc544\ub798\uc758 \uc758\uc874\uc131\uc744 \ucd94\uac00\r\n    implementation(\"com.google.devtools.ksp:symbol-processing-api:1.5.20-1.0.0-beta04\") \r\n}<\/pre>\n<p>\uc124\uc815\uc774 \uc815\uc0c1\uc801\uc73c\ub85c \ub05d\ub0ac\ub2e4\uba74 <strong>SymbolProcessor<\/strong>\uc640 <strong>SymbolProcessorProvider<\/strong>\ub97c \uad6c\ud604\ud574\uc57c \ud55c\ub2e4.\u00a0<\/p>\n<p><strong>SymbolProcessorProvider<br \/>\n<\/strong>SymbolProcessor\ub97c \ubc18\ud658\ud558\ub294 create() \ud568\uc218\ub97c \uac16\ub294 \uc778\ud130\ud398\uc774\uc2a4. KSP\uc5d0 \ud1b5\ud569\ub418\uc5b4 \ud50c\ub7ec\uadf8\uc778\uc5d0 \uc758\ud574 \uc0ac\uc6a9\ub41c\ub2e4.\u00a0<\/p>\n<pre class=\"lang:null decode:true lang:\">fun interface SymbolProcessorProvider {\r\n\r\n    fun create(environment: SymbolProcessorEnvironment): SymbolProcessor\r\n}<\/pre>\n<p>&nbsp;<\/p>\n<p><strong>SymbolProcessor<br \/>\n<\/strong>\uc2ec\ubcfc \ud504\ub85c\uc138\uc2f1\uc744 \uc704\ud574 \ub2e4\uc74c\uacfc \uac19\uc740 3\uac00\uc9c0 \uba54\uc11c\ub4dc\ub97c \uac16\ub294 \uc778\ud130\ud398\uc774\uc2a4\ub2e4.<strong><\/strong><\/p>\n<pre class=\"lang: decode:true\">interface SymbolProcessor {\r\n    \/**\r\n     * resolver\ub294 SymbolProcessor\uc5d0 \uc2ec\ubcfc(\uc560\ub178\ud14c\uc774\uc158)\uacfc \uac19\uc740 \ucef4\ud30c\uc77c\ub7ec \uc138\ubd80 \uc815\ubcf4\uc5d0 \ub300\ud55c \uc811\uadfc\uc744 \uc81c\uacf5\ud55c\ub2e4.\r\n     * \uc774 \ud568\uc218\uc5d0\uc11c\ub294 \ud504\ub85c\uc138\uc11c\uac00 \uc218\ud589\ud560 \uc218 \uc5c6\ub294 \uc720\uc608\ub41c \uc2ec\ubcfc \ubaa9\ub85d\uc744 \ubc18\ud658\ud55c\ub2e4.\r\n     *\/\r\n    fun process(resolver: Resolver): List&lt;KSAnnotated&gt;\r\n\r\n    \/**\r\n     * \ucd5c\uc885\uc801\uc778 \ub2e8\uacc4. \ud504\ub85c\uc138\uc2f1\uc744 \ub9c8\ubb34\ub9ac\uc9d3\ub294\ub2e4.\r\n     *\/\r\n    fun finish() {}\r\n\r\n    \/**\r\n     * \ub77c\uc6b4\ub4dc \uc218\ud589 \ud6c4 \uc5d0\ub7ec\ub97c \ucc98\ub9ac\r\n     *\/\r\n    fun onError() {}\r\n}<\/pre>\n<p>\ub2e4\uc74c\uacfc \uac19\uc774 IntentBuilderProcessor\uc640 IntentBuilderProcessorProvider\ub97c \uad6c\ud604\ud588\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">class IntentBuilderProcessor : SymbolProcessor {\r\n\r\n    companion object {\r\n        private val intentBuilderName = IntentBuilder::class.java.canonicalName\r\n    }\r\n\r\n    \/\/ \ucf54\ub4dc \uc0dd\uc131\uae30\r\n    private lateinit var codeGenerator: CodeGenerator\r\n    \/\/ \ub85c\uadf8 \ucd9c\ub825\uae30\r\n    private lateinit var logger: KSPLogger\r\n\r\n    fun init(\r\n        codeGenerator: CodeGenerator,\r\n        logger: KSPLogger\r\n    ) {\r\n        this.codeGenerator = codeGenerator\r\n        this.logger = logger\r\n    }\r\n\r\n    override fun process(resolver: Resolver): List&lt;KSAnnotated&gt; {\r\n        logger.warn(\"IntentBuilderProcessor \uc2dc\uc791\")\r\n\r\n        \/\/ getSymbolsWithAnnotation\uc744 \ud1b5\ud574 \uc6d0\ud558\ub294 \uc2ec\ubcfc\uc744 \uac00\uc838\uc640 \uc791\uc5c5\uc744 \uc218\ud589\ud560 \uc218 \uc788\ub2e4.\r\n        val symbols:Sequence&lt;KSAnnotated&gt; = resolver.getSymbolsWithAnnotation(intentBuilderName)\r\n\r\n        val ret = symbols.filter { !it.validate() }\r\n\r\n        \/\/ IntentBuilderVisitor\uc5d0\uac8c \uc791\uc5c5\uc744 \uc704\uc784\ud55c\ub2e4.\r\n        symbols\r\n            .filter { it is KSClassDeclaration &amp;&amp; it.validate() }\r\n            .forEach { it.accept(IntentBuilderVisitor(codeGenerator, logger), Unit) }\r\n        return ret.toList()\r\n    }\r\n\r\n    override fun finish() {\r\n        logger.warn(\"IntentBuilderProcessor \ub05d\")\r\n    }\r\n\r\n    override fun onError() {\r\n        logger.error(\"IntentBuilderProcessor \uc5d0\ub7ec\")\r\n    }\r\n\r\n}\r\n\r\nclass IntentBuilderProcessorProvider : SymbolProcessorProvider {\r\n    override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {\r\n        return IntentBuilderProcessor().apply {\r\n            init(environment.codeGenerator, environment.logger)\r\n        }\r\n    }\r\n}<\/pre>\n<p>\uae30\ubcf8\uc801\uc73c\ub85c KSVisitor \uc778\ud130\ud398\uc774\uc2a4\ub97c \uad6c\ud604\ud558\uc5ec \uc791\uc5c5\uc744 \uc218\ud589\ud560 \uc218 \uc788\ub2e4. \uc704 \ucf54\ub4dc\uc5d0\uc11c\ub294 KSVisitor\ub97c \uad6c\ud604\ud55c IntentBuilderVisitor\ub97c \uc791\uc131\ud558\uc5ec KSP \uc218\ud589\uc2dc \ud2b9\uc815 Activity\ub97c \uc704\ud55c IntentBuilder \ud074\ub798\uc2a4 \ucf54\ub4dc\ub97c \uad6c\ud604\ud558\ub3c4\ub85d \ud588\ub2e4.<\/p>\n<p>\uc608\uc81c\ucf54\ub4dc\ub77c \ub0b4\uc6a9\uc774 \ub9ce\uc774 \ubd80\uc2e4\ud55c \uac83\uc744 \uac10\uc548\ud574\uc57c \ud55c\ub2e4.<\/p>\n<pre class=\"lang: decode:true \">class IntentBuilderVisitor(\r\n    private val codeGenerator: CodeGenerator,\r\n    private val logger: KSPLogger\r\n) : KSVisitorVoid() {\r\n\r\n\r\n    override fun visitAnnotation(annotation: KSAnnotation, data: Unit) {\r\n        super.visitAnnotation(annotation, data)\r\n        logger.warn(\"visitAnnotation = $annotation\")\r\n    }\r\n\r\n    override fun visitAnnotated(annotated: KSAnnotated, data: Unit) {\r\n        super.visitAnnotated(annotated, data)\r\n        logger.warn(\"visitAnnotated = $annotated\")\r\n\r\n    }\r\n\r\n    override fun visitClassDeclaration(classDeclaration: KSClassDeclaration, data: Unit) {\r\n        logger.warn(\"@IntentBuilder -&gt; $classDeclaration \ubc1c\uacac\")\r\n\r\n        val candidates = ArrayList&lt;KSPropertyDeclaration&gt;()\r\n\r\n        \/\/ \ud6c4\ubcf4\uad70 \uc120\uc815\r\n        for (property in classDeclaration.getDeclaredProperties()) {\r\n            for (annotation in property.annotations) {\r\n                if (annotation.shortName.getShortName() == Extra::class.java.simpleName) {\r\n                    logger.warn(\"@Extra -&gt; ${property.parentDeclaration?.simpleName?.asString()}::${property.simpleName.getShortName()} \ubc1c\uacac\")\r\n                    candidates.add(property)\r\n                    break\r\n                }\r\n            }\r\n        }\r\n\r\n        val packageName = classDeclaration.packageName.asString()\r\n\r\n        \/\/\ube4c\ub354 \ub9cc\ub4e4\uae30\r\n        makeBuilderFile(packageName, classDeclaration, candidates)\r\n\r\n        \/\/\ud30c\uc11c \ub9cc\ub4e4\uae30\r\n        makeParserFile(packageName, classDeclaration, candidates)\r\n    }\r\n\r\n    override fun visitFunctionDeclaration(function: KSFunctionDeclaration, data: Unit) {\r\n        logger.warn(\"visitFunctionDeclaration = $function\")\r\n    }\r\n\r\n    private fun makeBuilderFile(\r\n        packageName: String,\r\n        classDeclaration: KSClassDeclaration,\r\n        candidates: ArrayList&lt;KSPropertyDeclaration&gt;\r\n    ) {\r\n\r\n        val className = \"${classDeclaration.simpleName.asString()}Builder\"\r\n        val file: OutputStream = codeGenerator.createNewFile(\r\n            dependencies = Dependencies(true, classDeclaration.containingFile!!),\r\n            packageName = packageName,\r\n            fileName = className\r\n        )\r\n\r\n        file.appendLine(\"package $packageName\")\r\n        file.appendLine(\"\")\r\n        file.appendLine(\"import android.content.Intent\")\r\n        file.appendLine(\"import android.content.Context\")\r\n        file.appendLine(\"\")\r\n        file.appendLine(\"class $className(\")\r\n\r\n        \/\/ \uc0dd\uc131\uc790 \ub9e4\uac1c\ubcc0\uc218 \ub9cc\ub4e4\uae30\r\n        file.appendLine(\"\\tprivate val context:Context,\")\r\n        for (candidate in candidates) {\r\n            file.appendLine(\r\n                \"\\tprivate val ${candidate.simpleName.asString()}: ${\r\n                    candidate.type.resolve().toString()\r\n                },\"\r\n            )\r\n        }\r\n        file.appendLine(\"){\")\r\n        file.appendLine(\"\\tfun build(): Intent {\")\r\n        file.appendLine(\"\\t\\treturn Intent(context, ${classDeclaration.qualifiedName?.asString()}::class.java).apply {\")\r\n\r\n        \/\/ Extra\uc0bd\uc785\r\n\r\n        for (candidate in candidates) {\r\n            file.appendLine(\"\\t\\t\\tputExtra(\\\"${candidate.simpleName.asString()}\\\", ${candidate.simpleName.asString()})\")\r\n        }\r\n\r\n        file.appendLine(\"\\t\\t}\")\r\n        file.appendLine(\"\\t}\")\r\n        file.appendLine(\"}\")\r\n        file.close()\r\n        logger.warn(\"$className \ud30c\uc77c \uc0dd\uc131 \uc644\ub8cc\")\r\n    }\r\n\r\n    private fun makeParserFile(\r\n        packageName: String,\r\n        classDeclaration: KSClassDeclaration,\r\n        candidates: ArrayList&lt;KSPropertyDeclaration&gt;\r\n    ) {\r\n        \/\/ \ud30c\uc11c \ub9cc\ub4e4\uae30\r\n        val className = \"${classDeclaration.simpleName.asString()}Parser\"\r\n        val file: OutputStream = codeGenerator.createNewFile(\r\n            dependencies = Dependencies(true, classDeclaration.containingFile!!),\r\n            packageName = packageName,\r\n            fileName = className\r\n        )\r\n\r\n        file.appendLine(\"package $packageName\")\r\n        file.appendLine(\"\")\r\n        file.appendLine(\"class $className(\")\r\n        file.appendLine(\"\\tprivate val activity:${classDeclaration.simpleName.asString()}\")\r\n        file.appendLine(\"){\")\r\n        file.appendLine(\"\")\r\n        file.appendLine(\"\\tfun parse(){\")\r\n        file.appendLine(\"\\t\\tval intent = activity.intent\")\r\n\r\n        for (candidate in candidates) {\r\n            when (candidate.type.resolve().toString()) {\r\n                \"String\", \"String?\" -&gt; {\r\n                    file.appendLine(\"\\t\\tactivity.${candidate.simpleName.asString()} = intent.getStringExtra(\\\"${candidate.simpleName.asString()}\\\")?:\\\"\\\"\")\r\n                }\r\n                \"Int\", \"Int?\" -&gt; {\r\n                    file.appendLine(\"\\t\\tactivity.${candidate.simpleName.asString()} = intent.getIntExtra(\\\"${candidate.simpleName.asString()}\\\",0)\")\r\n                }\r\n            }\r\n        }\r\n\r\n        file.appendLine(\"\\t}\")\r\n        file.appendLine(\"}\")\r\n\r\n        file.close()\r\n        logger.warn(\"$className \ud30c\uc77c \uc0dd\uc131 \uc644\ub8cc\")\r\n\r\n    }\r\n\r\n}\r\n\r\nfun OutputStream.appendLine(str: String) {\r\n    this.write(\"$str\\n\".toByteArray())\r\n}<\/pre>\n<p>\uac70\uc758 \ubaa8\ub4e0 \uc900\ube44\uac00 \ub05d\ub0ac\ub2e4. SymbolProcessor \ucf54\ub4dc \uc791\uc131 \ud6c4\uc5d0\ub294 \ucef4\ud30c\uc77c\ub7ec\uc5d0\uac8c \ud574\ub2f9 \ud504\ub85c\uc138\uc11c\uc758 SymbolProcessorProvider\ub97c \ub4f1\ub85d\ud574\uc918\uc57c \ud55c\ub2e4.<\/p>\n<p>\ub2e4\uc74c\uacfc \uac19\uc740 \uacbd\ub85c\uc5d0 \ud30c\uc77c\uc744 \uc0dd\uc131\ud558\uc5ec \ub4f1\ub85d \ud560 \uc218 \uc788\ub2e4.<\/p>\n<p><strong>resources\/META-INF\/services\/com.google.devtools.ksp.processing.SymbolProcessorProvider<\/strong><\/p>\n<p><strong><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot.png\" alt=\"\" width=\"990\" height=\"324\" class=\"alignnone size-full wp-image-45259\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot.png 990w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-300x98.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-768x251.png 768w\" sizes=\"(max-width: 990px) 100vw, 990px\" \/><\/a><\/strong><\/p>\n<p>\ud574\ub2f9 \ud30c\uc77c\ub0b4\uc5d0 \uc791\uc131\ud55c SymbolProcessorProvider\uc758 canonical \uc774\ub984\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uba85\uc2dc\ud55c\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">com.charlezz.intentbuilder_ksp.IntentBuilderProcessorProvider<\/pre>\n<h3>IntentBuilder \uc608\uc81c \uc2e4\ud589\ud558\uae30<\/h3>\n<p>app\ubaa8\ub4c8\uc758 build.gradle\uc744 \ub2e4\uc74c\uacfc \uac19\uc774 \uc124\uc815\ud55c\ub2e4.<\/p>\n<pre class=\"lang: decode:true \">plugins {\r\n    id(\"com.android.application\")\r\n    kotlin(\"android\")\r\n    id(\"com.google.devtools.ksp\")\r\n}\r\n\r\n\r\nandroid {\r\n    compileSdkVersion(Dependencies.compileSdk)\r\n    buildToolsVersion(Dependencies.buildToolVersion)\r\n\r\n    defaultConfig {\r\n        applicationId(\"com.charlezz.intentbuilder.sample\")\r\n        minSdkVersion(Dependencies.minSdk)\r\n        targetSdkVersion(Dependencies.targetSdk)\r\n        versionCode(1)\r\n        versionName(\"1.0\")\r\n    }\r\n\r\n    buildTypes {\r\n\r\n        getByName(\"debug\") {\r\n            sourceSets {\r\n                getByName(\"main\") {\r\n                    java.srcDir(File(\"build\/generated\/ksp\/debug\/kotlin\"))\r\n                }\r\n            }\r\n        }\r\n        ...\r\n    }\r\n    ...\r\n}\r\n\r\ndependencies {\r\n    ...\r\n    implementation(project(\":intentbuilder\"))\r\n    \"ksp\"(project(\":intentbuilder-ksp\"))\r\n\r\n}<\/pre>\n<p>\ub2e4\uc74c\uacfc \uac19\uc774 name\uacfc age\ub97c \ud544\uc694\ub85c \ud558\ub294 UserActivity\ub97c \ub9cc\ub4e4\uc5c8\ub2e4.<\/p>\n<pre class=\"lang: decode:true \">@IntentBuilder\r\nclass UserActivity : AppCompatActivity() {\r\n\r\n    @Extra\r\n    var name: String? = null\r\n\r\n    @Extra\r\n    var age: Int = 0\r\n\r\n    ...\r\n\r\n}<\/pre>\n<p>\ucef4\ud30c\uc77c \uc774\ud6c4 UserActivityBuilder\uc640 UserActivityParser\uac00 \uc0dd\uc131\ub41c \uac83\uc744 \ud655\uc778\ud560 \uc218 \uc788\ub2e4.<\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-17.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-17.png\" alt=\"\" width=\"924\" height=\"824\" class=\"alignnone size-full wp-image-45260\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-17.png 924w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-17-300x268.png 300w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-17-768x685.png 768w\" sizes=\"(max-width: 924px) 100vw, 924px\" \/><\/a><\/p>\n<p><a href=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-37.png\"><img decoding=\"async\" loading=\"lazy\" src=\"https:\/\/www.charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-37.png\" alt=\"\" width=\"602\" height=\"442\" class=\"alignnone size-full wp-image-45261\" srcset=\"https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-37.png 602w, https:\/\/charlezz.com\/wordpress\/wp-content\/uploads\/2021\/07\/www.charlezz.com-kapt-2-ksp-screenshot-37-300x220.png 300w\" sizes=\"(max-width: 602px) 100vw, 602px\" \/><\/a><\/p>\n<p>\uc0dd\uc131\ub41c \ucf54\ub4dc\ub85c UserActivity\ub97c \ub2e4\uc74c\uacfc \uac19\uc774 \ud638\ucd9c \ud560 \uc218 \uc788\ub2e4.<\/p>\n<pre class=\"lang: decode:true\">class MainActivity : AppCompatActivity() {\r\n\r\n    override fun onCreate(savedInstanceState: Bundle?) {\r\n        super.onCreate(savedInstanceState)\r\n        setContentView(R.layout.activity_main)\r\n\r\n        findViewById&lt;Button&gt;(R.id.submit).setOnClickListener {\r\n\r\n            val name = findViewById&lt;TextInputEditText&gt;(R.id.input_name).text.toString()\r\n            val age = findViewById&lt;TextInputEditText&gt;(R.id.input_age).text.toString().toIntOrNull()?:0\r\n\r\n            \/\/ UserActivityBuilder\ub97c \uc774\uc6a9\ud55c \uc778\ud150\ud2b8 \ub9cc\ub4e4\uae30\r\n            val intent:Intent = UserActivityBuilder(this, name, age).build()\r\n\r\n            \/\/ UserActivity \uc561\ud2f0\ube44\ud2f0 \ud638\ucd9c\r\n            startActivity(intent)\r\n        }\r\n\r\n    }\r\n}<\/pre>\n<h2>\ub9c8\uce58\uba70<\/h2>\n<p>\ud604\uc7ac KSP\ub294 beta \uc2a4\ud14c\uc774\uc9c0\uc774\uae30 \ub54c\ubb38\uc5d0 \uc131\uae09\ud788 \ud504\ub85c\ub355\ud2b8\uc5d0 \uc801\uc6a9\ud560 \ud544\uc694\ub294 \uc5c6\uc744 \uac83 \uac19\ub2e4. \ud558\uc9c0\ub9cc \ub300\uaddc\ubaa8 \ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c \uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc2f1\uc744 \ud558\uace0 \uc788\uac70\ub098 \ud639\uc740 KSP\uc758 \uac15\ub825\ud55c \uc131\ub2a5\uc744 \ub9db\ubcf4\uace0 \uc2f6\ub2e4\uba74 \uc9c0\uae08 \ub2f9\uc7a5 \uc2dc\uc791\ud574\ubcf4\ub294 \uac83\ub3c4 \ub098\uc058\uc9c0 \uc54a\ub2e4.<\/p>\n<p>\ud604\uc7ac KSP\ub97c \uc9c0\uc6d0\ud558\ub294 \uc624\ud508\uc18c\uc2a4 \ub77c\uc774\ube0c\ub7ec\ub9ac\ub294 Room, Moshi, Kotshi, Lyricist \ub4f1\uc774 \uc788\ub2e4. \ucd94\ud6c4 Hilt\ub098 Glide\uac19\uc740 \uacf3\uc5d0\ub3c4 \uc801\uc6a9\ub420 \uc608\uc815\uc774\ub2e4.<\/p>\n<p>&nbsp;<\/p>\n","protected":false},"excerpt":{"rendered":"<p>KSP(Kotlin Symbol Processing) KSP(Kotlin Symbol Processing)\ub294 \ucf54\ud2c0\ub9b0\uc5d0\uc11c \uacbd\ub7c9\ud654 \ub41c \ucef4\ud30c\uc77c\ub7ec \ud50c\ub7ec\uadf8\uc778\uc744 \uac1c\ubc1c\ud560 \uc218 \uc788\ub294 API\ub2e4.\u00a0 \ud559\uc2b5\uace1\uc120\uc744 \ucd5c\uc18c\ud55c\uc73c\ub85c \uc904\uc774\uace0, \ucf54\ud2c0\ub9b0\uc758 \uae30\ub2a5\uc744 \ud65c\uc6a9\ud560 \uc218 \uc788\ub294 \ub2e8\uc21c\ud654\ub41c API\ub97c \uc81c\uacf5\ud55c\ub2e4. KSP\ub294 \ucf54\ud2c0\ub9b0 1.4.30 \ubc84\uc804 \uc774\uc0c1\ubd80\ud130 \ud638\ud658\ub418\uba70, KAPT\uc640 \ube44\uad50\ud588\uc744 \ub54c KSP\ub97c \uc0ac\uc6a9\ud558\ub294 \uc560\ub178\ud14c\uc774\uc158 \ud504\ub85c\uc138\uc11c\ub294 \ucd5c\ub300 2\ubc30 \ub354 \ube60\ub974\uac8c \uc2e4\ud589\ud560 \uc218 \uc788\ub2e4. \uc790\uc138\ud55c \ub0b4\uc6a9\uc740 \u00a0KSP Github [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"om_disable_all_campaigns":false,"inline_featured_image":false,"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[5],"tags":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45255"}],"collection":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45255"}],"version-history":[{"count":4,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45255\/revisions"}],"predecessor-version":[{"id":45265,"href":"https:\/\/charlezz.com\/index.php?rest_route=\/wp\/v2\/posts\/45255\/revisions\/45265"}],"wp:attachment":[{"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45255"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45255"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/charlezz.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45255"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}