Merge pull request #90 from realm/al-cordova-update
Update version/Fix cordova example
This commit is contained in:
commit
6c3bfef73d
|
@ -159,7 +159,7 @@
|
|||
children = (
|
||||
021CDA2B1B9639C9002FADCE /* RealmJS.framework */,
|
||||
021CDA2D1B9639C9002FADCE /* RealmJSTests.xctest */,
|
||||
021CDA2F1B9639C9002FADCE /* libRealmReact.a */,
|
||||
021CDA2F1B9639C9002FADCE /* RealmReact.framework */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
|
@ -381,10 +381,10 @@
|
|||
remoteRef = 021CDA2C1B9639C9002FADCE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
021CDA2F1B9639C9002FADCE /* libRealmReact.a */ = {
|
||||
021CDA2F1B9639C9002FADCE /* RealmReact.framework */ = {
|
||||
isa = PBXReferenceProxy;
|
||||
fileType = archive.ar;
|
||||
path = libRealmReact.a;
|
||||
fileType = wrapper.framework;
|
||||
path = RealmReact.framework;
|
||||
remoteRef = 021CDA2E1B9639C9002FADCE /* PBXContainerItemProxy */;
|
||||
sourceTree = BUILT_PRODUCTS_DIR;
|
||||
};
|
||||
|
@ -506,7 +506,7 @@
|
|||
GCC_THUMB_SUPPORT = NO;
|
||||
GCC_VERSION = "";
|
||||
INFOPLIST_FILE = "RealmExample/RealmExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
CoreFoundation,
|
||||
|
@ -535,7 +535,7 @@
|
|||
GCC_THUMB_SUPPORT = NO;
|
||||
GCC_VERSION = "";
|
||||
INFOPLIST_FILE = "RealmExample/RealmExample-Info.plist";
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
CoreFoundation,
|
||||
|
@ -577,7 +577,7 @@
|
|||
"\"$(OBJROOT)/UninstalledProducts/include\"",
|
||||
"\"$(BUILT_PRODUCTS_DIR)\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
|
@ -621,7 +621,7 @@
|
|||
"\"$(OBJROOT)/UninstalledProducts/include\"",
|
||||
"\"$(BUILT_PRODUCTS_DIR)\"",
|
||||
);
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 6.0;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
|
||||
OTHER_LDFLAGS = (
|
||||
"-weak_framework",
|
||||
CoreFoundation,
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
//
|
||||
// Licensed to the Apache Software Foundation (ASF) under one
|
||||
// or more contributor license agreements. See the NOTICE file
|
||||
// distributed with this work for additional information
|
||||
// regarding copyright ownership. The ASF licenses this file
|
||||
// to you under the Apache License, Version 2.0 (the
|
||||
// "License"); you may not use this file except in compliance
|
||||
// with the License. You may obtain a copy of the License at
|
||||
//
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing,
|
||||
// software distributed under the License is distributed on an
|
||||
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
// KIND, either express or implied. See the License for the
|
||||
// specific language governing permissions and limitations
|
||||
// under the License.
|
||||
//
|
||||
|
||||
//
|
||||
// Auto-generated config file to override configuration files (build-release/build-debug).
|
||||
//
|
|
@ -1,323 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Creates a gap bridge iframe used to notify the native code about queued
|
||||
* commands.
|
||||
*/
|
||||
var cordova = require('cordova'),
|
||||
channel = require('cordova/channel'),
|
||||
utils = require('cordova/utils'),
|
||||
base64 = require('cordova/base64'),
|
||||
// XHR mode does not work on iOS 4.2.
|
||||
// XHR mode's main advantage is working around a bug in -webkit-scroll, which
|
||||
// doesn't exist only on iOS 5.x devices.
|
||||
// IFRAME_NAV is the fastest.
|
||||
// IFRAME_HASH could be made to enable synchronous bridge calls if we wanted this feature.
|
||||
jsToNativeModes = {
|
||||
IFRAME_NAV: 0, // Default. Uses a new iframe for each poke.
|
||||
// XHR bridge appears to be flaky sometimes: CB-3900, CB-3359, CB-5457, CB-4970, CB-4998, CB-5134
|
||||
XHR_NO_PAYLOAD: 1, // About the same speed as IFRAME_NAV. Performance not about the same as IFRAME_NAV, but more variable.
|
||||
XHR_WITH_PAYLOAD: 2, // Flakey, and not as performant
|
||||
XHR_OPTIONAL_PAYLOAD: 3, // Flakey, and not as performant
|
||||
IFRAME_HASH_NO_PAYLOAD: 4, // Not fully baked. A bit faster than IFRAME_NAV, but risks jank since poke happens synchronously.
|
||||
IFRAME_HASH_WITH_PAYLOAD: 5, // Slower than no payload. Maybe since it has to be URI encoded / decoded.
|
||||
WK_WEBVIEW_BINDING: 6 // Only way that works for WKWebView :)
|
||||
},
|
||||
bridgeMode,
|
||||
execIframe,
|
||||
execHashIframe,
|
||||
hashToggle = 1,
|
||||
execXhr,
|
||||
requestCount = 0,
|
||||
vcHeaderValue = null,
|
||||
commandQueue = [], // Contains pending JS->Native messages.
|
||||
isInContextOfEvalJs = 0,
|
||||
failSafeTimerId = 0;
|
||||
|
||||
function shouldBundleCommandJson() {
|
||||
if (bridgeMode === jsToNativeModes.XHR_WITH_PAYLOAD) {
|
||||
return true;
|
||||
}
|
||||
if (bridgeMode === jsToNativeModes.XHR_OPTIONAL_PAYLOAD) {
|
||||
var payloadLength = 0;
|
||||
for (var i = 0; i < commandQueue.length; ++i) {
|
||||
payloadLength += commandQueue[i].length;
|
||||
}
|
||||
// The value here was determined using the benchmark within CordovaLibApp on an iPad 3.
|
||||
return payloadLength < 4500;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
function massageArgsJsToNative(args) {
|
||||
if (!args || utils.typeName(args) != 'Array') {
|
||||
return args;
|
||||
}
|
||||
var ret = [];
|
||||
args.forEach(function(arg, i) {
|
||||
if (utils.typeName(arg) == 'ArrayBuffer') {
|
||||
ret.push({
|
||||
'CDVType': 'ArrayBuffer',
|
||||
'data': base64.fromArrayBuffer(arg)
|
||||
});
|
||||
} else {
|
||||
ret.push(arg);
|
||||
}
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
function massageMessageNativeToJs(message) {
|
||||
if (message.CDVType == 'ArrayBuffer') {
|
||||
var stringToArrayBuffer = function(str) {
|
||||
var ret = new Uint8Array(str.length);
|
||||
for (var i = 0; i < str.length; i++) {
|
||||
ret[i] = str.charCodeAt(i);
|
||||
}
|
||||
return ret.buffer;
|
||||
};
|
||||
var base64ToArrayBuffer = function(b64) {
|
||||
return stringToArrayBuffer(atob(b64));
|
||||
};
|
||||
message = base64ToArrayBuffer(message.data);
|
||||
}
|
||||
return message;
|
||||
}
|
||||
|
||||
function convertMessageToArgsNativeToJs(message) {
|
||||
var args = [];
|
||||
if (!message || !message.hasOwnProperty('CDVType')) {
|
||||
args.push(message);
|
||||
} else if (message.CDVType == 'MultiPart') {
|
||||
message.messages.forEach(function(e) {
|
||||
args.push(massageMessageNativeToJs(e));
|
||||
});
|
||||
} else {
|
||||
args.push(massageMessageNativeToJs(message));
|
||||
}
|
||||
return args;
|
||||
}
|
||||
|
||||
function iOSExec() {
|
||||
if (bridgeMode === undefined) {
|
||||
bridgeMode = jsToNativeModes.IFRAME_NAV;
|
||||
}
|
||||
|
||||
if (window.webkit && window.webkit.messageHandlers && window.webkit.messageHandlers.cordova && window.webkit.messageHandlers.cordova.postMessage) {
|
||||
bridgeMode = jsToNativeModes.WK_WEBVIEW_BINDING;
|
||||
}
|
||||
|
||||
var successCallback, failCallback, service, action, actionArgs, splitCommand;
|
||||
var callbackId = null;
|
||||
if (typeof arguments[0] !== "string") {
|
||||
// FORMAT ONE
|
||||
successCallback = arguments[0];
|
||||
failCallback = arguments[1];
|
||||
service = arguments[2];
|
||||
action = arguments[3];
|
||||
actionArgs = arguments[4];
|
||||
|
||||
// Since we need to maintain backwards compatibility, we have to pass
|
||||
// an invalid callbackId even if no callback was provided since plugins
|
||||
// will be expecting it. The Cordova.exec() implementation allocates
|
||||
// an invalid callbackId and passes it even if no callbacks were given.
|
||||
callbackId = 'INVALID';
|
||||
} else {
|
||||
// FORMAT TWO, REMOVED
|
||||
try {
|
||||
splitCommand = arguments[0].split(".");
|
||||
action = splitCommand.pop();
|
||||
service = splitCommand.join(".");
|
||||
actionArgs = Array.prototype.splice.call(arguments, 1);
|
||||
|
||||
console.log('The old format of this exec call has been removed (deprecated since 2.1). Change to: ' +
|
||||
"cordova.exec(null, null, \"" + service + "\", \"" + action + "\"," + JSON.stringify(actionArgs) + ");"
|
||||
);
|
||||
return;
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
// If actionArgs is not provided, default to an empty array
|
||||
actionArgs = actionArgs || [];
|
||||
|
||||
// Register the callbacks and add the callbackId to the positional
|
||||
// arguments if given.
|
||||
if (successCallback || failCallback) {
|
||||
callbackId = service + cordova.callbackId++;
|
||||
cordova.callbacks[callbackId] =
|
||||
{success:successCallback, fail:failCallback};
|
||||
}
|
||||
|
||||
actionArgs = massageArgsJsToNative(actionArgs);
|
||||
|
||||
var command = [callbackId, service, action, actionArgs];
|
||||
|
||||
// Stringify and queue the command. We stringify to command now to
|
||||
// effectively clone the command arguments in case they are mutated before
|
||||
// the command is executed.
|
||||
commandQueue.push(JSON.stringify(command));
|
||||
|
||||
if (bridgeMode === jsToNativeModes.WK_WEBVIEW_BINDING) {
|
||||
window.webkit.messageHandlers.cordova.postMessage(command);
|
||||
} else {
|
||||
// If we're in the context of a stringByEvaluatingJavaScriptFromString call,
|
||||
// then the queue will be flushed when it returns; no need for a poke.
|
||||
// Also, if there is already a command in the queue, then we've already
|
||||
// poked the native side, so there is no reason to do so again.
|
||||
if (!isInContextOfEvalJs && commandQueue.length == 1) {
|
||||
pokeNative();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function pokeNative() {
|
||||
switch (bridgeMode) {
|
||||
case jsToNativeModes.XHR_NO_PAYLOAD:
|
||||
case jsToNativeModes.XHR_WITH_PAYLOAD:
|
||||
case jsToNativeModes.XHR_OPTIONAL_PAYLOAD:
|
||||
pokeNativeViaXhr();
|
||||
break;
|
||||
default: // iframe-based.
|
||||
pokeNativeViaIframe();
|
||||
}
|
||||
}
|
||||
|
||||
function pokeNativeViaXhr() {
|
||||
// This prevents sending an XHR when there is already one being sent.
|
||||
// This should happen only in rare circumstances (refer to unit tests).
|
||||
if (execXhr && execXhr.readyState != 4) {
|
||||
execXhr = null;
|
||||
}
|
||||
// Re-using the XHR improves exec() performance by about 10%.
|
||||
execXhr = execXhr || new XMLHttpRequest();
|
||||
// Changing this to a GET will make the XHR reach the URIProtocol on 4.2.
|
||||
// For some reason it still doesn't work though...
|
||||
// Add a timestamp to the query param to prevent caching.
|
||||
execXhr.open('HEAD', "/!gap_exec?" + (+new Date()), true);
|
||||
if (!vcHeaderValue) {
|
||||
vcHeaderValue = /.*\((.*)\)$/.exec(navigator.userAgent)[1];
|
||||
}
|
||||
execXhr.setRequestHeader('vc', vcHeaderValue);
|
||||
execXhr.setRequestHeader('rc', ++requestCount);
|
||||
if (shouldBundleCommandJson()) {
|
||||
execXhr.setRequestHeader('cmds', iOSExec.nativeFetchMessages());
|
||||
}
|
||||
execXhr.send(null);
|
||||
}
|
||||
|
||||
function pokeNativeViaIframe() {
|
||||
// CB-5488 - Don't attempt to create iframe before document.body is available.
|
||||
if (!document.body) {
|
||||
setTimeout(pokeNativeViaIframe);
|
||||
return;
|
||||
}
|
||||
if (bridgeMode === jsToNativeModes.IFRAME_HASH_NO_PAYLOAD || bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
|
||||
// TODO: This bridge mode doesn't properly support being removed from the DOM (CB-7735)
|
||||
if (!execHashIframe) {
|
||||
execHashIframe = document.createElement('iframe');
|
||||
execHashIframe.style.display = 'none';
|
||||
document.body.appendChild(execHashIframe);
|
||||
// Hash changes don't work on about:blank, so switch it to file:///.
|
||||
execHashIframe.contentWindow.history.replaceState(null, null, 'file:///#');
|
||||
}
|
||||
// The delegate method is called only when the hash changes, so toggle it back and forth.
|
||||
hashToggle = hashToggle ^ 3;
|
||||
var hashValue = '%0' + hashToggle;
|
||||
if (bridgeMode === jsToNativeModes.IFRAME_HASH_WITH_PAYLOAD) {
|
||||
hashValue += iOSExec.nativeFetchMessages();
|
||||
}
|
||||
execHashIframe.contentWindow.location.hash = hashValue;
|
||||
} else {
|
||||
// Check if they've removed it from the DOM, and put it back if so.
|
||||
if (execIframe && execIframe.contentWindow) {
|
||||
execIframe.contentWindow.location = 'gap://ready';
|
||||
} else {
|
||||
execIframe = document.createElement('iframe');
|
||||
execIframe.style.display = 'none';
|
||||
execIframe.src = 'gap://ready';
|
||||
document.body.appendChild(execIframe);
|
||||
}
|
||||
// Use a timer to protect against iframe being unloaded during the poke (CB-7735).
|
||||
// This makes the bridge ~ 7% slower, but works around the poke getting lost
|
||||
// when the iframe is removed from the DOM.
|
||||
// An onunload listener could be used in the case where the iframe has just been
|
||||
// created, but since unload events fire only once, it doesn't work in the normal
|
||||
// case of iframe reuse (where unload will have already fired due to the attempted
|
||||
// navigation of the page).
|
||||
failSafeTimerId = setTimeout(function() {
|
||||
if (commandQueue.length) {
|
||||
pokeNative();
|
||||
}
|
||||
}, 50); // Making this > 0 improves performance (marginally) in the normal case (where it doesn't fire).
|
||||
}
|
||||
}
|
||||
|
||||
iOSExec.jsToNativeModes = jsToNativeModes;
|
||||
|
||||
iOSExec.setJsToNativeBridgeMode = function(mode) {
|
||||
// Remove the iFrame since it may be no longer required, and its existence
|
||||
// can trigger browser bugs.
|
||||
// https://issues.apache.org/jira/browse/CB-593
|
||||
if (execIframe) {
|
||||
if (execIframe.parentNode) {
|
||||
execIframe.parentNode.removeChild(execIframe);
|
||||
}
|
||||
execIframe = null;
|
||||
}
|
||||
bridgeMode = mode;
|
||||
};
|
||||
|
||||
iOSExec.nativeFetchMessages = function() {
|
||||
// Stop listing for window detatch once native side confirms poke.
|
||||
if (failSafeTimerId) {
|
||||
clearTimeout(failSafeTimerId);
|
||||
failSafeTimerId = 0;
|
||||
}
|
||||
// Each entry in commandQueue is a JSON string already.
|
||||
if (!commandQueue.length) {
|
||||
return '';
|
||||
}
|
||||
var json = '[' + commandQueue.join(',') + ']';
|
||||
commandQueue.length = 0;
|
||||
return json;
|
||||
};
|
||||
|
||||
iOSExec.nativeCallback = function(callbackId, status, message, keepCallback) {
|
||||
return iOSExec.nativeEvalAndFetch(function() {
|
||||
var success = status === 0 || status === 1;
|
||||
var args = convertMessageToArgsNativeToJs(message);
|
||||
cordova.callbackFromNative(callbackId, success, status, args, keepCallback);
|
||||
});
|
||||
};
|
||||
|
||||
iOSExec.nativeEvalAndFetch = function(func) {
|
||||
// This shouldn't be nested, but better to be safe.
|
||||
isInContextOfEvalJs++;
|
||||
try {
|
||||
func();
|
||||
return iOSExec.nativeFetchMessages();
|
||||
} finally {
|
||||
isInContextOfEvalJs--;
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = iOSExec;
|
|
@ -1,28 +0,0 @@
|
|||
/*
|
||||
*
|
||||
* Licensed to the Apache Software Foundation (ASF) under one
|
||||
* or more contributor license agreements. See the NOTICE file
|
||||
* distributed with this work for additional information
|
||||
* regarding copyright ownership. The ASF licenses this file
|
||||
* to you under the Apache License, Version 2.0 (the
|
||||
* "License"); you may not use this file except in compliance
|
||||
* with the License. You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*
|
||||
*/
|
||||
|
||||
module.exports = {
|
||||
id: 'ios',
|
||||
bootstrap: function() {
|
||||
require('cordova/channel').onNativeReady.fire();
|
||||
}
|
||||
};
|
||||
|
|
@ -21,7 +21,7 @@ function Todo() {}
|
|||
Todo.prototype.schema = {
|
||||
name: 'Todo',
|
||||
properties: [
|
||||
{name: 'text', type: 'RealmTypeString'},
|
||||
{name: 'text', type: Realm.Types.STRING},
|
||||
]
|
||||
};
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ function Todo() {}
|
|||
Todo.prototype.schema = {
|
||||
name: 'Todo',
|
||||
properties: [
|
||||
{name: 'text', type: 'RealmTypeString'},
|
||||
{name: 'text', type: Realm.Types.STRING},
|
||||
]
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue