{"id":167,"date":"2016-01-02T02:00:40","date_gmt":"2016-01-02T02:00:40","guid":{"rendered":"http:\/\/fluentreports.com\/blog\/?p=167"},"modified":"2019-04-15T17:51:50","modified_gmt":"2019-04-15T17:51:50","slug":"creating-a-plugin-using-third-party-code","status":"publish","type":"post","link":"http:\/\/fluentreports.com\/blog\/?p=167","title":{"rendered":"Creating a plugin using third party code"},"content":{"rendered":"<p style=\"text-align: center;\"><strong>(Please make sure to read the update at the bottom of the post)<\/strong><\/p>\n<p>So, I was minding my own business last week, by reading about everyone's issues in the NativeScript <a href=\"https:\/\/groups.google.com\/forum\/#!forum\/nativescript\" target=\"_blank\" rel=\"noopener noreferrer\">forum<\/a>.\u00a0 Well, ok, so I wasn't minding my own business, we can pretend I was...<\/p>\n<p>So, I saw this post about <a href=\"https:\/\/groups.google.com\/forum\/#!topic\/nativescript\/oBZL9MhG7oY\" target=\"_blank\" rel=\"noopener noreferrer\">CodeSign error: entitlements are required<\/a> and tried to help a little. The issue actually ends up being the newest version of XCode has some issues that has been causing problems for people in all sorts of communities.<\/p>\n<p>Well, I told Aaron, I would do a blog post the next day on the plugin.\u00a0 My how time flies when you are swamped with stuff to do and it also being Christmas week; so it has been a week since I said the next day.\u00a0\u00a0 (Sorry, about that Aaron!)<\/p>\n<p><a href=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/NS-ZXing.png\" rel=\"attachment wp-att-171\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-full wp-image-171\" src=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/NS-ZXing.png\" alt=\"NS-ZXing\" width=\"150\" height=\"150\" \/><\/a>So I am going to go with his ZXing plugin that he was trying to turn into a NativeScript plugin to show how to native Android and native iOS libraries and turn them into awesome NativeScript plugins.<\/p>\n<p>If you just want to look at the code or demo the repo is at <a href=\"https:\/\/github.com\/NathanaelA\/nativescript-zxing\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/NathanaelA\/nativescript-zxing<\/a>.\u00a0 So here is how I go about making a plugin in from a native library.<\/p>\n<ol>\n<li>Find the iOS (<a href=\"https:\/\/github.com\/TheLevelUp\/ZXingObjC\" target=\"_blank\" rel=\"noopener noreferrer\">ZXingObjC<\/a>) and Android (<a href=\"https:\/\/github.com\/zxing\/zxing\" target=\"_blank\" rel=\"noopener noreferrer\">ZXing<\/a>) versions.<\/li>\n<li>Study the documentation to see how to install them &amp; build the platform files.<\/li>\n<li>Study the documentation to see how to call them &amp; build the js wrappers.<\/li>\n<\/ol>\n<p><a href=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/folders.png\" rel=\"attachment wp-att-173\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-173\" src=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/folders-300x246.png\" alt=\"folders\" width=\"300\" height=\"246\" srcset=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/folders-300x246.png 300w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/folders.png 376w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a>First thing we need to do is create a new project folder; since this is for ZXing; I created a folder called <strong>nativescript-zxing<\/strong>.\u00a0 In this folder I created a several files.<\/p>\n<p><strong><span style=\"text-decoration: underline;\">The LICENSE file<\/span><\/strong><br \/>\nThe first file is the <strong>LICENSE<\/strong> file; I need to make sure that I give credit where credit is due and outline my license and the library authors licenses.\u00a0 Most the time I use a MIT license for my stuff; however in this case since both the iOS &amp; Android parts are already under the Apache license, I used the Apache license to keep everything the same.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>The package.json<\/strong><\/span><br \/>\nThe second file is the <strong>package.json<\/strong> file.\u00a0 This one pretty straight forward, however since I have seen several mistakes in other NativeScript plugins, I am going to cover it.<br \/>\n<pre>{\n&nbsp;&nbsp;&quot;name&quot;: &quot;nativescript-zxing&quot;,\n&nbsp;&nbsp;&quot;version&quot;: &quot;1.0.0&quot;,\n&nbsp;&nbsp;&quot;description&quot;: &quot;A Simple ZXing barcode reader\/writer wrapper&quot;,\n&nbsp;&nbsp;&quot;main&quot;: &quot;zxing.js&quot;,\n&nbsp;&nbsp;&quot;nativescript&quot;: {\n&nbsp;&nbsp; &quot;platforms&quot;: {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;android&quot;: &quot;1.4.0&quot;,\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;ios&quot;: &quot;1.4.0&quot;\n&nbsp;&nbsp; }\n&nbsp;&nbsp;},\n&nbsp;&nbsp;&quot;repository&quot;: {\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;type&quot;: &quot;git&quot;,\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;url&quot;: &quot;https:\/\/github.com\/nathanaela\/nativescript-zxing.git&quot;\n&nbsp;&nbsp;},\n&nbsp;&nbsp;&quot;keywords&quot;: [\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;NativeScript&quot;, &quot;Barcode&quot;, &quot;JavaScript&quot;, &quot;Android&quot;, &quot;iOS&quot;, &quot;ZXing&quot;\n&nbsp;&nbsp;],\n&nbsp;&nbsp;&quot;author&quot;: {\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;name&quot;: &quot;Nathanael Anderson&quot;,\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;email&quot;: &quot;nathan@master-technology.com&quot;\n&nbsp;&nbsp;},\n&nbsp;&nbsp;&quot;bugs&quot;: {\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;url&quot;: &quot;https:\/\/github.com\/nathanaela\/nativescript-zxing\/issues&quot;\n&nbsp;&nbsp;},\n&nbsp;&nbsp;&quot;license&quot;: {\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;type&quot;: &quot;APACHE&quot;,\n&nbsp;&nbsp;&nbsp;&nbsp;&quot;url&quot;: &quot;https:\/\/github.com\/nathanaela\/nativescript-zxing\/blob\/master\/LICENSE&quot;\n&nbsp;&nbsp;},\n&nbsp;&nbsp;&quot;homepage&quot;: &quot;https:\/\/github.com\/nathanaela\/nativescript-zxing&quot;,\n&nbsp;&nbsp;&quot;readmeFilename&quot;: &quot;README.md&quot;\n}<\/pre><br \/>\nThe important parts are:<\/p>\n<ol>\n<li>You must have the <strong>nativescript.platforms<\/strong> key section like I have.\u00a0 If you are not supporting iOS or Android you can remove one of those sub-keys; but you need to support at least one valid platform.\u00a0 Please note this version you use is the minimum platform version you support.\u00a0 DO NOT SET IT TO THE LATEST version unless it absolutely requires the latest version.\u00a0 Please use 1.x.0 so that it will work on all versions of 1.x -- I don't know how many plugins I've had to manually change this value to work on the latest Android runtime, because the author put the latest iOS runtime in both spots which is later than the Android version, so it throws an error during install.<\/li>\n<li>It is highly recommended you have the <strong>main<\/strong> key set so that NativeScript isn't guessing which is your main JavaScript file.\u00a0 This has causes problems several times so far, so set it.<\/li>\n<li>PLEASE link back to the <strong>repository<\/strong> for your plugin; it makes it a lot easier to report any issues, create pull requests and\/or see if anything has been fixed, etc...<\/li>\n<li>Please include the <strong>license<\/strong> information, it makes is easier to verify that the plugin can be used for my project.<\/li>\n<\/ol>\n<p><span style=\"text-decoration: underline;\"><strong>Android Runtime<\/strong><\/span><br \/>\nSo, lets start with the Android version; in this case after reading the documentation; I found out the <a href=\"https:\/\/github.com\/zxing\/zxing\/wiki\/Getting-Started-Developing\" target=\"_blank\" rel=\"noopener noreferrer\">wiki <\/a>has the information we need to know.\u00a0 Most the time the readme has enough information, but in this case I had to actually search for it, and finally found the pieces we need to know in the wiki.\u00a0 The documentation has a nice little section on using a prebuilt Jar or Maven.\u00a0 Since we are using Gradle for Android, we can use the Maven stuff and eliminate having to package up or compile anything (This is the best option).<\/p>\n<p>However, in some cases if the project is no longer being maintained or you have to create your own fixes you may need to build and distribute the .jar or .aar file with your project like I need with my <a href=\"https:\/\/github.com\/NathanaelA\/nativescript-websockets\" target=\"_blank\" rel=\"noopener noreferrer\">NativeScript-WebSockets<\/a> project.\u00a0 In the event you need to distribute your own JAR files; put them in the <strong>platforms\/android\/libs<\/strong> directory.<\/p>\n<p>In our case, since the project is maintained and on Maven, we can easily just create a <strong>include.gradle<\/strong> and then NativeScript will handle the rest.\u00a0 The <strong>include.gradle<\/strong> file needs to be put in the <strong>platforms\/android<\/strong> folder.\u00a0 The <strong>include.gradle<\/strong> file looks like this:<br \/>\n<pre>android { \n&nbsp;&nbsp;&nbsp;&nbsp;productFlavors {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&quot;nativescript-zxing&quot; {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;dimension &quot;nativescript-zxing&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;}\n}\n\ndependencies {\n&nbsp;&nbsp; compile &#039;com.google.zxing:android-core:3.2.1&#039;\n&nbsp;&nbsp; compile &#039;com.google.zxing:core:3.2.1&#039;&nbsp;&nbsp;\n}<\/pre><br \/>\nIn your file; you need to change both places for the plugin name.\u00a0 And the dependencies is where we link to the our libraries.\u00a0\u00a0 Now how do I know what they are named?\u00a0 Well first of all we used the Maven link from the Wiki documentation, and then went into the core folder to get the latest version.\u00a0 <strong>3.2.1<\/strong>; The project is called <strong>com.google.zxing<\/strong> and it is a sub-project called <strong>core<\/strong>.\u00a0 So the compile line is \"compile 'com.google.zxing:core:3.2.1'\".\u00a0\u00a0 The other compile line is an optional dependency that I decided to include on the Android side of the plugin.\u00a0 I'm not currently using it in the JS code; but in future versions it would be very useful.\u00a0 So I am including it in the build process. This is ALL that is required to get the Android version of the plugin to be built into your application.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>iOS Runtime<\/strong><\/span><br \/>\nThe iOS runtime is much simpler as the <a href=\"https:\/\/github.com\/TheLevelUp\/ZXingObjC#installation\" target=\"_blank\" rel=\"noopener noreferrer\">docs <\/a>on the site list what we need to know; we don't have to go searching anywhere else.\u00a0 So what you need to is create a file called <strong>Podfile<\/strong> and place it in your <strong>platforms\/ios<\/strong> folder.\u00a0 This file contains a single line:<br \/>\n<pre>pod &#039;ZXingObjC&#039;, &#039;~&amp;gt; 3.0&#039;<\/pre><br \/>\nNow the installation says to put a <em>platform :ios '7.0'<\/em> into your Podfile; however this is NOT recommended since NativeScript is handling the platform information and will actually set it to 8.0 when you are using Podfiles.\u00a0\u00a0 So it is better to only add the single <em>pod<\/em> line.<\/p>\n<p>We are now all done with the runtime side; the <strong>platforms\/ios\/Podfile<\/strong> and <strong>platforms\/android\/include.gradle<\/strong> will automatically download and install all the needed files to link it into your project.\u00a0 The next part is where the fun begins...<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Creating a cross platform wrapper<\/strong><\/span><br \/>\nThis where you have to put on your thinking hat.\u00a0 You need to decide how you want your api to be called and what features you want to expose.\u00a0 You can even do what NativeScript does in some cases and expose a ios or android property to access the underlying library. In our case the wrapper is going to be very simple; I just want to show you how do it.\u00a0 All I am going to do is expose how to create a new barcode image.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>iOS Wrapper<\/strong><\/span><br \/>\nSo first we need to create a zxing.ios.js file (please notice in my package.json I set the main key to \"zxing.js\").\u00a0 NativeScript will automatically RENAME the .ios. version of the plugin when it is building your app on the iOS platform and strip out the .ios; so the file will become zxing.js automatically.<\/p>\n<p>This file is a simple constructor that literally does nothing as I am trying to keep this example very simple.<br \/>\n<pre>function NativeZXing() {\n&nbsp;&nbsp;&nbsp;&nbsp;if (!this instanceof NativeZXing) { \n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return new NativeZXing();\n&nbsp;&nbsp;&nbsp;&nbsp;}\n}<\/pre><br \/>\nI do typically safe guards I try to add all of my plugins.\u00a0 It simplifies usage of the plugin you can actually do \"var zx = NativeZXing();\" forgetting the \"new\" and it will still work since the constructor function will call new for them.\u00a0 Some people prefer to throw an error rather than automatically using new.\u00a0 My policy is in plugins attempt to be as user friendly as possible.<\/p>\n<p>The next step is to create the function that will create a barcode.\u00a0 So looking at the documentation the way to create a CGImage is this code:<br \/>\n<pre>ZXMultiFormatWriter *writer = [ZXMultiFormatWriter writer];\nZXBitMatrix* result = [writer encode:@&quot;A string to encode&quot;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;format:kBarcodeFormatQRCode\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; width:500\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;height:500\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; error:&amp;amp;error;\n&nbsp;&nbsp;CGImageRef image = [[ZXImage imageWithMatrix:result] cgimage];\n<\/pre><br \/>\nSo I decided our function will look like this...<br \/>\n<pre>NativeZXing.prototype.createBarcode = function(options) {\n&nbsp;&nbsp;&nbsp;&nbsp;var encode=&quot;NOTHING&quot;, width=100, height=100, format = this.QR_CODE;\n&nbsp;&nbsp;&nbsp;&nbsp;if (options) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.encode) { encode = options.encode; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.width) { width = options.width; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.height) { height = options.height; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.format) { format = options.format; }\n&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;var error = new interop.Reference();\n&nbsp;&nbsp;&nbsp;&nbsp;var writer = ZXMultiFormatWriter.writer();\n&nbsp;&nbsp;&nbsp;&nbsp;var result = writer.encodeFormatWidthHeightError(encode, format, width, height, error);\n&nbsp;&nbsp;&nbsp;&nbsp;\n&nbsp;&nbsp;&nbsp;&nbsp;if (result) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return UIImage.alloc().initWithCGImage(ZXImage.imageWithMatrix(result).cgimage);\n&nbsp;&nbsp;&nbsp;&nbsp;} else {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;return error.localizedDescription().toString();\n&nbsp;&nbsp;&nbsp;&nbsp;}\n};<\/pre><br \/>\nThis first 7 lines are pretty simple; they set the defaults and allows the options dictionary to override the defaults.\u00a0 These might be better as properties on the object, but for simplicity they are parameters.\u00a0\u00a0 The next line might not be so obvious; \"<em>var error = new interop.Reference();<\/em>\" In ObjectiveC anytime we need to pass a pointer\/reference for <a href=\"http:\/\/docs.nativescript.org\/runtimes\/ios\/marshalling\/Marshalling-Overview.html#nserror--marshalling\" target=\"_blank\" rel=\"noopener noreferrer\">marshalling<\/a> into a runtime function call we need to create a reference.\u00a0 If you look up above in the example; you will see error being passed as <em>&amp;error<\/em>.\u00a0 That\u00a0 told me I needed to pre-create the reference so I could pass it in and get the result.\u00a0\u00a0 In most cases you can just pass <em>null<\/em> instead of an <em>interop.Reference()<\/em> if you don't want the results; but in this case I decided to capture the error.<\/p>\n<p>The next line is an easy conversion; the Documentation says <em>*writer = [ZXMultiFormatWriter writer]<\/em> this converted into NativeScript is simply <em>var writer = ZXMultiFormatWriter.writer(); <\/em><\/p>\n<p>The following line is a lot more complex to parse and really makes you have to think about how to convert it.\u00a0 So looking at the <em>[writer encode:@\"A string to encode\" format:kBarcodeFormatQRCode width:500 height:500 error:&amp;error].<\/em> The rule is the first parameter is ignored, lets parse this.\u00a0 The NativeScript code starts with <em>writer.encode<\/em> since that is the iOS call.\u00a0 Skip the first parameter, then the next parameter is \"format\" so we append a proper cased \"Format\" to the <em>writer.encode<\/em> to make it <em>writer.encodeFormat<\/em>. We proceed through each of the following parameters and appending a proper cased version.\u00a0 So the call finally ends up being <em>writer.encodeFormatWidthHeightError(... params ...);<\/em> Once you understand how it isn't too bad to parse.\u00a0 However, the issue can be if the documentation is wrong and their are other parameters.\u00a0 You MUST have every parameter accounted for in the function name for the NativeScript to be able to marshall the call into the iOS runtimes.<\/p>\n<p>The next line just checks to see if we got a result; if so we convert it to an image or we return the error.\u00a0 To convert the result into an image the next line is <em>[[ZXImage imageWithMatrix:result] cgimage]\u00a0<\/em> Again, the calls are not to hard to parse so this one ends up being; <em>var image = ZXImage.imageWithMatix(result).cgimage;<\/em><\/p>\n<p>Now in our plugin case I actually converted the CGImage into a UImage since all the NativeScript code seems to use UImage's.\u00a0 So that the extra <em>UIImage.alloc().initWithCGImage()<\/em> code that I added.<\/p>\n<p>The last two things I add to the wrapper are any ENUM or FEATURE flags, to keep consistency for your application code.\u00a0\u00a0 For example the format of the barcode can be chosen using format parameter.\u00a0\u00a0 Would your really want to add to you *application* code like\u00a0 ZXBarcodeFormat.kBarcodeFormatQRCode; for iOS and com.google.zxing.BarcodeFormat.QR_CODE for android to determine that you are using QR code barcodes?\u00a0\u00a0 No, me either.\u00a0 So I wrap the feature flags into JS feature flags like so:<br \/>\n<pre>NativeZXing.QR_CODE = NativeZXing.prototype.QR_CODE = ZXBarcodeFormat.kBarcodeFormatQRCode;<\/pre><br \/>\nIn this case since ZXing appears to only have a barcode types as the feature flags; I attach them directly.\u00a0\u00a0 But if ZXing had a lot of different features I would do something like this:<br \/>\n<pre>BARCODE = {QR_CODE: ZXBarcodeFormat.kBarcodeFormatQRCode,...};\nNativeZXing.BARCODE = NativeZXing.prototype.BARCODE = BARCODE<\/pre><br \/>\nAnd finally we next to export the entire module with this code:<br \/>\n<pre>module.exports = NativeZXing;<\/pre><br \/>\nAwesome the code is complete on iOS.\u00a0 When you<em> createBarcode({encode: \"Hi\"});<\/em> you will get a UImage back on iOS.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Android Wrapper<\/strong><\/span><br \/>\nJust like we did on iOS; we create a file called zxing.android.js.\u00a0 In this file we have the exact same constructor, it also has the same module export statement.\u00a0 However the actual code to generate the Image is different.\u00a0 So here is the Android version.<br \/>\n<pre>NativeZXing.prototype.createBarcode = function(options) {\n&nbsp;&nbsp; var encode=&quot;NOTHING&quot;, width=100, height=100, format = this.QR_CODE;\n&nbsp;&nbsp; if (options) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.encode) { encode = options.encode; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.width) { width = options.width; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.height) { height = options.height; }\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if (options.format) { format = options.format; }\n&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;var hints = null;\n&nbsp;&nbsp;&nbsp;&nbsp;var writer = new com.google.zxing.MultiFormatWriter();\n&nbsp;&nbsp;&nbsp;&nbsp;var result = writer.encode(encode, format, width, height, hints);\n&nbsp;&nbsp;&nbsp;&nbsp;width = result.getWidth();\n&nbsp;&nbsp;&nbsp;&nbsp;height = result.getHeight();\n&nbsp;&nbsp;&nbsp;&nbsp;var pixels = [];\n&nbsp;&nbsp;&nbsp;&nbsp;for (var y=0;y&amp;lt;height;y++) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;var offset = y*width;\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;for (var x=0;x&amp;lt;width;x++) {\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;pixels[offset+x] = result.get(x,y) ? 0xFF000000 : 0xFFFFFFFF;&nbsp;&nbsp;\/\/ Black : White\n&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;}\n&nbsp;&nbsp;&nbsp;&nbsp;var bitmap = android.graphics.Bitmap.createBitmap(width, height, android.graphics.Bitmap.Config.ARGB_8888);\n&nbsp;&nbsp;&nbsp;&nbsp;bitmap.setPixels(pixels, 0, width, 0, 0, width, height);\n&nbsp;&nbsp;&nbsp;&nbsp;return bitmap;\n};<\/pre><br \/>\nAs you can see the first 7 lines are the same.\u00a0 However, the writer line is different.\u00a0 Typically the documentation will tell where in the namespace the function resides.\u00a0 In this case I actually looked at the <a href=\"https:\/\/github.com\/zxing\/zxing\/blob\/master\/core\/src\/main\/java\/com\/google\/zxing\/MultiFormatWriter.java\" target=\"_blank\" rel=\"noopener noreferrer\">source <\/a>code to determine where the MultiFormatWriter function was at.\u00a0 It showed it was using \"<em>package <\/em><span class=\"pl-smi\"><em>com.google.zxing<\/em>\" namespace and is a class called <span class=\"pl-en\">MultiFormatWriter<\/span>.\u00a0\u00a0\u00a0 So that is converted to <em>var writer = new com.google.zxing.MultiFormatWriter();<\/em> The next line is equally simple since we are looking at the source code (Documentation is typically easier, but in this case the source was quicker). So it is called exactly as it is displayed in the source code: <em>var result = writer.encode(encode, format, width, height, hints); <\/em><\/span><\/p>\n<p>The examples I found on how to use MultiFormatWriter and convert it to an image; showed us basically scanning the result set and generating a simple pixel array. Creating a new Bitmap; and then you pass that array into your new bitmaps' setPixels function.\u00a0\u00a0 Converting that code to JS was trivial as basically all you need to do is go to the android <a href=\"http:\/\/developer.android.com\/reference\/android\/graphics\/Bitmap.html\" target=\"_blank\" rel=\"noopener noreferrer\">documentation <\/a>and find out the full namespace for the things.\u00a0 So the code <em>Bitmap.createBitmap<\/em> becomes <em>android.graphics.Bitmap.createBitmap<\/em>.\u00a0 And <em>Bitmap.Config.ARGB_8888<\/em> also gets prefixed with <em>android,graphics. <\/em>to become <em>android,graphics.Bitmap.Config.ARGB_8888<\/em>.<\/p>\n<p>The last thing we do is add our enum value for the Android side to our QR_CODE source<br \/>\n<pre>NativeZXing.QR_CODE = NativeZXing.prototype.QR_CODE = com.google.zxing.BarcodeFormat.QR_CODE;<\/pre><br \/>\nAgain, this keeps it so that in the application you can easily just use ZXing.QR_CODE and never have to worry about the actually underlying platform value.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Creating the readme.md<a href=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android.png\" rel=\"attachment wp-att-172\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-172\" src=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android-169x300.png\" alt=\"android\" width=\"169\" height=\"300\" srcset=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android-169x300.png 169w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android-768x1365.png 768w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android-576x1024.png 576w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android-624x1109.png 624w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/android.png 1080w\" sizes=\"auto, (max-width: 169px) 100vw, 169px\" \/><\/a><a href=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/ios.png\" rel=\"attachment wp-att-170\"><img loading=\"lazy\" decoding=\"async\" class=\"alignright size-medium wp-image-170\" src=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/ios-169x300.png\" alt=\"ios\" width=\"169\" height=\"300\" srcset=\"http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/ios-169x300.png 169w, http:\/\/fluentreports.com\/blog\/wp-content\/uploads\/2016\/01\/ios.png 375w\" sizes=\"auto, (max-width: 169px) 100vw, 169px\" \/><\/a><\/strong><\/span><br \/>\nThe next thing you need to do is create documentation; people need to understand how use you plugin.\u00a0 If you can create a demo that is even better.\u00a0 For example for this sample plugin I created a simple demo that lets you type in anything; and it will give you the QR code for it.\u00a0 You can use the demo to help implement the plugin if the instructions aren't enough.<\/p>\n<p><span style=\"text-decoration: underline;\"><strong>Wrapping it up<\/strong><\/span><br \/>\nThe final things you need to do is create a repo; and commit your code. \u00a0 If it is public publish it to npm so that everyone else can use it.\u00a0\u00a0 If this is a private plugin; you can do <strong>tns plugin add \/path\/to\/plugin<\/strong> to install it.\u00a0\u00a0 For example this plugin's repo is: <a href=\"https:\/\/github.com\/NathanaelA\/nativescript-zxing\" target=\"_blank\" rel=\"noopener noreferrer\">https:\/\/github.com\/NathanaelA\/nativescript-zxing<\/a> and can be installed via <strong>tns plugin add nativescript-zxing.<\/strong><\/p>\n<p>If you have any ideas on future blog posts; please feel free to comment.<\/p>\n<h1><strong>UPDATE<\/strong><\/h1>\n<p>The newer layout for plugins because of some changes in NPM is to do the following:<\/p>\n<p>\/demo\u00a0 &lt;--\u00a0 Your demo goes in here<br \/>\n\/src &lt;- Everything else (i.e. what was at the root directory) goes in here.<\/p>\n<p>So then all plugin source code now is in the <strong>src<\/strong> folder; then you can do <strong>tns plugin add ..\/src<\/strong> to add it to your demo.\u00a0 \u00a0 Do NOT leave the plugin source at the root anymore -- this will cause building of your demo to fail.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>(Please make sure to read the update at the bottom of the post) So, I was minding my own business last week, by reading about everyone's issues in the NativeScript forum.\u00a0 Well, ok, so I wasn't minding my own business, we can pretend I was... So, I saw this post about CodeSign error: entitlements are&hellip; <a class=\"more-link\" href=\"http:\/\/fluentreports.com\/blog\/?p=167\">Continue reading <span class=\"screen-reader-text\">Creating a plugin using third party code<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","footnotes":""},"categories":[15,51],"tags":[16,34],"class_list":["post-167","post","type-post","status-publish","format-standard","hentry","category-nativescript","category-plugins","tag-nativescript","tag-plugins","entry"],"_links":{"self":[{"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=167"}],"version-history":[{"count":9,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/167\/revisions"}],"predecessor-version":[{"id":730,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/167\/revisions\/730"}],"wp:attachment":[{"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=167"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/fluentreports.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}