New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Move away from WebCycript (et al) as a dependancy #8

Open
Matchstic opened this Issue Jan 19, 2017 · 7 comments

Comments

2 participants
@Matchstic
Copy link
Owner

Matchstic commented Jan 19, 2017

I propose to move away from WebCycript being utilised as an underlying dependancy for access to InfoStats 2 in widgets. This will remove the wait for fixes to WebCycript (if required) between iOS versions, and will serve to consolidate InfoStats 2 into a self-contained package.

To achieve this:

  1. A new method of bridging native code to JavaScript is required.
  2. A method to ensure backwards compatibility with Cycript is required.

Other benefits include code usually accessed via Cycript now runs outside JavaScript's environment, meaning speed improvements, and significant reliability/stability improvements.


For (1) I propose a simple extension to JavaScript, which will simply expose global variables with the namespace of the class names within InfoStats 2, such as IS2Weather.(method), IS2Location.(method) and so forth. Existing classes within SpringBoard can be accessed via another global variable with the namespace of SpringBoard.(class).(method).

This can be achieved in a similar manner to XWebView, which may be used as a basis.


For (2) I propose "compiling" from Cycript code into this new "IS2Script", using the form:

var thing = [IS2Weather doThing]; // existing
var thing = IS2Weather.doThing(); // new

var anotherThing = [[SBExampleClass sharedInstance] anotherThing]; // existing
var anotherThing = SpringBoard.SBExampleClass.sharedInstance().anotherThing(); // new

var object = [SBExampleClass sharedInstance]; // existing
var object = SpringBoard.SBExampleClass.sharedInstance(); // new
var thingWithObject = [object anotherThing]; // existing
var thingWithObject = object.anotherThing(); // new

This will utilise at minimum a deterministic finite automata, and will interpose the loading of web pages into both UIWebView and WKWebView. I also propose the addition of pre-processor flags to this compiler, which will be in the form of a comment within a <script> tag or a .js file, like so:

//@IS2: (flag here)

e.g.
//@IS2: no-compile

The handling of callback blocks will be an interesting conundrum, which some research required to best handle them. My current approach is to give them the form of:

IS2Weather.registerForWeatherUpdatesWithIdentifier:andCallback("identifier", function() {
// Callback block.
});

As you can see above, the handling of parameters not at the end of the method will also change. To compare, here is the current version of the above function:

[IS2Weather registerForWeatherUpdatesWithIdentifier:"identifier" andCallback: ^ (void) {
// Callback block.
}];


Please feel free to comment on this summary with suggestions and improvements.

@Rasputin007

This comment has been minimized.

Copy link

Rasputin007 commented Jan 19, 2017

Sounds like a very cool idea.
Am I right in thinking that this will include the IS2 API and any other info you can get from iOS, e.g model number, serial number etc?

@Matchstic

This comment has been minimized.

Copy link
Owner

Matchstic commented Jan 19, 2017

@Rasputin007 Yep, anything currently possible in IS2 will remain possible with this new approach.

For all intents and purposes, you can assume any pre-existing (or even new) Cycript code will work as expected, with IS2 handling conversion of it to the new syntax. It's more of an under-the-hood re-architecture that exposes new stuff, which is the new "IS2Script" syntax.

@Matchstic

This comment has been minimized.

Copy link
Owner

Matchstic commented Feb 13, 2017

I've done some more theoretical work surrounding this based upon my testing with XWebView. it seems that synchronous communication between JS <=> ObjC isn't publicly possible with the new WebKit API for iOS, due to multi-process nature of it. So, I'm planning to sidestep this by making it "pseudo-synchronous"; the coder sees a synchronous API, but in the compilation step InfoStats 2 will generate asynchronous code.

I've outlined a potential way of doing this here: https://ghostbin.com/paste/ewn28
(Note that the "IS2" global object will be injected via XWebView, and I will also need to extend that back to UIWebView).

The only "hard" problem to solve now is correctly parsing input text to generate code.

@Rasputin007

This comment has been minimized.

Copy link

Rasputin007 commented Feb 13, 2017

@Matchstic

This comment has been minimized.

Copy link
Owner

Matchstic commented Feb 13, 2017

No worries!

I just used those two as examples; anything currently possible via Cycript will be possible with this implementation. So, nope, the classes are not fixed!

@Rasputin007

This comment has been minimized.

Copy link

Rasputin007 commented Feb 13, 2017

@Matchstic

This comment has been minimized.

Copy link
Owner

Matchstic commented Nov 1, 2018

Raising this from the dead.

Had a couple of ideas. Can use frida-cycript (and it’s corresponding Mjolner project) to compile Cylang to plain JS, and use WebViewScriptBridge instead of that fork’s node.js bindings for webview<->library communication. Will need to hack all three up a bit to achieve this!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment