├── .gitignore
├── Assets.xcassets
├── AppIcon.appiconset
│ └── Contents.json
├── Contents.json
├── logo-anim.dataset
│ ├── Contents.json
│ └── logo-anim.swf
├── ruffle-blue-6.colorset
│ └── Contents.json
├── ruffle-blue-9.colorset
│ └── Contents.json
├── ruffle-blue.colorset
│ └── Contents.json
└── ruffle-orange.colorset
│ └── Contents.json
├── Base.lproj
├── LaunchScreen.storyboard
└── Main.storyboard
├── Cargo.lock
├── Cargo.toml
├── Info.plist
├── LICENSE.md
├── README.md
├── Ruffle.xcdatamodeld
└── Ruffle.xcdatamodel
│ └── contents
├── build-in-xcode.sh
├── file-icons
├── ATTRIBUTION.md
├── document_ruf.icns
├── document_swf.icns
└── file-icons.xcassets
│ ├── Contents.json
│ ├── document_ruf.imageset
│ ├── Contents.json
│ └── document_ruf.svg
│ └── document_swf.imageset
│ ├── 256x256.png
│ ├── 512x512.png
│ └── Contents.json
├── ruffle-ios.entitlements
├── ruffle-ios.xcodeproj
├── project.pbxproj
└── project.xcworkspace
│ ├── contents.xcworkspacedata
│ └── xcshareddata
│ └── IDEWorkspaceChecks.plist
├── rust-toolchain.toml
└── src
├── add_controller.rs
├── app_delegate.rs
├── bin
└── run_swf.rs
├── edit_controller.rs
├── lib.rs
├── library_controller.rs
├── main.rs
├── player_controller.rs
├── player_view.rs
├── scene_delegate.rs
├── storage.rs
└── storyboard_connections.h
/.gitignore:
--------------------------------------------------------------------------------
1 | # Rust
2 | /target
3 | /.cargo
4 |
5 | # Xcode user settings
6 | xcuserdata/
7 |
8 | # Xcode app packaging
9 | *.ipa
10 | *.dSYM.zip
11 | *.dSYM
12 |
--------------------------------------------------------------------------------
/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "universal",
5 | "platform" : "ios",
6 | "size" : "1024x1024"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Assets.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/Assets.xcassets/logo-anim.dataset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "data" : [
3 | {
4 | "filename" : "logo-anim.swf",
5 | "idiom" : "universal",
6 | "universal-type-identifier" : "swf"
7 | }
8 | ],
9 | "info" : {
10 | "author" : "xcode",
11 | "version" : 1
12 | }
13 | }
14 |
--------------------------------------------------------------------------------
/Assets.xcassets/logo-anim.dataset/logo-anim.swf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madsmtm/ruffle-ios/5cc5a5b0eea87b03531b8ac1217160915d635be4/Assets.xcassets/logo-anim.dataset/logo-anim.swf
--------------------------------------------------------------------------------
/Assets.xcassets/ruffle-blue-6.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0xB6",
9 | "green" : "0x71",
10 | "red" : "0x52"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Assets.xcassets/ruffle-blue-9.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0x80",
9 | "green" : "0x49",
10 | "red" : "0x2C"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Assets.xcassets/ruffle-blue.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0x8C",
9 | "green" : "0x52",
10 | "red" : "0x37"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Assets.xcassets/ruffle-orange.colorset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "colors" : [
3 | {
4 | "color" : {
5 | "color-space" : "srgb",
6 | "components" : {
7 | "alpha" : "1.000",
8 | "blue" : "0x33",
9 | "green" : "0xAD",
10 | "red" : "0xFF"
11 | }
12 | },
13 | "idiom" : "universal"
14 | }
15 | ],
16 | "info" : {
17 | "author" : "xcode",
18 | "version" : 1
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
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 |
--------------------------------------------------------------------------------
/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
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 |
71 |
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 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
195 |
196 |
197 |
198 |
199 |
200 |
201 |
202 |
203 |
204 |
205 |
206 |
207 |
208 |
209 |
210 |
211 |
212 |
213 |
214 |
215 |
216 |
217 |
223 |
229 |
230 |
231 |
232 |
233 |
234 |
235 |
236 |
237 |
238 |
239 |
240 |
241 |
242 |
243 |
244 |
245 |
246 |
252 |
253 |
254 |
255 |
256 |
257 |
258 |
259 |
260 |
261 |
262 |
263 |
264 |
265 |
266 |
267 |
268 |
269 |
270 |
271 |
272 |
273 |
274 |
275 |
276 |
277 |
278 |
279 |
280 |
281 |
282 |
283 |
284 |
285 |
286 |
287 |
288 |
289 |
290 |
291 |
292 |
293 |
294 |
295 |
296 |
297 |
298 |
299 |
300 |
301 |
302 |
303 |
304 |
305 |
306 |
307 |
308 |
309 |
310 |
311 |
312 |
319 |
320 |
321 |
322 |
323 |
324 |
325 |
326 |
327 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
381 |
382 |
383 |
384 |
385 |
386 |
387 |
388 |
389 |
390 |
391 |
392 |
393 |
394 |
395 |
396 |
397 |
398 |
399 |
400 |
401 |
402 |
403 |
404 |
405 |
406 |
407 |
408 |
409 |
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "ruffle-ios"
3 | version = "0.1.0"
4 | authors = ["Mads Marquart "]
5 | edition = "2021"
6 | license = "MIT OR Apache-2.0"
7 | rust-version = "1.81"
8 | publish = false
9 |
10 | [features]
11 | default = ["render_debug_labels"]
12 | render_debug_labels = ["ruffle_render_wgpu/render_debug_labels"]
13 |
14 | [dependencies]
15 | block2 = "0.6.2"
16 | objc2 = "0.6.3"
17 | objc2-core-data = "0.3.2"
18 | objc2-core-foundation = "0.3.2"
19 | objc2-foundation = "0.3.2"
20 | objc2-ui-kit = "0.3.2"
21 | objc2-metal = "0.3.2"
22 | objc2-quartz-core = "0.3.2"
23 |
24 | ruffle_core = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master", features = [
25 | "audio",
26 | "symphonia",
27 | "mp3",
28 | "nellymoser",
29 | "lzma",
30 | "default_compatibility_rules",
31 | "default_font",
32 | ] }
33 | ruffle_render = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master" }
34 | ruffle_render_wgpu = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master" }
35 | ruffle_video = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master" }
36 | ruffle_video_software = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master" }
37 | ruffle_frontend_utils = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master", features = [
38 | "cpal",
39 | ] }
40 | flv-rs = { git = "https://github.com/ruffle-rs/ruffle.git", branch = "master" }
41 |
42 | wgpu = "25.0.2"
43 | cpal = "0.15.3"
44 | url = "2.5.2"
45 | tokio = { version = "1.40.0", features = ["rt-multi-thread", "macros"] }
46 | libc = "0.2.158"
47 |
48 | tracing = "0.1.40"
49 | tracing-subscriber = { version = "0.3.20", features = ["env-filter"] }
50 | tracing-oslog = "0.3.0"
51 |
52 | [package.metadata.bundle.bin.run_swf]
53 | name = "Ruffle"
54 | identifier = "rs.ruffle.ios-dev"
55 |
56 | [patch."https://github.com/ruffle-rs/ruffle.git"]
57 | # Override Ruffle for local development.
58 | # ruffle_core = { path = "../ruffle/core" }
59 | # ruffle_render = { path = "../ruffle/render" }
60 | # ruffle_render_wgpu = { path = "../ruffle/render/wgpu" }
61 | # ruffle_video = { path = "../ruffle/video" }
62 | # ruffle_video_software = { path = "../ruffle/video/software" }
63 | # ruffle_frontend_utils = { path = "../ruffle/frontend-utils" }
64 | # flv-rs = { path = "../ruffle/flv" }
65 |
66 | [patch.crates-io]
67 | # Fix broken Mac Catalyst.
68 | cc = { git = "https://github.com/madsmtm/cc-rs.git", branch = "macabi" }
69 |
70 | # visionOS support
71 | # wgpu = { path = "../wgpu/wgpu" }
72 | # naga = { path = "../wgpu/naga" }
73 | # Cannot use git, see https://github.com/briansmith/ring/issues/2144
74 | # ring = { git = "https://github.com/briansmith/ring.git", rev = "2bec9b2e057416e8f58f2ad8d47ccc9599ea6146" }
75 |
--------------------------------------------------------------------------------
/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDocumentTypes
6 |
7 |
8 | CFBundleTypeName
9 | Bundle
10 | LSItemContentTypes
11 |
12 | com.example.rs.ruffle.bundle
13 |
14 | CFBundleTypeRole
15 | Viewer
16 | LSHandlerRank
17 | Owner
18 | LSTypeIsPackage
19 |
20 |
21 |
22 | CFBundleTypeName
23 | Shockwave Flash Movie
24 | LSItemContentTypes
25 |
26 | com.adobe.swf
27 |
28 | CFBundleTypeRole
29 | Viewer
30 | LSHandlerRank
31 | Owner
32 | LSTypeIsPackage
33 |
34 |
35 |
36 | UIApplicationSceneManifest
37 |
38 | UIApplicationSupportsMultipleScenes
39 |
40 | UISceneConfigurations
41 |
42 | UIWindowSceneSessionRoleApplication
43 |
44 |
45 | UISceneConfigurationName
46 | Default Configuration
47 | UISceneDelegateClassName
48 | SceneDelegate
49 | UISceneStoryboardFile
50 | Main
51 |
52 |
53 |
54 |
55 | UTExportedTypeDeclarations
56 |
57 |
58 | UTTypeIdentifier
59 | com.example.rs.ruffle.bundle
60 | UTTypeDescription
61 | Ruffle Bundle
62 | UTTypeIconFiles
63 |
64 | document_ruf.icns
65 |
66 | UTTypeConformsTo
67 |
68 | public.data
69 | public.content
70 | public.directory
71 | public.audiovisual-content
72 | com.apple.package
73 | public.archive
74 | public.zip-archive
75 |
76 | UTTypeTagSpecification
77 |
78 | public.filename-extension
79 |
80 | ruf
81 |
82 |
83 |
84 |
85 | UTImportedTypeDeclarations
86 |
87 |
88 | UTTypeIdentifier
89 | com.adobe.swf
90 | UTTypeDescription
91 | Shockwave Flash Movie
92 | UTTypeIconFiles
93 |
94 | document_swf.icns
95 |
96 | UTTypeConformsTo
97 |
98 | public.data
99 | public.content
100 | public.audiovisual-content
101 |
102 | UTTypeTagSpecification
103 |
104 | public.filename-extension
105 |
106 | swf
107 |
108 | public.mime-type
109 |
110 | application/vnd.adobe.flash.movie
111 | application/x-shockwave-flash
112 |
113 | com.apple.ostype
114 |
115 | SWFL
116 |
117 |
118 |
119 |
120 |
121 |
122 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # ruffle-ios license
2 |
3 | ruffle-ios is licensed under either of
4 |
5 | - Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
6 | - MIT license (http://opensource.org/licenses/MIT)
7 |
8 | at your option.
9 |
10 | ## MIT License
11 |
12 | Copyright (c) 2018-2022 Ruffle LLC and Ruffle contributors
13 | (https://github.com/ruffle-rs/ruffle/graphs/contributors)
14 |
15 | Permission is hereby granted, free of charge, to any
16 | person obtaining a copy of this software and associated
17 | documentation files (the "Software"), to deal in the
18 | Software without restriction, including without
19 | limitation the rights to use, copy, modify, merge,
20 | publish, distribute, sublicense, and/or sell copies of
21 | the Software, and to permit persons to whom the Software
22 | is furnished to do so, subject to the following
23 | conditions:
24 |
25 | The above copyright notice and this permission notice
26 | shall be included in all copies or substantial portions
27 | of the Software.
28 |
29 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
30 | ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
31 | TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
32 | PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
33 | SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
34 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
35 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
36 | IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
37 | DEALINGS IN THE SOFTWARE.
38 |
39 | ## Apache License, Version 2.0
40 |
41 | Apache License
42 | Version 2.0, January 2004
43 | http://www.apache.org/licenses/
44 |
45 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
46 |
47 | 1. Definitions.
48 |
49 | "License" shall mean the terms and conditions for use, reproduction,
50 | and distribution as defined by Sections 1 through 9 of this document.
51 |
52 | "Licensor" shall mean the copyright owner or entity authorized by
53 | the copyright owner that is granting the License.
54 |
55 | "Legal Entity" shall mean the union of the acting entity and all
56 | other entities that control, are controlled by, or are under common
57 | control with that entity. For the purposes of this definition,
58 | "control" means (i) the power, direct or indirect, to cause the
59 | direction or management of such entity, whether by contract or
60 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
61 | outstanding shares, or (iii) beneficial ownership of such entity.
62 |
63 | "You" (or "Your") shall mean an individual or Legal Entity
64 | exercising permissions granted by this License.
65 |
66 | "Source" form shall mean the preferred form for making modifications,
67 | including but not limited to software source code, documentation
68 | source, and configuration files.
69 |
70 | "Object" form shall mean any form resulting from mechanical
71 | transformation or translation of a Source form, including but
72 | not limited to compiled object code, generated documentation,
73 | and conversions to other media types.
74 |
75 | "Work" shall mean the work of authorship, whether in Source or
76 | Object form, made available under the License, as indicated by a
77 | copyright notice that is included in or attached to the work
78 | (an example is provided in the Appendix below).
79 |
80 | "Derivative Works" shall mean any work, whether in Source or Object
81 | form, that is based on (or derived from) the Work and for which the
82 | editorial revisions, annotations, elaborations, or other modifications
83 | represent, as a whole, an original work of authorship. For the purposes
84 | of this License, Derivative Works shall not include works that remain
85 | separable from, or merely link (or bind by name) to the interfaces of,
86 | the Work and Derivative Works thereof.
87 |
88 | "Contribution" shall mean any work of authorship, including
89 | the original version of the Work and any modifications or additions
90 | to that Work or Derivative Works thereof, that is intentionally
91 | submitted to Licensor for inclusion in the Work by the copyright owner
92 | or by an individual or Legal Entity authorized to submit on behalf of
93 | the copyright owner. For the purposes of this definition, "submitted"
94 | means any form of electronic, verbal, or written communication sent
95 | to the Licensor or its representatives, including but not limited to
96 | communication on electronic mailing lists, source code control systems,
97 | and issue tracking systems that are managed by, or on behalf of, the
98 | Licensor for the purpose of discussing and improving the Work, but
99 | excluding communication that is conspicuously marked or otherwise
100 | designated in writing by the copyright owner as "Not a Contribution."
101 |
102 | "Contributor" shall mean Licensor and any individual or Legal Entity
103 | on behalf of whom a Contribution has been received by Licensor and
104 | subsequently incorporated within the Work.
105 |
106 | 2. Grant of Copyright License. Subject to the terms and conditions of
107 | this License, each Contributor hereby grants to You a perpetual,
108 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
109 | copyright license to reproduce, prepare Derivative Works of,
110 | publicly display, publicly perform, sublicense, and distribute the
111 | Work and such Derivative Works in Source or Object form.
112 |
113 | 3. Grant of Patent License. Subject to the terms and conditions of
114 | this License, each Contributor hereby grants to You a perpetual,
115 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
116 | (except as stated in this section) patent license to make, have made,
117 | use, offer to sell, sell, import, and otherwise transfer the Work,
118 | where such license applies only to those patent claims licensable
119 | by such Contributor that are necessarily infringed by their
120 | Contribution(s) alone or by combination of their Contribution(s)
121 | with the Work to which such Contribution(s) was submitted. If You
122 | institute patent litigation against any entity (including a
123 | cross-claim or counterclaim in a lawsuit) alleging that the Work
124 | or a Contribution incorporated within the Work constitutes direct
125 | or contributory patent infringement, then any patent licenses
126 | granted to You under this License for that Work shall terminate
127 | as of the date such litigation is filed.
128 |
129 | 4. Redistribution. You may reproduce and distribute copies of the
130 | Work or Derivative Works thereof in any medium, with or without
131 | modifications, and in Source or Object form, provided that You
132 | meet the following conditions:
133 |
134 | (a) You must give any other recipients of the Work or
135 | Derivative Works a copy of this License; and
136 |
137 | (b) You must cause any modified files to carry prominent notices
138 | stating that You changed the files; and
139 |
140 | (c) You must retain, in the Source form of any Derivative Works
141 | that You distribute, all copyright, patent, trademark, and
142 | attribution notices from the Source form of the Work,
143 | excluding those notices that do not pertain to any part of
144 | the Derivative Works; and
145 |
146 | (d) If the Work includes a "NOTICE" text file as part of its
147 | distribution, then any Derivative Works that You distribute must
148 | include a readable copy of the attribution notices contained
149 | within such NOTICE file, excluding those notices that do not
150 | pertain to any part of the Derivative Works, in at least one
151 | of the following places: within a NOTICE text file distributed
152 | as part of the Derivative Works; within the Source form or
153 | documentation, if provided along with the Derivative Works; or,
154 | within a display generated by the Derivative Works, if and
155 | wherever such third-party notices normally appear. The contents
156 | of the NOTICE file are for informational purposes only and
157 | do not modify the License. You may add Your own attribution
158 | notices within Derivative Works that You distribute, alongside
159 | or as an addendum to the NOTICE text from the Work, provided
160 | that such additional attribution notices cannot be construed
161 | as modifying the License.
162 |
163 | You may add Your own copyright statement to Your modifications and
164 | may provide additional or different license terms and conditions
165 | for use, reproduction, or distribution of Your modifications, or
166 | for any such Derivative Works as a whole, provided Your use,
167 | reproduction, and distribution of the Work otherwise complies with
168 | the conditions stated in this License.
169 |
170 | 5. Submission of Contributions. Unless You explicitly state otherwise,
171 | any Contribution intentionally submitted for inclusion in the Work
172 | by You to the Licensor shall be under the terms and conditions of
173 | this License, without any additional terms or conditions.
174 | Notwithstanding the above, nothing herein shall supersede or modify
175 | the terms of any separate license agreement you may have executed
176 | with Licensor regarding such Contributions.
177 |
178 | 6. Trademarks. This License does not grant permission to use the trade
179 | names, trademarks, service marks, or product names of the Licensor,
180 | except as required for reasonable and customary use in describing the
181 | origin of the Work and reproducing the content of the NOTICE file.
182 |
183 | 7. Disclaimer of Warranty. Unless required by applicable law or
184 | agreed to in writing, Licensor provides the Work (and each
185 | Contributor provides its Contributions) on an "AS IS" BASIS,
186 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
187 | implied, including, without limitation, any warranties or conditions
188 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
189 | PARTICULAR PURPOSE. You are solely responsible for determining the
190 | appropriateness of using or redistributing the Work and assume any
191 | risks associated with Your exercise of permissions under this License.
192 |
193 | 8. Limitation of Liability. In no event and under no legal theory,
194 | whether in tort (including negligence), contract, or otherwise,
195 | unless required by applicable law (such as deliberate and grossly
196 | negligent acts) or agreed to in writing, shall any Contributor be
197 | liable to You for damages, including any direct, indirect, special,
198 | incidental, or consequential damages of any character arising as a
199 | result of this License or out of the use or inability to use the
200 | Work (including but not limited to damages for loss of goodwill,
201 | work stoppage, computer failure or malfunction, or any and all
202 | other commercial damages or losses), even if such Contributor
203 | has been advised of the possibility of such damages.
204 |
205 | 9. Accepting Warranty or Additional Liability. While redistributing
206 | the Work or Derivative Works thereof, You may choose to offer,
207 | and charge a fee for, acceptance of support, warranty, indemnity,
208 | or other liability obligations and/or rights consistent with this
209 | License. However, in accepting such obligations, You may act only
210 | on Your own behalf and on Your sole responsibility, not on behalf
211 | of any other Contributor, and only if You agree to indemnify,
212 | defend, and hold each Contributor harmless for any liability
213 | incurred by, or claims asserted against, such Contributor by reason
214 | of your accepting any such warranty or additional liability.
215 |
216 | END OF TERMS AND CONDITIONS
217 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # The Ruffle Flash Player emulator on iOS
2 |
3 | Work in progress.
4 |
5 | See [ruffle.rs](https://ruffle.rs/) for a general introduction.
6 |
7 |
8 | ## Design choices
9 |
10 | A normal person might have wrapped the Rust in some `extern "C" fn`s, and then used SwiftUI, or at least Objective-C for the UI shell. I would probably recommend that for most use-cases.
11 |
12 | I'm developing [`objc2`](https://github.com/madsmtm/objc2) though, and I want to improve the user-interface of that, so I decided to be a bit unortodox, and do everything in Rust.
13 |
14 | ## Testing
15 |
16 | Run the core player on Mac Catalyst with:
17 | ```
18 | # Mac Catalyst uses the macOS SDK
19 | export COREAUDIO_SDK_PATH=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk
20 | cargo bundle --target=aarch64-apple-ios-macabi --bin run_swf && ./target/aarch64-apple-ios-macabi/debug/bundle/ios/Ruffle.app/run_swf
21 | ```
22 |
23 | The proper application can also be launched from the iOS Simulator by opening [the Xcode project](./ruffle-ios.xcodeproj).
24 |
25 | To open an SWF/Ruffle bundle, simply drag and drop the `.swf`/`.ruf` onto the simulator window, see:
26 | https://developer.apple.com/documentation/xcode/sharing-data-with-simulator
27 |
28 | NOTE: The simulator has to have read permissions for the file, you may have to place it outside the `Desktop`/`Documents`/... folders, which require special permission setup.
29 |
30 | ## UI
31 |
32 | Similar to https://getutm.app/, we should have:
33 | - A library of "installed" SWFs/bundles/saved links, editable.
34 | - When selecting an SWF, the navigation bar at the top shows various options
35 | - Opening keyboard (maybe?)
36 | - Context menu "play, rewind, forward, back, etc."?
37 | - Allow changing between scale
38 | - Back button to go back to library
39 | - "Add" and "edit" are two different flows, and should show two different UIs
40 | - "Add" doesn't have to show all the extra settings; it is only about getting the file. The user can edit it later.
41 |
42 | ## Library item settings
43 |
44 | Settings are stored per Ruffle Bundle.
45 |
46 | - `PlayerOptions`
47 | - https://github.com/ruffle-rs/ruffle/blob/master/frontend-utils/src/bundle/README.md#player
48 | - Inputs:
49 | - Configurable
50 | - Swipe for arrow keys?
51 | - https://openemu.org/ does it pretty well, equivalent for iOS?
52 | - Custom name?
53 | - Custom image?
54 |
55 |
56 | ## Storage
57 |
58 | We do not store Ruffle Bundles / SWFs, the user is responsible for doing that themselves in the Files app. We only store "bookmarks" to these, to allow easily re-opening from within the app, and to store user data.
59 |
60 | This can be synced to iCloud, though the user may have to re-select the referenced Ruffle Bundle (in case it was stored locally, and not in iCloud).
61 |
62 | Goal: Be backwards and forwards compatible with new versions of the Ruffle app.
63 | - Upheld for [Ruffle Bundles](https://discord.com/channels/610531541889581066/1225519553916829736/1232031955751665777).
64 | - Should also be fine for user settings.
65 |
66 | See [src/storage.rs] for implementation.
67 |
68 |
69 | ## Terminology
70 |
71 | What do we call an SWF / a Ruffle Bundle? "Game"? "Movie"? "SWF"? "Flash Animation"?
72 |
73 | Internally: "movie".
74 |
75 |
76 | ## Plan
77 |
78 | 1. Get the Ruffle UI running in a `UIView`
79 | 2. Wire up some way to start it using an SWF on the local device
80 |
81 |
82 | ## TODO
83 |
84 | - Set `idleTimerDisabled` at the appropriate time
85 | - Use white for labels, orange for buttons
86 | - Add settings button in library item
87 | - Add quicklook thumbnail generator app extension
88 | - Figure out what `UIDocument` actually does?
89 | - Ensure that CoreData stores a bookmark of the NSURL, and if not, do that ourselves.
90 | - https://developer.apple.com/documentation/foundation/nsurl/1417795-bookmarkdatawithoptions?language=objc
91 | - https://developer.apple.com/documentation/foundation/nsurl/1408532-writebookmarkdata?language=objc
92 | - Sync
93 | - https://developer.apple.com/documentation/xcode/configuring-icloud-services?language=objc
94 | - https://developer.apple.com/documentation/foundation/optimizing_your_app_s_data_for_icloud_backup?language=objc
95 | - https://developer.apple.com/library/archive/documentation/General/Conceptual/iCloudDesignGuide/Chapters/DesigningForDocumentsIniCloud.html#//apple_ref/doc/uid/TP40012094-CH2
96 | - https://developer.apple.com/documentation/uikit/synchronizing-documents-in-the-icloud-environment?language=objc
97 |
98 | ## Choices
99 |
100 | - Intentionally use `public.app-category.games` to get better performance ("Game Mode" on macOS).
101 | - This is not necessarily the correct choice for Ruffle, but it's the closest.
102 | - It doesn't make sense to have root settings like in the desktop version
103 | - No tab bar, not really desired, since we generally want the SWF's UI to fill most of the screen
104 | - Though if we decide to add an easy way to download from "trusted" sources, we could add a tab bar for that
105 | - A navigation bar is useful though
106 | - To display some settings for the current swf
107 | - To go back to library
108 | - Hide when entering full screen?
109 |
--------------------------------------------------------------------------------
/Ruffle.xcdatamodeld/Ruffle.xcdatamodel/contents:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
--------------------------------------------------------------------------------
/build-in-xcode.sh:
--------------------------------------------------------------------------------
1 | # Modified from https://gitlab.com/kornelski/cargo-xcode/-/blob/9b1679b950d16f42eb14fb8446ae1a80e2c867d2/src/xcodebuild.sh
2 |
3 | set -euo pipefail;
4 | export PATH="$HOME/.cargo/bin:$PATH:/usr/local/bin:/opt/homebrew/bin";
5 | # don't use ios/watchos linker for build scripts and proc macros
6 | export CARGO_TARGET_AARCH64_APPLE_DARWIN_LINKER=/usr/bin/ld
7 | export CARGO_TARGET_X86_64_APPLE_DARWIN_LINKER=/usr/bin/ld
8 | export NO_COLOR=1
9 | OTHER_INPUT_FILE_FLAGS=""
10 |
11 | # Make Cargo output cache files in Xcode's directories
12 | export CARGO_TARGET_DIR=$DERIVED_FILE_DIR
13 |
14 | case "$PLATFORM_NAME" in
15 | "macosx")
16 | CARGO_XCODE_TARGET_OS=darwin
17 | if [ "${IS_MACCATALYST-NO}" = YES ]; then
18 | CARGO_XCODE_TARGET_OS=ios-macabi
19 | fi
20 | ;;
21 | "iphoneos") CARGO_XCODE_TARGET_OS=ios ;;
22 | "iphonesimulator") CARGO_XCODE_TARGET_OS=ios-sim ;;
23 | "appletvos" | "appletvsimulator") CARGO_XCODE_TARGET_OS=tvos ;;
24 | "watchos") CARGO_XCODE_TARGET_OS=watchos ;;
25 | "watchsimulator") CARGO_XCODE_TARGET_OS=watchos-sim ;;
26 | "xros") CARGO_XCODE_TARGET_OS=visionos ;;
27 | "xrsimulator") CARGO_XCODE_TARGET_OS=visionos-sim ;;
28 | *)
29 | CARGO_XCODE_TARGET_OS="$PLATFORM_NAME"
30 | echo >&2 "warning: cargo-xcode needs to be updated to handle $PLATFORM_NAME"
31 | ;;
32 | esac
33 |
34 | case "$CONFIGURATION" in
35 | "Debug")
36 | CARGO_XCODE_BUILD_PROFILE=debug
37 | ;;
38 | "Release")
39 | CARGO_XCODE_BUILD_PROFILE=release
40 | OTHER_INPUT_FILE_FLAGS+=" --release"
41 | ;;
42 | *)
43 | echo >&2 "warning: cargo-xcode needs to be updated to handle CONFIGURATION=$CONFIGURATION"
44 | ;;
45 | esac
46 |
47 | CARGO_XCODE_TARGET_TRIPLES=""
48 | CARGO_XCODE_TARGET_FLAGS=""
49 | LIPO_ARGS=""
50 | for arch in $ARCHS; do
51 | if [[ "$arch" == "arm64" ]]; then arch=aarch64; fi
52 | if [[ "$arch" == "i386" && "$CARGO_XCODE_TARGET_OS" != "ios" ]]; then arch=i686; fi
53 | triple="${arch}-apple-$CARGO_XCODE_TARGET_OS"
54 | CARGO_XCODE_TARGET_TRIPLES+=" $triple"
55 | CARGO_XCODE_TARGET_FLAGS+=" --target=$triple"
56 | LIPO_ARGS+="$CARGO_TARGET_DIR/$triple/$CARGO_XCODE_BUILD_PROFILE/$EXECUTABLE_NAME
57 | "
58 | done
59 |
60 | echo >&2 "Cargo $CONFIGURATION $ACTION for $PLATFORM_NAME $ARCHS =$CARGO_XCODE_TARGET_TRIPLES; using ${SDK_NAMES:-}. \$PATH is:"
61 | tr >&2 : '\n' <<<"$PATH"
62 |
63 | if [ "$ACTION" = clean ]; then
64 | cargo clean --verbose $CARGO_XCODE_TARGET_FLAGS $OTHER_INPUT_FILE_FLAGS;
65 | rm -f "$SCRIPT_OUTPUT_FILE_0"
66 | exit 0
67 | fi
68 |
69 | { cargo build --features="${CARGO_XCODE_FEATURES:-}" $CARGO_XCODE_TARGET_FLAGS $OTHER_INPUT_FILE_FLAGS --verbose --message-format=short 2>&1 | sed -E 's/^([^ :]+:[0-9]+:[0-9]+: error)/\1: /' >&2; } || { echo >&2 "error: cargo-xcode project build failed; $CARGO_XCODE_TARGET_TRIPLES"; exit 1; }
70 |
71 | tr '\n' '\0' <<<"$LIPO_ARGS" | xargs -0 lipo -create -output "$SCRIPT_OUTPUT_FILE_0"
72 |
73 | if [ ${LD_DYLIB_INSTALL_NAME:+1} ]; then
74 | install_name_tool -id "$LD_DYLIB_INSTALL_NAME" "$SCRIPT_OUTPUT_FILE_0"
75 | fi
76 |
77 | DEP_FILE_DST="$DERIVED_FILE_DIR/${ARCHS}-${EXECUTABLE_NAME}.d"
78 | echo "" > "$DEP_FILE_DST"
79 | for triple in $CARGO_XCODE_TARGET_TRIPLES; do
80 | BUILT_SRC="$CARGO_TARGET_DIR/$triple/$CARGO_XCODE_BUILD_PROFILE/$EXECUTABLE_NAME"
81 |
82 | # cargo generates a dep file, but for its own path, so append our rename to it
83 | DEP_FILE_SRC="$CARGO_TARGET_DIR/$triple/$CARGO_XCODE_BUILD_PROFILE/$EXECUTABLE_NAME.d"
84 | if [ -f "$DEP_FILE_SRC" ]; then
85 | cat "$DEP_FILE_SRC" >> "$DEP_FILE_DST"
86 | fi
87 | echo >> "$DEP_FILE_DST" "${SCRIPT_OUTPUT_FILE_0/ /\\ /}: ${BUILT_SRC/ /\\ /}"
88 | done
89 | cat "$DEP_FILE_DST"
90 |
91 | echo "success: $ACTION of $SCRIPT_OUTPUT_FILE_0 for $CARGO_XCODE_TARGET_TRIPLES"
92 |
--------------------------------------------------------------------------------
/file-icons/ATTRIBUTION.md:
--------------------------------------------------------------------------------
1 | # File Icon Attribution
2 |
3 | The `document_swf` icon is taken directly from Flash Player, produced by Adobe, and of unknown license.
4 |
5 | The `document_ruf` icon is taken from [here](https://discord.com/channels/610531541889581066/1225519553916829736/1225933184630521926).
6 |
7 | Conversion between the different formats is done with the `icnsutil` Python package.
8 |
--------------------------------------------------------------------------------
/file-icons/document_ruf.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madsmtm/ruffle-ios/5cc5a5b0eea87b03531b8ac1217160915d635be4/file-icons/document_ruf.icns
--------------------------------------------------------------------------------
/file-icons/document_swf.icns:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madsmtm/ruffle-ios/5cc5a5b0eea87b03531b8ac1217160915d635be4/file-icons/document_swf.icns
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "info" : {
3 | "author" : "xcode",
4 | "version" : 1
5 | }
6 | }
7 |
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/document_ruf.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "document_ruf.svg",
5 | "idiom" : "universal"
6 | }
7 | ],
8 | "info" : {
9 | "author" : "xcode",
10 | "version" : 1
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/document_ruf.imageset/document_ruf.svg:
--------------------------------------------------------------------------------
1 |
18 |
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/document_swf.imageset/256x256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madsmtm/ruffle-ios/5cc5a5b0eea87b03531b8ac1217160915d635be4/file-icons/file-icons.xcassets/document_swf.imageset/256x256.png
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/document_swf.imageset/512x512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/madsmtm/ruffle-ios/5cc5a5b0eea87b03531b8ac1217160915d635be4/file-icons/file-icons.xcassets/document_swf.imageset/512x512.png
--------------------------------------------------------------------------------
/file-icons/file-icons.xcassets/document_swf.imageset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "filename" : "256x256.png",
5 | "idiom" : "universal",
6 | "scale" : "1x"
7 | },
8 | {
9 | "filename" : "512x512.png",
10 | "idiom" : "universal",
11 | "scale" : "2x"
12 | },
13 | {
14 | "idiom" : "universal",
15 | "scale" : "3x"
16 | }
17 | ],
18 | "info" : {
19 | "author" : "xcode",
20 | "version" : 1
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/ruffle-ios.entitlements:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | com.apple.security.app-sandbox
6 |
7 | com.apple.security.files.bookmarks.document-scope
8 |
9 | com.apple.security.files.user-selected.read-write
10 |
11 | com.apple.security.network.client
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/ruffle-ios.xcodeproj/project.pbxproj:
--------------------------------------------------------------------------------
1 | // !$*UTF8*$!
2 | {
3 | archiveVersion = 1;
4 | classes = {
5 | };
6 | objectVersion = 56;
7 | objects = {
8 |
9 | /* Begin PBXBuildFile section */
10 | EC3BA0B72C93A6CA0072939D /* Base in Resources */ = {isa = PBXBuildFile; fileRef = EC3BA0B62C93A6CA0072939D /* Base */; };
11 | EC3BA0BC2C93A6CB0072939D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC3BA0BB2C93A6CB0072939D /* Assets.xcassets */; };
12 | EC3BA0BF2C93A6CB0072939D /* Base in Resources */ = {isa = PBXBuildFile; fileRef = EC3BA0BE2C93A6CB0072939D /* Base */; };
13 | EC42DF8D2C98FADB009998B2 /* document_swf.icns in Resources */ = {isa = PBXBuildFile; fileRef = EC42DF892C98FADB009998B2 /* document_swf.icns */; };
14 | EC42DF8E2C98FADB009998B2 /* file-icons.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = EC42DF8A2C98FADB009998B2 /* file-icons.xcassets */; };
15 | EC42DF902C98FE4A009998B2 /* document_ruf.icns in Resources */ = {isa = PBXBuildFile; fileRef = EC42DF8F2C98FE4A009998B2 /* document_ruf.icns */; };
16 | EC5247022D4B11C30040F6D0 /* Ruffle.xcdatamodeld in Sources */ = {isa = PBXBuildFile; fileRef = EC5246FC2D4B03C00040F6D0 /* Ruffle.xcdatamodeld */; };
17 | /* End PBXBuildFile section */
18 |
19 | /* Begin PBXFileReference section */
20 | EC3BA0A92C93A6CA0072939D /* ruffle-ios.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = "ruffle-ios.app"; sourceTree = BUILT_PRODUCTS_DIR; };
21 | EC3BA0B62C93A6CA0072939D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; };
22 | EC3BA0BB2C93A6CB0072939D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; };
23 | EC3BA0BE2C93A6CB0072939D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; };
24 | EC3BA0C02C93A6CB0072939D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; };
25 | EC3BA0C82C93A7400072939D /* ruffle-ios.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = "ruffle-ios.entitlements"; sourceTree = ""; };
26 | EC3BA0C92C93A87E0072939D /* src */ = {isa = PBXFileReference; lastKnownFileType = folder; path = src; sourceTree = ""; };
27 | EC3BA0CB2C93A8890072939D /* Cargo.lock */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cargo.lock; sourceTree = ""; };
28 | EC3BA0CC2C93A8890072939D /* Cargo.toml */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = Cargo.toml; sourceTree = ""; };
29 | EC42DF882C98FADB009998B2 /* ATTRIBUTION.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = ATTRIBUTION.md; sourceTree = ""; };
30 | EC42DF892C98FADB009998B2 /* document_swf.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = document_swf.icns; sourceTree = ""; };
31 | EC42DF8A2C98FADB009998B2 /* file-icons.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = "file-icons.xcassets"; sourceTree = ""; };
32 | EC42DF8F2C98FE4A009998B2 /* document_ruf.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; path = document_ruf.icns; sourceTree = ""; };
33 | EC5246FD2D4B03C00040F6D0 /* Ruffle.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = Ruffle.xcdatamodel; sourceTree = ""; };
34 | ECEA01DB2C948F9A00C9D3D6 /* build-in-xcode.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = "build-in-xcode.sh"; sourceTree = ""; };
35 | ECEA01DF2C9495C700C9D3D6 /* .cargo */ = {isa = PBXFileReference; lastKnownFileType = folder; path = .cargo; sourceTree = ""; };
36 | /* End PBXFileReference section */
37 |
38 | /* Begin PBXGroup section */
39 | EC3BA0A02C93A6CA0072939D = {
40 | isa = PBXGroup;
41 | children = (
42 | EC42DF8B2C98FADB009998B2 /* file-icons */,
43 | EC3BA0C02C93A6CB0072939D /* Info.plist */,
44 | EC3BA0C82C93A7400072939D /* ruffle-ios.entitlements */,
45 | EC3BA0BD2C93A6CB0072939D /* LaunchScreen.storyboard */,
46 | EC3BA0B52C93A6CA0072939D /* Main.storyboard */,
47 | EC3BA0BB2C93A6CB0072939D /* Assets.xcassets */,
48 | EC5246FC2D4B03C00040F6D0 /* Ruffle.xcdatamodeld */,
49 | ECEA01DB2C948F9A00C9D3D6 /* build-in-xcode.sh */,
50 | EC3BA0CC2C93A8890072939D /* Cargo.toml */,
51 | EC3BA0CB2C93A8890072939D /* Cargo.lock */,
52 | ECEA01DF2C9495C700C9D3D6 /* .cargo */,
53 | EC3BA0C92C93A87E0072939D /* src */,
54 | EC3BA0AA2C93A6CA0072939D /* Products */,
55 | );
56 | sourceTree = "";
57 | };
58 | EC3BA0AA2C93A6CA0072939D /* Products */ = {
59 | isa = PBXGroup;
60 | children = (
61 | EC3BA0A92C93A6CA0072939D /* ruffle-ios.app */,
62 | );
63 | name = Products;
64 | sourceTree = "";
65 | };
66 | EC42DF8B2C98FADB009998B2 /* file-icons */ = {
67 | isa = PBXGroup;
68 | children = (
69 | EC42DF882C98FADB009998B2 /* ATTRIBUTION.md */,
70 | EC42DF8A2C98FADB009998B2 /* file-icons.xcassets */,
71 | EC42DF8F2C98FE4A009998B2 /* document_ruf.icns */,
72 | EC42DF892C98FADB009998B2 /* document_swf.icns */,
73 | );
74 | path = "file-icons";
75 | sourceTree = "";
76 | };
77 | /* End PBXGroup section */
78 |
79 | /* Begin PBXNativeTarget section */
80 | EC3BA0A82C93A6CA0072939D /* ruffle-ios */ = {
81 | isa = PBXNativeTarget;
82 | buildConfigurationList = EC3BA0C52C93A6CB0072939D /* Build configuration list for PBXNativeTarget "ruffle-ios" */;
83 | buildPhases = (
84 | EC5247012D4B11BE0040F6D0 /* Sources */,
85 | ECEA01DC2C948FAD00C9D3D6 /* ShellScript */,
86 | ECEA01DE2C94929900C9D3D6 /* ShellScript */,
87 | EC3BA0A72C93A6CA0072939D /* Resources */,
88 | );
89 | buildRules = (
90 | );
91 | dependencies = (
92 | );
93 | name = "ruffle-ios";
94 | productName = "ruffle-ios";
95 | productReference = EC3BA0A92C93A6CA0072939D /* ruffle-ios.app */;
96 | productType = "com.apple.product-type.application";
97 | };
98 | /* End PBXNativeTarget section */
99 |
100 | /* Begin PBXProject section */
101 | EC3BA0A12C93A6CA0072939D /* Project object */ = {
102 | isa = PBXProject;
103 | attributes = {
104 | BuildIndependentTargetsInParallel = 1;
105 | LastUpgradeCheck = 1540;
106 | TargetAttributes = {
107 | EC3BA0A82C93A6CA0072939D = {
108 | CreatedOnToolsVersion = 15.4;
109 | };
110 | };
111 | };
112 | buildConfigurationList = EC3BA0A42C93A6CA0072939D /* Build configuration list for PBXProject "ruffle-ios" */;
113 | compatibilityVersion = "Xcode 14.0";
114 | developmentRegion = en;
115 | hasScannedForEncodings = 0;
116 | knownRegions = (
117 | en,
118 | Base,
119 | );
120 | mainGroup = EC3BA0A02C93A6CA0072939D;
121 | productRefGroup = EC3BA0AA2C93A6CA0072939D /* Products */;
122 | projectDirPath = "";
123 | projectRoot = "";
124 | targets = (
125 | EC3BA0A82C93A6CA0072939D /* ruffle-ios */,
126 | );
127 | };
128 | /* End PBXProject section */
129 |
130 | /* Begin PBXResourcesBuildPhase section */
131 | EC3BA0A72C93A6CA0072939D /* Resources */ = {
132 | isa = PBXResourcesBuildPhase;
133 | buildActionMask = 2147483647;
134 | files = (
135 | EC3BA0BC2C93A6CB0072939D /* Assets.xcassets in Resources */,
136 | EC3BA0BF2C93A6CB0072939D /* Base in Resources */,
137 | EC3BA0B72C93A6CA0072939D /* Base in Resources */,
138 | EC42DF902C98FE4A009998B2 /* document_ruf.icns in Resources */,
139 | EC42DF8E2C98FADB009998B2 /* file-icons.xcassets in Resources */,
140 | EC42DF8D2C98FADB009998B2 /* document_swf.icns in Resources */,
141 | );
142 | runOnlyForDeploymentPostprocessing = 0;
143 | };
144 | /* End PBXResourcesBuildPhase section */
145 |
146 | /* Begin PBXShellScriptBuildPhase section */
147 | ECEA01DC2C948FAD00C9D3D6 /* ShellScript */ = {
148 | isa = PBXShellScriptBuildPhase;
149 | buildActionMask = 2147483647;
150 | dependencyFile = "$(DERIVED_FILE_DIR)/$(ARCHS)-$(EXECUTABLE_NAME).d";
151 | files = (
152 | );
153 | inputFileListPaths = (
154 | );
155 | inputPaths = (
156 | "$(SRCROOT)/Cargo.toml",
157 | "$(SRCROOT)/build-in-xcode.sh",
158 | "$(SRCROOT)/.cargo/config.toml",
159 | );
160 | outputFileListPaths = (
161 | );
162 | outputPaths = (
163 | "$(OBJECT_FILE_DIR)/$(EXECUTABLE_NAME)",
164 | );
165 | runOnlyForDeploymentPostprocessing = 0;
166 | shellPath = /bin/sh;
167 | shellScript = "./build-in-xcode.sh\n";
168 | };
169 | ECEA01DE2C94929900C9D3D6 /* ShellScript */ = {
170 | isa = PBXShellScriptBuildPhase;
171 | buildActionMask = 2147483647;
172 | files = (
173 | );
174 | inputFileListPaths = (
175 | );
176 | inputPaths = (
177 | "$(OBJECT_FILE_DIR)/$(EXECUTABLE_NAME)",
178 | );
179 | outputFileListPaths = (
180 | );
181 | outputPaths = (
182 | "$(TARGET_BUILD_DIR)/$(EXECUTABLE_PATH)",
183 | );
184 | runOnlyForDeploymentPostprocessing = 0;
185 | shellPath = /bin/sh;
186 | shellScript = "# Type a script or drag a script file from your workspace to insert its path.\ncp $OBJECT_FILE_DIR/$EXECUTABLE_NAME $TARGET_BUILD_DIR/$EXECUTABLE_PATH\n";
187 | };
188 | /* End PBXShellScriptBuildPhase section */
189 |
190 | /* Begin PBXSourcesBuildPhase section */
191 | EC5247012D4B11BE0040F6D0 /* Sources */ = {
192 | isa = PBXSourcesBuildPhase;
193 | buildActionMask = 2147483647;
194 | files = (
195 | EC5247022D4B11C30040F6D0 /* Ruffle.xcdatamodeld in Sources */,
196 | );
197 | runOnlyForDeploymentPostprocessing = 0;
198 | };
199 | /* End PBXSourcesBuildPhase section */
200 |
201 | /* Begin PBXVariantGroup section */
202 | EC3BA0B52C93A6CA0072939D /* Main.storyboard */ = {
203 | isa = PBXVariantGroup;
204 | children = (
205 | EC3BA0B62C93A6CA0072939D /* Base */,
206 | );
207 | name = Main.storyboard;
208 | sourceTree = "";
209 | };
210 | EC3BA0BD2C93A6CB0072939D /* LaunchScreen.storyboard */ = {
211 | isa = PBXVariantGroup;
212 | children = (
213 | EC3BA0BE2C93A6CB0072939D /* Base */,
214 | );
215 | name = LaunchScreen.storyboard;
216 | sourceTree = "";
217 | };
218 | /* End PBXVariantGroup section */
219 |
220 | /* Begin XCBuildConfiguration section */
221 | EC3BA0C32C93A6CB0072939D /* Debug */ = {
222 | isa = XCBuildConfiguration;
223 | buildSettings = {
224 | ALWAYS_SEARCH_USER_PATHS = NO;
225 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
226 | CLANG_ANALYZER_NONNULL = YES;
227 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
228 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
229 | CLANG_ENABLE_MODULES = YES;
230 | CLANG_ENABLE_OBJC_ARC = YES;
231 | CLANG_ENABLE_OBJC_WEAK = YES;
232 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
233 | CLANG_WARN_BOOL_CONVERSION = YES;
234 | CLANG_WARN_COMMA = YES;
235 | CLANG_WARN_CONSTANT_CONVERSION = YES;
236 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
237 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
238 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
239 | CLANG_WARN_EMPTY_BODY = YES;
240 | CLANG_WARN_ENUM_CONVERSION = YES;
241 | CLANG_WARN_INFINITE_RECURSION = YES;
242 | CLANG_WARN_INT_CONVERSION = YES;
243 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
244 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
245 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
246 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
247 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
248 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
249 | CLANG_WARN_STRICT_PROTOTYPES = YES;
250 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
251 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
252 | CLANG_WARN_UNREACHABLE_CODE = YES;
253 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
254 | COPY_PHASE_STRIP = NO;
255 | DEBUG_INFORMATION_FORMAT = dwarf;
256 | ENABLE_STRICT_OBJC_MSGSEND = YES;
257 | ENABLE_TESTABILITY = YES;
258 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
259 | GCC_C_LANGUAGE_STANDARD = gnu17;
260 | GCC_DYNAMIC_NO_PIC = NO;
261 | GCC_NO_COMMON_BLOCKS = YES;
262 | GCC_OPTIMIZATION_LEVEL = 0;
263 | GCC_PREPROCESSOR_DEFINITIONS = (
264 | "DEBUG=1",
265 | "$(inherited)",
266 | );
267 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
268 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
269 | GCC_WARN_UNDECLARED_SELECTOR = YES;
270 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
271 | GCC_WARN_UNUSED_FUNCTION = YES;
272 | GCC_WARN_UNUSED_VARIABLE = YES;
273 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
274 | MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE;
275 | MTL_FAST_MATH = YES;
276 | ONLY_ACTIVE_ARCH = YES;
277 | SDKROOT = iphoneos;
278 | };
279 | name = Debug;
280 | };
281 | EC3BA0C42C93A6CB0072939D /* Release */ = {
282 | isa = XCBuildConfiguration;
283 | buildSettings = {
284 | ALWAYS_SEARCH_USER_PATHS = NO;
285 | ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
286 | CLANG_ANALYZER_NONNULL = YES;
287 | CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE;
288 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++20";
289 | CLANG_ENABLE_MODULES = YES;
290 | CLANG_ENABLE_OBJC_ARC = YES;
291 | CLANG_ENABLE_OBJC_WEAK = YES;
292 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
293 | CLANG_WARN_BOOL_CONVERSION = YES;
294 | CLANG_WARN_COMMA = YES;
295 | CLANG_WARN_CONSTANT_CONVERSION = YES;
296 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
297 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
298 | CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
299 | CLANG_WARN_EMPTY_BODY = YES;
300 | CLANG_WARN_ENUM_CONVERSION = YES;
301 | CLANG_WARN_INFINITE_RECURSION = YES;
302 | CLANG_WARN_INT_CONVERSION = YES;
303 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
304 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
305 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
306 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
307 | CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES;
308 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
309 | CLANG_WARN_STRICT_PROTOTYPES = YES;
310 | CLANG_WARN_SUSPICIOUS_MOVE = YES;
311 | CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE;
312 | CLANG_WARN_UNREACHABLE_CODE = YES;
313 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
314 | COPY_PHASE_STRIP = NO;
315 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
316 | ENABLE_NS_ASSERTIONS = NO;
317 | ENABLE_STRICT_OBJC_MSGSEND = YES;
318 | ENABLE_USER_SCRIPT_SANDBOXING = YES;
319 | GCC_C_LANGUAGE_STANDARD = gnu17;
320 | GCC_NO_COMMON_BLOCKS = YES;
321 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
322 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
323 | GCC_WARN_UNDECLARED_SELECTOR = YES;
324 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
325 | GCC_WARN_UNUSED_FUNCTION = YES;
326 | GCC_WARN_UNUSED_VARIABLE = YES;
327 | LOCALIZATION_PREFERS_STRING_CATALOGS = YES;
328 | MTL_ENABLE_DEBUG_INFO = NO;
329 | MTL_FAST_MATH = YES;
330 | SDKROOT = iphoneos;
331 | VALIDATE_PRODUCT = YES;
332 | };
333 | name = Release;
334 | };
335 | EC3BA0C62C93A6CB0072939D /* Debug */ = {
336 | isa = XCBuildConfiguration;
337 | buildSettings = {
338 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
339 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "ruffle-orange";
340 | CODE_SIGN_ENTITLEMENTS = "ruffle-ios.entitlements";
341 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
342 | CODE_SIGN_STYLE = Automatic;
343 | CURRENT_PROJECT_VERSION = 1;
344 | DEVELOPMENT_TEAM = "";
345 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
346 | GENERATE_INFOPLIST_FILE = YES;
347 | INFOPLIST_FILE = Info.plist;
348 | INFOPLIST_KEY_CFBundleDisplayName = Ruffle;
349 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
350 | INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
351 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
352 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
353 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
354 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
355 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
356 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
357 | LD_RUNPATH_SEARCH_PATHS = (
358 | "$(inherited)",
359 | "@executable_path/Frameworks",
360 | );
361 | MARKETING_VERSION = 0.1;
362 | PRODUCT_BUNDLE_IDENTIFIER = "rs.ruffle.ruffle-ios";
363 | PRODUCT_NAME = "$(TARGET_NAME)";
364 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
365 | SUPPORTS_MACCATALYST = YES;
366 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
367 | SWIFT_EMIT_LOC_STRINGS = YES;
368 | TARGETED_DEVICE_FAMILY = "1,2,6,7";
369 | XROS_DEPLOYMENT_TARGET = 1.0;
370 | };
371 | name = Debug;
372 | };
373 | EC3BA0C72C93A6CB0072939D /* Release */ = {
374 | isa = XCBuildConfiguration;
375 | buildSettings = {
376 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
377 | ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = "ruffle-orange";
378 | CODE_SIGN_ENTITLEMENTS = "ruffle-ios.entitlements";
379 | "CODE_SIGN_IDENTITY[sdk=macosx*]" = "-";
380 | CODE_SIGN_STYLE = Automatic;
381 | CURRENT_PROJECT_VERSION = 1;
382 | DEVELOPMENT_TEAM = "";
383 | ENABLE_USER_SCRIPT_SANDBOXING = NO;
384 | GENERATE_INFOPLIST_FILE = YES;
385 | INFOPLIST_FILE = Info.plist;
386 | INFOPLIST_KEY_CFBundleDisplayName = Ruffle;
387 | INFOPLIST_KEY_LSApplicationCategoryType = "public.app-category.games";
388 | INFOPLIST_KEY_LSSupportsOpeningDocumentsInPlace = YES;
389 | INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES;
390 | INFOPLIST_KEY_UILaunchStoryboardName = LaunchScreen;
391 | INFOPLIST_KEY_UIMainStoryboardFile = Main;
392 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
393 | INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight";
394 | IPHONEOS_DEPLOYMENT_TARGET = 13.0;
395 | LD_RUNPATH_SEARCH_PATHS = (
396 | "$(inherited)",
397 | "@executable_path/Frameworks",
398 | );
399 | MARKETING_VERSION = 0.1;
400 | PRODUCT_BUNDLE_IDENTIFIER = "rs.ruffle.ruffle-ios";
401 | PRODUCT_NAME = "$(TARGET_NAME)";
402 | SUPPORTED_PLATFORMS = "iphoneos iphonesimulator xros xrsimulator";
403 | SUPPORTS_MACCATALYST = YES;
404 | SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO;
405 | SWIFT_EMIT_LOC_STRINGS = YES;
406 | TARGETED_DEVICE_FAMILY = "1,2,6,7";
407 | XROS_DEPLOYMENT_TARGET = 1.0;
408 | };
409 | name = Release;
410 | };
411 | /* End XCBuildConfiguration section */
412 |
413 | /* Begin XCConfigurationList section */
414 | EC3BA0A42C93A6CA0072939D /* Build configuration list for PBXProject "ruffle-ios" */ = {
415 | isa = XCConfigurationList;
416 | buildConfigurations = (
417 | EC3BA0C32C93A6CB0072939D /* Debug */,
418 | EC3BA0C42C93A6CB0072939D /* Release */,
419 | );
420 | defaultConfigurationIsVisible = 0;
421 | defaultConfigurationName = Release;
422 | };
423 | EC3BA0C52C93A6CB0072939D /* Build configuration list for PBXNativeTarget "ruffle-ios" */ = {
424 | isa = XCConfigurationList;
425 | buildConfigurations = (
426 | EC3BA0C62C93A6CB0072939D /* Debug */,
427 | EC3BA0C72C93A6CB0072939D /* Release */,
428 | );
429 | defaultConfigurationIsVisible = 0;
430 | defaultConfigurationName = Release;
431 | };
432 | /* End XCConfigurationList section */
433 |
434 | /* Begin XCVersionGroup section */
435 | EC5246FC2D4B03C00040F6D0 /* Ruffle.xcdatamodeld */ = {
436 | isa = XCVersionGroup;
437 | children = (
438 | EC5246FD2D4B03C00040F6D0 /* Ruffle.xcdatamodel */,
439 | );
440 | currentVersion = EC5246FD2D4B03C00040F6D0 /* Ruffle.xcdatamodel */;
441 | path = Ruffle.xcdatamodeld;
442 | sourceTree = "";
443 | versionGroupType = wrapper.xcdatamodel;
444 | };
445 | /* End XCVersionGroup section */
446 | };
447 | rootObject = EC3BA0A12C93A6CA0072939D /* Project object */;
448 | }
449 |
--------------------------------------------------------------------------------
/ruffle-ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata:
--------------------------------------------------------------------------------
1 |
2 |
4 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/ruffle-ios.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | IDEDidComputeMac32BitWarning
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/rust-toolchain.toml:
--------------------------------------------------------------------------------
1 | [toolchain]
2 | # Until 1.83 comes out
3 | channel = "nightly"
4 | components = ["rust-src"]
5 | targets = [
6 | "aarch64-apple-ios",
7 | "aarch64-apple-ios-sim",
8 | "aarch64-apple-ios-macabi",
9 | ]
10 |
--------------------------------------------------------------------------------
/src/add_controller.rs:
--------------------------------------------------------------------------------
1 | use objc2::rc::{Allocated, Retained};
2 | use objc2::{define_class, msg_send};
3 | use objc2_foundation::{NSBundle, NSCoder, NSObjectProtocol, NSString};
4 | use objc2_ui_kit::UIViewController;
5 |
6 | #[derive(Default, Debug)]
7 | pub struct Ivars {}
8 |
9 | define_class!(
10 | #[unsafe(super(UIViewController))]
11 | #[name = "AddController"]
12 | #[ivars = Ivars]
13 | #[derive(Debug)]
14 | pub struct AddController;
15 |
16 | unsafe impl NSObjectProtocol for AddController {}
17 |
18 | /// UIViewController.
19 | impl AddController {
20 | #[unsafe(method_id(initWithNibName:bundle:))]
21 | fn _init_with_nib_name_bundle(
22 | this: Allocated,
23 | nib_name_or_nil: Option<&NSString>,
24 | nib_bundle_or_nil: Option<&NSBundle>,
25 | ) -> Retained {
26 | tracing::info!("add init");
27 | let this = this.set_ivars(Ivars::default());
28 | unsafe {
29 | msg_send![super(this), initWithNibName: nib_name_or_nil, bundle: nib_bundle_or_nil]
30 | }
31 | }
32 |
33 | #[unsafe(method_id(initWithCoder:))]
34 | fn _init_with_coder(this: Allocated, coder: &NSCoder) -> Option> {
35 | tracing::info!("add init");
36 | let this = this.set_ivars(Ivars::default());
37 | unsafe { msg_send![super(this), initWithCoder: coder] }
38 | }
39 |
40 | #[unsafe(method(viewDidLoad))]
41 | fn _view_did_load(&self) {
42 | // Xcode template calls super at the beginning
43 | let _: () = unsafe { msg_send![super(self), viewDidLoad] };
44 | self.view_did_load();
45 | }
46 |
47 | #[unsafe(method(viewWillAppear:))]
48 | fn _view_will_appear(&self, animated: bool) {
49 | self.view_will_appear();
50 | // Docs say to call super
51 | let _: () = unsafe { msg_send![super(self), viewWillAppear: animated] };
52 | }
53 |
54 | #[unsafe(method(viewDidAppear:))]
55 | fn _view_did_appear(&self, animated: bool) {
56 | self.view_did_appear();
57 | // Docs say to call super
58 | let _: () = unsafe { msg_send![super(self), viewDidAppear: animated] };
59 | }
60 | }
61 |
62 | /// Storyboard
63 | /// See storyboard_connections.h
64 | impl AddController {
65 | // #[unsafe(method(setTableView:))]
66 | // fn _set_table_view(&self, table_view: &UITableView) {
67 | // tracing::trace!("edit set table view");
68 | // self.ivars()
69 | // .table_view
70 | // .set(table_view.retain())
71 | // .expect("only set table view once");
72 | // }
73 | }
74 | );
75 |
76 | impl AddController {
77 | fn view_did_load(&self) {
78 | tracing::info!("edit viewDidLoad");
79 | }
80 |
81 | fn view_will_appear(&self) {
82 | tracing::info!("edit viewWillAppear:");
83 | }
84 |
85 | fn view_did_appear(&self) {
86 | tracing::info!("edit viewDidAppear:");
87 | }
88 | }
89 |
--------------------------------------------------------------------------------
/src/app_delegate.rs:
--------------------------------------------------------------------------------
1 | use objc2::rc::{Allocated, Retained};
2 | use objc2::runtime::AnyObject;
3 | use objc2::{define_class, msg_send, DefinedClass, MainThreadOnly, Message};
4 | use objc2_foundation::{
5 | ns_string, MainThreadMarker, NSDictionary, NSObject, NSObjectProtocol, NSSet,
6 | };
7 | use objc2_ui_kit::{
8 | UIApplication, UIApplicationDelegate, UIApplicationLaunchOptionsKey, UISceneConfiguration,
9 | UISceneConnectionOptions, UISceneSession, UIWindow,
10 | };
11 |
12 | use crate::storage;
13 |
14 | pub struct Ivars {
15 | window: std::cell::Cell