@aigens/aigens-sdk-core 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,7 @@ npx cap sync
16
16
  * [`echo(...)`](#echo)
17
17
  * [`finish(...)`](#finish)
18
18
  * [`openBrowser(...)`](#openbrowser)
19
+ * [`scan(...)`](#scan)
19
20
 
20
21
  </docgen-index>
21
22
 
@@ -66,4 +67,19 @@ openBrowser(options: any) => Promise<any>
66
67
 
67
68
  --------------------
68
69
 
70
+
71
+ ### scan(...)
72
+
73
+ ```typescript
74
+ scan(options: any) => Promise<any>
75
+ ```
76
+
77
+ | Param | Type |
78
+ | ------------- | ---------------- |
79
+ | **`options`** | <code>any</code> |
80
+
81
+ **Returns:** <code>Promise&lt;any&gt;</code>
82
+
83
+ --------------------
84
+
69
85
  </docgen-api>
@@ -52,6 +52,10 @@ dependencies {
52
52
  implementation fileTree(dir: 'libs', include: ['*.jar'])
53
53
  implementation project(':capacitor-android')
54
54
  implementation "androidx.appcompat:appcompat:$androidxAppCompatVersion"
55
+
56
+ implementation('com.journeyapps:zxing-android-embedded:4.3.0') { transitive = false }
57
+ implementation 'com.google.zxing:core:3.3.0'
58
+
55
59
  testImplementation "junit:junit:$junitVersion"
56
60
  androidTestImplementation "androidx.test.ext:junit:$androidxJunitVersion"
57
61
  androidTestImplementation "androidx.test.espresso:espresso-core:$androidxEspressoCoreVersion"
@@ -2,7 +2,13 @@ package com.aigens.sdk;
2
2
 
3
3
  import android.content.Intent;
4
4
  import android.content.res.AssetManager;
5
+ import android.graphics.Bitmap;
6
+ import android.net.Uri;
5
7
  import android.os.Bundle;
8
+ import android.webkit.WebResourceRequest;
9
+ import android.webkit.WebResourceResponse;
10
+ import android.webkit.WebView;
11
+ import android.webkit.WebViewClient;
6
12
 
7
13
  import com.getcapacitor.BridgeActivity;
8
14
  import com.getcapacitor.CapConfig;
@@ -32,9 +38,9 @@ public class WebContainerActivity extends BridgeActivity {
32
38
  Intent intent = getIntent();
33
39
  String url = intent.getStringExtra("URL");
34
40
 
35
- System.err.println("URL INPUT:"+ url);
41
+ System.out.println("OPEN URL:"+ url);
36
42
 
37
- if(url != null){
43
+ if(url == null){
38
44
  System.err.println("CONFIG ERROR MISSING NATIVE URL");
39
45
  }
40
46
 
@@ -60,7 +66,7 @@ public class WebContainerActivity extends BridgeActivity {
60
66
  for(Class c: auto){
61
67
 
62
68
  String clsName = c.getName();
63
- System.err.println("auto loaded plugins:" + clsName);
69
+ //System.err.println("auto loaded plugins:" + clsName);
64
70
 
65
71
  if(clsName.endsWith("SplashScreenPlugin")){
66
72
  //don't add the splash screen plugin so it doesn't show the splash screen again
@@ -76,10 +82,11 @@ public class WebContainerActivity extends BridgeActivity {
76
82
  //plugins.add(AppPlugin.class);
77
83
  //plugins.add(GeolocationPlugin.class);
78
84
 
79
-
80
-
81
85
  super.init(savedInstanceState, plugins, cc);
82
86
 
87
+ //still have time to override webview client to avoid any intercept
88
+ BypassWebViewClient wvc = new BypassWebViewClient();
89
+ this.bridge.getWebView().setWebViewClient(wvc);
83
90
 
84
91
  }
85
92
 
@@ -146,4 +153,38 @@ public class WebContainerActivity extends BridgeActivity {
146
153
  }
147
154
  }
148
155
 
156
+ //BridgeWebViewClient
157
+ class BypassWebViewClient extends WebViewClient {
158
+
159
+ @Override
160
+ public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
161
+
162
+ return null;
163
+ }
164
+
165
+
166
+ @Override
167
+ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
168
+ //System.err.println("shouldOverrideUrlLoading:" + request.getUrl());
169
+ //Uri url = request.getUrl();
170
+ return false;
171
+ }
172
+
173
+ @Override
174
+ public boolean shouldOverrideUrlLoading(WebView view, String url) {
175
+ //System.err.println("shouldOverrideUrlLoadingOld:" + url);
176
+ //return bridge.launchIntent(Uri.parse(url));
177
+ return false;
178
+ }
179
+
180
+ @Override
181
+ public void onPageStarted(WebView view, String url, Bitmap favicon) {
182
+
183
+ //System.err.println("onPageStarted:" + url);
184
+
185
+ //super.onPageStarted(view, url, favicon);
186
+
187
+ }
188
+ }
189
+
149
190
  }
@@ -3,16 +3,28 @@ package com.aigens.sdk.plugins;
3
3
  import android.app.Activity;
4
4
  import android.content.Intent;
5
5
 
6
+ import androidx.activity.result.ActivityResultLauncher;
7
+ import androidx.appcompat.app.AppCompatActivity;
8
+
6
9
  import com.aigens.sdk.WebContainerActivity;
7
10
  import com.getcapacitor.JSObject;
8
11
  import com.getcapacitor.Plugin;
9
12
  import com.getcapacitor.PluginCall;
10
13
  import com.getcapacitor.PluginMethod;
11
14
  import com.getcapacitor.annotation.CapacitorPlugin;
15
+ import com.journeyapps.barcodescanner.ScanContract;
16
+ import com.journeyapps.barcodescanner.ScanOptions;
12
17
 
13
18
  @CapacitorPlugin(name = "Core")
14
19
  public class CorePlugin extends Plugin {
15
20
 
21
+
22
+ @Override
23
+ protected void handleOnStart(){
24
+
25
+ prepareScan();
26
+ }
27
+
16
28
  @PluginMethod()
17
29
  public void echo(PluginCall call) {
18
30
  String value = call.getString("value");
@@ -22,6 +34,89 @@ public class CorePlugin extends Plugin {
22
34
  call.resolve(ret);
23
35
  }
24
36
 
37
+ private PluginCall scanCall;
38
+
39
+ @PluginMethod()
40
+ public void scan(PluginCall call) {
41
+
42
+ System.err.println("SCANNING!!");
43
+
44
+ this.scanCall = call;
45
+ scanRaw();
46
+
47
+
48
+ }
49
+
50
+ // Register the launcher and result handler
51
+
52
+ private ActivityResultLauncher<ScanOptions> barcodeLauncher;
53
+
54
+ private void prepareScan(){
55
+
56
+ AppCompatActivity act = getActivity();
57
+
58
+ barcodeLauncher = act.registerForActivityResult(new ScanContract(),
59
+ result -> {
60
+
61
+ if(scanCall == null){
62
+ System.err.println("Missing scan callback");
63
+ return;
64
+ }
65
+
66
+ if(result.getContents() == null) {
67
+ //Toast.makeText(MyActivity.this, "Cancelled", Toast.LENGTH_LONG).show();
68
+ System.err.println("scan cancelled");
69
+ JSObject ret = new JSObject();
70
+ ret.put("hasContent", false);
71
+ ret.put("success", false);
72
+ scanCall.resolve(ret);
73
+ } else {
74
+ //Toast.makeText(MyActivity.this, "Scanned: " + result.getContents(), Toast.LENGTH_LONG).show();
75
+ String val = result.getContents();
76
+
77
+ System.err.println("scan result:" + val);
78
+
79
+ if(val != null && val.length() > 0){
80
+
81
+ JSObject ret = new JSObject();
82
+ ret.put("content", val);
83
+ ret.put("hasContent", true);
84
+ ret.put("success", true);
85
+ scanCall.resolve(ret);
86
+ }else{
87
+
88
+ JSObject ret = new JSObject();
89
+ ret.put("hasContent", false);
90
+ ret.put("success", false);
91
+ scanCall.resolve(ret);
92
+ }
93
+
94
+
95
+
96
+ }
97
+ scanCall = null;
98
+ });
99
+ }
100
+
101
+ private void scanRaw(){
102
+
103
+ ScanOptions options = new ScanOptions();
104
+ //options.setDesiredBarcodeFormats(ScanOptions.ONE_D_CODE_TYPES);
105
+ options.setPrompt("");
106
+ //options.setCameraId(0); // Use a specific camera of the device
107
+ options.setBeepEnabled(false);
108
+ options.setOrientationLocked(false);
109
+ options.setBarcodeImageEnabled(true);
110
+
111
+ //options.setBarcodeImageEnabled(true);
112
+ barcodeLauncher.launch(options);
113
+ }
114
+
115
+ // Launch
116
+ //public void onButtonClick(View view) {
117
+ // barcodeLauncher.launch(new ScanOptions());
118
+ //}
119
+
25
120
  @PluginMethod()
26
121
  public void finish(PluginCall call) {
27
122
 
package/dist/docs.json CHANGED
@@ -52,6 +52,22 @@
52
52
  "docs": "",
53
53
  "complexTypes": [],
54
54
  "slug": "openbrowser"
55
+ },
56
+ {
57
+ "name": "scan",
58
+ "signature": "(options: any) => Promise<any>",
59
+ "parameters": [
60
+ {
61
+ "name": "options",
62
+ "docs": "",
63
+ "type": "any"
64
+ }
65
+ ],
66
+ "returns": "Promise<any>",
67
+ "tags": [],
68
+ "docs": "",
69
+ "complexTypes": [],
70
+ "slug": "scan"
55
71
  }
56
72
  ],
57
73
  "properties": []
@@ -2,4 +2,5 @@ export interface CorePlugin {
2
2
  echo(options: any): Promise<any>;
3
3
  finish(options: any): Promise<any>;
4
4
  openBrowser(options: any): Promise<any>;
5
+ scan(options: any): Promise<any>;
5
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CorePlugin {\n echo(options: any): Promise<any>;\n finish(options: any): Promise<any>;\n openBrowser(options: any): Promise<any>;\n}\n"]}
1
+ {"version":3,"file":"definitions.js","sourceRoot":"","sources":["../../src/definitions.ts"],"names":[],"mappings":"","sourcesContent":["export interface CorePlugin {\n echo(options: any): Promise<any>;\n finish(options: any): Promise<any>;\n openBrowser(options: any): Promise<any>;\n scan(options: any): Promise<any>;\n}\n"]}
package/dist/esm/web.d.ts CHANGED
@@ -4,4 +4,5 @@ export declare class CoreWeb extends WebPlugin implements CorePlugin {
4
4
  echo(options: any): Promise<any>;
5
5
  finish(options: any): Promise<any>;
6
6
  openBrowser(options: any): Promise<any>;
7
+ scan(options: any): Promise<any>;
7
8
  }
package/dist/esm/web.js CHANGED
@@ -12,5 +12,9 @@ export class CoreWeb extends WebPlugin {
12
12
  console.log(options);
13
13
  throw new Error('Method not implemented.');
14
14
  }
15
+ async scan(options) {
16
+ console.log(options);
17
+ throw new Error('Method not implemented.');
18
+ }
15
19
  }
16
20
  //# sourceMappingURL=web.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,OAAQ,SAAQ,SAAS;IAClC,KAAK,CAAC,IAAI,CAAC,OAAY;QACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAY;QACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAY;QAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC/C,CAAC;CACJ","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { CorePlugin } from './definitions';\n\nexport class CoreWeb extends WebPlugin implements CorePlugin {\n async echo(options: any): Promise<any> {\n console.log('ECHO', options);\n return options;\n }\n\n async finish(options: any): Promise<any> {\n console.log('FINISH', options);\n return options;\n }\n\n async openBrowser(options: any): Promise<any> {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n"]}
1
+ {"version":3,"file":"web.js","sourceRoot":"","sources":["../../src/web.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAI5C,MAAM,OAAO,OAAQ,SAAQ,SAAS;IAClC,KAAK,CAAC,IAAI,CAAC,OAAY;QACnB,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC7B,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,OAAY;QACrB,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;QAC/B,OAAO,OAAO,CAAC;IACnB,CAAC;IAED,KAAK,CAAC,WAAW,CAAC,OAAY;QAC1B,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,OAAY;QACnB,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;QACrB,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IAC/C,CAAC;CACJ","sourcesContent":["import { WebPlugin } from '@capacitor/core';\n\nimport type { CorePlugin } from './definitions';\n\nexport class CoreWeb extends WebPlugin implements CorePlugin {\n async echo(options: any): Promise<any> {\n console.log('ECHO', options);\n return options;\n }\n\n async finish(options: any): Promise<any> {\n console.log('FINISH', options);\n return options;\n }\n\n async openBrowser(options: any): Promise<any> {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n\n async scan(options: any): Promise<any> {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n"]}
@@ -21,6 +21,10 @@ class CoreWeb extends core.WebPlugin {
21
21
  console.log(options);
22
22
  throw new Error('Method not implemented.');
23
23
  }
24
+ async scan(options) {
25
+ console.log(options);
26
+ throw new Error('Method not implemented.');
27
+ }
24
28
  }
25
29
 
26
30
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Core = registerPlugin('Core', {\n web: () => import('./web').then(m => new m.CoreWeb()),\n});\nexport * from './definitions';\nexport { Core };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CoreWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n async finish(options) {\n console.log('FINISH', options);\n return options;\n }\n async openBrowser(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;;;AACK,MAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;AACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACzD,CAAC;;ACFM,MAAM,OAAO,SAASC,cAAS,CAAC;AACvC,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL,IAAI,MAAM,MAAM,CAAC,OAAO,EAAE;AAC1B,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;AAC/B,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;AACnD,KAAK;AACL;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.cjs.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Core = registerPlugin('Core', {\n web: () => import('./web').then(m => new m.CoreWeb()),\n});\nexport * from './definitions';\nexport { Core };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CoreWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n async finish(options) {\n console.log('FINISH', options);\n return options;\n }\n async openBrowser(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n async scan(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;;;;AACK,MAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;AACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;AACzD,CAAC;;ACFM,MAAM,OAAO,SAASC,cAAS,CAAC;AACvC,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AACrC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL,IAAI,MAAM,MAAM,CAAC,OAAO,EAAE;AAC1B,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;AACvC,QAAQ,OAAO,OAAO,CAAC;AACvB,KAAK;AACL,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;AAC/B,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;AACnD,KAAK;AACL,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;AACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;AAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;AACnD,KAAK;AACL;;;;;;;;;"}
package/dist/plugin.js CHANGED
@@ -18,6 +18,10 @@ var capacitorCore = (function (exports, core) {
18
18
  console.log(options);
19
19
  throw new Error('Method not implemented.');
20
20
  }
21
+ async scan(options) {
22
+ console.log(options);
23
+ throw new Error('Method not implemented.');
24
+ }
21
25
  }
22
26
 
23
27
  var web = /*#__PURE__*/Object.freeze({
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Core = registerPlugin('Core', {\n web: () => import('./web').then(m => new m.CoreWeb()),\n});\nexport * from './definitions';\nexport { Core };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CoreWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n async finish(options) {\n console.log('FINISH', options);\n return options;\n }\n async openBrowser(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;IACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;;ICFM,MAAM,OAAO,SAASC,cAAS,CAAC;IACvC,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL,IAAI,MAAM,MAAM,CAAC,OAAO,EAAE;IAC1B,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;IAC/B,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"plugin.js","sources":["esm/index.js","esm/web.js"],"sourcesContent":["import { registerPlugin } from '@capacitor/core';\nconst Core = registerPlugin('Core', {\n web: () => import('./web').then(m => new m.CoreWeb()),\n});\nexport * from './definitions';\nexport { Core };\n//# sourceMappingURL=index.js.map","import { WebPlugin } from '@capacitor/core';\nexport class CoreWeb extends WebPlugin {\n async echo(options) {\n console.log('ECHO', options);\n return options;\n }\n async finish(options) {\n console.log('FINISH', options);\n return options;\n }\n async openBrowser(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n async scan(options) {\n console.log(options);\n throw new Error('Method not implemented.');\n }\n}\n//# sourceMappingURL=web.js.map"],"names":["registerPlugin","WebPlugin"],"mappings":";;;AACK,UAAC,IAAI,GAAGA,mBAAc,CAAC,MAAM,EAAE;IACpC,IAAI,GAAG,EAAE,MAAM,mDAAe,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;IACzD,CAAC;;ICFM,MAAM,OAAO,SAASC,cAAS,CAAC;IACvC,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACrC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL,IAAI,MAAM,MAAM,CAAC,OAAO,EAAE;IAC1B,QAAQ,OAAO,CAAC,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IACvC,QAAQ,OAAO,OAAO,CAAC;IACvB,KAAK;IACL,IAAI,MAAM,WAAW,CAAC,OAAO,EAAE;IAC/B,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL,IAAI,MAAM,IAAI,CAAC,OAAO,EAAE;IACxB,QAAQ,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC7B,QAAQ,MAAM,IAAI,KAAK,CAAC,yBAAyB,CAAC,CAAC;IACnD,KAAK;IACL;;;;;;;;;;;;;;;;;"}
@@ -7,4 +7,5 @@ CAP_PLUGIN(CorePlugin, "Core",
7
7
  CAP_PLUGIN_METHOD(echo, CAPPluginReturnPromise);
8
8
  CAP_PLUGIN_METHOD(finish, CAPPluginReturnPromise);
9
9
  CAP_PLUGIN_METHOD(openBrowser, CAPPluginReturnPromise);
10
+ CAP_PLUGIN_METHOD(scan, CAPPluginReturnPromise);
10
11
  )
@@ -1,18 +1,18 @@
1
1
  import Foundation
2
2
  import Capacitor
3
+ import AVFoundation
4
+ import UIKit
3
5
 
4
6
  /**
5
7
  * Please read the Capacitor iOS Plugin Development Guide
6
8
  * here: https://capacitorjs.com/docs/plugins/ios
7
9
  */
8
10
  @objc(CorePlugin)
9
- public class CorePlugin: CAPPlugin {
11
+ public class CorePlugin: CAPPlugin, AVCaptureMetadataOutputObjectsDelegate {
10
12
  private let implementation = Core()
11
13
 
12
14
  @objc func echo(_ call: CAPPluginCall) {
13
15
 
14
- print("ECHO CALLED")
15
-
16
16
  let value = call.getString("value") ?? ""
17
17
  call.resolve([
18
18
  "value": implementation.echo(value)
@@ -22,8 +22,6 @@ public class CorePlugin: CAPPlugin {
22
22
 
23
23
  @objc func finish(_ call: CAPPluginCall) {
24
24
 
25
- print("FINISH CALLED")
26
-
27
25
  DispatchQueue.main.async {
28
26
  self.bridge?.viewController?.dismiss(animated: true);
29
27
  }
@@ -36,6 +34,21 @@ public class CorePlugin: CAPPlugin {
36
34
  ])
37
35
  }
38
36
 
37
+ @objc func scan(_ call: CAPPluginCall) {
38
+
39
+ let cancelButton = call.getString("cancelButton")
40
+ if(cancelButton != nil){
41
+ self.cancelText = cancelButton!
42
+ }else{
43
+ self.cancelText = "Cancel"
44
+ }
45
+
46
+ DispatchQueue.main.async {
47
+ self.loadScan()
48
+ self.startScan(call)
49
+ }
50
+ }
51
+
39
52
 
40
53
  @objc func openBrowser(_ call: CAPPluginCall) {
41
54
 
@@ -48,8 +61,6 @@ public class CorePlugin: CAPPlugin {
48
61
 
49
62
  DispatchQueue.main.async {
50
63
 
51
- print("OPEN RUN", url!)
52
-
53
64
  let bridgeVC = WebContainerViewController()
54
65
 
55
66
  var options = [String: AnyObject]()
@@ -68,4 +79,636 @@ public class CorePlugin: CAPPlugin {
68
79
  //"value": implementation.echo(value)
69
80
  ])
70
81
  }
82
+
83
+ //SCAN PLAUGIN HERE
84
+
85
+ class CameraView: UIView {
86
+ var videoPreviewLayer:AVCaptureVideoPreviewLayer?
87
+
88
+ func interfaceOrientationToVideoOrientation(_ orientation : UIInterfaceOrientation) -> AVCaptureVideoOrientation {
89
+ switch (orientation) {
90
+ case UIInterfaceOrientation.portrait:
91
+ return AVCaptureVideoOrientation.portrait
92
+ case UIInterfaceOrientation.portraitUpsideDown:
93
+ return AVCaptureVideoOrientation.portraitUpsideDown
94
+ case UIInterfaceOrientation.landscapeLeft:
95
+ return AVCaptureVideoOrientation.landscapeLeft
96
+ case UIInterfaceOrientation.landscapeRight:
97
+ return AVCaptureVideoOrientation.landscapeRight
98
+ default:
99
+ return AVCaptureVideoOrientation.portraitUpsideDown
100
+ }
101
+ }
102
+
103
+ override func layoutSubviews() {
104
+ super.layoutSubviews()
105
+ if let sublayers = self.layer.sublayers {
106
+ for layer in sublayers {
107
+ layer.frame = self.bounds
108
+ }
109
+ }
110
+
111
+ self.videoPreviewLayer?.connection?.videoOrientation = interfaceOrientationToVideoOrientation(UIApplication.shared.statusBarOrientation)
112
+ }
113
+
114
+
115
+ func addPreviewLayer(_ previewLayer:AVCaptureVideoPreviewLayer?) {
116
+ previewLayer!.videoGravity = AVLayerVideoGravity.resizeAspectFill
117
+ previewLayer!.frame = self.bounds
118
+ self.layer.addSublayer(previewLayer!)
119
+ self.videoPreviewLayer = previewLayer
120
+ }
121
+
122
+ func removePreviewLayer() {
123
+ if self.videoPreviewLayer != nil {
124
+ self.videoPreviewLayer!.removeFromSuperlayer()
125
+ self.videoPreviewLayer = nil
126
+ }
127
+ }
128
+ }
129
+
130
+ var cameraView: CameraView!
131
+ var cancelButton: UIButton!
132
+ var captureSession:AVCaptureSession?
133
+ var captureVideoPreviewLayer:AVCaptureVideoPreviewLayer?
134
+ var metaOutput: AVCaptureMetadataOutput?
135
+
136
+ var currentCamera: Int = 0
137
+ var frontCamera: AVCaptureDevice?
138
+ var backCamera: AVCaptureDevice?
139
+
140
+ var cancelText: String = "Cancel"
141
+ var isScanning: Bool = false
142
+ var shouldRunScan: Bool = false
143
+ var didRunCameraSetup: Bool = false
144
+ var didRunCameraPrepare: Bool = false
145
+ var isBackgroundHidden: Bool = false
146
+
147
+ var savedCall: CAPPluginCall? = nil
148
+ var scanningPaused: Bool = false
149
+ var lastScanResult: String? = nil
150
+
151
+ enum SupportedFormat: String, CaseIterable {
152
+ // 1D Product
153
+ //!\ UPC_A is part of EAN_13 according to Apple docs
154
+ case UPC_E
155
+ //!\ UPC_EAN_EXTENSION is not supported by AVFoundation
156
+ case EAN_8
157
+ case EAN_13
158
+ // 1D Industrial
159
+ case CODE_39
160
+ case CODE_39_MOD_43
161
+ case CODE_93
162
+ case CODE_128
163
+ //!\ CODABAR is not supported by AVFoundation
164
+ case ITF
165
+ case ITF_14
166
+ // 2D
167
+ case AZTEC
168
+ case DATA_MATRIX
169
+ //!\ MAXICODE is not supported by AVFoundation
170
+ case PDF_417
171
+ case QR_CODE
172
+ //!\ RSS_14 is not supported by AVFoundation
173
+ //!\ RSS_EXPANDED is not supported by AVFoundation
174
+
175
+ var value: AVMetadataObject.ObjectType {
176
+ switch self {
177
+ // 1D Product
178
+ case .UPC_E: return AVMetadataObject.ObjectType.upce
179
+ case .EAN_8: return AVMetadataObject.ObjectType.ean8
180
+ case .EAN_13: return AVMetadataObject.ObjectType.ean13
181
+ // 1D Industrial
182
+ case .CODE_39: return AVMetadataObject.ObjectType.code39
183
+ case .CODE_39_MOD_43: return AVMetadataObject.ObjectType.code39Mod43
184
+ case .CODE_93: return AVMetadataObject.ObjectType.code93
185
+ case .CODE_128: return AVMetadataObject.ObjectType.code128
186
+ case .ITF: return AVMetadataObject.ObjectType.interleaved2of5
187
+ case .ITF_14: return AVMetadataObject.ObjectType.itf14
188
+ // 2D
189
+ case .AZTEC: return AVMetadataObject.ObjectType.aztec
190
+ case .DATA_MATRIX: return AVMetadataObject.ObjectType.dataMatrix
191
+ case .PDF_417: return AVMetadataObject.ObjectType.pdf417
192
+ case .QR_CODE: return AVMetadataObject.ObjectType.qr
193
+ }
194
+ }
195
+ }
196
+
197
+ var targetedFormats = [AVMetadataObject.ObjectType]()
198
+
199
+ enum CaptureError: Error {
200
+ case backCameraUnavailable
201
+ case frontCameraUnavailable
202
+ case couldNotCaptureInput(error: NSError)
203
+ }
204
+
205
+ @objc func buttonTapped( _ button : UIButton)
206
+ {
207
+
208
+ self.destroy()
209
+ }
210
+
211
+
212
+
213
+ private func loadScan() {
214
+
215
+ if(self.cameraView != nil){
216
+ return
217
+ }
218
+
219
+
220
+ self.cameraView = CameraView(frame: CGRect(x: 0, y: 0, width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height))
221
+ self.cameraView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
222
+
223
+ let button = UIButton()
224
+ //button.backgroundColor = UIColor.orange
225
+
226
+ //let iconImage = UIImage(named: "search")
227
+ //button.setImage(iconImage, for: .normal)
228
+
229
+ button.setTitle("< " + self.cancelText, for: .normal)
230
+ button.contentMode = UIView.ContentMode.scaleToFill
231
+ button.frame = CGRect(x: 20, y: 10, width:200 , height:100)
232
+ button.titleLabel?.textColor = UIColor.white
233
+ button.contentHorizontalAlignment = .left
234
+
235
+ button.addTarget(self, action: #selector(self.buttonTapped(_:)), for: UIControl.Event.touchUpInside)
236
+
237
+ self.cancelButton = button
238
+
239
+ }
240
+
241
+ private func hasCameraPermission() -> Bool {
242
+ let status = AVCaptureDevice.authorizationStatus(for: AVMediaType.video)
243
+ if (status == AVAuthorizationStatus.authorized) {
244
+ return true
245
+ }
246
+ return false
247
+ }
248
+
249
+ private func addViews(){
250
+ self.webView!.superview!.insertSubview(cameraView, aboveSubview: self.webView!)
251
+ self.webView!.superview!.insertSubview(cancelButton, aboveSubview: cameraView)
252
+ }
253
+
254
+ private func removeViews(){
255
+
256
+ DispatchQueue.main.async {
257
+ self.cancelButton.removeFromSuperview()
258
+ self.cameraView.removeFromSuperview()
259
+ }
260
+
261
+ }
262
+
263
+ private func setupCamera(cameraDirection: String? = "back") -> Bool {
264
+ do {
265
+ var cameraDir = cameraDirection
266
+ cameraView.backgroundColor = UIColor.clear
267
+ //self.webView!.superview!.insertSubview(cameraView, belowSubview: self.webView!)
268
+
269
+ //self.webView!.superview!.insertSubview(cameraView, aboveSubview: self.webView!)
270
+ //self.webView!.superview!.insertSubview(cancelButton, aboveSubview: cameraView)
271
+ addViews()
272
+
273
+ let availableVideoDevices = discoverCaptureDevices()
274
+ for device in availableVideoDevices {
275
+ if device.position == AVCaptureDevice.Position.back {
276
+ backCamera = device
277
+ }
278
+ else if device.position == AVCaptureDevice.Position.front {
279
+ frontCamera = device
280
+ }
281
+ }
282
+ // older iPods have no back camera
283
+ if (cameraDir == "back") {
284
+ if (backCamera == nil) {
285
+ cameraDir = "front"
286
+ }
287
+ } else {
288
+ if (frontCamera == nil) {
289
+ cameraDir = "back"
290
+ }
291
+ }
292
+ let input: AVCaptureDeviceInput
293
+ input = try self.createCaptureDeviceInput(cameraDirection: cameraDir)
294
+ captureSession = AVCaptureSession()
295
+ captureSession!.addInput(input)
296
+ metaOutput = AVCaptureMetadataOutput()
297
+ captureSession!.addOutput(metaOutput!)
298
+ metaOutput!.setMetadataObjectsDelegate(self, queue: DispatchQueue.main)
299
+ captureVideoPreviewLayer = AVCaptureVideoPreviewLayer(session: captureSession!)
300
+ cameraView.addPreviewLayer(captureVideoPreviewLayer)
301
+ self.didRunCameraSetup = true
302
+ return true
303
+ } catch CaptureError.backCameraUnavailable {
304
+ //
305
+ } catch CaptureError.frontCameraUnavailable {
306
+ //
307
+ } catch CaptureError.couldNotCaptureInput {
308
+ //
309
+ } catch {
310
+ //
311
+ }
312
+ return false
313
+ }
314
+
315
+ @available(swift, deprecated: 5.6, message: "New Xcode? Check if `AVCaptureDevice.DeviceType` has new types and add them accordingly.")
316
+ private func discoverCaptureDevices() -> [AVCaptureDevice] {
317
+ if #available(iOS 13.0, *) {
318
+ return AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInTripleCamera, .builtInDualCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera, .builtInUltraWideCamera, .builtInDualWideCamera, .builtInWideAngleCamera], mediaType: .video, position: .unspecified).devices
319
+ } else {
320
+ return AVCaptureDevice.DiscoverySession(deviceTypes: [.builtInDualCamera, .builtInWideAngleCamera, .builtInTelephotoCamera, .builtInTrueDepthCamera], mediaType: .video, position: .unspecified).devices
321
+ }
322
+ }
323
+
324
+ private func createCaptureDeviceInput(cameraDirection: String? = "back") throws -> AVCaptureDeviceInput {
325
+ var captureDevice: AVCaptureDevice
326
+ if(cameraDirection == "back"){
327
+ if(backCamera != nil){
328
+ captureDevice = backCamera!
329
+ } else {
330
+ throw CaptureError.backCameraUnavailable
331
+ }
332
+ } else {
333
+ if(frontCamera != nil){
334
+ captureDevice = frontCamera!
335
+ } else {
336
+ throw CaptureError.frontCameraUnavailable
337
+ }
338
+ }
339
+ let captureDeviceInput: AVCaptureDeviceInput
340
+ do {
341
+ captureDeviceInput = try AVCaptureDeviceInput(device: captureDevice)
342
+ } catch let error as NSError {
343
+ throw CaptureError.couldNotCaptureInput(error: error)
344
+ }
345
+ return captureDeviceInput
346
+ }
347
+
348
+ private func dismantleCamera() {
349
+ // opposite of setupCamera
350
+
351
+ if (self.captureSession != nil) {
352
+ DispatchQueue.main.async {
353
+ self.captureSession!.stopRunning()
354
+ self.cameraView.removePreviewLayer()
355
+ self.captureVideoPreviewLayer = nil
356
+ self.metaOutput = nil
357
+ self.captureSession = nil
358
+ self.frontCamera = nil
359
+ self.backCamera = nil
360
+ }
361
+ }
362
+
363
+ self.isScanning = false
364
+ self.didRunCameraSetup = false
365
+ self.didRunCameraPrepare = false
366
+
367
+ // If a call is saved and a scan will not run, free the saved call
368
+ if (self.savedCall != nil && !self.shouldRunScan) {
369
+ self.savedCall = nil
370
+ }
371
+ }
372
+
373
+ private func prepare(_ call: CAPPluginCall? = nil) {
374
+ // undo previous setup
375
+ // because it may be prepared with a different config
376
+ self.dismantleCamera()
377
+
378
+ DispatchQueue.main.async {
379
+ // setup camera with new config
380
+ if (self.setupCamera(cameraDirection: call?.getString("cameraDirection") ?? "back")) {
381
+ // indicate this method was run
382
+ self.didRunCameraPrepare = true
383
+
384
+ if (self.shouldRunScan) {
385
+ self.scan()
386
+ }
387
+ } else {
388
+ self.shouldRunScan = false
389
+ }
390
+ }
391
+ }
392
+
393
+ private func destroy() {
394
+
395
+ self.removeViews()
396
+
397
+ self.showBackground()
398
+
399
+ self.dismantleCamera()
400
+ }
401
+
402
+ private func scan() {
403
+ if (!self.didRunCameraPrepare) {
404
+ //In iOS 14 don't identify permissions needed, so force to ask it's better than nothing. Provisional.
405
+ var iOS14min: Bool = false
406
+ if #available(iOS 14.0, *) { iOS14min = true; }
407
+ if (!self.hasCameraPermission() && !iOS14min) {
408
+ // @TODO()
409
+ // requestPermission()
410
+ } else {
411
+ self.shouldRunScan = true
412
+ self.prepare(savedCall)
413
+ }
414
+ } else {
415
+ self.didRunCameraPrepare = false
416
+
417
+ self.shouldRunScan = false
418
+
419
+ targetedFormats = [AVMetadataObject.ObjectType]();
420
+
421
+ if ((savedCall?.options["targetedFormats"]) != nil) {
422
+ let _targetedFormats = savedCall?.getArray("targetedFormats", String.self)
423
+
424
+ if (_targetedFormats != nil && _targetedFormats?.count ?? 0 > 0) {
425
+ _targetedFormats?.forEach { targetedFormat in
426
+ if let value = SupportedFormat(rawValue: targetedFormat)?.value {
427
+ print(value)
428
+ targetedFormats.append(value)
429
+ }
430
+ }
431
+ }
432
+
433
+ if (targetedFormats.count == 0) {
434
+ print("The property targetedFormats was not set correctly.")
435
+ }
436
+ }
437
+
438
+ if (targetedFormats.count == 0) {
439
+ for supportedFormat in SupportedFormat.allCases {
440
+ targetedFormats.append(supportedFormat.value)
441
+ }
442
+ }
443
+
444
+ DispatchQueue.main.async {
445
+ self.metaOutput!.metadataObjectTypes = self.targetedFormats
446
+ self.captureSession!.startRunning()
447
+ }
448
+
449
+ self.hideBackground()
450
+
451
+ self.isScanning = true
452
+ }
453
+ }
454
+
455
+ private func hideBackground() {
456
+ /*
457
+ DispatchQueue.main.async {
458
+ self.bridge?.webView!.isOpaque = false
459
+ self.bridge?.webView!.backgroundColor = UIColor.clear
460
+ self.bridge?.webView!.scrollView.backgroundColor = UIColor.clear
461
+
462
+ let javascript = "document.documentElement.style.backgroundColor = 'transparent'"
463
+
464
+ self.bridge?.webView!.evaluateJavaScript(javascript)
465
+ }*/
466
+ }
467
+
468
+ private func showBackground() {
469
+
470
+ /*
471
+ DispatchQueue.main.async {
472
+ let javascript = "document.documentElement.style.backgroundColor = ''"
473
+
474
+ self.bridge?.webView!.evaluateJavaScript(javascript) { (result, error) in
475
+ self.bridge?.webView!.isOpaque = true
476
+ self.bridge?.webView!.backgroundColor = UIColor.white
477
+ self.bridge?.webView!.scrollView.backgroundColor = UIColor.white
478
+ }
479
+ }*/
480
+ }
481
+
482
+ // This method processes metadataObjects captured by iOS.
483
+ public func metadataOutput(_ captureOutput: AVCaptureMetadataOutput, didOutput metadataObjects: [AVMetadataObject], from connection: AVCaptureConnection) {
484
+
485
+ if (metadataObjects.count == 0 || !self.isScanning) {
486
+ // while nothing is detected, or if scanning is false, do nothing.
487
+ return
488
+ }
489
+
490
+ let found = metadataObjects[0] as! AVMetadataMachineReadableCodeObject
491
+ if (targetedFormats.contains(found.type)) {
492
+ var jsObject = PluginCallResultData()
493
+
494
+ if (found.stringValue != nil) {
495
+ jsObject["hasContent"] = true
496
+ jsObject["content"] = found.stringValue
497
+ jsObject["format"] = formatStringFromMetadata(found.type)
498
+ } else {
499
+ jsObject["hasContent"] = false
500
+ }
501
+
502
+ if (savedCall != nil) {
503
+ if (savedCall!.keepAlive) {
504
+ if (!scanningPaused && found.stringValue != lastScanResult ) {
505
+ lastScanResult = found.stringValue
506
+ savedCall!.resolve(jsObject)
507
+ }
508
+ } else {
509
+ savedCall!.resolve(jsObject)
510
+ savedCall = nil
511
+ destroy()
512
+ }
513
+ } else {
514
+ self.destroy()
515
+ }
516
+ }
517
+ }
518
+
519
+ private func formatStringFromMetadata(_ type: AVMetadataObject.ObjectType) -> String {
520
+ switch type {
521
+ case AVMetadataObject.ObjectType.upce:
522
+ return "UPC_E"
523
+ case AVMetadataObject.ObjectType.ean8:
524
+ return "EAN_8"
525
+ case AVMetadataObject.ObjectType.ean13:
526
+ return "EAN_13"
527
+ case AVMetadataObject.ObjectType.code39:
528
+ return "CODE_39"
529
+ case AVMetadataObject.ObjectType.code39Mod43:
530
+ return "CODE_39_MOD_43"
531
+ case AVMetadataObject.ObjectType.code93:
532
+ return "CODE_93"
533
+ case AVMetadataObject.ObjectType.code128:
534
+ return "CODE_128"
535
+ case AVMetadataObject.ObjectType.interleaved2of5:
536
+ return "ITF"
537
+ case AVMetadataObject.ObjectType.itf14:
538
+ return "ITF_14"
539
+ case AVMetadataObject.ObjectType.aztec:
540
+ return "AZTEC"
541
+ case AVMetadataObject.ObjectType.dataMatrix:
542
+ return "DATA_MATRIX"
543
+ case AVMetadataObject.ObjectType.pdf417:
544
+ return "PDF_417"
545
+ case AVMetadataObject.ObjectType.qr:
546
+ return "QR_CODE"
547
+ default:
548
+ return type.rawValue
549
+ }
550
+ }
551
+
552
+ @objc func prepare(_ call: CAPPluginCall) {
553
+ self.prepare()
554
+ call.resolve()
555
+ }
556
+
557
+ @objc func hideBackground(_ call: CAPPluginCall) {
558
+ self.hideBackground()
559
+ call.resolve()
560
+ }
561
+
562
+ @objc func showBackground(_ call: CAPPluginCall) {
563
+ self.showBackground()
564
+ call.resolve()
565
+ }
566
+
567
+ @objc func startScan(_ call: CAPPluginCall) {
568
+ self.savedCall = call
569
+ self.scan()
570
+ }
571
+
572
+ @objc func startScanning(_ call: CAPPluginCall) {
573
+ self.savedCall = call
574
+ self.savedCall?.keepAlive = true
575
+ scanningPaused = false
576
+ lastScanResult = nil
577
+ self.scan()
578
+ }
579
+
580
+ @objc func pauseScanning(_ call: CAPPluginCall) {
581
+ scanningPaused = true
582
+ call.resolve()
583
+ }
584
+
585
+ @objc func resumeScanning(_ call: CAPPluginCall) {
586
+ scanningPaused = false
587
+ call.resolve()
588
+ }
589
+
590
+ @objc func stopScan(_ call: CAPPluginCall) {
591
+ if ((call.getBool("resolveScan") ?? false) && self.savedCall != nil) {
592
+ var jsObject = PluginCallResultData()
593
+ jsObject["hasContent"] = false
594
+
595
+ savedCall?.resolve(jsObject)
596
+ savedCall = nil
597
+ }
598
+
599
+ self.destroy()
600
+ call.resolve()
601
+ }
602
+
603
+ @objc func checkPermission(_ call: CAPPluginCall) {
604
+ let force = call.getBool("force") ?? false
605
+
606
+ var savedReturnObject = PluginCallResultData()
607
+
608
+ DispatchQueue.main.async {
609
+ switch AVCaptureDevice.authorizationStatus(for: .video) {
610
+ case .authorized:
611
+ savedReturnObject["granted"] = true
612
+ case .denied:
613
+ savedReturnObject["denied"] = true
614
+ case .notDetermined:
615
+ savedReturnObject["neverAsked"] = true
616
+ case .restricted:
617
+ savedReturnObject["restricted"] = true
618
+ @unknown default:
619
+ savedReturnObject["unknown"] = true
620
+ }
621
+
622
+ if (force && savedReturnObject["neverAsked"] != nil) {
623
+ savedReturnObject["asked"] = true
624
+
625
+ AVCaptureDevice.requestAccess(for: .video) { (authorized) in
626
+ if (authorized) {
627
+ savedReturnObject["granted"] = true
628
+ } else {
629
+ savedReturnObject["denied"] = true
630
+ }
631
+ call.resolve(savedReturnObject)
632
+ }
633
+ } else {
634
+ call.resolve(savedReturnObject)
635
+ }
636
+ }
637
+ }
638
+
639
+ @objc func openAppSettings(_ call: CAPPluginCall) {
640
+ guard let settingsUrl = URL(string: UIApplication.openSettingsURLString) else {
641
+ return
642
+ }
643
+
644
+ DispatchQueue.main.async {
645
+ if UIApplication.shared.canOpenURL(settingsUrl) {
646
+ UIApplication.shared.open(settingsUrl, completionHandler: { (success) in
647
+ call.resolve()
648
+ })
649
+ }
650
+ }
651
+ }
652
+
653
+ @objc func enableTorch(_ call: CAPPluginCall) {
654
+ guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
655
+ guard device.hasTorch else { return }
656
+ guard device.isTorchAvailable else { return }
657
+
658
+ do {
659
+ try device.lockForConfiguration()
660
+
661
+ do {
662
+ try device.setTorchModeOn(level: 1.0)
663
+ } catch {
664
+ print(error)
665
+ }
666
+
667
+ device.unlockForConfiguration()
668
+ } catch {
669
+ print(error)
670
+ }
671
+
672
+ call.resolve()
673
+ }
674
+
675
+ @objc func disableTorch(_ call: CAPPluginCall) {
676
+ guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
677
+ guard device.hasTorch else { return }
678
+ guard device.isTorchAvailable else { return }
679
+
680
+ do {
681
+ try device.lockForConfiguration()
682
+ device.torchMode = .off
683
+
684
+ device.unlockForConfiguration()
685
+ } catch {
686
+ print(error)
687
+ }
688
+
689
+ call.resolve()
690
+ }
691
+
692
+ @objc func toggleTorch(_ call: CAPPluginCall) {
693
+ guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
694
+ guard device.hasTorch else { return }
695
+ guard device.isTorchAvailable else { return }
696
+
697
+ if (device.torchMode == .on) {
698
+ self.disableTorch(call)
699
+ } else {
700
+ self.enableTorch(call)
701
+ }
702
+ }
703
+
704
+ @objc func getTorchState(_ call: CAPPluginCall) {
705
+ guard let device = AVCaptureDevice.default(for: AVMediaType.video) else { return }
706
+
707
+ var result = PluginCallResultData()
708
+
709
+ result["isEnabled"] = device.torchMode == .on
710
+
711
+ call.resolve(result)
712
+ }
713
+
71
714
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aigens/aigens-sdk-core",
3
- "version": "0.0.2",
3
+ "version": "0.0.3",
4
4
  "description": "Aigens Order.Place Core Plugin",
5
5
  "main": "dist/plugin.cjs.js",
6
6
  "module": "dist/esm/index.js",