Skip to content

Commit 11a56fe

Browse files
committed
✨ Write detailed README
1 parent db93fe0 commit 11a56fe

File tree

2 files changed

+159
-2
lines changed

2 files changed

+159
-2
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ env:
1313
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=10.0" PLATFORM="iOS"
1414
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=10.1" PLATFORM="iOS"
1515
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=10.2" PLATFORM="iOS"
16-
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=10.3" PLATFORM="iOS"
16+
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=10.3.1" PLATFORM="iOS"
1717
- SCHEME="JavaScriptKit-iOS" DESTINATION="platform=iOS Simulator,name=iPhone 6,OS=11.0" PLATFORM="iOS"
1818

1919
before_install:

README.md

Lines changed: 158 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@ JavaScriptKit is a powerful replacement for JavaScriptCore to use with your WebK
1111

1212
- Generate and evaluate type-safe JavaScript expressions in WKWebView
1313
- Automatically encode and decode values, JSON objects and enumerations to and from JavaScript
14-
- Easily handle errors
14+
- Easy error handling
15+
- [Documented](https://alexaubry.github.io/JavaScriptKit)
1516

1617
## Installation
1718

@@ -38,6 +39,162 @@ github "alexaubry/JavaScriptKit" ~> 1.0
3839
| Minimum macOS Version | 10.10 |
3940
| Supported Swift Version(s) | 4.0.x |
4041

42+
## How it works
43+
44+
The library is structured around the `JSExpression` protocol. Expressions can be represented as a JavaScript expression string, and have their return type defined at compile-time for better type safety.
45+
46+
You can evaluate expressions inside of a `WKWebView`. You provide a callback block that will be called with a `Result` object, containing either the value returned on success, or the error thrown by the web view on failure. Callback blocks are always executed on the main thread.
47+
48+
When the web view returns the result, `JavaScriptKit` uses a custom [`Decoder`](https://developer.apple.com/documentation/swift/decoder) to decode it into the return type you specified. This allows you to set the return type to any [`Decodable`](https://developer.apple.com/documentation/swift/decodable) type (structures, classes, primitive types, enumeration, array, dictionary, ...).
49+
50+
## Usage
51+
52+
### Get the value of a variable
53+
54+
Use the `JSVariable` expression type to get the value of a variable at the specified key path.
55+
56+
#### Example 1.1
57+
58+
> Get the title of the current document
59+
60+
~~~swift
61+
let titleVariable = JSVariable<String>("document.title")
62+
63+
titleVariable.evaluate(in: webView) { result in
64+
65+
switch result {
66+
case .success(let title):
67+
// do something with the `title` string
68+
69+
case .failure(let error):
70+
// handle error
71+
}
72+
73+
}
74+
~~~
75+
76+
- The `title` value provided on success is a `String`.
77+
78+
### Call a function
79+
80+
Use the `JSFunction` expression type to call a function at the specified key path. You can pass as many arguments as needed. They must conform to the `Encodable` protocol to be converted to a JavaScript representation.
81+
82+
When the function does not return a value, use the `JSVoid` return type.
83+
84+
#### Example 2.1
85+
86+
> URI-Encode a String
87+
88+
~~~swift
89+
let encodeURI = JSFunction<String>("window.encodeURI", arguments: "Hello world")
90+
91+
encodeURI.evaluate(in: webView) { result in
92+
93+
switch result {
94+
case .success(let encodedURI):
95+
// do something with the `encodedURI` string
96+
97+
case .failure(let error):
98+
// handle error
99+
}
100+
101+
}
102+
~~~
103+
104+
- The `alert` expression will be converted to: `"this.window.encodeURI("Hello world");"`.
105+
- The `encodedURI` value provided on success is a `String`.
106+
107+
#### Example 2.2
108+
109+
> Show an alert
110+
111+
~~~swift
112+
let alert = JSFunction<JSVoid>("window.alert", arguments: "Hello from Swift!")
113+
114+
alert.evaluate(in: webView, completionHandler: nil)
115+
~~~
116+
117+
- The `alert` expression will be converted to: `"this.window.alert("Hello from Swift!");"`.
118+
- To ignore the result of the expression, pass `nil` for the `completionHandler` argument.
119+
120+
#### Example 2.3
121+
122+
> Reload the window
123+
124+
~~~swift
125+
let reload = JSFunction<JSVoid>("location.reload")
126+
127+
reload.evaluate(in: webView, completionHandler: nil)
128+
~~~
129+
130+
- You can omit the `arguments` parameter if the function takes no arguments.
131+
132+
### Run your custom scripts
133+
134+
Use the `JSScript` expression type to run your custom scripts. To create custom scripts, you define a `String` that contains the script to run and define the return value.
135+
136+
The last evaluated statement in your script will be used as the return value. Do not use `return` at the end of the script, as it would yield an invalid value.
137+
138+
#### Example 3.1
139+
140+
> Get the time of the day from a time string in the document
141+
142+
~~~swift
143+
enum TimeOfDay: String, Decodable {
144+
case night, morning, afternoon, evening
145+
}
146+
147+
let scriptBody = """
148+
function getTimeOfDay(hour) {
149+
150+
if (hour >= 0 && hour < 6) {
151+
return "night";
152+
} else if (hour >= 6 && hour < 12) {
153+
return "morning"
154+
} else if (hour >= 12 && hour < 18) {
155+
return "afternoon"
156+
} else if (hour >= 18 && hour > 0) {
157+
return "evening"
158+
}
159+
160+
}
161+
162+
var postPublishDate = document.getElementById("publish-date").innerHTML
163+
var hours = new Date(postPublishDate).getHours();
164+
165+
getTimeOfDay(hours);
166+
"""
167+
168+
let script = JSScript<TimeOfDay>(scriptBody)
169+
170+
script.evaluate(in: webView) { result in
171+
172+
switch result {
173+
case .success(let timeOfDay):
174+
// do something with the `timeOfDay` object
175+
176+
case .failure(let error):
177+
// handle error
178+
}
179+
180+
}
181+
~~~
182+
183+
- The `timeOfDay` value provided on success is a case of `TimeOfDay`.
184+
- `TimeOfDay` is a supported return type because it implements the `Decodable` protocol.
185+
186+
## Contributing
187+
188+
Contributions are welcome and appreciated! Here's how you should sumbit code contributions:
189+
190+
- Fork and clone the repository
191+
- Create a new branch for your fixes (ex: `git checkout -b [your branch name]`)
192+
- Get the development dependencies by running `carthage bootstrap`
193+
- Code your changes and commit them to your branch
194+
- Submit a PR to the `main` branch
195+
196+
If you find a bug or think a feature is missing, please [submit an issue](https://github.com/alexaubry/JavaScriptKit/issues).
197+
41198
## Authors
42199

43200
Alexis Aubry, me@alexaubry.fr <[@_alexaubry](https://twitter.com/_alexaubry)>

0 commit comments

Comments
 (0)