-
Notifications
You must be signed in to change notification settings - Fork 4
/
FuseCDVPluginAdapter.uno
151 lines (128 loc) · 4.6 KB
/
FuseCDVPluginAdapter.uno
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
using Fuse;
using Fuse.Scripting;
using Fuse.Reactive;
using Uno.UX;
using Uno.Compiler.ExportTargetInterop;
using Uno;
using Uno.Text;
using Uno.Collections;
[ForeignInclude(Language.ObjC, "FuseCDVPluginUtilities.h")]
public class FuseCDVPluginAdapter : NativeModule
{
// identifier used for this plugin
protected internal string _ID;
protected internal extern(iOS) ObjC.Object _nativeLib;
protected internal FuseCDVBridge _bridge;
Dictionary<string, Dictionary<string, object>> _contextCallbackMap;
// { callbackId => { type => string(cordova), context => Context, success => Function, failure => Function}
public FuseCDVPluginAdapter(string pluginId)
{
_ID = pluginId;
_bridge = FuseCDVBridge.getInstance();
_contextCallbackMap = new Dictionary<string, Dictionary<string, object>>();
}
extern(iOS)
public ObjC.Object getNativePlugin() {
return _nativeLib;
}
extern(iOS)
public void handlePluginResult(string callbackId, int status, string jsonArgs) {
debug_log(_ID + " - Got a result from command delegate");
debug_log(callbackId + " " + status + " " + jsonArgs);
if (_contextCallbackMap.ContainsKey(callbackId))
InvokeCallbackClosure(callbackId, status, jsonArgs);
}
protected internal string RegisterCordovaCallbackClosure(Context c, Function successCb, Function failureCb)
{
string callbackId = GetUUID();
debug_log(_ID + " - Adding " + callbackId + " to closure map for cordova requests");
Dictionary<string, object> callbackMap = new Dictionary<string, object>();
callbackMap.Add("context", c);
callbackMap.Add("success", successCb);
callbackMap.Add("failure", failureCb);
callbackMap.Add("type", "cordova");
_contextCallbackMap.Add(callbackId, callbackMap);
return callbackId;
}
class InvokeClosure
{
Function _callback;
string _arg;
public InvokeClosure(Function callback, string arg)
{
_callback = callback;
_arg = arg;
}
public void Call()
{
_callback.Call(_arg);
}
}
protected internal void InvokeCallbackClosure(string callbackId, int status, string args)
{
Dictionary<string, object> callbackMap = _contextCallbackMap[callbackId];
if (callbackMap != null)
{
Context context = callbackMap["context"] as Context;
Function successCb = callbackMap["success"] as Function;
Function failureCb = callbackMap["failure"] as Function;
string type = callbackMap["type"] as string;
if (context != null && type == "cordova")
{
// TODO: change this status check to reference the CDVCommandStatus enum in CDVPluginResult.h
if (status == 9 && failureCb != null) { // CDVCommandStatus_ERROR
context.Dispatcher.Invoke(new InvokeClosure(failureCb, args).Call);
} else if (successCb != null) {
context.Dispatcher.Invoke(new InvokeClosure(successCb, args).Call);
}
}
}
}
protected string convertArgsArrayToJson(object[] args){
var sb = new StringBuilder();
sb.Append("[");
for (int i = 0; i < args.Length; i++)
{
if (i > 0) sb.Append(",");
sb.Append(Json.Stringify(args[i]));
}
sb.Append("]");
return sb.ToString();
}
[Foreign(Language.ObjC)]
extern(iOS)
public void performSelector(ObjC.Object nativeLib, string selector, string callbackId, string jsonArgs)
@{
NSString* className = @{FuseCDVPluginAdapter:Of(_this)._ID:Get()};
NSData* jsonData = [jsonArgs dataUsingEncoding:NSUTF8StringEncoding];
NSError* jsonError;
NSArray* args = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONWritingPrettyPrinted error:&jsonError];
CDVInvokedUrlCommand* command =
[CDVCommandFactory initWithArguments:args
callbackId:callbackId
className:className
methodName:selector];
NSString* selectorPlus = [NSString stringWithFormat:@"%@%@", selector, @":"];
// TODO: research why performing on main thread works, and what the downsides are
// [nativeLib performSelector:NSSelectorFromString(selectorPlus) withObject:command afterDelay:0];
[nativeLib performSelectorOnMainThread:NSSelectorFromString(selectorPlus) withObject:command waitUntilDone:YES];
@}
[Foreign(Language.Java)]
extern(Android)
public static string GetUUID()
@{
return UUID.randomUUID().toString();
@}
[Foreign(Language.ObjC)]
extern(iOS)
public static string GetUUID()
@{
NSString *uuid = [[NSUUID UUID] UUIDString];
return uuid;
@}
extern(!(iOS || Android))
public static string GetUUID()
{
return "0000";
}
}