자답입니다.
찾아보니 안드로이드 웹뷰도 alert 창이 html 코드로는 뜨지 않는다고 나오네요.
결론은 앱에서 받아서 앱의 createdialog로 alert를 만들어 띄우는 식으로 해결했습니다.
그리고 질문주신 Jockey를 쓰는 이유는 빈번하게 앱과 웹이 이벤트 및 메시지를 주고받아야 해서 Jockey를 사용하고 있습니다.
저희는 웹페이지가 리모트에 있어서 ti의 webview로는 서로 통신하기기 까다롭더군요.
다른 질문에서 알려주신 리모트페이지일때도 webview로 통신하는 방법을 써보았습니다만 제대로 먹혀지지가 않습니다.
보안상의 문제로 Ti.App의 일부 API 만 허용하게 해줬다고 하는데…그것마저도 막혔는지 아니면 제가 제대로 못해서 그런건지
안되더군요.
그래서 별수없이 Jockey를 쓰고 있습니다.
jockey를 써보진 않아서 그 내부 구조는 모르지만 tiatnium에서 로컬 html을 webview에서 연 상황에서 webview안에서 Ti.API를 쓰기위해 하는 일이 결국에는 javascript 코드를 밀어 넣는 방식입니다. ^^
다음은 titanium_mobile의 iphone/TiUIWebview.m 에서 해당 코드를 밀어 넣는 부분입니다.
밀어 넣은 코드(위에서 kTitaniumJavascript변수에 해당하는 코드이며 아래 코드 참조)를 보면 한마디로 url을 가지고 장난하는건데요 app://appid 형태의 주소로 ajax call 하는 방식으로 웹뷰에서 ti로 데이터를 넘깁니다. 반대로 ti에서 webview로 넘기는것은 evalJS로 하면 되고요.
이 말은 원격이어도 위와같이 밀어넣으면 동작하는데는 아무 문제 없다는 거죠. 그래서 전에 한번은, 원격 소스에서도 Ti.App.fireEvent를 쓸수 있도록 코드를 강제로 evaljs로 강제로 밀어 넣어서 쓰긴 했었습니다.
이제 blacklistedURLs이 웹뷰에 추가되니 좀 더 다양하게 웹뷰와 장난 할 수 있겠네요.
html에 밀어 넣는 코드는 아래와 같습니다.
Ti.App = {};
Ti.API = {};
Ti.App._listeners = {};
Ti.App._listener_id = 1;
Ti.App.id = Ti.appId;
Ti.App._xhr = XMLHttpRequest;
Ti._broker = function(module, method, data) {
try {
var url = 'app://' + Ti.appId + '/_TiA0_' + Ti.pageToken + '/' + module + '/' + method + '?' + Ti.App._JSON(data, 1);
var xhr = new Ti.App._xhr();
xhr.open('GET', url, false);
xhr.send()
} catch (X) {}
};
Ti._hexish = function(a) {
var r = '';
var e = a.length;
var c = 0;
var h;
while (c < e) {
h = a.charCodeAt(c++).toString(16);
r += '\\\\u';
var l = 4 - h.length;
while (l-- > 0) {
r += '0'
};
r += h
}
return r
};
Ti._bridgeEnc = function(o) {
return '<' + Ti._hexish(o) + '>'
};
Ti.App._JSON = function(object, bridge) {
var type = typeof object;
switch (type) {
case 'undefined':
case 'function':
case 'unknown':
return undefined;
case 'number':
case 'boolean':
return object;
case 'string':
if (bridge === 1) return Ti._bridgeEnc(object);
return '\"' + object.replace(/\"/g, '\\\\\"').replace(/\\n/g, '\\\\n').replace(/\\r/g, '\\\\r') + '\"'
}
if ((object === null) || (object.nodeType == 1)) return 'null';
if (object.constructor.toString().indexOf('Date') != -1) {
return 'new Date(' + object.getTime() + ')'
}
if (object.constructor.toString().indexOf('Array') != -1) {
var res = '[';
var pre = '';
var len = object.length;
for (var i = 0; i < len; i++) {
var value = object[i];
if (value !== undefined) value = Ti.App._JSON(value, bridge);
if (value !== undefined) {
res += pre + value;
pre = ', '
}
}
return res + ']'
}
var objects = [];
for (var prop in object) {
var value = object[prop];
if (value !== undefined) {
value = Ti.App._JSON(value, bridge)
}
if (value !== undefined) {
objects.push(Ti.App._JSON(prop, bridge) + ': ' + value)
}
}
return '{' + objects.join(',') + '}'
};
Ti.App._dispatchEvent = function(type, evtid, evt) {
var listeners = Ti.App._listeners[type];
if (listeners) {
for (var c = 0; c < listeners.length; c++) {
var entry = listeners[c];
if (entry.id == evtid) {
entry.callback.call(entry.callback, evt)
}
}
}
};
Ti.App.fireEvent = function(name, evt) {
Ti._broker('App', 'fireEvent', {
name: name,
event: evt
})
};
Ti.API.log = function(a, b) {
Ti._broker('API', 'log', {
level: a,
message: b
})
};
Ti.API.debug = function(e) {
Ti._broker('API', 'log', {
level: 'debug',
message: e
})
};
Ti.API.error = function(e) {
Ti._broker('API', 'log', {
level: 'error',
message: e
})
};
Ti.API.info = function(e) {
Ti._broker('API', 'log', {
level: 'info',
message: e
})
};
Ti.API.fatal = function(e) {
Ti._broker('API', 'log', {
level: 'fatal',
message: e
})
};
Ti.API.warn = function(e) {
Ti._broker('API', 'log', {
level: 'warn',
message: e
})
};
Ti.App.addEventListener = function(name, fn) {
var listeners = Ti.App._listeners[name];
if (typeof(listeners) == 'undefined') {
listeners = [];
Ti.App._listeners[name] = listeners
}
var newid = Ti.pageToken + Ti.App._listener_id++;
listeners.push({
callback: fn,
id: newid
});
Ti._broker('App', 'addEventListener', {
name: name,
id: newid
})
};
Ti.App.removeEventListener = function(name, fn) {
var listeners = Ti.App._listeners[name];
if (listeners) {
for (var c = 0; c < listeners.length; c++) {
var entry = listeners[c];
if (entry.callback == fn) {
listeners.splice(c, 1);
Ti._broker('App', 'removeEventListener', {
name: name,
id: entry.id
});
break
}
}
}
};