├── .gitignore ├── App.tsx ├── README.md ├── Spawn.wav ├── app.json ├── assets ├── adaptive-icon.png ├── favicon.png ├── icon.png └── splash.png ├── babel.config.js ├── haptics ├── texture.json └── thing1 │ ├── altitude_open.mp3 │ ├── battery_gravity_1.json │ └── battery_gravity_1.wav ├── ios ├── .gitignore ├── .xcode.env ├── Podfile ├── Podfile.lock ├── Podfile.properties.json ├── ShieldA.wav ├── capnahap.xcodeproj │ ├── project.pbxproj │ └── xcshareddata │ │ └── xcschemes │ │ └── capnahap.xcscheme ├── capnahap.xcworkspace │ ├── contents.xcworkspacedata │ └── xcshareddata │ │ └── IDEWorkspaceChecks.plist └── capnahap │ ├── AppDelegate.h │ ├── AppDelegate.mm │ ├── Images.xcassets │ ├── AppIcon.appiconset │ │ ├── App-Icon-1024x1024@1x.png │ │ └── Contents.json │ ├── Contents.json │ ├── SplashScreen.imageset │ │ ├── Contents.json │ │ └── image.png │ └── SplashScreenBackground.imageset │ │ ├── Contents.json │ │ └── image.png │ ├── Info.plist │ ├── SplashScreen.storyboard │ ├── Supporting │ └── Expo.plist │ ├── capnahap-Bridging-Header.h │ ├── capnahap.entitlements │ ├── main.m │ └── noop-file.swift ├── metro.config.js ├── modules └── ahap │ ├── _package.json │ ├── expo-module.config.json │ ├── index.ts │ ├── ios │ ├── Ahap.podspec │ └── AhapModule.swift │ └── src │ ├── Ahap.types.ts │ ├── AhapModule.ts │ └── AhapModule.web.ts ├── package.json ├── tsconfig.json └── yarn.lock /.gitignore: -------------------------------------------------------------------------------- 1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files 2 | 3 | # dependencies 4 | node_modules/ 5 | 6 | # Expo 7 | .expo/ 8 | dist/ 9 | web-build/ 10 | 11 | # Native 12 | *.orig.* 13 | *.jks 14 | *.p8 15 | *.p12 16 | *.key 17 | *.mobileprovision 18 | 19 | # Metro 20 | .metro-health-check* 21 | 22 | # debug 23 | npm-debug.* 24 | yarn-debug.* 25 | yarn-error.* 26 | 27 | # macOS 28 | .DS_Store 29 | *.pem 30 | 31 | # local env files 32 | .env*.local 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | -------------------------------------------------------------------------------- /App.tsx: -------------------------------------------------------------------------------- 1 | import { StatusBar } from "expo-status-bar"; 2 | import { StyleSheet, Text, View } from "react-native"; 3 | import * as Ahap from "local:ahap"; 4 | import React from "react"; 5 | import * as FS from "expo-file-system"; 6 | import { Asset } from "expo-asset"; 7 | import textureAhap from "./haptics/texture.json"; 8 | function useAudioInDocumentsDir(res) { 9 | const [audioName, setName] = React.useState(null); 10 | 11 | React.useEffect(() => { 12 | Asset.fromModule(res) 13 | // Asset.fromModule(require("./Spawn.wav")) 14 | .downloadAsync() 15 | .then(async (result) => { 16 | const audioName = result.localUri.split("/").pop(); 17 | // move to the ios folder 18 | await FS.copyAsync({ 19 | from: result.localUri, 20 | to: FS.documentDirectory + audioName, 21 | }); 22 | 23 | setName(audioName); 24 | }); 25 | }, [res]); 26 | 27 | return audioName; 28 | } 29 | 30 | function useCustomPlayer() { 31 | const [player, setPlayer] = React.useState(null); 32 | const audioName = useAudioInDocumentsDir( 33 | require("./Spawn.wav") 34 | // require("./haptics/thing1/altitude_open.mp3") 35 | ); 36 | React.useEffect(() => { 37 | if (!audioName) return; 38 | const player = new Ahap.Player({ 39 | Pattern: [ 40 | { 41 | Event: { 42 | Time: 0.0, 43 | EventType: "HapticContinuous", 44 | EventDuration: 0.6, 45 | EventParameters: [ 46 | { ParameterID: "HapticIntensity", ParameterValue: 1.0 }, 47 | { ParameterID: "HapticSharpness", ParameterValue: 0.5 }, 48 | ], 49 | }, 50 | }, 51 | { 52 | ParameterCurve: { 53 | ParameterID: "HapticIntensityControl", 54 | Time: 0.0, 55 | ParameterCurveControlPoints: [ 56 | { Time: 0, ParameterValue: 0.2 }, 57 | { Time: 0.6, ParameterValue: 0.7 }, 58 | { Time: 0.601, ParameterValue: 1.0 }, 59 | ], 60 | }, 61 | }, 62 | { 63 | ParameterCurve: { 64 | ParameterID: "HapticSharpnessControl", 65 | Time: 0.0, 66 | ParameterCurveControlPoints: [ 67 | { Time: 0, ParameterValue: -0.5 }, 68 | { Time: 0.6, ParameterValue: 0.5 }, 69 | ], 70 | }, 71 | }, 72 | 73 | { 74 | Event: { 75 | Time: 0.601, 76 | EventType: "HapticTransient", 77 | EventParameters: [ 78 | { ParameterID: "HapticIntensity", ParameterValue: 1.0 }, 79 | { ParameterID: "HapticSharpness", ParameterValue: 0.7 }, 80 | ], 81 | }, 82 | }, 83 | { 84 | Event: { 85 | Time: 0.0, 86 | EventType: "AudioCustom", 87 | EventWaveformPath: audioName, 88 | EventParameters: [ 89 | { ParameterID: "AudioVolume", ParameterValue: 0.4 }, 90 | ], 91 | }, 92 | }, 93 | ], 94 | }); 95 | setPlayer(player); 96 | return () => { 97 | player?.unregister?.(); 98 | setPlayer(null); 99 | }; 100 | }, [audioName]); 101 | 102 | return player; 103 | } 104 | 105 | function useStandardPlayer(ahap) { 106 | const player = React.useRef(new Ahap.Player(ahap)).current; 107 | 108 | React.useEffect(() => { 109 | return () => { 110 | player?.unregister?.(); 111 | }; 112 | }, []); 113 | return player; 114 | } 115 | 116 | export default function App() { 117 | const player = useCustomPlayer(); 118 | const texturePlayer = useStandardPlayer(textureAhap); 119 | 120 | // player.addEventListener(() => { 121 | // console.log("done"); 122 | // }); 123 | 124 | React.useEffect(() => { 125 | // texturePlayer.playbackRate = 2; 126 | texturePlayer.loopEnabled = true; 127 | texturePlayer.start(); 128 | }, []); 129 | 130 | const play = React.useCallback(() => { 131 | player?.start(); 132 | }, [player]); 133 | 134 | return ( 135 | 136 | { 138 | texturePlayer.sendParameters( 139 | [ 140 | { 141 | ParameterID: "HapticIntensityControl", 142 | ParameterValue: 0.45, 143 | Time: 0, 144 | }, 145 | ], 146 | 0 147 | ); 148 | }} 149 | > 150 | Texture high 151 | 152 | { 154 | texturePlayer.sendParameters( 155 | [ 156 | { 157 | ParameterID: "HapticIntensityControl", 158 | ParameterValue: 0, 159 | Time: 0, 160 | }, 161 | ], 162 | 0 163 | ); 164 | }} 165 | > 166 | Texture low 167 | 168 | { 170 | texturePlayer.stop(); 171 | }} 172 | > 173 | Stop texture 174 | 175 | { 177 | player.loopEnabled = !player.loopEnabled; 178 | }} 179 | > 180 | Loop 181 | 182 | play()}> 183 | Open up App.js to start working on your app! 184 | 185 | 186 | 187 | 188 | ); 189 | } 190 | 191 | const styles = StyleSheet.create({ 192 | container: { 193 | flex: 1, 194 | backgroundColor: "#fff", 195 | alignItems: "center", 196 | justifyContent: "center", 197 | }, 198 | }); 199 | 200 | // const player = new Ahap.Player({ 201 | // Pattern: [ 202 | // { 203 | // Event: { 204 | // Time: 0.05490196078431372, 205 | // EventType: "HapticContinuous", 206 | // EventDuration: 0.7241830065359477, 207 | // EventParameters: [ 208 | // { 209 | // ParameterID: "HapticIntensity", 210 | // ParameterValue: 0.6264705882352941, 211 | // }, 212 | // { 213 | // ParameterID: "HapticSharpness", 214 | // ParameterValue: 0.6264705882352941, 215 | // }, 216 | // ], 217 | // }, 218 | // }, 219 | // { 220 | // Event: { 221 | // Time: 0.19084967320261434, 222 | // EventType: "HapticTransient", 223 | // EventParameters: [ 224 | // { 225 | // ParameterID: "HapticIntensity", 226 | // ParameterValue: 0.8911764705882353, 227 | // }, 228 | // { 229 | // ParameterID: "HapticSharpness", 230 | // ParameterValue: 0.8911764705882353, 231 | // }, 232 | // ], 233 | // }, 234 | // }, 235 | // { 236 | // Event: { 237 | // Time: 0.28366013071895424, 238 | // EventType: "HapticTransient", 239 | // EventParameters: [ 240 | // { 241 | // ParameterID: "HapticIntensity", 242 | // ParameterValue: 0.8558823529411764, 243 | // }, 244 | // { 245 | // ParameterID: "HapticSharpness", 246 | // ParameterValue: 0.8558823529411764, 247 | // }, 248 | // ], 249 | // }, 250 | // }, 251 | // { 252 | // Event: { 253 | // Time: 0.37908496732026137, 254 | // EventType: "HapticTransient", 255 | // EventParameters: [ 256 | // { 257 | // ParameterID: "HapticIntensity", 258 | // ParameterValue: 0.8558823529411764, 259 | // }, 260 | // { 261 | // ParameterID: "HapticSharpness", 262 | // ParameterValue: 0.8558823529411764, 263 | // }, 264 | // ], 265 | // }, 266 | // }, 267 | // { 268 | // Event: { 269 | // Time: 0.37908496732026137, 270 | // EventType: "HapticTransient", 271 | // EventParameters: [ 272 | // { 273 | // ParameterID: "HapticIntensity", 274 | // ParameterValue: 0.8558823529411764, 275 | // }, 276 | // { 277 | // ParameterID: "HapticSharpness", 278 | // ParameterValue: 0.8558823529411764, 279 | // }, 280 | // ], 281 | // }, 282 | // }, 283 | // { 284 | // Event: { 285 | // Time: 0.46274509803921565, 286 | // EventType: "HapticTransient", 287 | // EventParameters: [ 288 | // { 289 | // ParameterID: "HapticIntensity", 290 | // ParameterValue: 0.8205882352941176, 291 | // }, 292 | // { 293 | // ParameterID: "HapticSharpness", 294 | // ParameterValue: 0.8205882352941176, 295 | // }, 296 | // ], 297 | // }, 298 | // }, 299 | // { 300 | // Event: { 301 | // Time: 0.5281045751633986, 302 | // EventType: "HapticContinuous", 303 | // EventDuration: 0.006999999999999999, 304 | // EventParameters: [ 305 | // { 306 | // ParameterID: "HapticIntensity", 307 | // ParameterValue: 0.8205882352941176, 308 | // }, 309 | // { 310 | // ParameterID: "HapticSharpness", 311 | // ParameterValue: 0.8205882352941176, 312 | // }, 313 | // ], 314 | // }, 315 | // }, 316 | // { 317 | // Event: { 318 | // Time: 0.5281045751633986, 319 | // EventType: "HapticTransient", 320 | // EventParameters: [ 321 | // { 322 | // ParameterID: "HapticIntensity", 323 | // ParameterValue: 0.8205882352941176, 324 | // }, 325 | // { 326 | // ParameterID: "HapticSharpness", 327 | // ParameterValue: 0.8205882352941176, 328 | // }, 329 | // ], 330 | // }, 331 | // }, 332 | // { 333 | // Event: { 334 | // Time: 0.5581699346405229, 335 | // EventType: "HapticContinuous", 336 | // EventDuration: 0.006999999999999999, 337 | // EventParameters: [ 338 | // { 339 | // ParameterID: "HapticIntensity", 340 | // ParameterValue: 0.8264705882352941, 341 | // }, 342 | // { 343 | // ParameterID: "HapticSharpness", 344 | // ParameterValue: 0.8264705882352941, 345 | // }, 346 | // ], 347 | // }, 348 | // }, 349 | // { 350 | // Event: { 351 | // Time: 0.5581699346405229, 352 | // EventType: "HapticTransient", 353 | // EventParameters: [ 354 | // { 355 | // ParameterID: "HapticIntensity", 356 | // ParameterValue: 0.8264705882352941, 357 | // }, 358 | // { 359 | // ParameterID: "HapticSharpness", 360 | // ParameterValue: 0.8264705882352941, 361 | // }, 362 | // ], 363 | // }, 364 | // }, 365 | // { 366 | // Event: { 367 | // Time: 0.5803921568627451, 368 | // EventType: "HapticTransient", 369 | // EventParameters: [ 370 | // { 371 | // ParameterID: "HapticIntensity", 372 | // ParameterValue: 0.8264705882352941, 373 | // }, 374 | // { 375 | // ParameterID: "HapticSharpness", 376 | // ParameterValue: 0.8264705882352941, 377 | // }, 378 | // ], 379 | // }, 380 | // }, 381 | // { 382 | // Event: { 383 | // Time: 0.5895424836601307, 384 | // EventType: "HapticTransient", 385 | // EventParameters: [ 386 | // { 387 | // ParameterID: "HapticIntensity", 388 | // ParameterValue: 0.7441176470588236, 389 | // }, 390 | // { 391 | // ParameterID: "HapticSharpness", 392 | // ParameterValue: 0.7441176470588236, 393 | // }, 394 | // ], 395 | // }, 396 | // }, 397 | // { 398 | // Event: { 399 | // Time: 0.5895424836601307, 400 | // EventType: "HapticTransient", 401 | // EventParameters: [ 402 | // { 403 | // ParameterID: "HapticIntensity", 404 | // ParameterValue: 0.6088235294117647, 405 | // }, 406 | // { 407 | // ParameterID: "HapticSharpness", 408 | // ParameterValue: 0.6088235294117647, 409 | // }, 410 | // ], 411 | // }, 412 | // }, 413 | // { 414 | // Event: { 415 | // Time: 0.5986928104575163, 416 | // EventType: "HapticTransient", 417 | // EventParameters: [ 418 | // { 419 | // ParameterID: "HapticIntensity", 420 | // ParameterValue: 0.5088235294117647, 421 | // }, 422 | // { 423 | // ParameterID: "HapticSharpness", 424 | // ParameterValue: 0.5088235294117647, 425 | // }, 426 | // ], 427 | // }, 428 | // }, 429 | // { 430 | // Event: { 431 | // Time: 0.6326797385620915, 432 | // EventType: "HapticContinuous", 433 | // EventDuration: 0.006999999999999999, 434 | // EventParameters: [ 435 | // { 436 | // ParameterID: "HapticIntensity", 437 | // ParameterValue: 0.5852941176470589, 438 | // }, 439 | // { 440 | // ParameterID: "HapticSharpness", 441 | // ParameterValue: 0.5852941176470589, 442 | // }, 443 | // ], 444 | // }, 445 | // }, 446 | // { 447 | // Event: { 448 | // Time: 0.6326797385620915, 449 | // EventType: "HapticTransient", 450 | // EventParameters: [ 451 | // { 452 | // ParameterID: "HapticIntensity", 453 | // ParameterValue: 0.5852941176470589, 454 | // }, 455 | // { 456 | // ParameterID: "HapticSharpness", 457 | // ParameterValue: 0.5852941176470589, 458 | // }, 459 | // ], 460 | // }, 461 | // }, 462 | // { 463 | // Event: { 464 | // Time: 0.6326797385620915, 465 | // EventType: "HapticTransient", 466 | // EventParameters: [ 467 | // { 468 | // ParameterID: "HapticIntensity", 469 | // ParameterValue: 0.7264705882352941, 470 | // }, 471 | // { 472 | // ParameterID: "HapticSharpness", 473 | // ParameterValue: 0.7264705882352941, 474 | // }, 475 | // ], 476 | // }, 477 | // }, 478 | // { 479 | // Event: { 480 | // Time: 0.6705882352941176, 481 | // EventType: "HapticTransient", 482 | // EventParameters: [ 483 | // { 484 | // ParameterID: "HapticIntensity", 485 | // ParameterValue: 0.8323529411764706, 486 | // }, 487 | // { 488 | // ParameterID: "HapticSharpness", 489 | // ParameterValue: 0.8323529411764706, 490 | // }, 491 | // ], 492 | // }, 493 | // }, 494 | // { 495 | // Event: { 496 | // Time: 0.7503267973856208, 497 | // EventType: "HapticTransient", 498 | // EventParameters: [ 499 | // { 500 | // ParameterID: "HapticIntensity", 501 | // ParameterValue: 0.8264705882352941, 502 | // }, 503 | // { 504 | // ParameterID: "HapticSharpness", 505 | // ParameterValue: 0.8264705882352941, 506 | // }, 507 | // ], 508 | // }, 509 | // }, 510 | // { 511 | // Event: { 512 | // Time: 0.792156862745098, 513 | // EventType: "HapticTransient", 514 | // EventParameters: [ 515 | // { 516 | // ParameterID: "HapticIntensity", 517 | // ParameterValue: 0.5617647058823529, 518 | // }, 519 | // { 520 | // ParameterID: "HapticSharpness", 521 | // ParameterValue: 0.5617647058823529, 522 | // }, 523 | // ], 524 | // }, 525 | // }, 526 | // { 527 | // Event: { 528 | // Time: 0.7986928104575163, 529 | // EventType: "HapticTransient", 530 | // EventParameters: [ 531 | // { 532 | // ParameterID: "HapticIntensity", 533 | // ParameterValue: 0.4147058823529412, 534 | // }, 535 | // { 536 | // ParameterID: "HapticSharpness", 537 | // ParameterValue: 0.4147058823529412, 538 | // }, 539 | // ], 540 | // }, 541 | // }, 542 | // { 543 | // Event: { 544 | // Time: 0.8535947712418301, 545 | // EventType: "HapticTransient", 546 | // EventParameters: [ 547 | // { 548 | // ParameterID: "HapticIntensity", 549 | // ParameterValue: 0.26176470588235295, 550 | // }, 551 | // { 552 | // ParameterID: "HapticSharpness", 553 | // ParameterValue: 0.26176470588235295, 554 | // }, 555 | // ], 556 | // }, 557 | // }, 558 | // { 559 | // Event: { 560 | // Time: 0.8666666666666667, 561 | // EventType: "HapticContinuous", 562 | // EventDuration: 0.006999999999999999, 563 | // EventParameters: [ 564 | // { 565 | // ParameterID: "HapticIntensity", 566 | // ParameterValue: 0.6735294117647059, 567 | // }, 568 | // { 569 | // ParameterID: "HapticSharpness", 570 | // ParameterValue: 0.6735294117647059, 571 | // }, 572 | // ], 573 | // }, 574 | // }, 575 | // { 576 | // Event: { 577 | // Time: 0.8666666666666667, 578 | // EventType: "HapticTransient", 579 | // EventParameters: [ 580 | // { 581 | // ParameterID: "HapticIntensity", 582 | // ParameterValue: 0.6735294117647059, 583 | // }, 584 | // { 585 | // ParameterID: "HapticSharpness", 586 | // ParameterValue: 0.6735294117647059, 587 | // }, 588 | // ], 589 | // }, 590 | // }, 591 | // { 592 | // Event: { 593 | // Time: 0.9202614379084967, 594 | // EventType: "HapticTransient", 595 | // EventParameters: [ 596 | // { 597 | // ParameterID: "HapticIntensity", 598 | // ParameterValue: 0.8794117647058823, 599 | // }, 600 | // { 601 | // ParameterID: "HapticSharpness", 602 | // ParameterValue: 0.8794117647058823, 603 | // }, 604 | // ], 605 | // }, 606 | // }, 607 | // { 608 | // Event: { 609 | // Time: 0.9477124183006536, 610 | // EventType: "HapticContinuous", 611 | // EventDuration: 0.006999999999999999, 612 | // EventParameters: [ 613 | // { 614 | // ParameterID: "HapticIntensity", 615 | // ParameterValue: 0.5323529411764706, 616 | // }, 617 | // { 618 | // ParameterID: "HapticSharpness", 619 | // ParameterValue: 0.5323529411764706, 620 | // }, 621 | // ], 622 | // }, 623 | // }, 624 | // { 625 | // Event: { 626 | // Time: 0.9477124183006536, 627 | // EventType: "HapticTransient", 628 | // EventParameters: [ 629 | // { 630 | // ParameterID: "HapticIntensity", 631 | // ParameterValue: 0.5323529411764706, 632 | // }, 633 | // { 634 | // ParameterID: "HapticSharpness", 635 | // ParameterValue: 0.5323529411764706, 636 | // }, 637 | // ], 638 | // }, 639 | // }, 640 | // { 641 | // Event: { 642 | // Time: 0.9581699346405228, 643 | // EventType: "HapticTransient", 644 | // EventParameters: [ 645 | // { 646 | // ParameterID: "HapticIntensity", 647 | // ParameterValue: 0.3323529411764706, 648 | // }, 649 | // { 650 | // ParameterID: "HapticSharpness", 651 | // ParameterValue: 0.3323529411764706, 652 | // }, 653 | // ], 654 | // }, 655 | // }, 656 | // { 657 | // Event: { 658 | // Time: 1.0457516339869282, 659 | // EventType: "HapticTransient", 660 | // EventParameters: [ 661 | // { 662 | // ParameterID: "HapticIntensity", 663 | // ParameterValue: 0.3323529411764706, 664 | // }, 665 | // { 666 | // ParameterID: "HapticSharpness", 667 | // ParameterValue: 0.3323529411764706, 668 | // }, 669 | // ], 670 | // }, 671 | // }, 672 | // { 673 | // Event: { 674 | // Time: 1.0457516339869282, 675 | // EventType: "HapticTransient", 676 | // EventParameters: [ 677 | // { 678 | // ParameterID: "HapticIntensity", 679 | // ParameterValue: 0.4852941176470588, 680 | // }, 681 | // { 682 | // ParameterID: "HapticSharpness", 683 | // ParameterValue: 0.4852941176470588, 684 | // }, 685 | // ], 686 | // }, 687 | // }, 688 | // { 689 | // Event: { 690 | // Time: 1.0836601307189542, 691 | // EventType: "HapticTransient", 692 | // EventParameters: [ 693 | // { 694 | // ParameterID: "HapticIntensity", 695 | // ParameterValue: 0.6676470588235294, 696 | // }, 697 | // { 698 | // ParameterID: "HapticSharpness", 699 | // ParameterValue: 0.6676470588235294, 700 | // }, 701 | // ], 702 | // }, 703 | // }, 704 | // { 705 | // Event: { 706 | // Time: 1.0836601307189542, 707 | // EventType: "HapticTransient", 708 | // EventParameters: [ 709 | // { 710 | // ParameterID: "HapticIntensity", 711 | // ParameterValue: 0.6676470588235294, 712 | // }, 713 | // { 714 | // ParameterID: "HapticSharpness", 715 | // ParameterValue: 0.6676470588235294, 716 | // }, 717 | // ], 718 | // }, 719 | // }, 720 | // { 721 | // Event: { 722 | // Time: 1.1594771241830066, 723 | // EventType: "HapticTransient", 724 | // EventParameters: [ 725 | // { 726 | // ParameterID: "HapticIntensity", 727 | // ParameterValue: 0.43823529411764706, 728 | // }, 729 | // { 730 | // ParameterID: "HapticSharpness", 731 | // ParameterValue: 0.43823529411764706, 732 | // }, 733 | // ], 734 | // }, 735 | // }, 736 | // { 737 | // Event: { 738 | // Time: 1.1712418300653595, 739 | // EventType: "HapticTransient", 740 | // EventParameters: [ 741 | // { 742 | // ParameterID: "HapticIntensity", 743 | // ParameterValue: 0.25588235294117645, 744 | // }, 745 | // { 746 | // ParameterID: "HapticSharpness", 747 | // ParameterValue: 0.25588235294117645, 748 | // }, 749 | // ], 750 | // }, 751 | // }, 752 | // { 753 | // Event: { 754 | // Time: 1.2405228758169933, 755 | // EventType: "HapticTransient", 756 | // EventParameters: [ 757 | // { 758 | // ParameterID: "HapticIntensity", 759 | // ParameterValue: 0.25588235294117645, 760 | // }, 761 | // { 762 | // ParameterID: "HapticSharpness", 763 | // ParameterValue: 0.25588235294117645, 764 | // }, 765 | // ], 766 | // }, 767 | // }, 768 | // { 769 | // Event: { 770 | // Time: 1.2732026143790849, 771 | // EventType: "HapticTransient", 772 | // EventParameters: [ 773 | // { 774 | // ParameterID: "HapticIntensity", 775 | // ParameterValue: 0.5558823529411765, 776 | // }, 777 | // { 778 | // ParameterID: "HapticSharpness", 779 | // ParameterValue: 0.5558823529411765, 780 | // }, 781 | // ], 782 | // }, 783 | // }, 784 | // { 785 | // Event: { 786 | // Time: 1.318954248366013, 787 | // EventType: "HapticContinuous", 788 | // EventDuration: 0.006999999999999999, 789 | // EventParameters: [ 790 | // { 791 | // ParameterID: "HapticIntensity", 792 | // ParameterValue: 0.6264705882352941, 793 | // }, 794 | // { 795 | // ParameterID: "HapticSharpness", 796 | // ParameterValue: 0.6264705882352941, 797 | // }, 798 | // ], 799 | // }, 800 | // }, 801 | // { 802 | // Event: { 803 | // Time: 1.3202614379084967, 804 | // EventType: "HapticTransient", 805 | // EventParameters: [ 806 | // { 807 | // ParameterID: "HapticIntensity", 808 | // ParameterValue: 0.6264705882352941, 809 | // }, 810 | // { 811 | // ParameterID: "HapticSharpness", 812 | // ParameterValue: 0.6264705882352941, 813 | // }, 814 | // ], 815 | // }, 816 | // }, 817 | // { 818 | // Event: { 819 | // Time: 1.3738562091503266, 820 | // EventType: "HapticTransient", 821 | // EventParameters: [ 822 | // { 823 | // ParameterID: "HapticIntensity", 824 | // ParameterValue: 0.061764705882352944, 825 | // }, 826 | // { 827 | // ParameterID: "HapticSharpness", 828 | // ParameterValue: 0.061764705882352944, 829 | // }, 830 | // ], 831 | // }, 832 | // }, 833 | // { 834 | // Event: { 835 | // Time: 1.4819794584500467, 836 | // EventType: "HapticTransient", 837 | // EventParameters: [ 838 | // { 839 | // ParameterID: "HapticIntensity", 840 | // ParameterValue: 0.5205882352941177, 841 | // }, 842 | // { 843 | // ParameterID: "HapticSharpness", 844 | // ParameterValue: 0.5205882352941177, 845 | // }, 846 | // ], 847 | // }, 848 | // }, 849 | // { 850 | // Event: { 851 | // Time: 1.9929038281979459, 852 | // EventType: "HapticTransient", 853 | // EventParameters: [ 854 | // { 855 | // ParameterID: "HapticIntensity", 856 | // ParameterValue: 0.4852941176470588, 857 | // }, 858 | // { 859 | // ParameterID: "HapticSharpness", 860 | // ParameterValue: 0.4852941176470588, 861 | // }, 862 | // ], 863 | // }, 864 | // }, 865 | // { 866 | // Event: { 867 | // Time: 2.0526610644257706, 868 | // EventType: "HapticContinuous", 869 | // EventDuration: 0.016, 870 | // EventParameters: [ 871 | // { 872 | // ParameterID: "HapticIntensity", 873 | // ParameterValue: 0.4852941176470588, 874 | // }, 875 | // { 876 | // ParameterID: "HapticSharpness", 877 | // ParameterValue: 0.4852941176470588, 878 | // }, 879 | // ], 880 | // }, 881 | // }, 882 | // { 883 | // Event: { 884 | // Time: 2.0526610644257706, 885 | // EventType: "HapticTransient", 886 | // EventParameters: [ 887 | // { 888 | // ParameterID: "HapticIntensity", 889 | // ParameterValue: 0.4852941176470588, 890 | // }, 891 | // { 892 | // ParameterID: "HapticSharpness", 893 | // ParameterValue: 0.4852941176470588, 894 | // }, 895 | // ], 896 | // }, 897 | // }, 898 | // { 899 | // Event: { 900 | // Time: 2.3215686274509806, 901 | // EventType: "HapticTransient", 902 | // EventParameters: [ 903 | // { 904 | // ParameterID: "HapticIntensity", 905 | // ParameterValue: 0.4852941176470588, 906 | // }, 907 | // { 908 | // ParameterID: "HapticSharpness", 909 | // ParameterValue: 0.4852941176470588, 910 | // }, 911 | // ], 912 | // }, 913 | // }, 914 | // { 915 | // Event: { 916 | // Time: 2.3484593837535015, 917 | // EventType: "HapticContinuous", 918 | // EventDuration: 0.016, 919 | // EventParameters: [ 920 | // { 921 | // ParameterID: "HapticIntensity", 922 | // ParameterValue: 0.4852941176470588, 923 | // }, 924 | // { 925 | // ParameterID: "HapticSharpness", 926 | // ParameterValue: 0.4852941176470588, 927 | // }, 928 | // ], 929 | // }, 930 | // }, 931 | // { 932 | // Event: { 933 | // Time: 2.3484593837535015, 934 | // EventType: "HapticTransient", 935 | // EventParameters: [ 936 | // { 937 | // ParameterID: "HapticIntensity", 938 | // ParameterValue: 0.4852941176470588, 939 | // }, 940 | // { 941 | // ParameterID: "HapticSharpness", 942 | // ParameterValue: 0.4852941176470588, 943 | // }, 944 | // ], 945 | // }, 946 | // }, 947 | // { 948 | // Event: { 949 | // Time: 2.6651727357609714, 950 | // EventType: "HapticContinuous", 951 | // EventDuration: 0.016, 952 | // EventParameters: [ 953 | // { 954 | // ParameterID: "HapticIntensity", 955 | // ParameterValue: 0.4852941176470588, 956 | // }, 957 | // { 958 | // ParameterID: "HapticSharpness", 959 | // ParameterValue: 0.4852941176470588, 960 | // }, 961 | // ], 962 | // }, 963 | // }, 964 | // { 965 | // Event: { 966 | // Time: 2.6651727357609714, 967 | // EventType: "HapticTransient", 968 | // EventParameters: [ 969 | // { 970 | // ParameterID: "HapticIntensity", 971 | // ParameterValue: 0.4852941176470588, 972 | // }, 973 | // { 974 | // ParameterID: "HapticSharpness", 975 | // ParameterValue: 0.4852941176470588, 976 | // }, 977 | // ], 978 | // }, 979 | // }, 980 | // ], 981 | // }); 982 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # expo-ahap 2 | 3 | React Native module for loading and interacting with Apple ahap files 4 | 5 | - Implements the Apple API for building custom haptics. Learn more: [WWDC 2021](https://developer.apple.com/videos/play/wwdc2021/10278). 6 | - You can create ahap files online: [Here](https://ahap.fancypixel.it/). 7 | 8 | > This library is not an official part of the Expo SDK! 9 | 10 | You can install (at your own discretion) with: 11 | 12 | ```sh 13 | yarn add expo-ahap 14 | ``` 15 | 16 | Be sure to build on a physical iOS device, running iOS 13 or greater! `npx expo run:ios -d` 17 | 18 | ## API 19 | 20 | ```js 21 | import { Player } from "expo-ahap"; 22 | 23 | const player = new Player({ 24 | // Ahap file 25 | }); 26 | 27 | player.start(); 28 | 29 | // Be sure to unregister later... 30 | 31 | player.unregister(); 32 | ``` 33 | 34 | ## Example 35 | 36 | Running this and pressing "Start!" should feel like _bbbbrrrppp!_ in your hand. 37 | 38 | ```js 39 | import { StatusBar } from "expo-status-bar"; 40 | import { StyleSheet, Text, View } from "react-native"; 41 | import { Player } from "expo-ahap"; 42 | 43 | const player = new Player({ 44 | Pattern: [ 45 | { 46 | Event: { 47 | Time: 0.0, 48 | EventType: "HapticContinuous", 49 | EventDuration: 0.6, 50 | EventParameters: [ 51 | { ParameterID: "HapticIntensity", ParameterValue: 1.0 }, 52 | { ParameterID: "HapticSharpness", ParameterValue: 0.5 }, 53 | ], 54 | }, 55 | }, 56 | { 57 | ParameterCurve: { 58 | ParameterID: "HapticIntensityControl", 59 | Time: 0.0, 60 | ParameterCurveControlPoints: [ 61 | { Time: 0, ParameterValue: 0.2 }, 62 | { Time: 0.6, ParameterValue: 0.7 }, 63 | { Time: 0.601, ParameterValue: 1.0 }, 64 | ], 65 | }, 66 | }, 67 | { 68 | ParameterCurve: { 69 | ParameterID: "HapticSharpnessControl", 70 | Time: 0.0, 71 | ParameterCurveControlPoints: [ 72 | { Time: 0, ParameterValue: -0.5 }, 73 | { Time: 0.6, ParameterValue: 0.5 }, 74 | ], 75 | }, 76 | }, 77 | 78 | { 79 | Event: { 80 | Time: 0.601, 81 | EventType: "HapticTransient", 82 | EventParameters: [ 83 | { ParameterID: "HapticIntensity", ParameterValue: 1.0 }, 84 | { ParameterID: "HapticSharpness", ParameterValue: 0.7 }, 85 | ], 86 | }, 87 | }, 88 | ], 89 | }); 90 | 91 | export default function App() { 92 | return ( 93 | 94 | player.start()}>Start! 95 | 96 | 97 | ); 98 | } 99 | 100 | const styles = StyleSheet.create({ 101 | container: { 102 | flex: 1, 103 | backgroundColor: "#fff", 104 | alignItems: "center", 105 | justifyContent: "center", 106 | }, 107 | }); 108 | ``` 109 | 110 | ## Audio 111 | 112 | Audio files can be used OTA, so long as you copy the audio into the iOS Documents Directory, this can be done with `expo-file-system`: 113 | 114 | ```ts 115 | import React from "react"; 116 | import * as FS from "expo-file-system"; 117 | import { Asset } from "expo-asset"; 118 | 119 | function useAudioInDocumentsDir(res) { 120 | const [audioName, setName] = React.useState(null); 121 | 122 | React.useEffect(() => { 123 | Asset.fromModule(res) 124 | .downloadAsync() 125 | .then(async (result) => { 126 | const audioName = result.localUri.split("/").pop(); 127 | // move to the ios folder 128 | await FS.copyAsync({ 129 | from: result.localUri, 130 | to: FS.documentDirectory + audioName, 131 | }); 132 | 133 | setName(audioName); 134 | }); 135 | }, [res]); 136 | 137 | return audioName; 138 | } 139 | 140 | // Later... 141 | 142 | const audioName = useAudioInDocumentsDir(require("./path/to/audio.wav")); 143 | ``` 144 | 145 | Alternatively, you can use the [link-assets config plugin](https://github.com/evanbacon/link-assets#readme) to copy audio directly into the binary. Both generally have the same performance. 146 | 147 | 148 | The types were converted as best-effort from the resources I could find, tested a number of methods and most things seem to work. If you find any issues, please open a PR! 149 | 150 | 151 | -------------------------------------------------------------------------------- /Spawn.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/Spawn.wav -------------------------------------------------------------------------------- /app.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo": { 3 | "name": "capn-ahap", 4 | "slug": "capn-ahap", 5 | "version": "1.0.0", 6 | "orientation": "portrait", 7 | "icon": "./assets/icon.png", 8 | "userInterfaceStyle": "light", 9 | "splash": { 10 | "image": "./assets/splash.png", 11 | "resizeMode": "contain", 12 | "backgroundColor": "#ffffff" 13 | }, 14 | "assetBundlePatterns": ["**/*"], 15 | "ios": { 16 | "supportsTablet": true, 17 | "bundleIdentifier": "com.bacon.capn-ahap" 18 | }, 19 | "android": { 20 | "adaptiveIcon": { 21 | "foregroundImage": "./assets/adaptive-icon.png", 22 | "backgroundColor": "#ffffff" 23 | } 24 | }, 25 | "experiments": { 26 | "tsconfigPaths": true 27 | }, 28 | "web": { 29 | "favicon": "./assets/favicon.png" 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /assets/adaptive-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/assets/adaptive-icon.png -------------------------------------------------------------------------------- /assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/assets/favicon.png -------------------------------------------------------------------------------- /assets/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/assets/icon.png -------------------------------------------------------------------------------- /assets/splash.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/assets/splash.png -------------------------------------------------------------------------------- /babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = function(api) { 2 | api.cache(true); 3 | return { 4 | presets: ['babel-preset-expo'], 5 | }; 6 | }; 7 | -------------------------------------------------------------------------------- /haptics/texture.json: -------------------------------------------------------------------------------- 1 | { 2 | "Version": 1.0, 3 | "Metadata": 4 | { 5 | "Project" : "Haptic Ricochet", 6 | "Created" : "1 June 2021", 7 | "Description" : "A sequence of low sharpness, tightly spaced transient events and parameter variations to create a gravel-like texture." 8 | }, 9 | "Pattern": 10 | [ 11 | { 12 | "Event": { 13 | "Time": 0.00, 14 | "EventType": "HapticTransient", 15 | "EventParameters": 16 | [ 17 | { 18 | "ParameterID": "HapticIntensity", 19 | "ParameterValue": 0.7 20 | }, 21 | { 22 | "ParameterID": "HapticSharpness", 23 | "ParameterValue": 0.0 24 | } 25 | ] 26 | } 27 | }, 28 | { 29 | "Event": { 30 | "Time": 0.02, 31 | "EventType": "HapticTransient", 32 | "EventParameters": 33 | [ 34 | { 35 | "ParameterID": "HapticIntensity", 36 | "ParameterValue": 0.7 37 | }, 38 | { 39 | "ParameterID": "HapticSharpness", 40 | "ParameterValue": 0.0 41 | } 42 | ] 43 | } 44 | }, 45 | { 46 | "Event": { 47 | "Time": 0.04, 48 | "EventType": "HapticTransient", 49 | "EventParameters": 50 | [ 51 | { 52 | "ParameterID": "HapticIntensity", 53 | "ParameterValue": 0.7 54 | }, 55 | { 56 | "ParameterID": "HapticSharpness", 57 | "ParameterValue": 0.0 58 | } 59 | ] 60 | } 61 | }, 62 | { 63 | "Event": { 64 | "Time": 0.05, 65 | "EventType": "HapticTransient", 66 | "EventParameters": 67 | [ 68 | { 69 | "ParameterID": "HapticIntensity", 70 | "ParameterValue": 1.0 71 | }, 72 | { 73 | "ParameterID": "HapticSharpness", 74 | "ParameterValue": 0.2 75 | } 76 | ] 77 | } 78 | }, 79 | { 80 | "Event": { 81 | "Time": 0.07, 82 | "EventType": "HapticTransient", 83 | "EventParameters": 84 | [ 85 | { 86 | "ParameterID": "HapticIntensity", 87 | "ParameterValue": 1.0 88 | }, 89 | { 90 | "ParameterID": "HapticSharpness", 91 | "ParameterValue": 0.2 92 | } 93 | ] 94 | } 95 | }, 96 | { 97 | "Event": { 98 | "Time": 0.09, 99 | "EventType": "HapticTransient", 100 | "EventParameters": 101 | [ 102 | { 103 | "ParameterID": "HapticIntensity", 104 | "ParameterValue": 1.0 105 | }, 106 | { 107 | "ParameterID": "HapticSharpness", 108 | "ParameterValue": 0.2 109 | } 110 | ] 111 | } 112 | }, 113 | { 114 | "Event": { 115 | "Time": 0.11, 116 | "EventType": "HapticTransient", 117 | "EventParameters": 118 | [ 119 | { 120 | "ParameterID": "HapticIntensity", 121 | "ParameterValue": 1.0 122 | }, 123 | { 124 | "ParameterID": "HapticSharpness", 125 | "ParameterValue": 0.2 126 | } 127 | ] 128 | } 129 | }, 130 | { 131 | "Event": { 132 | "Time": 0.14, 133 | "EventType": "HapticTransient", 134 | "EventParameters": 135 | [ 136 | { 137 | "ParameterID": "HapticIntensity", 138 | "ParameterValue": 0.7 139 | }, 140 | { 141 | "ParameterID": "HapticSharpness", 142 | "ParameterValue": 0.0 143 | } 144 | ] 145 | } 146 | }, 147 | { 148 | "Event": { 149 | "Time": 0.16, 150 | "EventType": "HapticTransient", 151 | "EventParameters": 152 | [ 153 | { 154 | "ParameterID": "HapticIntensity", 155 | "ParameterValue": 0.7 156 | }, 157 | { 158 | "ParameterID": "HapticSharpness", 159 | "ParameterValue": 0.0 160 | } 161 | ] 162 | } 163 | }, 164 | { 165 | "Event": { 166 | "Time": 0.17, 167 | "EventType": "HapticTransient", 168 | "EventParameters": 169 | [ 170 | { 171 | "ParameterID": "HapticIntensity", 172 | "ParameterValue": 1.0 173 | }, 174 | { 175 | "ParameterID": "HapticSharpness", 176 | "ParameterValue": 0.2 177 | } 178 | ] 179 | } 180 | }, 181 | { 182 | "Event": { 183 | "Time": 0.2, 184 | "EventType": "HapticTransient", 185 | "EventParameters": 186 | [ 187 | { 188 | "ParameterID": "HapticIntensity", 189 | "ParameterValue": 0.7 190 | }, 191 | { 192 | "ParameterID": "HapticSharpness", 193 | "ParameterValue": 0.0 194 | } 195 | ] 196 | } 197 | }, 198 | { 199 | "Event": { 200 | "Time": 0.21, 201 | "EventType": "HapticTransient", 202 | "EventParameters": 203 | [ 204 | { 205 | "ParameterID": "HapticIntensity", 206 | "ParameterValue": 1.0 207 | }, 208 | { 209 | "ParameterID": "HapticSharpness", 210 | "ParameterValue": 0.2 211 | } 212 | ] 213 | } 214 | }, 215 | { 216 | "Event": { 217 | "Time": 0.24, 218 | "EventType": "HapticTransient", 219 | "EventParameters": 220 | [ 221 | { 222 | "ParameterID": "HapticIntensity", 223 | "ParameterValue": 0.7 224 | }, 225 | { 226 | "ParameterID": "HapticSharpness", 227 | "ParameterValue": 0.0 228 | } 229 | ] 230 | } 231 | }, 232 | { 233 | "Event": { 234 | "Time": 0.25, 235 | "EventType": "HapticTransient", 236 | "EventParameters": 237 | [ 238 | { 239 | "ParameterID": "HapticIntensity", 240 | "ParameterValue": 1.0 241 | }, 242 | { 243 | "ParameterID": "HapticSharpness", 244 | "ParameterValue": 0.2 245 | } 246 | ] 247 | } 248 | }, 249 | { 250 | "Event": { 251 | "Time": 0.28, 252 | "EventType": "HapticTransient", 253 | "EventParameters": 254 | [ 255 | { 256 | "ParameterID": "HapticIntensity", 257 | "ParameterValue": 0.7 258 | }, 259 | { 260 | "ParameterID": "HapticSharpness", 261 | "ParameterValue": 0.0 262 | } 263 | ] 264 | } 265 | }, 266 | { 267 | "Event": { 268 | "Time": 0.29, 269 | "EventType": "HapticTransient", 270 | "EventParameters": 271 | [ 272 | { 273 | "ParameterID": "HapticIntensity", 274 | "ParameterValue": 1.0 275 | }, 276 | { 277 | "ParameterID": "HapticSharpness", 278 | "ParameterValue": 0.2 279 | } 280 | ] 281 | } 282 | }, 283 | { 284 | "Event": { 285 | "Time": 0.31, 286 | "EventType": "HapticTransient", 287 | "EventParameters": 288 | [ 289 | { 290 | "ParameterID": "HapticIntensity", 291 | "ParameterValue": 1.0 292 | }, 293 | { 294 | "ParameterID": "HapticSharpness", 295 | "ParameterValue": 0.2 296 | } 297 | ] 298 | } 299 | }, 300 | { 301 | "Event": { 302 | "Time": 0.33, 303 | "EventType": "HapticTransient", 304 | "EventParameters": 305 | [ 306 | { 307 | "ParameterID": "HapticIntensity", 308 | "ParameterValue": 1.0 309 | }, 310 | { 311 | "ParameterID": "HapticSharpness", 312 | "ParameterValue": 0.2 313 | } 314 | ] 315 | } 316 | }, 317 | { 318 | "Event": { 319 | "Time": 0.35, 320 | "EventType": "HapticTransient", 321 | "EventParameters": 322 | [ 323 | { 324 | "ParameterID": "HapticIntensity", 325 | "ParameterValue": 1.0 326 | }, 327 | { 328 | "ParameterID": "HapticSharpness", 329 | "ParameterValue": 0.2 330 | } 331 | ] 332 | } 333 | }, 334 | { 335 | "Event": { 336 | "Time": 0.38, 337 | "EventType": "HapticTransient", 338 | "EventParameters": 339 | [ 340 | { 341 | "ParameterID": "HapticIntensity", 342 | "ParameterValue": 0.7 343 | }, 344 | { 345 | "ParameterID": "HapticSharpness", 346 | "ParameterValue": 0.0 347 | } 348 | ] 349 | } 350 | }, 351 | { 352 | "Event": { 353 | "Time": 0.39, 354 | "EventType": "HapticTransient", 355 | "EventParameters": 356 | [ 357 | { 358 | "ParameterID": "HapticIntensity", 359 | "ParameterValue": 1.0 360 | }, 361 | { 362 | "ParameterID": "HapticSharpness", 363 | "ParameterValue": 0.2 364 | } 365 | ] 366 | } 367 | }, 368 | { 369 | "Event": { 370 | "Time": 0.42, 371 | "EventType": "HapticTransient", 372 | "EventParameters": 373 | [ 374 | { 375 | "ParameterID": "HapticIntensity", 376 | "ParameterValue": 0.7 377 | }, 378 | { 379 | "ParameterID": "HapticSharpness", 380 | "ParameterValue": 0.0 381 | } 382 | ] 383 | } 384 | }, 385 | { 386 | "Event": { 387 | "Time": 0.43, 388 | "EventType": "HapticTransient", 389 | "EventParameters": 390 | [ 391 | { 392 | "ParameterID": "HapticIntensity", 393 | "ParameterValue": 1.0 394 | }, 395 | { 396 | "ParameterID": "HapticSharpness", 397 | "ParameterValue": 0.2 398 | } 399 | ] 400 | } 401 | }, 402 | { 403 | "Event": { 404 | "Time": 0.46, 405 | "EventType": "HapticTransient", 406 | "EventParameters": 407 | [ 408 | { 409 | "ParameterID": "HapticIntensity", 410 | "ParameterValue": 0.7 411 | }, 412 | { 413 | "ParameterID": "HapticSharpness", 414 | "ParameterValue": 0.0 415 | } 416 | ] 417 | } 418 | }, 419 | { 420 | "Event": { 421 | "Time": 0.48, 422 | "EventType": "HapticTransient", 423 | "EventParameters": 424 | [ 425 | { 426 | "ParameterID": "HapticIntensity", 427 | "ParameterValue": 0.7 428 | }, 429 | { 430 | "ParameterID": "HapticSharpness", 431 | "ParameterValue": 0.0 432 | } 433 | ] 434 | } 435 | }, 436 | { 437 | "Event": { 438 | "Time": 0.5, 439 | "EventType": "HapticTransient", 440 | "EventParameters": 441 | [ 442 | { 443 | "ParameterID": "HapticIntensity", 444 | "ParameterValue": 0.7 445 | }, 446 | { 447 | "ParameterID": "HapticSharpness", 448 | "ParameterValue": 0.0 449 | } 450 | ] 451 | } 452 | }, 453 | { 454 | "Event": { 455 | "Time": 0.52, 456 | "EventType": "HapticTransient", 457 | "EventParameters": 458 | [ 459 | { 460 | "ParameterID": "HapticIntensity", 461 | "ParameterValue": 0.7 462 | }, 463 | { 464 | "ParameterID": "HapticSharpness", 465 | "ParameterValue": 0.0 466 | } 467 | ] 468 | } 469 | }, 470 | { 471 | "Event": { 472 | "Time": 0.53, 473 | "EventType": "HapticTransient", 474 | "EventParameters": 475 | [ 476 | { 477 | "ParameterID": "HapticIntensity", 478 | "ParameterValue": 1.0 479 | }, 480 | { 481 | "ParameterID": "HapticSharpness", 482 | "ParameterValue": 0.2 483 | } 484 | ] 485 | } 486 | }, 487 | { 488 | "Event": { 489 | "Time": 0.56, 490 | "EventType": "HapticTransient", 491 | "EventParameters": 492 | [ 493 | { 494 | "ParameterID": "HapticIntensity", 495 | "ParameterValue": 0.7 496 | }, 497 | { 498 | "ParameterID": "HapticSharpness", 499 | "ParameterValue": 0.0 500 | } 501 | ] 502 | } 503 | }, 504 | { 505 | "Event": { 506 | "Time": 0.57, 507 | "EventType": "HapticTransient", 508 | "EventParameters": 509 | [ 510 | { 511 | "ParameterID": "HapticIntensity", 512 | "ParameterValue": 1.0 513 | }, 514 | { 515 | "ParameterID": "HapticSharpness", 516 | "ParameterValue": 0.2 517 | } 518 | ] 519 | } 520 | }, 521 | { 522 | "Event": { 523 | "Time": 0.6, 524 | "EventType": "HapticTransient", 525 | "EventParameters": 526 | [ 527 | { 528 | "ParameterID": "HapticIntensity", 529 | "ParameterValue": 0.7 530 | }, 531 | { 532 | "ParameterID": "HapticSharpness", 533 | "ParameterValue": 0.0 534 | } 535 | ] 536 | } 537 | }, 538 | { 539 | "Event": { 540 | "Time": 0.62, 541 | "EventType": "HapticTransient", 542 | "EventParameters": 543 | [ 544 | { 545 | "ParameterID": "HapticIntensity", 546 | "ParameterValue": 0.7 547 | }, 548 | { 549 | "ParameterID": "HapticSharpness", 550 | "ParameterValue": 0.0 551 | } 552 | ] 553 | } 554 | }, 555 | { 556 | "Event": { 557 | "Time": 0.64, 558 | "EventType": "HapticTransient", 559 | "EventParameters": 560 | [ 561 | { 562 | "ParameterID": "HapticIntensity", 563 | "ParameterValue": 0.7 564 | }, 565 | { 566 | "ParameterID": "HapticSharpness", 567 | "ParameterValue": 0.0 568 | } 569 | ] 570 | } 571 | }, 572 | { 573 | "Event": { 574 | "Time": 0.65, 575 | "EventType": "HapticTransient", 576 | "EventParameters": 577 | [ 578 | { 579 | "ParameterID": "HapticIntensity", 580 | "ParameterValue": 1.0 581 | }, 582 | { 583 | "ParameterID": "HapticSharpness", 584 | "ParameterValue": 0.2 585 | } 586 | ] 587 | } 588 | }, 589 | { 590 | "Event": { 591 | "Time": 0.67, 592 | "EventType": "HapticTransient", 593 | "EventParameters": 594 | [ 595 | { 596 | "ParameterID": "HapticIntensity", 597 | "ParameterValue": 1.0 598 | }, 599 | { 600 | "ParameterID": "HapticSharpness", 601 | "ParameterValue": 0.2 602 | } 603 | ] 604 | } 605 | }, 606 | { 607 | "Event": { 608 | "Time": 0.69, 609 | "EventType": "HapticTransient", 610 | "EventParameters": 611 | [ 612 | { 613 | "ParameterID": "HapticIntensity", 614 | "ParameterValue": 1.0 615 | }, 616 | { 617 | "ParameterID": "HapticSharpness", 618 | "ParameterValue": 0.2 619 | } 620 | ] 621 | } 622 | }, 623 | { 624 | "Event": { 625 | "Time": 0.72, 626 | "EventType": "HapticTransient", 627 | "EventParameters": 628 | [ 629 | { 630 | "ParameterID": "HapticIntensity", 631 | "ParameterValue": 0.7 632 | }, 633 | { 634 | "ParameterID": "HapticSharpness", 635 | "ParameterValue": 0.0 636 | } 637 | ] 638 | } 639 | }, 640 | { 641 | "Event": { 642 | "Time": 0.74, 643 | "EventType": "HapticTransient", 644 | "EventParameters": 645 | [ 646 | { 647 | "ParameterID": "HapticIntensity", 648 | "ParameterValue": 0.7 649 | }, 650 | { 651 | "ParameterID": "HapticSharpness", 652 | "ParameterValue": 0.0 653 | } 654 | ] 655 | } 656 | }, 657 | { 658 | "Event": { 659 | "Time": 0.76, 660 | "EventType": "HapticTransient", 661 | "EventParameters": 662 | [ 663 | { 664 | "ParameterID": "HapticIntensity", 665 | "ParameterValue": 0.7 666 | }, 667 | { 668 | "ParameterID": "HapticSharpness", 669 | "ParameterValue": 0.0 670 | } 671 | ] 672 | } 673 | }, 674 | { 675 | "Event": { 676 | "Time": 0.78, 677 | "EventType": "HapticTransient", 678 | "EventParameters": 679 | [ 680 | { 681 | "ParameterID": "HapticIntensity", 682 | "ParameterValue": 0.7 683 | }, 684 | { 685 | "ParameterID": "HapticSharpness", 686 | "ParameterValue": 0.0 687 | } 688 | ] 689 | } 690 | }, 691 | { 692 | "Event": { 693 | "Time": 0.8, 694 | "EventType": "HapticTransient", 695 | "EventParameters": 696 | [ 697 | { 698 | "ParameterID": "HapticIntensity", 699 | "ParameterValue": 0.7 700 | }, 701 | { 702 | "ParameterID": "HapticSharpness", 703 | "ParameterValue": 0.0 704 | } 705 | ] 706 | } 707 | }, 708 | { 709 | "Event": { 710 | "Time": 0.81, 711 | "EventType": "HapticTransient", 712 | "EventParameters": 713 | [ 714 | { 715 | "ParameterID": "HapticIntensity", 716 | "ParameterValue": 1.0 717 | }, 718 | { 719 | "ParameterID": "HapticSharpness", 720 | "ParameterValue": 0.2 721 | } 722 | ] 723 | } 724 | }, 725 | { 726 | "Event": { 727 | "Time": 0.84, 728 | "EventType": "HapticTransient", 729 | "EventParameters": 730 | [ 731 | { 732 | "ParameterID": "HapticIntensity", 733 | "ParameterValue": 0.7 734 | }, 735 | { 736 | "ParameterID": "HapticSharpness", 737 | "ParameterValue": 0.0 738 | } 739 | ] 740 | } 741 | }, 742 | { 743 | "Event": { 744 | "Time": 0.85, 745 | "EventType": "HapticTransient", 746 | "EventParameters": 747 | [ 748 | { 749 | "ParameterID": "HapticIntensity", 750 | "ParameterValue": 1.0 751 | }, 752 | { 753 | "ParameterID": "HapticSharpness", 754 | "ParameterValue": 0.2 755 | } 756 | ] 757 | } 758 | }, 759 | { 760 | "Event": { 761 | "Time": 0.88, 762 | "EventType": "HapticTransient", 763 | "EventParameters": 764 | [ 765 | { 766 | "ParameterID": "HapticIntensity", 767 | "ParameterValue": 0.7 768 | }, 769 | { 770 | "ParameterID": "HapticSharpness", 771 | "ParameterValue": 0.0 772 | } 773 | ] 774 | } 775 | }, 776 | { 777 | "Event": { 778 | "Time": 0.89, 779 | "EventType": "HapticTransient", 780 | "EventParameters": 781 | [ 782 | { 783 | "ParameterID": "HapticIntensity", 784 | "ParameterValue": 1.0 785 | }, 786 | { 787 | "ParameterID": "HapticSharpness", 788 | "ParameterValue": 0.2 789 | } 790 | ] 791 | } 792 | }, 793 | { 794 | "Event": { 795 | "Time": 0.92, 796 | "EventType": "HapticTransient", 797 | "EventParameters": 798 | [ 799 | { 800 | "ParameterID": "HapticIntensity", 801 | "ParameterValue": 0.7 802 | }, 803 | { 804 | "ParameterID": "HapticSharpness", 805 | "ParameterValue": 0.0 806 | } 807 | ] 808 | } 809 | }, 810 | { 811 | "Event": { 812 | "Time": 0.94, 813 | "EventType": "HapticTransient", 814 | "EventParameters": 815 | [ 816 | { 817 | "ParameterID": "HapticIntensity", 818 | "ParameterValue": 0.7 819 | }, 820 | { 821 | "ParameterID": "HapticSharpness", 822 | "ParameterValue": 0.0 823 | } 824 | ] 825 | } 826 | }, 827 | { 828 | "Event": { 829 | "Time": 0.96, 830 | "EventType": "HapticTransient", 831 | "EventParameters": 832 | [ 833 | { 834 | "ParameterID": "HapticIntensity", 835 | "ParameterValue": 0.7 836 | }, 837 | { 838 | "ParameterID": "HapticSharpness", 839 | "ParameterValue": 0.0 840 | } 841 | ] 842 | } 843 | }, 844 | { 845 | "Event": { 846 | "Time": 0.98, 847 | "EventType": "HapticTransient", 848 | "EventParameters": 849 | [ 850 | { 851 | "ParameterID": "HapticIntensity", 852 | "ParameterValue": 0.7 853 | }, 854 | { 855 | "ParameterID": "HapticSharpness", 856 | "ParameterValue": 0.0 857 | } 858 | ] 859 | } 860 | }, 861 | { 862 | "Event": { 863 | "Time": 1.0, 864 | "EventType": "HapticTransient", 865 | "EventParameters": 866 | [ 867 | { 868 | "ParameterID": "HapticIntensity", 869 | "ParameterValue": 0.7 870 | }, 871 | { 872 | "ParameterID": "HapticSharpness", 873 | "ParameterValue": 0.0 874 | } 875 | ] 876 | } 877 | }, 878 | { 879 | "Event": { 880 | "Time": 1.01, 881 | "EventType": "HapticTransient", 882 | "EventParameters": 883 | [ 884 | { 885 | "ParameterID": "HapticIntensity", 886 | "ParameterValue": 1.0 887 | }, 888 | { 889 | "ParameterID": "HapticSharpness", 890 | "ParameterValue": 0.2 891 | } 892 | ] 893 | } 894 | }, 895 | { 896 | "Event": { 897 | "Time": 1.04, 898 | "EventType": "HapticTransient", 899 | "EventParameters": 900 | [ 901 | { 902 | "ParameterID": "HapticIntensity", 903 | "ParameterValue": 0.7 904 | }, 905 | { 906 | "ParameterID": "HapticSharpness", 907 | "ParameterValue": 0.0 908 | } 909 | ] 910 | } 911 | }, 912 | { 913 | "Event": { 914 | "Time": 1.06, 915 | "EventType": "HapticTransient", 916 | "EventParameters": 917 | [ 918 | { 919 | "ParameterID": "HapticIntensity", 920 | "ParameterValue": 0.7 921 | }, 922 | { 923 | "ParameterID": "HapticSharpness", 924 | "ParameterValue": 0.0 925 | } 926 | ] 927 | } 928 | }, 929 | { 930 | "Event": { 931 | "Time": 1.07, 932 | "EventType": "HapticTransient", 933 | "EventParameters": 934 | [ 935 | { 936 | "ParameterID": "HapticIntensity", 937 | "ParameterValue": 1.0 938 | }, 939 | { 940 | "ParameterID": "HapticSharpness", 941 | "ParameterValue": 0.2 942 | } 943 | ] 944 | } 945 | }, 946 | { 947 | "Event": { 948 | "Time": 1.09, 949 | "EventType": "HapticTransient", 950 | "EventParameters": 951 | [ 952 | { 953 | "ParameterID": "HapticIntensity", 954 | "ParameterValue": 1.0 955 | }, 956 | { 957 | "ParameterID": "HapticSharpness", 958 | "ParameterValue": 0.2 959 | } 960 | ] 961 | } 962 | }, 963 | { 964 | "Event": { 965 | "Time": 1.11, 966 | "EventType": "HapticTransient", 967 | "EventParameters": 968 | [ 969 | { 970 | "ParameterID": "HapticIntensity", 971 | "ParameterValue": 1.0 972 | }, 973 | { 974 | "ParameterID": "HapticSharpness", 975 | "ParameterValue": 0.2 976 | } 977 | ] 978 | } 979 | }, 980 | { 981 | "Event": { 982 | "Time": 1.14, 983 | "EventType": "HapticTransient", 984 | "EventParameters": 985 | [ 986 | { 987 | "ParameterID": "HapticIntensity", 988 | "ParameterValue": 0.7 989 | }, 990 | { 991 | "ParameterID": "HapticSharpness", 992 | "ParameterValue": 0.0 993 | } 994 | ] 995 | } 996 | }, 997 | { 998 | "Event": { 999 | "Time": 1.15, 1000 | "EventType": "HapticTransient", 1001 | "EventParameters": 1002 | [ 1003 | { 1004 | "ParameterID": "HapticIntensity", 1005 | "ParameterValue": 1.0 1006 | }, 1007 | { 1008 | "ParameterID": "HapticSharpness", 1009 | "ParameterValue": 0.2 1010 | } 1011 | ] 1012 | } 1013 | }, 1014 | { 1015 | "Event": { 1016 | "Time": 1.18, 1017 | "EventType": "HapticTransient", 1018 | "EventParameters": 1019 | [ 1020 | { 1021 | "ParameterID": "HapticIntensity", 1022 | "ParameterValue": 0.7 1023 | }, 1024 | { 1025 | "ParameterID": "HapticSharpness", 1026 | "ParameterValue": 0.0 1027 | } 1028 | ] 1029 | } 1030 | }, 1031 | { 1032 | "Event": { 1033 | "Time": 1.19, 1034 | "EventType": "HapticTransient", 1035 | "EventParameters": 1036 | [ 1037 | { 1038 | "ParameterID": "HapticIntensity", 1039 | "ParameterValue": 1.0 1040 | }, 1041 | { 1042 | "ParameterID": "HapticSharpness", 1043 | "ParameterValue": 0.2 1044 | } 1045 | ] 1046 | } 1047 | }, 1048 | { 1049 | "Event": { 1050 | "Time": 1.21, 1051 | "EventType": "HapticTransient", 1052 | "EventParameters": 1053 | [ 1054 | { 1055 | "ParameterID": "HapticIntensity", 1056 | "ParameterValue": 1.0 1057 | }, 1058 | { 1059 | "ParameterID": "HapticSharpness", 1060 | "ParameterValue": 0.2 1061 | } 1062 | ] 1063 | } 1064 | }, 1065 | { 1066 | "Event": { 1067 | "Time": 1.24, 1068 | "EventType": "HapticTransient", 1069 | "EventParameters": 1070 | [ 1071 | { 1072 | "ParameterID": "HapticIntensity", 1073 | "ParameterValue": 0.7 1074 | }, 1075 | { 1076 | "ParameterID": "HapticSharpness", 1077 | "ParameterValue": 0.0 1078 | } 1079 | ] 1080 | } 1081 | }, 1082 | { 1083 | "Event": { 1084 | "Time": 1.26, 1085 | "EventType": "HapticTransient", 1086 | "EventParameters": 1087 | [ 1088 | { 1089 | "ParameterID": "HapticIntensity", 1090 | "ParameterValue": 0.7 1091 | }, 1092 | { 1093 | "ParameterID": "HapticSharpness", 1094 | "ParameterValue": 0.0 1095 | } 1096 | ] 1097 | } 1098 | }, 1099 | { 1100 | "Event": { 1101 | "Time": 1.27, 1102 | "EventType": "HapticTransient", 1103 | "EventParameters": 1104 | [ 1105 | { 1106 | "ParameterID": "HapticIntensity", 1107 | "ParameterValue": 1.0 1108 | }, 1109 | { 1110 | "ParameterID": "HapticSharpness", 1111 | "ParameterValue": 0.2 1112 | } 1113 | ] 1114 | } 1115 | }, 1116 | { 1117 | "Event": { 1118 | "Time": 1.3, 1119 | "EventType": "HapticTransient", 1120 | "EventParameters": 1121 | [ 1122 | { 1123 | "ParameterID": "HapticIntensity", 1124 | "ParameterValue": 0.7 1125 | }, 1126 | { 1127 | "ParameterID": "HapticSharpness", 1128 | "ParameterValue": 0.0 1129 | } 1130 | ] 1131 | } 1132 | }, 1133 | { 1134 | "Event": { 1135 | "Time": 1.31, 1136 | "EventType": "HapticTransient", 1137 | "EventParameters": 1138 | [ 1139 | { 1140 | "ParameterID": "HapticIntensity", 1141 | "ParameterValue": 1.0 1142 | }, 1143 | { 1144 | "ParameterID": "HapticSharpness", 1145 | "ParameterValue": 0.2 1146 | } 1147 | ] 1148 | } 1149 | }, 1150 | { 1151 | "Event": { 1152 | "Time": 1.34, 1153 | "EventType": "HapticTransient", 1154 | "EventParameters": 1155 | [ 1156 | { 1157 | "ParameterID": "HapticIntensity", 1158 | "ParameterValue": 0.7 1159 | }, 1160 | { 1161 | "ParameterID": "HapticSharpness", 1162 | "ParameterValue": 0.0 1163 | } 1164 | ] 1165 | } 1166 | }, 1167 | { 1168 | "Event": { 1169 | "Time": 1.35, 1170 | "EventType": "HapticTransient", 1171 | "EventParameters": 1172 | [ 1173 | { 1174 | "ParameterID": "HapticIntensity", 1175 | "ParameterValue": 1.0 1176 | }, 1177 | { 1178 | "ParameterID": "HapticSharpness", 1179 | "ParameterValue": 0.2 1180 | } 1181 | ] 1182 | } 1183 | }, 1184 | { 1185 | "Event": { 1186 | "Time": 1.38, 1187 | "EventType": "HapticTransient", 1188 | "EventParameters": 1189 | [ 1190 | { 1191 | "ParameterID": "HapticIntensity", 1192 | "ParameterValue": 0.7 1193 | }, 1194 | { 1195 | "ParameterID": "HapticSharpness", 1196 | "ParameterValue": 0.0 1197 | } 1198 | ] 1199 | } 1200 | }, 1201 | { 1202 | "Event": { 1203 | "Time": 1.4, 1204 | "EventType": "HapticTransient", 1205 | "EventParameters": 1206 | [ 1207 | { 1208 | "ParameterID": "HapticIntensity", 1209 | "ParameterValue": 0.7 1210 | }, 1211 | { 1212 | "ParameterID": "HapticSharpness", 1213 | "ParameterValue": 0.0 1214 | } 1215 | ] 1216 | } 1217 | }, 1218 | { 1219 | "Event": { 1220 | "Time": 1.41, 1221 | "EventType": "HapticTransient", 1222 | "EventParameters": 1223 | [ 1224 | { 1225 | "ParameterID": "HapticIntensity", 1226 | "ParameterValue": 1.0 1227 | }, 1228 | { 1229 | "ParameterID": "HapticSharpness", 1230 | "ParameterValue": 0.2 1231 | } 1232 | ] 1233 | } 1234 | }, 1235 | { 1236 | "Event": { 1237 | "Time": 1.43, 1238 | "EventType": "HapticTransient", 1239 | "EventParameters": 1240 | [ 1241 | { 1242 | "ParameterID": "HapticIntensity", 1243 | "ParameterValue": 1.0 1244 | }, 1245 | { 1246 | "ParameterID": "HapticSharpness", 1247 | "ParameterValue": 0.2 1248 | } 1249 | ] 1250 | } 1251 | }, 1252 | { 1253 | "Event": { 1254 | "Time": 1.46, 1255 | "EventType": "HapticTransient", 1256 | "EventParameters": 1257 | [ 1258 | { 1259 | "ParameterID": "HapticIntensity", 1260 | "ParameterValue": 0.7 1261 | }, 1262 | { 1263 | "ParameterID": "HapticSharpness", 1264 | "ParameterValue": 0.0 1265 | } 1266 | ] 1267 | } 1268 | }, 1269 | { 1270 | "Event": { 1271 | "Time": 1.48, 1272 | "EventType": "HapticTransient", 1273 | "EventParameters": 1274 | [ 1275 | { 1276 | "ParameterID": "HapticIntensity", 1277 | "ParameterValue": 0.7 1278 | }, 1279 | { 1280 | "ParameterID": "HapticSharpness", 1281 | "ParameterValue": 0.0 1282 | } 1283 | ] 1284 | } 1285 | }, 1286 | { 1287 | "Event": { 1288 | "Time": 1.49, 1289 | "EventType": "HapticTransient", 1290 | "EventParameters": 1291 | [ 1292 | { 1293 | "ParameterID": "HapticIntensity", 1294 | "ParameterValue": 1.0 1295 | }, 1296 | { 1297 | "ParameterID": "HapticSharpness", 1298 | "ParameterValue": 0.2 1299 | } 1300 | ] 1301 | } 1302 | }, 1303 | { 1304 | "Event": { 1305 | "Time": 1.51, 1306 | "EventType": "HapticTransient", 1307 | "EventParameters": 1308 | [ 1309 | { 1310 | "ParameterID": "HapticIntensity", 1311 | "ParameterValue": 1.0 1312 | }, 1313 | { 1314 | "ParameterID": "HapticSharpness", 1315 | "ParameterValue": 0.2 1316 | } 1317 | ] 1318 | } 1319 | }, 1320 | { 1321 | "Event": { 1322 | "Time": 1.54, 1323 | "EventType": "HapticTransient", 1324 | "EventParameters": 1325 | [ 1326 | { 1327 | "ParameterID": "HapticIntensity", 1328 | "ParameterValue": 0.7 1329 | }, 1330 | { 1331 | "ParameterID": "HapticSharpness", 1332 | "ParameterValue": 0.0 1333 | } 1334 | ] 1335 | } 1336 | }, 1337 | { 1338 | "Event": { 1339 | "Time": 1.56, 1340 | "EventType": "HapticTransient", 1341 | "EventParameters": 1342 | [ 1343 | { 1344 | "ParameterID": "HapticIntensity", 1345 | "ParameterValue": 0.7 1346 | }, 1347 | { 1348 | "ParameterID": "HapticSharpness", 1349 | "ParameterValue": 0.0 1350 | } 1351 | ] 1352 | } 1353 | }, 1354 | { 1355 | "Event": { 1356 | "Time": 1.57, 1357 | "EventType": "HapticTransient", 1358 | "EventParameters": 1359 | [ 1360 | { 1361 | "ParameterID": "HapticIntensity", 1362 | "ParameterValue": 1.0 1363 | }, 1364 | { 1365 | "ParameterID": "HapticSharpness", 1366 | "ParameterValue": 0.2 1367 | } 1368 | ] 1369 | } 1370 | }, 1371 | { 1372 | "Event": { 1373 | "Time": 1.59, 1374 | "EventType": "HapticTransient", 1375 | "EventParameters": 1376 | [ 1377 | { 1378 | "ParameterID": "HapticIntensity", 1379 | "ParameterValue": 1.0 1380 | }, 1381 | { 1382 | "ParameterID": "HapticSharpness", 1383 | "ParameterValue": 0.2 1384 | } 1385 | ] 1386 | } 1387 | }, 1388 | { 1389 | "Event": { 1390 | "Time": 1.61, 1391 | "EventType": "HapticTransient", 1392 | "EventParameters": 1393 | [ 1394 | { 1395 | "ParameterID": "HapticIntensity", 1396 | "ParameterValue": 1.0 1397 | }, 1398 | { 1399 | "ParameterID": "HapticSharpness", 1400 | "ParameterValue": 0.2 1401 | } 1402 | ] 1403 | } 1404 | }, 1405 | { 1406 | "Event": { 1407 | "Time": 1.64, 1408 | "EventType": "HapticTransient", 1409 | "EventParameters": 1410 | [ 1411 | { 1412 | "ParameterID": "HapticIntensity", 1413 | "ParameterValue": 0.7 1414 | }, 1415 | { 1416 | "ParameterID": "HapticSharpness", 1417 | "ParameterValue": 0.0 1418 | } 1419 | ] 1420 | } 1421 | }, 1422 | { 1423 | "Event": { 1424 | "Time": 1.66, 1425 | "EventType": "HapticTransient", 1426 | "EventParameters": 1427 | [ 1428 | { 1429 | "ParameterID": "HapticIntensity", 1430 | "ParameterValue": 0.7 1431 | }, 1432 | { 1433 | "ParameterID": "HapticSharpness", 1434 | "ParameterValue": 0.0 1435 | } 1436 | ] 1437 | } 1438 | }, 1439 | { 1440 | "Event": { 1441 | "Time": 1.68, 1442 | "EventType": "HapticTransient", 1443 | "EventParameters": 1444 | [ 1445 | { 1446 | "ParameterID": "HapticIntensity", 1447 | "ParameterValue": 0.7 1448 | }, 1449 | { 1450 | "ParameterID": "HapticSharpness", 1451 | "ParameterValue": 0.0 1452 | } 1453 | ] 1454 | } 1455 | }, 1456 | { 1457 | "Event": { 1458 | "Time": 1.69, 1459 | "EventType": "HapticTransient", 1460 | "EventParameters": 1461 | [ 1462 | { 1463 | "ParameterID": "HapticIntensity", 1464 | "ParameterValue": 1.0 1465 | }, 1466 | { 1467 | "ParameterID": "HapticSharpness", 1468 | "ParameterValue": 0.2 1469 | } 1470 | ] 1471 | } 1472 | }, 1473 | { 1474 | "Event": { 1475 | "Time": 1.72, 1476 | "EventType": "HapticTransient", 1477 | "EventParameters": 1478 | [ 1479 | { 1480 | "ParameterID": "HapticIntensity", 1481 | "ParameterValue": 0.7 1482 | }, 1483 | { 1484 | "ParameterID": "HapticSharpness", 1485 | "ParameterValue": 0.0 1486 | } 1487 | ] 1488 | } 1489 | }, 1490 | { 1491 | "Event": { 1492 | "Time": 1.73, 1493 | "EventType": "HapticTransient", 1494 | "EventParameters": 1495 | [ 1496 | { 1497 | "ParameterID": "HapticIntensity", 1498 | "ParameterValue": 1.0 1499 | }, 1500 | { 1501 | "ParameterID": "HapticSharpness", 1502 | "ParameterValue": 0.2 1503 | } 1504 | ] 1505 | } 1506 | }, 1507 | { 1508 | "Event": { 1509 | "Time": 1.76, 1510 | "EventType": "HapticTransient", 1511 | "EventParameters": 1512 | [ 1513 | { 1514 | "ParameterID": "HapticIntensity", 1515 | "ParameterValue": 0.7 1516 | }, 1517 | { 1518 | "ParameterID": "HapticSharpness", 1519 | "ParameterValue": 0.0 1520 | } 1521 | ] 1522 | } 1523 | }, 1524 | { 1525 | "Event": { 1526 | "Time": 1.77, 1527 | "EventType": "HapticTransient", 1528 | "EventParameters": 1529 | [ 1530 | { 1531 | "ParameterID": "HapticIntensity", 1532 | "ParameterValue": 1.0 1533 | }, 1534 | { 1535 | "ParameterID": "HapticSharpness", 1536 | "ParameterValue": 0.2 1537 | } 1538 | ] 1539 | } 1540 | }, 1541 | { 1542 | "Event": { 1543 | "Time": 1.79, 1544 | "EventType": "HapticTransient", 1545 | "EventParameters": 1546 | [ 1547 | { 1548 | "ParameterID": "HapticIntensity", 1549 | "ParameterValue": 1.0 1550 | }, 1551 | { 1552 | "ParameterID": "HapticSharpness", 1553 | "ParameterValue": 0.2 1554 | } 1555 | ] 1556 | } 1557 | }, 1558 | { 1559 | "Event": { 1560 | "Time": 1.81, 1561 | "EventType": "HapticTransient", 1562 | "EventParameters": 1563 | [ 1564 | { 1565 | "ParameterID": "HapticIntensity", 1566 | "ParameterValue": 1.0 1567 | }, 1568 | { 1569 | "ParameterID": "HapticSharpness", 1570 | "ParameterValue": 0.2 1571 | } 1572 | ] 1573 | } 1574 | }, 1575 | { 1576 | "Event": { 1577 | "Time": 1.84, 1578 | "EventType": "HapticTransient", 1579 | "EventParameters": 1580 | [ 1581 | { 1582 | "ParameterID": "HapticIntensity", 1583 | "ParameterValue": 0.7 1584 | }, 1585 | { 1586 | "ParameterID": "HapticSharpness", 1587 | "ParameterValue": 0.0 1588 | } 1589 | ] 1590 | } 1591 | }, 1592 | { 1593 | "Event": { 1594 | "Time": 1.85, 1595 | "EventType": "HapticTransient", 1596 | "EventParameters": 1597 | [ 1598 | { 1599 | "ParameterID": "HapticIntensity", 1600 | "ParameterValue": 1.0 1601 | }, 1602 | { 1603 | "ParameterID": "HapticSharpness", 1604 | "ParameterValue": 0.2 1605 | } 1606 | ] 1607 | } 1608 | }, 1609 | { 1610 | "Event": { 1611 | "Time": 1.87, 1612 | "EventType": "HapticTransient", 1613 | "EventParameters": 1614 | [ 1615 | { 1616 | "ParameterID": "HapticIntensity", 1617 | "ParameterValue": 1.0 1618 | }, 1619 | { 1620 | "ParameterID": "HapticSharpness", 1621 | "ParameterValue": 0.2 1622 | } 1623 | ] 1624 | } 1625 | }, 1626 | { 1627 | "Event": { 1628 | "Time": 1.89, 1629 | "EventType": "HapticTransient", 1630 | "EventParameters": 1631 | [ 1632 | { 1633 | "ParameterID": "HapticIntensity", 1634 | "ParameterValue": 1.0 1635 | }, 1636 | { 1637 | "ParameterID": "HapticSharpness", 1638 | "ParameterValue": 0.2 1639 | } 1640 | ] 1641 | } 1642 | }, 1643 | { 1644 | "Event": { 1645 | "Time": 1.91, 1646 | "EventType": "HapticTransient", 1647 | "EventParameters": 1648 | [ 1649 | { 1650 | "ParameterID": "HapticIntensity", 1651 | "ParameterValue": 1.0 1652 | }, 1653 | { 1654 | "ParameterID": "HapticSharpness", 1655 | "ParameterValue": 0.2 1656 | } 1657 | ] 1658 | } 1659 | }, 1660 | { 1661 | "Event": { 1662 | "Time": 1.94, 1663 | "EventType": "HapticTransient", 1664 | "EventParameters": 1665 | [ 1666 | { 1667 | "ParameterID": "HapticIntensity", 1668 | "ParameterValue": 0.7 1669 | }, 1670 | { 1671 | "ParameterID": "HapticSharpness", 1672 | "ParameterValue": 0.0 1673 | } 1674 | ] 1675 | } 1676 | }, 1677 | { 1678 | "Event": { 1679 | "Time": 1.95, 1680 | "EventType": "HapticTransient", 1681 | "EventParameters": 1682 | [ 1683 | { 1684 | "ParameterID": "HapticIntensity", 1685 | "ParameterValue": 1.0 1686 | }, 1687 | { 1688 | "ParameterID": "HapticSharpness", 1689 | "ParameterValue": 0.2 1690 | } 1691 | ] 1692 | } 1693 | }, 1694 | { 1695 | "Event": { 1696 | "Time": 1.97, 1697 | "EventType": "HapticTransient", 1698 | "EventParameters": 1699 | [ 1700 | { 1701 | "ParameterID": "HapticIntensity", 1702 | "ParameterValue": 1.0 1703 | }, 1704 | { 1705 | "ParameterID": "HapticSharpness", 1706 | "ParameterValue": 0.2 1707 | } 1708 | ] 1709 | } 1710 | }, 1711 | { 1712 | "Event": { 1713 | "Time": 2.0, 1714 | "EventType": "HapticTransient", 1715 | "EventParameters": 1716 | [ 1717 | { 1718 | "ParameterID": "HapticIntensity", 1719 | "ParameterValue": 0.7 1720 | }, 1721 | { 1722 | "ParameterID": "HapticSharpness", 1723 | "ParameterValue": 0.0 1724 | } 1725 | ] 1726 | } 1727 | } 1728 | ] 1729 | } 1730 | -------------------------------------------------------------------------------- /haptics/thing1/altitude_open.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/haptics/thing1/altitude_open.mp3 -------------------------------------------------------------------------------- /haptics/thing1/battery_gravity_1.json: -------------------------------------------------------------------------------- 1 | {"version":{"major":1,"minor":0,"patch":0},"metadata":{"author":"ryan@growpixel.com","editor":"Lofelt Studio","source":"../wav/battery_gravity_1.wav","project":"battery_gravity_1","tags":[],"description":""},"signals":{"continuous":{"envelopes":{"amplitude":[{"time":0,"amplitude":0.00016393959},{"time":0.5934306195492994,"amplitude":1},{"time":0.645628321070576,"amplitude":0.07223810052631582},{"time":0.7419501,"amplitude":0.054701842},{"time":1.4018141,"amplitude":0.00022400863},{"time":1.4019048,"amplitude":0.00022400863}],"frequency":[{"time":0,"frequency":0},{"time":0.29656265810321825,"frequency":0.3195595902022682},{"time":0.5051415950409947,"frequency":1},{"time":0.6449608940059068,"frequency":0.08750264529628483},{"time":1.3204663,"frequency":0.12652206},{"time":1.4019048,"frequency":0}]}}}} -------------------------------------------------------------------------------- /haptics/thing1/battery_gravity_1.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/haptics/thing1/battery_gravity_1.wav -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | # OSX 2 | # 3 | .DS_Store 4 | 5 | # Xcode 6 | # 7 | build/ 8 | *.pbxuser 9 | !default.pbxuser 10 | *.mode1v3 11 | !default.mode1v3 12 | *.mode2v3 13 | !default.mode2v3 14 | *.perspectivev3 15 | !default.perspectivev3 16 | xcuserdata 17 | *.xccheckout 18 | *.moved-aside 19 | DerivedData 20 | *.hmap 21 | *.ipa 22 | *.xcuserstate 23 | project.xcworkspace 24 | .xcode.env.local 25 | 26 | # Bundle artifacts 27 | *.jsbundle 28 | 29 | # CocoaPods 30 | /Pods/ 31 | -------------------------------------------------------------------------------- /ios/.xcode.env: -------------------------------------------------------------------------------- 1 | # This `.xcode.env` file is versioned and is used to source the environment 2 | # used when running script phases inside Xcode. 3 | # To customize your local environment, you can create an `.xcode.env.local` 4 | # file that is not versioned. 5 | 6 | # NODE_BINARY variable contains the PATH to the node executable. 7 | # 8 | # Customize the NODE_BINARY variable here. 9 | # For example, to use nvm with brew, add the following line 10 | # . "$(brew --prefix nvm)/nvm.sh" --no-use 11 | export NODE_BINARY=$(command -v node) 12 | -------------------------------------------------------------------------------- /ios/Podfile: -------------------------------------------------------------------------------- 1 | require File.join(File.dirname(`node --print "require.resolve('expo/package.json')"`), "scripts/autolinking") 2 | require File.join(File.dirname(`node --print "require.resolve('react-native/package.json')"`), "scripts/react_native_pods") 3 | 4 | require 'json' 5 | podfile_properties = JSON.parse(File.read(File.join(__dir__, 'Podfile.properties.json'))) rescue {} 6 | 7 | ENV['RCT_NEW_ARCH_ENABLED'] = podfile_properties['newArchEnabled'] == 'true' ? '1' : '0' 8 | ENV['EX_DEV_CLIENT_NETWORK_INSPECTOR'] = podfile_properties['EX_DEV_CLIENT_NETWORK_INSPECTOR'] 9 | 10 | platform :ios, podfile_properties['ios.deploymentTarget'] || '13.0' 11 | install! 'cocoapods', 12 | :deterministic_uuids => false 13 | 14 | prepare_react_native_project! 15 | 16 | # If you are using a `react-native-flipper` your iOS build will fail when `NO_FLIPPER=1` is set. 17 | # because `react-native-flipper` depends on (FlipperKit,...), which will be excluded. To fix this, 18 | # you can also exclude `react-native-flipper` in `react-native.config.js` 19 | # 20 | # ```js 21 | # module.exports = { 22 | # dependencies: { 23 | # ...(process.env.NO_FLIPPER ? { 'react-native-flipper': { platforms: { ios: null } } } : {}), 24 | # } 25 | # } 26 | # ``` 27 | flipper_config = FlipperConfiguration.disabled 28 | if ENV['NO_FLIPPER'] == '1' then 29 | # Explicitly disabled through environment variables 30 | flipper_config = FlipperConfiguration.disabled 31 | elsif podfile_properties.key?('ios.flipper') then 32 | # Configure Flipper in Podfile.properties.json 33 | if podfile_properties['ios.flipper'] == 'true' then 34 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"]) 35 | elsif podfile_properties['ios.flipper'] != 'false' then 36 | flipper_config = FlipperConfiguration.enabled(["Debug", "Release"], { 'Flipper' => podfile_properties['ios.flipper'] }) 37 | end 38 | end 39 | 40 | target 'capnahap' do 41 | use_expo_modules! 42 | config = use_native_modules! 43 | 44 | use_frameworks! :linkage => podfile_properties['ios.useFrameworks'].to_sym if podfile_properties['ios.useFrameworks'] 45 | use_frameworks! :linkage => ENV['USE_FRAMEWORKS'].to_sym if ENV['USE_FRAMEWORKS'] 46 | 47 | # Flags change depending on the env values. 48 | flags = get_default_flags() 49 | 50 | use_react_native!( 51 | :path => config[:reactNativePath], 52 | :hermes_enabled => podfile_properties['expo.jsEngine'] == nil || podfile_properties['expo.jsEngine'] == 'hermes', 53 | :fabric_enabled => flags[:fabric_enabled], 54 | # An absolute path to your application root. 55 | :app_path => "#{Pod::Config.instance.installation_root}/..", 56 | # Note that if you have use_frameworks! enabled, Flipper will not work if enabled 57 | :flipper_configuration => flipper_config 58 | ) 59 | 60 | post_install do |installer| 61 | react_native_post_install( 62 | installer, 63 | config[:reactNativePath], 64 | :mac_catalyst_enabled => false 65 | ) 66 | __apply_Xcode_12_5_M1_post_install_workaround(installer) 67 | 68 | # This is necessary for Xcode 14, because it signs resource bundles by default 69 | # when building for devices. 70 | installer.target_installation_results.pod_target_installation_results 71 | .each do |pod_name, target_installation_result| 72 | target_installation_result.resource_bundle_targets.each do |resource_bundle_target| 73 | resource_bundle_target.build_configurations.each do |config| 74 | config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' 75 | end 76 | end 77 | end 78 | end 79 | 80 | post_integrate do |installer| 81 | begin 82 | expo_patch_react_imports!(installer) 83 | rescue => e 84 | Pod::UI.warn e 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Ahap (1.0.0): 3 | - ExpoModulesCore 4 | - boost (1.76.0) 5 | - DoubleConversion (1.1.6) 6 | - EXApplication (5.3.0): 7 | - ExpoModulesCore 8 | - EXConstants (14.4.2): 9 | - ExpoModulesCore 10 | - EXFileSystem (15.4.3): 11 | - ExpoModulesCore 12 | - EXFont (11.4.0): 13 | - ExpoModulesCore 14 | - Expo (49.0.8): 15 | - ExpoModulesCore 16 | - ExpoHaptics (12.4.0): 17 | - ExpoModulesCore 18 | - ExpoKeepAwake (12.3.0): 19 | - ExpoModulesCore 20 | - ExpoModulesCore (1.5.10): 21 | - RCT-Folly (= 2021.07.22.00) 22 | - React-Core 23 | - React-NativeModulesApple 24 | - React-RCTAppDelegate 25 | - ReactCommon/turbomodule/core 26 | - EXSplashScreen (0.20.5): 27 | - ExpoModulesCore 28 | - RCT-Folly (= 2021.07.22.00) 29 | - React-Core 30 | - FBLazyVector (0.72.4) 31 | - FBReactNativeSpec (0.72.4): 32 | - RCT-Folly (= 2021.07.22.00) 33 | - RCTRequired (= 0.72.4) 34 | - RCTTypeSafety (= 0.72.4) 35 | - React-Core (= 0.72.4) 36 | - React-jsi (= 0.72.4) 37 | - ReactCommon/turbomodule/core (= 0.72.4) 38 | - fmt (6.2.1) 39 | - glog (0.3.5) 40 | - hermes-engine (0.72.4): 41 | - hermes-engine/Pre-built (= 0.72.4) 42 | - hermes-engine/Pre-built (0.72.4) 43 | - libevent (2.1.12) 44 | - RCT-Folly (2021.07.22.00): 45 | - boost 46 | - DoubleConversion 47 | - fmt (~> 6.2.1) 48 | - glog 49 | - RCT-Folly/Default (= 2021.07.22.00) 50 | - RCT-Folly/Default (2021.07.22.00): 51 | - boost 52 | - DoubleConversion 53 | - fmt (~> 6.2.1) 54 | - glog 55 | - RCT-Folly/Futures (2021.07.22.00): 56 | - boost 57 | - DoubleConversion 58 | - fmt (~> 6.2.1) 59 | - glog 60 | - libevent 61 | - RCTRequired (0.72.4) 62 | - RCTTypeSafety (0.72.4): 63 | - FBLazyVector (= 0.72.4) 64 | - RCTRequired (= 0.72.4) 65 | - React-Core (= 0.72.4) 66 | - React (0.72.4): 67 | - React-Core (= 0.72.4) 68 | - React-Core/DevSupport (= 0.72.4) 69 | - React-Core/RCTWebSocket (= 0.72.4) 70 | - React-RCTActionSheet (= 0.72.4) 71 | - React-RCTAnimation (= 0.72.4) 72 | - React-RCTBlob (= 0.72.4) 73 | - React-RCTImage (= 0.72.4) 74 | - React-RCTLinking (= 0.72.4) 75 | - React-RCTNetwork (= 0.72.4) 76 | - React-RCTSettings (= 0.72.4) 77 | - React-RCTText (= 0.72.4) 78 | - React-RCTVibration (= 0.72.4) 79 | - React-callinvoker (0.72.4) 80 | - React-Codegen (0.72.4): 81 | - DoubleConversion 82 | - FBReactNativeSpec 83 | - glog 84 | - hermes-engine 85 | - RCT-Folly 86 | - RCTRequired 87 | - RCTTypeSafety 88 | - React-Core 89 | - React-jsi 90 | - React-jsiexecutor 91 | - React-NativeModulesApple 92 | - React-rncore 93 | - ReactCommon/turbomodule/bridging 94 | - ReactCommon/turbomodule/core 95 | - React-Core (0.72.4): 96 | - glog 97 | - hermes-engine 98 | - RCT-Folly (= 2021.07.22.00) 99 | - React-Core/Default (= 0.72.4) 100 | - React-cxxreact 101 | - React-hermes 102 | - React-jsi 103 | - React-jsiexecutor 104 | - React-perflogger 105 | - React-runtimeexecutor 106 | - React-utils 107 | - SocketRocket (= 0.6.1) 108 | - Yoga 109 | - React-Core/CoreModulesHeaders (0.72.4): 110 | - glog 111 | - hermes-engine 112 | - RCT-Folly (= 2021.07.22.00) 113 | - React-Core/Default 114 | - React-cxxreact 115 | - React-hermes 116 | - React-jsi 117 | - React-jsiexecutor 118 | - React-perflogger 119 | - React-runtimeexecutor 120 | - React-utils 121 | - SocketRocket (= 0.6.1) 122 | - Yoga 123 | - React-Core/Default (0.72.4): 124 | - glog 125 | - hermes-engine 126 | - RCT-Folly (= 2021.07.22.00) 127 | - React-cxxreact 128 | - React-hermes 129 | - React-jsi 130 | - React-jsiexecutor 131 | - React-perflogger 132 | - React-runtimeexecutor 133 | - React-utils 134 | - SocketRocket (= 0.6.1) 135 | - Yoga 136 | - React-Core/DevSupport (0.72.4): 137 | - glog 138 | - hermes-engine 139 | - RCT-Folly (= 2021.07.22.00) 140 | - React-Core/Default (= 0.72.4) 141 | - React-Core/RCTWebSocket (= 0.72.4) 142 | - React-cxxreact 143 | - React-hermes 144 | - React-jsi 145 | - React-jsiexecutor 146 | - React-jsinspector (= 0.72.4) 147 | - React-perflogger 148 | - React-runtimeexecutor 149 | - React-utils 150 | - SocketRocket (= 0.6.1) 151 | - Yoga 152 | - React-Core/RCTActionSheetHeaders (0.72.4): 153 | - glog 154 | - hermes-engine 155 | - RCT-Folly (= 2021.07.22.00) 156 | - React-Core/Default 157 | - React-cxxreact 158 | - React-hermes 159 | - React-jsi 160 | - React-jsiexecutor 161 | - React-perflogger 162 | - React-runtimeexecutor 163 | - React-utils 164 | - SocketRocket (= 0.6.1) 165 | - Yoga 166 | - React-Core/RCTAnimationHeaders (0.72.4): 167 | - glog 168 | - hermes-engine 169 | - RCT-Folly (= 2021.07.22.00) 170 | - React-Core/Default 171 | - React-cxxreact 172 | - React-hermes 173 | - React-jsi 174 | - React-jsiexecutor 175 | - React-perflogger 176 | - React-runtimeexecutor 177 | - React-utils 178 | - SocketRocket (= 0.6.1) 179 | - Yoga 180 | - React-Core/RCTBlobHeaders (0.72.4): 181 | - glog 182 | - hermes-engine 183 | - RCT-Folly (= 2021.07.22.00) 184 | - React-Core/Default 185 | - React-cxxreact 186 | - React-hermes 187 | - React-jsi 188 | - React-jsiexecutor 189 | - React-perflogger 190 | - React-runtimeexecutor 191 | - React-utils 192 | - SocketRocket (= 0.6.1) 193 | - Yoga 194 | - React-Core/RCTImageHeaders (0.72.4): 195 | - glog 196 | - hermes-engine 197 | - RCT-Folly (= 2021.07.22.00) 198 | - React-Core/Default 199 | - React-cxxreact 200 | - React-hermes 201 | - React-jsi 202 | - React-jsiexecutor 203 | - React-perflogger 204 | - React-runtimeexecutor 205 | - React-utils 206 | - SocketRocket (= 0.6.1) 207 | - Yoga 208 | - React-Core/RCTLinkingHeaders (0.72.4): 209 | - glog 210 | - hermes-engine 211 | - RCT-Folly (= 2021.07.22.00) 212 | - React-Core/Default 213 | - React-cxxreact 214 | - React-hermes 215 | - React-jsi 216 | - React-jsiexecutor 217 | - React-perflogger 218 | - React-runtimeexecutor 219 | - React-utils 220 | - SocketRocket (= 0.6.1) 221 | - Yoga 222 | - React-Core/RCTNetworkHeaders (0.72.4): 223 | - glog 224 | - hermes-engine 225 | - RCT-Folly (= 2021.07.22.00) 226 | - React-Core/Default 227 | - React-cxxreact 228 | - React-hermes 229 | - React-jsi 230 | - React-jsiexecutor 231 | - React-perflogger 232 | - React-runtimeexecutor 233 | - React-utils 234 | - SocketRocket (= 0.6.1) 235 | - Yoga 236 | - React-Core/RCTSettingsHeaders (0.72.4): 237 | - glog 238 | - hermes-engine 239 | - RCT-Folly (= 2021.07.22.00) 240 | - React-Core/Default 241 | - React-cxxreact 242 | - React-hermes 243 | - React-jsi 244 | - React-jsiexecutor 245 | - React-perflogger 246 | - React-runtimeexecutor 247 | - React-utils 248 | - SocketRocket (= 0.6.1) 249 | - Yoga 250 | - React-Core/RCTTextHeaders (0.72.4): 251 | - glog 252 | - hermes-engine 253 | - RCT-Folly (= 2021.07.22.00) 254 | - React-Core/Default 255 | - React-cxxreact 256 | - React-hermes 257 | - React-jsi 258 | - React-jsiexecutor 259 | - React-perflogger 260 | - React-runtimeexecutor 261 | - React-utils 262 | - SocketRocket (= 0.6.1) 263 | - Yoga 264 | - React-Core/RCTVibrationHeaders (0.72.4): 265 | - glog 266 | - hermes-engine 267 | - RCT-Folly (= 2021.07.22.00) 268 | - React-Core/Default 269 | - React-cxxreact 270 | - React-hermes 271 | - React-jsi 272 | - React-jsiexecutor 273 | - React-perflogger 274 | - React-runtimeexecutor 275 | - React-utils 276 | - SocketRocket (= 0.6.1) 277 | - Yoga 278 | - React-Core/RCTWebSocket (0.72.4): 279 | - glog 280 | - hermes-engine 281 | - RCT-Folly (= 2021.07.22.00) 282 | - React-Core/Default (= 0.72.4) 283 | - React-cxxreact 284 | - React-hermes 285 | - React-jsi 286 | - React-jsiexecutor 287 | - React-perflogger 288 | - React-runtimeexecutor 289 | - React-utils 290 | - SocketRocket (= 0.6.1) 291 | - Yoga 292 | - React-CoreModules (0.72.4): 293 | - RCT-Folly (= 2021.07.22.00) 294 | - RCTTypeSafety (= 0.72.4) 295 | - React-Codegen (= 0.72.4) 296 | - React-Core/CoreModulesHeaders (= 0.72.4) 297 | - React-jsi (= 0.72.4) 298 | - React-RCTBlob 299 | - React-RCTImage (= 0.72.4) 300 | - ReactCommon/turbomodule/core (= 0.72.4) 301 | - SocketRocket (= 0.6.1) 302 | - React-cxxreact (0.72.4): 303 | - boost (= 1.76.0) 304 | - DoubleConversion 305 | - glog 306 | - hermes-engine 307 | - RCT-Folly (= 2021.07.22.00) 308 | - React-callinvoker (= 0.72.4) 309 | - React-debug (= 0.72.4) 310 | - React-jsi (= 0.72.4) 311 | - React-jsinspector (= 0.72.4) 312 | - React-logger (= 0.72.4) 313 | - React-perflogger (= 0.72.4) 314 | - React-runtimeexecutor (= 0.72.4) 315 | - React-debug (0.72.4) 316 | - React-hermes (0.72.4): 317 | - DoubleConversion 318 | - glog 319 | - hermes-engine 320 | - RCT-Folly (= 2021.07.22.00) 321 | - RCT-Folly/Futures (= 2021.07.22.00) 322 | - React-cxxreact (= 0.72.4) 323 | - React-jsi 324 | - React-jsiexecutor (= 0.72.4) 325 | - React-jsinspector (= 0.72.4) 326 | - React-perflogger (= 0.72.4) 327 | - React-jsi (0.72.4): 328 | - boost (= 1.76.0) 329 | - DoubleConversion 330 | - glog 331 | - hermes-engine 332 | - RCT-Folly (= 2021.07.22.00) 333 | - React-jsiexecutor (0.72.4): 334 | - DoubleConversion 335 | - glog 336 | - hermes-engine 337 | - RCT-Folly (= 2021.07.22.00) 338 | - React-cxxreact (= 0.72.4) 339 | - React-jsi (= 0.72.4) 340 | - React-perflogger (= 0.72.4) 341 | - React-jsinspector (0.72.4) 342 | - React-logger (0.72.4): 343 | - glog 344 | - React-NativeModulesApple (0.72.4): 345 | - hermes-engine 346 | - React-callinvoker 347 | - React-Core 348 | - React-cxxreact 349 | - React-jsi 350 | - React-runtimeexecutor 351 | - ReactCommon/turbomodule/bridging 352 | - ReactCommon/turbomodule/core 353 | - React-perflogger (0.72.4) 354 | - React-RCTActionSheet (0.72.4): 355 | - React-Core/RCTActionSheetHeaders (= 0.72.4) 356 | - React-RCTAnimation (0.72.4): 357 | - RCT-Folly (= 2021.07.22.00) 358 | - RCTTypeSafety (= 0.72.4) 359 | - React-Codegen (= 0.72.4) 360 | - React-Core/RCTAnimationHeaders (= 0.72.4) 361 | - React-jsi (= 0.72.4) 362 | - ReactCommon/turbomodule/core (= 0.72.4) 363 | - React-RCTAppDelegate (0.72.4): 364 | - RCT-Folly 365 | - RCTRequired 366 | - RCTTypeSafety 367 | - React-Core 368 | - React-CoreModules 369 | - React-hermes 370 | - React-NativeModulesApple 371 | - React-RCTImage 372 | - React-RCTNetwork 373 | - React-runtimescheduler 374 | - ReactCommon/turbomodule/core 375 | - React-RCTBlob (0.72.4): 376 | - hermes-engine 377 | - RCT-Folly (= 2021.07.22.00) 378 | - React-Codegen (= 0.72.4) 379 | - React-Core/RCTBlobHeaders (= 0.72.4) 380 | - React-Core/RCTWebSocket (= 0.72.4) 381 | - React-jsi (= 0.72.4) 382 | - React-RCTNetwork (= 0.72.4) 383 | - ReactCommon/turbomodule/core (= 0.72.4) 384 | - React-RCTImage (0.72.4): 385 | - RCT-Folly (= 2021.07.22.00) 386 | - RCTTypeSafety (= 0.72.4) 387 | - React-Codegen (= 0.72.4) 388 | - React-Core/RCTImageHeaders (= 0.72.4) 389 | - React-jsi (= 0.72.4) 390 | - React-RCTNetwork (= 0.72.4) 391 | - ReactCommon/turbomodule/core (= 0.72.4) 392 | - React-RCTLinking (0.72.4): 393 | - React-Codegen (= 0.72.4) 394 | - React-Core/RCTLinkingHeaders (= 0.72.4) 395 | - React-jsi (= 0.72.4) 396 | - ReactCommon/turbomodule/core (= 0.72.4) 397 | - React-RCTNetwork (0.72.4): 398 | - RCT-Folly (= 2021.07.22.00) 399 | - RCTTypeSafety (= 0.72.4) 400 | - React-Codegen (= 0.72.4) 401 | - React-Core/RCTNetworkHeaders (= 0.72.4) 402 | - React-jsi (= 0.72.4) 403 | - ReactCommon/turbomodule/core (= 0.72.4) 404 | - React-RCTSettings (0.72.4): 405 | - RCT-Folly (= 2021.07.22.00) 406 | - RCTTypeSafety (= 0.72.4) 407 | - React-Codegen (= 0.72.4) 408 | - React-Core/RCTSettingsHeaders (= 0.72.4) 409 | - React-jsi (= 0.72.4) 410 | - ReactCommon/turbomodule/core (= 0.72.4) 411 | - React-RCTText (0.72.4): 412 | - React-Core/RCTTextHeaders (= 0.72.4) 413 | - React-RCTVibration (0.72.4): 414 | - RCT-Folly (= 2021.07.22.00) 415 | - React-Codegen (= 0.72.4) 416 | - React-Core/RCTVibrationHeaders (= 0.72.4) 417 | - React-jsi (= 0.72.4) 418 | - ReactCommon/turbomodule/core (= 0.72.4) 419 | - React-rncore (0.72.4) 420 | - React-runtimeexecutor (0.72.4): 421 | - React-jsi (= 0.72.4) 422 | - React-runtimescheduler (0.72.4): 423 | - glog 424 | - hermes-engine 425 | - RCT-Folly (= 2021.07.22.00) 426 | - React-callinvoker 427 | - React-debug 428 | - React-jsi 429 | - React-runtimeexecutor 430 | - React-utils (0.72.4): 431 | - glog 432 | - RCT-Folly (= 2021.07.22.00) 433 | - React-debug 434 | - ReactCommon/turbomodule/bridging (0.72.4): 435 | - DoubleConversion 436 | - glog 437 | - hermes-engine 438 | - RCT-Folly (= 2021.07.22.00) 439 | - React-callinvoker (= 0.72.4) 440 | - React-cxxreact (= 0.72.4) 441 | - React-jsi (= 0.72.4) 442 | - React-logger (= 0.72.4) 443 | - React-perflogger (= 0.72.4) 444 | - ReactCommon/turbomodule/core (0.72.4): 445 | - DoubleConversion 446 | - glog 447 | - hermes-engine 448 | - RCT-Folly (= 2021.07.22.00) 449 | - React-callinvoker (= 0.72.4) 450 | - React-cxxreact (= 0.72.4) 451 | - React-jsi (= 0.72.4) 452 | - React-logger (= 0.72.4) 453 | - React-perflogger (= 0.72.4) 454 | - SocketRocket (0.6.1) 455 | - Yoga (1.14.0) 456 | 457 | DEPENDENCIES: 458 | - Ahap (from `../modules/ahap/ios`) 459 | - boost (from `../node_modules/react-native/third-party-podspecs/boost.podspec`) 460 | - DoubleConversion (from `../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec`) 461 | - EXApplication (from `../node_modules/expo-application/ios`) 462 | - EXConstants (from `../node_modules/expo-constants/ios`) 463 | - EXFileSystem (from `../node_modules/expo-file-system/ios`) 464 | - EXFont (from `../node_modules/expo-font/ios`) 465 | - Expo (from `../node_modules/expo`) 466 | - ExpoHaptics (from `../node_modules/expo-haptics/ios`) 467 | - ExpoKeepAwake (from `../node_modules/expo-keep-awake/ios`) 468 | - ExpoModulesCore (from `../node_modules/expo-modules-core`) 469 | - EXSplashScreen (from `../node_modules/expo-splash-screen/ios`) 470 | - FBLazyVector (from `../node_modules/react-native/Libraries/FBLazyVector`) 471 | - FBReactNativeSpec (from `../node_modules/react-native/React/FBReactNativeSpec`) 472 | - glog (from `../node_modules/react-native/third-party-podspecs/glog.podspec`) 473 | - hermes-engine (from `../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec`) 474 | - libevent (~> 2.1.12) 475 | - RCT-Folly (from `../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec`) 476 | - RCTRequired (from `../node_modules/react-native/Libraries/RCTRequired`) 477 | - RCTTypeSafety (from `../node_modules/react-native/Libraries/TypeSafety`) 478 | - React (from `../node_modules/react-native/`) 479 | - React-callinvoker (from `../node_modules/react-native/ReactCommon/callinvoker`) 480 | - React-Codegen (from `build/generated/ios`) 481 | - React-Core (from `../node_modules/react-native/`) 482 | - React-Core/RCTWebSocket (from `../node_modules/react-native/`) 483 | - React-CoreModules (from `../node_modules/react-native/React/CoreModules`) 484 | - React-cxxreact (from `../node_modules/react-native/ReactCommon/cxxreact`) 485 | - React-debug (from `../node_modules/react-native/ReactCommon/react/debug`) 486 | - React-hermes (from `../node_modules/react-native/ReactCommon/hermes`) 487 | - React-jsi (from `../node_modules/react-native/ReactCommon/jsi`) 488 | - React-jsiexecutor (from `../node_modules/react-native/ReactCommon/jsiexecutor`) 489 | - React-jsinspector (from `../node_modules/react-native/ReactCommon/jsinspector`) 490 | - React-logger (from `../node_modules/react-native/ReactCommon/logger`) 491 | - React-NativeModulesApple (from `../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios`) 492 | - React-perflogger (from `../node_modules/react-native/ReactCommon/reactperflogger`) 493 | - React-RCTActionSheet (from `../node_modules/react-native/Libraries/ActionSheetIOS`) 494 | - React-RCTAnimation (from `../node_modules/react-native/Libraries/NativeAnimation`) 495 | - React-RCTAppDelegate (from `../node_modules/react-native/Libraries/AppDelegate`) 496 | - React-RCTBlob (from `../node_modules/react-native/Libraries/Blob`) 497 | - React-RCTImage (from `../node_modules/react-native/Libraries/Image`) 498 | - React-RCTLinking (from `../node_modules/react-native/Libraries/LinkingIOS`) 499 | - React-RCTNetwork (from `../node_modules/react-native/Libraries/Network`) 500 | - React-RCTSettings (from `../node_modules/react-native/Libraries/Settings`) 501 | - React-RCTText (from `../node_modules/react-native/Libraries/Text`) 502 | - React-RCTVibration (from `../node_modules/react-native/Libraries/Vibration`) 503 | - React-rncore (from `../node_modules/react-native/ReactCommon`) 504 | - React-runtimeexecutor (from `../node_modules/react-native/ReactCommon/runtimeexecutor`) 505 | - React-runtimescheduler (from `../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler`) 506 | - React-utils (from `../node_modules/react-native/ReactCommon/react/utils`) 507 | - ReactCommon/turbomodule/core (from `../node_modules/react-native/ReactCommon`) 508 | - Yoga (from `../node_modules/react-native/ReactCommon/yoga`) 509 | 510 | SPEC REPOS: 511 | trunk: 512 | - fmt 513 | - libevent 514 | - SocketRocket 515 | 516 | EXTERNAL SOURCES: 517 | Ahap: 518 | :path: "../modules/ahap/ios" 519 | boost: 520 | :podspec: "../node_modules/react-native/third-party-podspecs/boost.podspec" 521 | DoubleConversion: 522 | :podspec: "../node_modules/react-native/third-party-podspecs/DoubleConversion.podspec" 523 | EXApplication: 524 | :path: "../node_modules/expo-application/ios" 525 | EXConstants: 526 | :path: "../node_modules/expo-constants/ios" 527 | EXFileSystem: 528 | :path: "../node_modules/expo-file-system/ios" 529 | EXFont: 530 | :path: "../node_modules/expo-font/ios" 531 | Expo: 532 | :path: "../node_modules/expo" 533 | ExpoHaptics: 534 | :path: "../node_modules/expo-haptics/ios" 535 | ExpoKeepAwake: 536 | :path: "../node_modules/expo-keep-awake/ios" 537 | ExpoModulesCore: 538 | :path: "../node_modules/expo-modules-core" 539 | EXSplashScreen: 540 | :path: "../node_modules/expo-splash-screen/ios" 541 | FBLazyVector: 542 | :path: "../node_modules/react-native/Libraries/FBLazyVector" 543 | FBReactNativeSpec: 544 | :path: "../node_modules/react-native/React/FBReactNativeSpec" 545 | glog: 546 | :podspec: "../node_modules/react-native/third-party-podspecs/glog.podspec" 547 | hermes-engine: 548 | :podspec: "../node_modules/react-native/sdks/hermes-engine/hermes-engine.podspec" 549 | :tag: hermes-2023-08-07-RNv0.72.4-813b2def12bc9df02654b3e3653ae4a68d0572e0 550 | RCT-Folly: 551 | :podspec: "../node_modules/react-native/third-party-podspecs/RCT-Folly.podspec" 552 | RCTRequired: 553 | :path: "../node_modules/react-native/Libraries/RCTRequired" 554 | RCTTypeSafety: 555 | :path: "../node_modules/react-native/Libraries/TypeSafety" 556 | React: 557 | :path: "../node_modules/react-native/" 558 | React-callinvoker: 559 | :path: "../node_modules/react-native/ReactCommon/callinvoker" 560 | React-Codegen: 561 | :path: build/generated/ios 562 | React-Core: 563 | :path: "../node_modules/react-native/" 564 | React-CoreModules: 565 | :path: "../node_modules/react-native/React/CoreModules" 566 | React-cxxreact: 567 | :path: "../node_modules/react-native/ReactCommon/cxxreact" 568 | React-debug: 569 | :path: "../node_modules/react-native/ReactCommon/react/debug" 570 | React-hermes: 571 | :path: "../node_modules/react-native/ReactCommon/hermes" 572 | React-jsi: 573 | :path: "../node_modules/react-native/ReactCommon/jsi" 574 | React-jsiexecutor: 575 | :path: "../node_modules/react-native/ReactCommon/jsiexecutor" 576 | React-jsinspector: 577 | :path: "../node_modules/react-native/ReactCommon/jsinspector" 578 | React-logger: 579 | :path: "../node_modules/react-native/ReactCommon/logger" 580 | React-NativeModulesApple: 581 | :path: "../node_modules/react-native/ReactCommon/react/nativemodule/core/platform/ios" 582 | React-perflogger: 583 | :path: "../node_modules/react-native/ReactCommon/reactperflogger" 584 | React-RCTActionSheet: 585 | :path: "../node_modules/react-native/Libraries/ActionSheetIOS" 586 | React-RCTAnimation: 587 | :path: "../node_modules/react-native/Libraries/NativeAnimation" 588 | React-RCTAppDelegate: 589 | :path: "../node_modules/react-native/Libraries/AppDelegate" 590 | React-RCTBlob: 591 | :path: "../node_modules/react-native/Libraries/Blob" 592 | React-RCTImage: 593 | :path: "../node_modules/react-native/Libraries/Image" 594 | React-RCTLinking: 595 | :path: "../node_modules/react-native/Libraries/LinkingIOS" 596 | React-RCTNetwork: 597 | :path: "../node_modules/react-native/Libraries/Network" 598 | React-RCTSettings: 599 | :path: "../node_modules/react-native/Libraries/Settings" 600 | React-RCTText: 601 | :path: "../node_modules/react-native/Libraries/Text" 602 | React-RCTVibration: 603 | :path: "../node_modules/react-native/Libraries/Vibration" 604 | React-rncore: 605 | :path: "../node_modules/react-native/ReactCommon" 606 | React-runtimeexecutor: 607 | :path: "../node_modules/react-native/ReactCommon/runtimeexecutor" 608 | React-runtimescheduler: 609 | :path: "../node_modules/react-native/ReactCommon/react/renderer/runtimescheduler" 610 | React-utils: 611 | :path: "../node_modules/react-native/ReactCommon/react/utils" 612 | ReactCommon: 613 | :path: "../node_modules/react-native/ReactCommon" 614 | Yoga: 615 | :path: "../node_modules/react-native/ReactCommon/yoga" 616 | 617 | SPEC CHECKSUMS: 618 | Ahap: 443a8f7b37588054fb8c8f9a900e452d2fe9ed77 619 | boost: 57d2868c099736d80fcd648bf211b4431e51a558 620 | DoubleConversion: 5189b271737e1565bdce30deb4a08d647e3f5f54 621 | EXApplication: 02655a251434d564bb0e73291f5a490c74b5b76f 622 | EXConstants: ce5bbea779da8031ac818c36bea41b10e14d04e1 623 | EXFileSystem: 941b273758aee14be2ecc671dacb4f10dd28c833 624 | EXFont: 738c44c390953ebcbab075a4848bfbef025fd9ee 625 | Expo: 900dc423a0e2c7e822b2c683a89426e82695fb27 626 | ExpoHaptics: 360af6898407ee4e8265d30a1a8fb16491a660eb 627 | ExpoKeepAwake: be4cbd52d9b177cde0fd66daa1913afa3161fc1d 628 | ExpoModulesCore: e5a168deba84f74c0e558befa31dbaea06c00af0 629 | EXSplashScreen: c0e7f2d4a640f3b875808ed0b88575538daf6d82 630 | FBLazyVector: 5d4a3b7f411219a45a6d952f77d2c0a6c9989da5 631 | FBReactNativeSpec: 3fc2d478e1c4b08276f9dd9128f80ec6d5d85c1f 632 | fmt: ff9d55029c625d3757ed641535fd4a75fedc7ce9 633 | glog: 04b94705f318337d7ead9e6d17c019bd9b1f6b1b 634 | hermes-engine: 81191603c4eaa01f5e4ae5737a9efcf64756c7b2 635 | libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913 636 | RCT-Folly: 424b8c9a7a0b9ab2886ffe9c3b041ef628fd4fb1 637 | RCTRequired: c0569ecc035894e4a68baecb30fe6a7ea6e399f9 638 | RCTTypeSafety: e90354072c21236e0bcf1699011e39acd25fea2f 639 | React: a1be3c6dc0a6e949ccd3e659781aa47bbae1868f 640 | React-callinvoker: 1020b33f6cb1a1824f9ca2a86609fbce2a73c6ed 641 | React-Codegen: a0a26badf098d4a779acda922caf74f6ecabed28 642 | React-Core: 52075b80f10c26f62219d7b5d13d7d8089f027b3 643 | React-CoreModules: 21abab85d7ad9038ce2b1c33d39e3baaf7dc9244 644 | React-cxxreact: 4ad1cc861e32fb533dad6ff7a4ea25680fa1c994 645 | React-debug: 17366a3d5c5d2f5fc04f09101a4af38cb42b54ae 646 | React-hermes: 37377d0a56aa0cf55c65248271866ce3268cde3f 647 | React-jsi: 6de8b0ccc6b765b58e4eee9ee38049dbeaf5c221 648 | React-jsiexecutor: c7f826e40fa9cab5d37cab6130b1af237332b594 649 | React-jsinspector: aaed4cf551c4a1c98092436518c2d267b13a673f 650 | React-logger: da1ebe05ae06eb6db4b162202faeafac4b435e77 651 | React-NativeModulesApple: edb5ace14f73f4969df6e7b1f3e41bef0012740f 652 | React-perflogger: 496a1a3dc6737f964107cb3ddae7f9e265ddda58 653 | React-RCTActionSheet: 02904b932b50e680f4e26e7a686b33ebf7ef3c00 654 | React-RCTAnimation: 88feaf0a85648fb8fd497ce749829774910276d6 655 | React-RCTAppDelegate: 5792ac0f0feccb584765fdd7aa81ea320c4d9b0b 656 | React-RCTBlob: 0dbc9e2a13d241b37d46b53e54630cbad1f0e141 657 | React-RCTImage: b111645ab901f8e59fc68fbe31f5731bdbeef087 658 | React-RCTLinking: 3d719727b4c098aad3588aa3559361ee0579f5de 659 | React-RCTNetwork: b44d3580be05d74556ba4efbf53570f17e38f734 660 | React-RCTSettings: c0c54b330442c29874cd4dae6e94190dc11a6f6f 661 | React-RCTText: 9b9f5589d9b649d7246c3f336e116496df28cfe6 662 | React-RCTVibration: 691c67f3beaf1d084ceed5eb5c1dddd9afa8591e 663 | React-rncore: 142268f6c92e296dc079aadda3fade778562f9e4 664 | React-runtimeexecutor: d465ba0c47ef3ed8281143f59605cacc2244d5c7 665 | React-runtimescheduler: 4941cc1b3cf08b792fbf666342c9fc95f1969035 666 | React-utils: b79f2411931f9d3ea5781404dcbb2fa8a837e13a 667 | ReactCommon: 4b2bdcb50a3543e1c2b2849ad44533686610826d 668 | SocketRocket: f32cd54efbe0f095c4d7594881e52619cfe80b17 669 | Yoga: 3efc43e0d48686ce2e8c60f99d4e6bd349aff981 670 | 671 | PODFILE CHECKSUM: fc992cf45df0bf48fbc58d7ef25b60da4f507f16 672 | 673 | COCOAPODS: 1.11.3 674 | -------------------------------------------------------------------------------- /ios/Podfile.properties.json: -------------------------------------------------------------------------------- 1 | { 2 | "expo.jsEngine": "hermes", 3 | "EX_DEV_CLIENT_NETWORK_INSPECTOR": "true" 4 | } 5 | -------------------------------------------------------------------------------- /ios/ShieldA.wav: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/ios/ShieldA.wav -------------------------------------------------------------------------------- /ios/capnahap.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 54; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB01A68108700A75B9A /* AppDelegate.mm */; }; 11 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 13B07FB51A68108700A75B9A /* Images.xcassets */; }; 12 | 13B07FC11A68108700A75B9A /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 13B07FB71A68108700A75B9A /* main.m */; }; 13 | 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */; }; 14 | 548CD6962EAF436AA2CE65D6 /* noop-file.swift in Sources */ = {isa = PBXBuildFile; fileRef = 597A3718917542C09D0D5E22 /* noop-file.swift */; }; 15 | 96905EF65AED1B983A6B3ABC /* libPods-capnahap.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-capnahap.a */; }; 16 | B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */; }; 17 | BB2F792D24A3F905000567C9 /* Expo.plist in Resources */ = {isa = PBXBuildFile; fileRef = BB2F792C24A3F905000567C9 /* Expo.plist */; }; 18 | CDEC01252A981207006DB9B7 /* ShieldA.wav in Resources */ = {isa = PBXBuildFile; fileRef = CDEC01242A981207006DB9B7 /* ShieldA.wav */; }; 19 | /* End PBXBuildFile section */ 20 | 21 | /* Begin PBXFileReference section */ 22 | 13B07F961A680F5B00A75B9A /* capnahap.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = capnahap.app; sourceTree = BUILT_PRODUCTS_DIR; }; 23 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = AppDelegate.h; path = capnahap/AppDelegate.h; sourceTree = ""; }; 24 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = AppDelegate.mm; path = capnahap/AppDelegate.mm; sourceTree = ""; }; 25 | 13B07FB51A68108700A75B9A /* Images.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; name = Images.xcassets; path = capnahap/Images.xcassets; sourceTree = ""; }; 26 | 13B07FB61A68108700A75B9A /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = capnahap/Info.plist; sourceTree = ""; }; 27 | 13B07FB71A68108700A75B9A /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = main.m; path = capnahap/main.m; sourceTree = ""; }; 28 | 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-capnahap.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-capnahap.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 29 | 597A3718917542C09D0D5E22 /* noop-file.swift */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.swift; name = "noop-file.swift"; path = "capnahap/noop-file.swift"; sourceTree = ""; }; 30 | 6C2E3173556A471DD304B334 /* Pods-capnahap.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-capnahap.debug.xcconfig"; path = "Target Support Files/Pods-capnahap/Pods-capnahap.debug.xcconfig"; sourceTree = ""; }; 31 | 7A4D352CD337FB3A3BF06240 /* Pods-capnahap.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-capnahap.release.xcconfig"; path = "Target Support Files/Pods-capnahap/Pods-capnahap.release.xcconfig"; sourceTree = ""; }; 32 | AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; name = SplashScreen.storyboard; path = capnahap/SplashScreen.storyboard; sourceTree = ""; }; 33 | BB2F792C24A3F905000567C9 /* Expo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = Expo.plist; sourceTree = ""; }; 34 | CDEC01242A981207006DB9B7 /* ShieldA.wav */ = {isa = PBXFileReference; lastKnownFileType = audio.wav; path = ShieldA.wav; sourceTree = ""; }; 35 | E5B8E006B1EB40A0ABFEE808 /* capnahap-Bridging-Header.h */ = {isa = PBXFileReference; explicitFileType = undefined; fileEncoding = 4; includeInIndex = 0; lastKnownFileType = sourcecode.c.h; name = "capnahap-Bridging-Header.h"; path = "capnahap/capnahap-Bridging-Header.h"; sourceTree = ""; }; 36 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; }; 37 | FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ExpoModulesProvider.swift; path = "Pods/Target Support Files/Pods-capnahap/ExpoModulesProvider.swift"; sourceTree = ""; }; 38 | /* End PBXFileReference section */ 39 | 40 | /* Begin PBXFrameworksBuildPhase section */ 41 | 13B07F8C1A680F5B00A75B9A /* Frameworks */ = { 42 | isa = PBXFrameworksBuildPhase; 43 | buildActionMask = 2147483647; 44 | files = ( 45 | 96905EF65AED1B983A6B3ABC /* libPods-capnahap.a in Frameworks */, 46 | ); 47 | runOnlyForDeploymentPostprocessing = 0; 48 | }; 49 | /* End PBXFrameworksBuildPhase section */ 50 | 51 | /* Begin PBXGroup section */ 52 | 13B07FAE1A68108700A75B9A /* capnahap */ = { 53 | isa = PBXGroup; 54 | children = ( 55 | BB2F792B24A3F905000567C9 /* Supporting */, 56 | 13B07FAF1A68108700A75B9A /* AppDelegate.h */, 57 | 13B07FB01A68108700A75B9A /* AppDelegate.mm */, 58 | 13B07FB51A68108700A75B9A /* Images.xcassets */, 59 | 13B07FB61A68108700A75B9A /* Info.plist */, 60 | 13B07FB71A68108700A75B9A /* main.m */, 61 | AA286B85B6C04FC6940260E9 /* SplashScreen.storyboard */, 62 | 597A3718917542C09D0D5E22 /* noop-file.swift */, 63 | E5B8E006B1EB40A0ABFEE808 /* capnahap-Bridging-Header.h */, 64 | ); 65 | name = capnahap; 66 | sourceTree = ""; 67 | }; 68 | 2D16E6871FA4F8E400B85C8A /* Frameworks */ = { 69 | isa = PBXGroup; 70 | children = ( 71 | ED297162215061F000B7C4FE /* JavaScriptCore.framework */, 72 | 58EEBF8E8E6FB1BC6CAF49B5 /* libPods-capnahap.a */, 73 | ); 74 | name = Frameworks; 75 | sourceTree = ""; 76 | }; 77 | 832341AE1AAA6A7D00B99B32 /* Libraries */ = { 78 | isa = PBXGroup; 79 | children = ( 80 | ); 81 | name = Libraries; 82 | sourceTree = ""; 83 | }; 84 | 83CBB9F61A601CBA00E9B192 = { 85 | isa = PBXGroup; 86 | children = ( 87 | CDEC01242A981207006DB9B7 /* ShieldA.wav */, 88 | 13B07FAE1A68108700A75B9A /* capnahap */, 89 | 832341AE1AAA6A7D00B99B32 /* Libraries */, 90 | 83CBBA001A601CBA00E9B192 /* Products */, 91 | 2D16E6871FA4F8E400B85C8A /* Frameworks */, 92 | D65327D7A22EEC0BE12398D9 /* Pods */, 93 | D7E4C46ADA2E9064B798F356 /* ExpoModulesProviders */, 94 | ); 95 | indentWidth = 2; 96 | sourceTree = ""; 97 | tabWidth = 2; 98 | usesTabs = 0; 99 | }; 100 | 83CBBA001A601CBA00E9B192 /* Products */ = { 101 | isa = PBXGroup; 102 | children = ( 103 | 13B07F961A680F5B00A75B9A /* capnahap.app */, 104 | ); 105 | name = Products; 106 | sourceTree = ""; 107 | }; 108 | 92DBD88DE9BF7D494EA9DA96 /* capnahap */ = { 109 | isa = PBXGroup; 110 | children = ( 111 | FAC715A2D49A985799AEE119 /* ExpoModulesProvider.swift */, 112 | ); 113 | name = capnahap; 114 | sourceTree = ""; 115 | }; 116 | BB2F792B24A3F905000567C9 /* Supporting */ = { 117 | isa = PBXGroup; 118 | children = ( 119 | BB2F792C24A3F905000567C9 /* Expo.plist */, 120 | ); 121 | name = Supporting; 122 | path = capnahap/Supporting; 123 | sourceTree = ""; 124 | }; 125 | D65327D7A22EEC0BE12398D9 /* Pods */ = { 126 | isa = PBXGroup; 127 | children = ( 128 | 6C2E3173556A471DD304B334 /* Pods-capnahap.debug.xcconfig */, 129 | 7A4D352CD337FB3A3BF06240 /* Pods-capnahap.release.xcconfig */, 130 | ); 131 | path = Pods; 132 | sourceTree = ""; 133 | }; 134 | D7E4C46ADA2E9064B798F356 /* ExpoModulesProviders */ = { 135 | isa = PBXGroup; 136 | children = ( 137 | 92DBD88DE9BF7D494EA9DA96 /* capnahap */, 138 | ); 139 | name = ExpoModulesProviders; 140 | sourceTree = ""; 141 | }; 142 | /* End PBXGroup section */ 143 | 144 | /* Begin PBXNativeTarget section */ 145 | 13B07F861A680F5B00A75B9A /* capnahap */ = { 146 | isa = PBXNativeTarget; 147 | buildConfigurationList = 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "capnahap" */; 148 | buildPhases = ( 149 | 08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */, 150 | FD10A7F022414F080027D42C /* Start Packager */, 151 | 3F792C65EE094AF267C5D4E6 /* [Expo] Configure project */, 152 | 13B07F871A680F5B00A75B9A /* Sources */, 153 | 13B07F8C1A680F5B00A75B9A /* Frameworks */, 154 | 13B07F8E1A680F5B00A75B9A /* Resources */, 155 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */, 156 | 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */, 157 | 3FC6E339E65B45B061E5E04D /* [CP] Embed Pods Frameworks */, 158 | ); 159 | buildRules = ( 160 | ); 161 | dependencies = ( 162 | ); 163 | name = capnahap; 164 | productName = capnahap; 165 | productReference = 13B07F961A680F5B00A75B9A /* capnahap.app */; 166 | productType = "com.apple.product-type.application"; 167 | }; 168 | /* End PBXNativeTarget section */ 169 | 170 | /* Begin PBXProject section */ 171 | 83CBB9F71A601CBA00E9B192 /* Project object */ = { 172 | isa = PBXProject; 173 | attributes = { 174 | LastUpgradeCheck = 1130; 175 | TargetAttributes = { 176 | 13B07F861A680F5B00A75B9A = { 177 | DevelopmentTeam = QQ57RJ5UTD; 178 | LastSwiftMigration = 1250; 179 | ProvisioningStyle = Automatic; 180 | }; 181 | }; 182 | }; 183 | buildConfigurationList = 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "capnahap" */; 184 | compatibilityVersion = "Xcode 3.2"; 185 | developmentRegion = en; 186 | hasScannedForEncodings = 0; 187 | knownRegions = ( 188 | en, 189 | Base, 190 | ); 191 | mainGroup = 83CBB9F61A601CBA00E9B192; 192 | productRefGroup = 83CBBA001A601CBA00E9B192 /* Products */; 193 | projectDirPath = ""; 194 | projectRoot = ""; 195 | targets = ( 196 | 13B07F861A680F5B00A75B9A /* capnahap */, 197 | ); 198 | }; 199 | /* End PBXProject section */ 200 | 201 | /* Begin PBXResourcesBuildPhase section */ 202 | 13B07F8E1A680F5B00A75B9A /* Resources */ = { 203 | isa = PBXResourcesBuildPhase; 204 | buildActionMask = 2147483647; 205 | files = ( 206 | BB2F792D24A3F905000567C9 /* Expo.plist in Resources */, 207 | CDEC01252A981207006DB9B7 /* ShieldA.wav in Resources */, 208 | 13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */, 209 | 3E461D99554A48A4959DE609 /* SplashScreen.storyboard in Resources */, 210 | ); 211 | runOnlyForDeploymentPostprocessing = 0; 212 | }; 213 | /* End PBXResourcesBuildPhase section */ 214 | 215 | /* Begin PBXShellScriptBuildPhase section */ 216 | 00DD1BFF1BD5951E006B06BC /* Bundle React Native code and images */ = { 217 | isa = PBXShellScriptBuildPhase; 218 | buildActionMask = 2147483647; 219 | files = ( 220 | ); 221 | inputPaths = ( 222 | ); 223 | name = "Bundle React Native code and images"; 224 | outputPaths = ( 225 | ); 226 | runOnlyForDeploymentPostprocessing = 0; 227 | shellPath = /bin/sh; 228 | shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\n# The project root by default is one level up from the ios directory\nexport PROJECT_ROOT=\"$PROJECT_DIR\"/..\n\nif [[ \"$CONFIGURATION\" = *Debug* ]]; then\n export SKIP_BUNDLING=1\nfi\nif [[ -z \"$ENTRY_FILE\" ]]; then\n # Set the entry JS file using the bundler's entry resolution.\n export ENTRY_FILE=\"$(\"$NODE_BINARY\" -e \"require('expo/scripts/resolveAppEntry')\" \"$PROJECT_ROOT\" ios relative | tail -n 1)\"\nfi\n\nif [[ -z \"$CLI_PATH\" ]]; then\n # Use Expo CLI\n export CLI_PATH=\"$(\"$NODE_BINARY\" --print \"require.resolve('@expo/cli')\")\"\nfi\nif [[ -z \"$BUNDLE_COMMAND\" ]]; then\n # Default Expo CLI command for bundling\n export BUNDLE_COMMAND=\"export:embed\"\nfi\n\n`\"$NODE_BINARY\" --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/react-native-xcode.sh'\"`\n\n"; 229 | }; 230 | 08A4A3CD28434E44B6B9DE2E /* [CP] Check Pods Manifest.lock */ = { 231 | isa = PBXShellScriptBuildPhase; 232 | buildActionMask = 2147483647; 233 | files = ( 234 | ); 235 | inputFileListPaths = ( 236 | ); 237 | inputPaths = ( 238 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 239 | "${PODS_ROOT}/Manifest.lock", 240 | ); 241 | name = "[CP] Check Pods Manifest.lock"; 242 | outputFileListPaths = ( 243 | ); 244 | outputPaths = ( 245 | "$(DERIVED_FILE_DIR)/Pods-capnahap-checkManifestLockResult.txt", 246 | ); 247 | runOnlyForDeploymentPostprocessing = 0; 248 | shellPath = /bin/sh; 249 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 250 | showEnvVarsInLog = 0; 251 | }; 252 | 3F792C65EE094AF267C5D4E6 /* [Expo] Configure project */ = { 253 | isa = PBXShellScriptBuildPhase; 254 | alwaysOutOfDate = 1; 255 | buildActionMask = 2147483647; 256 | files = ( 257 | ); 258 | inputFileListPaths = ( 259 | ); 260 | inputPaths = ( 261 | ); 262 | name = "[Expo] Configure project"; 263 | outputFileListPaths = ( 264 | ); 265 | outputPaths = ( 266 | ); 267 | runOnlyForDeploymentPostprocessing = 0; 268 | shellPath = /bin/sh; 269 | shellScript = "# This script configures Expo modules and generates the modules provider file.\nbash -l -c \"./Pods/Target\\ Support\\ Files/Pods-capnahap/expo-configure-project.sh\"\n"; 270 | }; 271 | 3FC6E339E65B45B061E5E04D /* [CP] Embed Pods Frameworks */ = { 272 | isa = PBXShellScriptBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | ); 276 | inputPaths = ( 277 | "${PODS_ROOT}/Target Support Files/Pods-capnahap/Pods-capnahap-frameworks.sh", 278 | "${PODS_XCFRAMEWORKS_BUILD_DIR}/hermes-engine/Pre-built/hermes.framework/hermes", 279 | ); 280 | name = "[CP] Embed Pods Frameworks"; 281 | outputPaths = ( 282 | "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/hermes.framework", 283 | ); 284 | runOnlyForDeploymentPostprocessing = 0; 285 | shellPath = /bin/sh; 286 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-capnahap/Pods-capnahap-frameworks.sh\"\n"; 287 | showEnvVarsInLog = 0; 288 | }; 289 | 800E24972A6A228C8D4807E9 /* [CP] Copy Pods Resources */ = { 290 | isa = PBXShellScriptBuildPhase; 291 | buildActionMask = 2147483647; 292 | files = ( 293 | ); 294 | inputPaths = ( 295 | "${PODS_ROOT}/Target Support Files/Pods-capnahap/Pods-capnahap-resources.sh", 296 | "${PODS_CONFIGURATION_BUILD_DIR}/EXConstants/EXConstants.bundle", 297 | "${PODS_CONFIGURATION_BUILD_DIR}/React-Core/AccessibilityResources.bundle", 298 | ); 299 | name = "[CP] Copy Pods Resources"; 300 | outputPaths = ( 301 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/EXConstants.bundle", 302 | "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/AccessibilityResources.bundle", 303 | ); 304 | runOnlyForDeploymentPostprocessing = 0; 305 | shellPath = /bin/sh; 306 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-capnahap/Pods-capnahap-resources.sh\"\n"; 307 | showEnvVarsInLog = 0; 308 | }; 309 | FD10A7F022414F080027D42C /* Start Packager */ = { 310 | isa = PBXShellScriptBuildPhase; 311 | buildActionMask = 2147483647; 312 | files = ( 313 | ); 314 | inputFileListPaths = ( 315 | ); 316 | inputPaths = ( 317 | ); 318 | name = "Start Packager"; 319 | outputFileListPaths = ( 320 | ); 321 | outputPaths = ( 322 | ); 323 | runOnlyForDeploymentPostprocessing = 0; 324 | shellPath = /bin/sh; 325 | shellScript = "if [[ -f \"$PODS_ROOT/../.xcode.env\" ]]; then\n source \"$PODS_ROOT/../.xcode.env\"\nfi\nif [[ -f \"$PODS_ROOT/../.xcode.env.local\" ]]; then\n source \"$PODS_ROOT/../.xcode.env.local\"\nfi\n\nexport RCT_METRO_PORT=\"${RCT_METRO_PORT:=8081}\"\necho \"export RCT_METRO_PORT=${RCT_METRO_PORT}\" > `$NODE_BINARY --print \"require('path').dirname(require.resolve('react-native/package.json')) + '/scripts/.packager.env'\"`\nif [ -z \"${RCT_NO_LAUNCH_PACKAGER+xxx}\" ] ; then\n if nc -w 5 -z localhost ${RCT_METRO_PORT} ; then\n if ! curl -s \"http://localhost:${RCT_METRO_PORT}/status\" | grep -q \"packager-status:running\" ; then\n echo \"Port ${RCT_METRO_PORT} already in use, packager is either not running or not running correctly\"\n exit 2\n fi\n else\n open `$NODE_BINARY --print \"require('path').dirname(require.resolve('expo/package.json')) + '/scripts/launchPackager.command'\"` || echo \"Can't start packager automatically\"\n fi\nfi\n"; 326 | showEnvVarsInLog = 0; 327 | }; 328 | /* End PBXShellScriptBuildPhase section */ 329 | 330 | /* Begin PBXSourcesBuildPhase section */ 331 | 13B07F871A680F5B00A75B9A /* Sources */ = { 332 | isa = PBXSourcesBuildPhase; 333 | buildActionMask = 2147483647; 334 | files = ( 335 | 13B07FBC1A68108700A75B9A /* AppDelegate.mm in Sources */, 336 | 13B07FC11A68108700A75B9A /* main.m in Sources */, 337 | B18059E884C0ABDD17F3DC3D /* ExpoModulesProvider.swift in Sources */, 338 | 548CD6962EAF436AA2CE65D6 /* noop-file.swift in Sources */, 339 | ); 340 | runOnlyForDeploymentPostprocessing = 0; 341 | }; 342 | /* End PBXSourcesBuildPhase section */ 343 | 344 | /* Begin XCBuildConfiguration section */ 345 | 13B07F941A680F5B00A75B9A /* Debug */ = { 346 | isa = XCBuildConfiguration; 347 | baseConfigurationReference = 6C2E3173556A471DD304B334 /* Pods-capnahap.debug.xcconfig */; 348 | buildSettings = { 349 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 350 | CLANG_ENABLE_MODULES = YES; 351 | CODE_SIGN_ENTITLEMENTS = capnahap/capnahap.entitlements; 352 | CODE_SIGN_IDENTITY = "Apple Development"; 353 | CODE_SIGN_STYLE = Automatic; 354 | CURRENT_PROJECT_VERSION = 1; 355 | DEVELOPMENT_TEAM = QQ57RJ5UTD; 356 | ENABLE_BITCODE = NO; 357 | GCC_PREPROCESSOR_DEFINITIONS = ( 358 | "$(inherited)", 359 | "FB_SONARKIT_ENABLED=1", 360 | ); 361 | INFOPLIST_FILE = capnahap/Info.plist; 362 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 363 | LD_RUNPATH_SEARCH_PATHS = ( 364 | "$(inherited)", 365 | "@executable_path/Frameworks", 366 | ); 367 | MARKETING_VERSION = 1.0; 368 | OTHER_LDFLAGS = ( 369 | "$(inherited)", 370 | "-ObjC", 371 | "-lc++", 372 | ); 373 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_DEBUG"; 374 | PRODUCT_BUNDLE_IDENTIFIER = "com.bacon.capn-ahap"; 375 | PRODUCT_NAME = capnahap; 376 | SWIFT_OBJC_BRIDGING_HEADER = "capnahap/capnahap-Bridging-Header.h"; 377 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 378 | SWIFT_VERSION = 5.0; 379 | TARGETED_DEVICE_FAMILY = "1,2"; 380 | VERSIONING_SYSTEM = "apple-generic"; 381 | }; 382 | name = Debug; 383 | }; 384 | 13B07F951A680F5B00A75B9A /* Release */ = { 385 | isa = XCBuildConfiguration; 386 | baseConfigurationReference = 7A4D352CD337FB3A3BF06240 /* Pods-capnahap.release.xcconfig */; 387 | buildSettings = { 388 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 389 | CLANG_ENABLE_MODULES = YES; 390 | CODE_SIGN_ENTITLEMENTS = capnahap/capnahap.entitlements; 391 | CODE_SIGN_IDENTITY = "Apple Development"; 392 | CODE_SIGN_STYLE = Automatic; 393 | CURRENT_PROJECT_VERSION = 1; 394 | DEVELOPMENT_TEAM = QQ57RJ5UTD; 395 | INFOPLIST_FILE = capnahap/Info.plist; 396 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 397 | LD_RUNPATH_SEARCH_PATHS = ( 398 | "$(inherited)", 399 | "@executable_path/Frameworks", 400 | ); 401 | MARKETING_VERSION = 1.0; 402 | OTHER_LDFLAGS = ( 403 | "$(inherited)", 404 | "-ObjC", 405 | "-lc++", 406 | ); 407 | OTHER_SWIFT_FLAGS = "$(inherited) -D EXPO_CONFIGURATION_RELEASE"; 408 | PRODUCT_BUNDLE_IDENTIFIER = "com.bacon.capn-ahap"; 409 | PRODUCT_NAME = capnahap; 410 | SWIFT_OBJC_BRIDGING_HEADER = "capnahap/capnahap-Bridging-Header.h"; 411 | SWIFT_VERSION = 5.0; 412 | TARGETED_DEVICE_FAMILY = "1,2"; 413 | VERSIONING_SYSTEM = "apple-generic"; 414 | }; 415 | name = Release; 416 | }; 417 | 83CBBA201A601CBA00E9B192 /* Debug */ = { 418 | isa = XCBuildConfiguration; 419 | buildSettings = { 420 | ALWAYS_SEARCH_USER_PATHS = NO; 421 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 422 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 423 | CLANG_CXX_LIBRARY = "libc++"; 424 | CLANG_ENABLE_MODULES = YES; 425 | CLANG_ENABLE_OBJC_ARC = YES; 426 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 427 | CLANG_WARN_BOOL_CONVERSION = YES; 428 | CLANG_WARN_COMMA = YES; 429 | CLANG_WARN_CONSTANT_CONVERSION = YES; 430 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 431 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 432 | CLANG_WARN_EMPTY_BODY = YES; 433 | CLANG_WARN_ENUM_CONVERSION = YES; 434 | CLANG_WARN_INFINITE_RECURSION = YES; 435 | CLANG_WARN_INT_CONVERSION = YES; 436 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 437 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 438 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 439 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 440 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 441 | CLANG_WARN_STRICT_PROTOTYPES = YES; 442 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 443 | CLANG_WARN_UNREACHABLE_CODE = YES; 444 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 445 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 446 | COPY_PHASE_STRIP = NO; 447 | ENABLE_STRICT_OBJC_MSGSEND = YES; 448 | ENABLE_TESTABILITY = YES; 449 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 450 | GCC_C_LANGUAGE_STANDARD = gnu99; 451 | GCC_DYNAMIC_NO_PIC = NO; 452 | GCC_NO_COMMON_BLOCKS = YES; 453 | GCC_OPTIMIZATION_LEVEL = 0; 454 | GCC_PREPROCESSOR_DEFINITIONS = ( 455 | "DEBUG=1", 456 | "$(inherited)", 457 | ); 458 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 459 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 460 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 461 | GCC_WARN_UNDECLARED_SELECTOR = YES; 462 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 463 | GCC_WARN_UNUSED_FUNCTION = YES; 464 | GCC_WARN_UNUSED_VARIABLE = YES; 465 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 466 | LD_RUNPATH_SEARCH_PATHS = ( 467 | /usr/lib/swift, 468 | "$(inherited)", 469 | ); 470 | LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\""; 471 | MTL_ENABLE_DEBUG_INFO = YES; 472 | ONLY_ACTIVE_ARCH = YES; 473 | OTHER_CFLAGS = "$(inherited)"; 474 | OTHER_CPLUSPLUSFLAGS = "$(inherited)"; 475 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 476 | SDKROOT = iphoneos; 477 | }; 478 | name = Debug; 479 | }; 480 | 83CBBA211A601CBA00E9B192 /* Release */ = { 481 | isa = XCBuildConfiguration; 482 | buildSettings = { 483 | ALWAYS_SEARCH_USER_PATHS = NO; 484 | CLANG_ANALYZER_LOCALIZABILITY_NONLOCALIZED = YES; 485 | CLANG_CXX_LANGUAGE_STANDARD = "c++17"; 486 | CLANG_CXX_LIBRARY = "libc++"; 487 | CLANG_ENABLE_MODULES = YES; 488 | CLANG_ENABLE_OBJC_ARC = YES; 489 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 490 | CLANG_WARN_BOOL_CONVERSION = YES; 491 | CLANG_WARN_COMMA = YES; 492 | CLANG_WARN_CONSTANT_CONVERSION = YES; 493 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 494 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 495 | CLANG_WARN_EMPTY_BODY = YES; 496 | CLANG_WARN_ENUM_CONVERSION = YES; 497 | CLANG_WARN_INFINITE_RECURSION = YES; 498 | CLANG_WARN_INT_CONVERSION = YES; 499 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 500 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 501 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 502 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 503 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 504 | CLANG_WARN_STRICT_PROTOTYPES = YES; 505 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 506 | CLANG_WARN_UNREACHABLE_CODE = YES; 507 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 508 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 509 | COPY_PHASE_STRIP = YES; 510 | ENABLE_NS_ASSERTIONS = NO; 511 | ENABLE_STRICT_OBJC_MSGSEND = YES; 512 | "EXCLUDED_ARCHS[sdk=iphonesimulator*]" = i386; 513 | GCC_C_LANGUAGE_STANDARD = gnu99; 514 | GCC_NO_COMMON_BLOCKS = YES; 515 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 516 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 517 | GCC_WARN_UNDECLARED_SELECTOR = YES; 518 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 519 | GCC_WARN_UNUSED_FUNCTION = YES; 520 | GCC_WARN_UNUSED_VARIABLE = YES; 521 | IPHONEOS_DEPLOYMENT_TARGET = 13.0; 522 | LD_RUNPATH_SEARCH_PATHS = ( 523 | /usr/lib/swift, 524 | "$(inherited)", 525 | ); 526 | LIBRARY_SEARCH_PATHS = "$(SDKROOT)/usr/lib/swift\"$(inherited)\""; 527 | MTL_ENABLE_DEBUG_INFO = NO; 528 | OTHER_CFLAGS = "$(inherited)"; 529 | OTHER_CPLUSPLUSFLAGS = "$(inherited)"; 530 | REACT_NATIVE_PATH = "${PODS_ROOT}/../../node_modules/react-native"; 531 | SDKROOT = iphoneos; 532 | VALIDATE_PRODUCT = YES; 533 | }; 534 | name = Release; 535 | }; 536 | /* End XCBuildConfiguration section */ 537 | 538 | /* Begin XCConfigurationList section */ 539 | 13B07F931A680F5B00A75B9A /* Build configuration list for PBXNativeTarget "capnahap" */ = { 540 | isa = XCConfigurationList; 541 | buildConfigurations = ( 542 | 13B07F941A680F5B00A75B9A /* Debug */, 543 | 13B07F951A680F5B00A75B9A /* Release */, 544 | ); 545 | defaultConfigurationIsVisible = 0; 546 | defaultConfigurationName = Release; 547 | }; 548 | 83CBB9FA1A601CBA00E9B192 /* Build configuration list for PBXProject "capnahap" */ = { 549 | isa = XCConfigurationList; 550 | buildConfigurations = ( 551 | 83CBBA201A601CBA00E9B192 /* Debug */, 552 | 83CBBA211A601CBA00E9B192 /* Release */, 553 | ); 554 | defaultConfigurationIsVisible = 0; 555 | defaultConfigurationName = Release; 556 | }; 557 | /* End XCConfigurationList section */ 558 | }; 559 | rootObject = 83CBB9F71A601CBA00E9B192 /* Project object */; 560 | } 561 | -------------------------------------------------------------------------------- /ios/capnahap.xcodeproj/xcshareddata/xcschemes/capnahap.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 33 | 39 | 40 | 41 | 42 | 43 | 53 | 55 | 61 | 62 | 63 | 64 | 70 | 72 | 78 | 79 | 80 | 81 | 83 | 84 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /ios/capnahap.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ios/capnahap.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ios/capnahap/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import 4 | 5 | @interface AppDelegate : EXAppDelegateWrapper 6 | 7 | @end 8 | -------------------------------------------------------------------------------- /ios/capnahap/AppDelegate.mm: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | 3 | #import 4 | #import 5 | 6 | @implementation AppDelegate 7 | 8 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions 9 | { 10 | self.moduleName = @"main"; 11 | 12 | // You can add your custom initial props in the dictionary below. 13 | // They will be passed down to the ViewController used by React Native. 14 | self.initialProps = @{}; 15 | 16 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 17 | } 18 | 19 | - (NSURL *)sourceURLForBridge:(RCTBridge *)bridge 20 | { 21 | #if DEBUG 22 | return [[RCTBundleURLProvider sharedSettings] jsBundleURLForBundleRoot:@".expo/.virtual-metro-entry"]; 23 | #else 24 | return [[NSBundle mainBundle] URLForResource:@"main" withExtension:@"jsbundle"]; 25 | #endif 26 | } 27 | 28 | // Linking API 29 | - (BOOL)application:(UIApplication *)application openURL:(NSURL *)url options:(NSDictionary *)options { 30 | return [super application:application openURL:url options:options] || [RCTLinkingManager application:application openURL:url options:options]; 31 | } 32 | 33 | // Universal Links 34 | - (BOOL)application:(UIApplication *)application continueUserActivity:(nonnull NSUserActivity *)userActivity restorationHandler:(nonnull void (^)(NSArray> * _Nullable))restorationHandler { 35 | BOOL result = [RCTLinkingManager application:application continueUserActivity:userActivity restorationHandler:restorationHandler]; 36 | return [super application:application continueUserActivity:userActivity restorationHandler:restorationHandler] || result; 37 | } 38 | 39 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 40 | - (void)application:(UIApplication *)application didRegisterForRemoteNotificationsWithDeviceToken:(NSData *)deviceToken 41 | { 42 | return [super application:application didRegisterForRemoteNotificationsWithDeviceToken:deviceToken]; 43 | } 44 | 45 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 46 | - (void)application:(UIApplication *)application didFailToRegisterForRemoteNotificationsWithError:(NSError *)error 47 | { 48 | return [super application:application didFailToRegisterForRemoteNotificationsWithError:error]; 49 | } 50 | 51 | // Explicitly define remote notification delegates to ensure compatibility with some third-party libraries 52 | - (void)application:(UIApplication *)application didReceiveRemoteNotification:(NSDictionary *)userInfo fetchCompletionHandler:(void (^)(UIBackgroundFetchResult))completionHandler 53 | { 54 | return [super application:application didReceiveRemoteNotification:userInfo fetchCompletionHandler:completionHandler]; 55 | } 56 | 57 | @end 58 | -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/ios/capnahap/Images.xcassets/AppIcon.appiconset/App-Icon-1024x1024@1x.png -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "filename": "App-Icon-1024x1024@1x.png", 5 | "idiom": "universal", 6 | "platform": "ios", 7 | "size": "1024x1024" 8 | } 9 | ], 10 | "info": { 11 | "version": 1, 12 | "author": "expo" 13 | } 14 | } -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "expo" 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/SplashScreen.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/SplashScreen.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/ios/capnahap/Images.xcassets/SplashScreen.imageset/image.png -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/SplashScreenBackground.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images": [ 3 | { 4 | "idiom": "universal", 5 | "filename": "image.png", 6 | "scale": "1x" 7 | }, 8 | { 9 | "idiom": "universal", 10 | "scale": "2x" 11 | }, 12 | { 13 | "idiom": "universal", 14 | "scale": "3x" 15 | } 16 | ], 17 | "info": { 18 | "version": 1, 19 | "author": "expo" 20 | } 21 | } -------------------------------------------------------------------------------- /ios/capnahap/Images.xcassets/SplashScreenBackground.imageset/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/EvanBacon/expo-ahap/2eb7cfe2981578d77520d6cdfc5c570d176e2324/ios/capnahap/Images.xcassets/SplashScreenBackground.imageset/image.png -------------------------------------------------------------------------------- /ios/capnahap/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CADisableMinimumFrameDurationOnPhone 6 | 7 | CFBundleDevelopmentRegion 8 | $(DEVELOPMENT_LANGUAGE) 9 | CFBundleDisplayName 10 | capn-ahap 11 | CFBundleExecutable 12 | $(EXECUTABLE_NAME) 13 | CFBundleIdentifier 14 | $(PRODUCT_BUNDLE_IDENTIFIER) 15 | CFBundleInfoDictionaryVersion 16 | 6.0 17 | CFBundleName 18 | $(PRODUCT_NAME) 19 | CFBundlePackageType 20 | $(PRODUCT_BUNDLE_PACKAGE_TYPE) 21 | CFBundleShortVersionString 22 | 1.0.0 23 | CFBundleSignature 24 | ???? 25 | CFBundleURLTypes 26 | 27 | 28 | CFBundleURLSchemes 29 | 30 | com.bacon.capn-ahap 31 | 32 | 33 | 34 | CFBundleVersion 35 | 1 36 | LSRequiresIPhoneOS 37 | 38 | NSAppTransportSecurity 39 | 40 | NSAllowsArbitraryLoads 41 | 42 | NSExceptionDomains 43 | 44 | localhost 45 | 46 | NSExceptionAllowsInsecureHTTPLoads 47 | 48 | 49 | 50 | 51 | UILaunchStoryboardName 52 | SplashScreen 53 | UIRequiredDeviceCapabilities 54 | 55 | armv7 56 | 57 | UIRequiresFullScreen 58 | 59 | UIStatusBarStyle 60 | UIStatusBarStyleDefault 61 | UISupportedInterfaceOrientations 62 | 63 | UIInterfaceOrientationPortrait 64 | UIInterfaceOrientationPortraitUpsideDown 65 | 66 | UISupportedInterfaceOrientations~ipad 67 | 68 | UIInterfaceOrientationPortrait 69 | UIInterfaceOrientationPortraitUpsideDown 70 | UIInterfaceOrientationLandscapeLeft 71 | UIInterfaceOrientationLandscapeRight 72 | 73 | UIUserInterfaceStyle 74 | Light 75 | UIViewControllerBasedStatusBarAppearance 76 | 77 | 78 | -------------------------------------------------------------------------------- /ios/capnahap/SplashScreen.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 | -------------------------------------------------------------------------------- /ios/capnahap/Supporting/Expo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | EXUpdatesCheckOnLaunch 6 | ALWAYS 7 | EXUpdatesEnabled 8 | 9 | EXUpdatesLaunchWaitMs 10 | 0 11 | EXUpdatesSDKVersion 12 | 49.0.0 13 | 14 | -------------------------------------------------------------------------------- /ios/capnahap/capnahap-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | // 2 | // Use this file to import your target's public headers that you would like to expose to Swift. 3 | // 4 | -------------------------------------------------------------------------------- /ios/capnahap/capnahap.entitlements: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | aps-environment 6 | development 7 | 8 | -------------------------------------------------------------------------------- /ios/capnahap/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char * argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | 11 | -------------------------------------------------------------------------------- /ios/capnahap/noop-file.swift: -------------------------------------------------------------------------------- 1 | // 2 | // @generated 3 | // A blank Swift file must be created for native modules with Swift files to work correctly. 4 | // 5 | -------------------------------------------------------------------------------- /metro.config.js: -------------------------------------------------------------------------------- 1 | // Learn more https://docs.expo.io/guides/customizing-metro 2 | const { getDefaultConfig } = require("expo/metro-config"); 3 | 4 | /** @type {import('expo/metro-config').MetroConfig} */ 5 | const config = getDefaultConfig(__dirname); 6 | 7 | config.resolver.assetExts.push("wav"); 8 | module.exports = config; 9 | -------------------------------------------------------------------------------- /modules/ahap/_package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "expo-ahap", 3 | "version": "0.0.1", 4 | "description": "", 5 | "main": "index.ts", 6 | "repository": { 7 | "type": "git", 8 | "url": "https://github.com/evanbacon/expo-ahap.git", 9 | "directory": "packages/expo-ahap" 10 | }, 11 | "bugs": { 12 | "url": "https://github.com/evanbacon/expo-ahap/issues" 13 | }, 14 | "author": "Evan Bacon", 15 | "scripts": { 16 | "test": "echo \"Error: no test specified\" && exit 1" 17 | }, 18 | "keywords": ["expo", "react", "apple"], 19 | "license": "ISC" 20 | } 21 | -------------------------------------------------------------------------------- /modules/ahap/expo-module.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "platforms": ["ios"], 3 | "ios": { 4 | "modules": ["AhapModule"] 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /modules/ahap/index.ts: -------------------------------------------------------------------------------- 1 | import { 2 | NativeModulesProxy, 3 | EventEmitter, 4 | Subscription, 5 | } from "expo-modules-core"; 6 | 7 | // Import the native module. On web, it will be resolved to Ahap.web.ts 8 | // and on native platforms to Ahap.ts 9 | import AhapModule from "./src/AhapModule"; 10 | import { ChangeEventPayload } from "./src/Ahap.types"; 11 | 12 | /** 13 | * Parameters used to modify individual haptic and/or audio events. 14 | * 15 | * Event parameters are specified as part of the creation of a CHHapticEvent or in an event definition in a haptic pattern. 16 | * The combination of Event parameters will determine the character of the haptic or audio event. 17 | */ 18 | export type CHHapticEventParameterID = 19 | /** 20 | * The perceived intensity (volume) of a haptic event. 21 | * Range: 0.0 (maximum attenuation) to 1.0 (no attenuation). 22 | */ 23 | | "HapticIntensity" 24 | 25 | /** 26 | * Depending on the event's signal content, this may map to frequency, frequency content (i.e., filtering), 27 | * or some other signal processing. 28 | * Range: 0.0 (least sharp) to 1.0 (most sharp). 29 | */ 30 | | "HapticSharpness" 31 | 32 | /** 33 | * The attack time adjuster for a Continuous event's envelope. 34 | * Range: 0.0 to 1.0, with default: 0.0 (shortest attack time). Higher values increase the time exponentially. 35 | * Not all event types respond to this parameter. 36 | */ 37 | | "AttackTime" 38 | 39 | /** 40 | * The decay time adjuster for a Continuous event's envelope. 41 | * Range: 0.0 to 1.0, with default: 0.0 (shortest decay time). Higher values increase the time exponentially. 42 | * For envelope decay to take effect, the `Sustained` parameter must be set to 0.0. 43 | * Not all event types respond to this parameter.*/ 44 | | "DecayTime" 45 | 46 | /** 47 | * The release time adjuster for a Continuous event's envelope. 48 | * Range: 0.0 to 1.0, with default: 0.0 (shortest release time). Higher values increase the time exponentially. 49 | * Not all Continuous event types respond to this parameter. 50 | */ 51 | | "ReleaseTime" 52 | 53 | /** 54 | * A boolean (1.0 or 0.0) which indicates whether a Continuous event sustains for its specified duration 55 | * (using an Attack/Release envelope) or whether the event ends when its envelope decay segment reaches its minimum 56 | * (i.e., using an Attack/Decay envelope with no sustain). 57 | * Default: 1.0 (sustained, Attack/Release). 58 | */ 59 | | "Sustained" 60 | 61 | /** The volume of an audio event. 62 | * Range: 0.0 (maximum attenuation) to 1.0 (no attenuation). 63 | */ 64 | | "AudioVolume" 65 | 66 | /** 67 | * The pitch adjuster for audio events. 68 | * Range: -1.0 (lowest pitch) to 1.0 (highest pitch). 69 | */ 70 | | "AudioPitch" 71 | 72 | /** 73 | * The stereo panning for an audio event. 74 | * Range: -1.0 (panned full left) to 1.0 (panned full right). 75 | * Default: 0.0 (panned center). 76 | */ 77 | | "AudioPan" 78 | /** 79 | * The high frequency content an audio event. 80 | * Range: 0.0 (frequency content reduced the most) to 1.0 (no reduction of frequency content). 81 | * Default: 1.0. 82 | */ 83 | | "AudioBrightness"; 84 | 85 | /** 86 | * Parameters used to dynamically modify all haptic or audio events within a pattern. 87 | * 88 | * Dynamic parameters are not tied to specific events; each dynamic parameter modifies (modulates) the 89 | * effect of the corresponding event parameter for events which respond to the parameter. 90 | * 91 | * The `CHHapticDynamicParameterIDHaptic` types only affect haptic event types, and the `CHHapticDynamicParameterIDAudio` 92 | * types only affect audio event types. Not all `CHHapticDynamicParameterID`s will have an effect on every `CHHapticEventType`. 93 | */ 94 | export type CHHapticDynamicParameterID = 95 | /** 96 | * Adjusts the intensity of all active and future haptic events. 97 | * @range 0.0 (event intensities reduced by the maximum amount) to 1.0 (no effect on event intensities). 98 | * @default 1.0 99 | */ 100 | | "HapticIntensityControl" 101 | 102 | /** 103 | * This will adjust the frequency, frequency content (i.e., filtering), or other aspects of all active and future haptic events. 104 | * @range -1.0 (less sharp) to 1.0 (more sharp). 105 | * @default 0.0 (no effect). 106 | */ 107 | | "HapticSharpnessControl" 108 | /** 109 | * Adjusts the envelope attack time of all active and future haptic events. 110 | * @range -1.0 (event attacks shorter) to 1.0 (event attacks longer). 111 | * @default 0.0 (no effect). 112 | * Not all haptic event types respond to this parameter. 113 | */ 114 | | "HapticAttackTimeControl" 115 | 116 | /** 117 | * Adjusts the envelope decay time of all active and future Transient haptic events. 118 | * @range -1.0 (event decays shorter) to 1.0 (event decays longer). 119 | * @default 0.0 (no effect). 120 | * Not all haptic event types respond to this parameter. 121 | */ 122 | | "HapticDecayTimeControl" 123 | 124 | /** 125 | * Adjusts the envelope release time of all active and future Continuous haptic events. 126 | * @range -1.0 (event releases shorter) to 1.0 (event releases longer). 127 | * @default 0.0 (no effect). 128 | * Not all haptic event types respond to this parameter. 129 | */ 130 | | "HapticReleaseTimeControl" 131 | 132 | /** 133 | * Adjusts the volume of all active and future audio events. 134 | * @range 0.0 (event intensities reduced by the maximum amount) to 1.0 (no effect). 135 | * @default 1.0 136 | */ 137 | | "AudioVolumeControl" 138 | 139 | /** 140 | * Adjusts the panning of all active and future audio events. 141 | * @range -1.0 (events panned more left) to 1.0 (event panned more right). 142 | * @default 0.0 (no effect). 143 | */ 144 | | "AudioPanControl" 145 | /** 146 | * Adjusts the high frequency content of all active and future audio events. 147 | * @range -1.0 (more filtering) to 1.0 (less filtering). 148 | * @default 0.0 (no effect). 149 | * */ 150 | | "AudioBrightnessControl" 151 | /** 152 | * Adjusts the transposition of the audio event. 153 | * @range -1.0 to 1.0. Negative values decrease pitch; positive values increase pitch. 154 | * @default 0.0 (no effect). 155 | */ 156 | | "AudioPitchControl" 157 | 158 | /** 159 | * Adjusts the envelope attack time of all active and future audio events. 160 | * @range -1.0 (event attacks shorter) to 1.0 (event attacks longer). 161 | * @default 0.0 (no effect). 162 | * Not all audio event types respond to this parameter. 163 | */ 164 | | "AudioAttackTimeControl" 165 | 166 | /** 167 | * Adjusts the envelope decay time of all active and future Transient audio events. 168 | * @range -1.0 (event decays shorter) to 1.0 (event decays longer). 169 | * @default 0.0 (no effect). 170 | * Not all audio event types respond to this parameter. 171 | */ 172 | | "AudioDecayTimeControl" 173 | 174 | /** 175 | * Adjusts the envelope release time of all active and future Continuous audio events. 176 | * @range -1.0 (event releases shorter) to 1.0 (event releases longer). 177 | * @default 0.0 (no effect). 178 | * Not all audio event types respond to this parameter. 179 | */ 180 | | "AudioReleaseTimeControl"; 181 | 182 | export type AhapEventPatternValue = { 183 | ParameterID: CHHapticEventParameterID; 184 | ParameterValue: number; 185 | }; 186 | 187 | export type AhapParameterCurveControlPoints = { 188 | Time: number; 189 | ParameterValue: number; 190 | }; 191 | 192 | export type AhapEventPattern = { 193 | Event: 194 | | { 195 | EventType: "HapticContinuous"; 196 | Time: number; 197 | EventDuration: number; 198 | EventParameters: AhapEventPatternValue[]; 199 | } 200 | | { 201 | EventType: "HapticTransient"; 202 | Time: number; 203 | EventParameters: AhapEventPatternValue[]; 204 | } 205 | | { 206 | EventType: "AudioCustom"; 207 | Time: number; 208 | EventWaveformPath: string; 209 | EventParameters: AhapEventPatternValue[]; 210 | }; 211 | }; 212 | 213 | export type AhapParameterCurvePattern = { 214 | ParameterCurve: { 215 | ParameterID: CHHapticDynamicParameterID; 216 | Time: number; 217 | ParameterCurveControlPoints: AhapParameterCurveControlPoints[]; 218 | }; 219 | }; 220 | 221 | export type AhapType = { 222 | Version?: 1.0; 223 | Metadata?: { 224 | Project: string; 225 | Created: string; 226 | Description: string; 227 | }; 228 | Pattern: (AhapEventPattern | AhapParameterCurvePattern)[]; 229 | }; 230 | 231 | export class Player { 232 | private id = Math.random().toString(); 233 | private subscription: Subscription; 234 | 235 | private subscribers: Set<() => void> = new Set(); 236 | 237 | constructor(pattern: AhapType) { 238 | AhapModule.register(this.id, pattern); 239 | 240 | this.subscription = addChangeListener((event) => { 241 | if (event.name === this.id) { 242 | for (const subscriber of this.subscribers) { 243 | subscriber(); 244 | } 245 | } 246 | }); 247 | } 248 | 249 | addEventListener(callback: () => void) { 250 | this.subscribers.add(callback); 251 | return () => { 252 | this.subscribers.delete(callback); 253 | }; 254 | } 255 | 256 | get isMuted(): boolean { 257 | return AhapModule.getIsMuted(this.id); 258 | } 259 | set isMuted(value: boolean) { 260 | AhapModule.setIsMuted(this.id, value); 261 | } 262 | 263 | get loopEnabled(): boolean { 264 | return AhapModule.getLoopEnabled(this.id); 265 | } 266 | set loopEnabled(value: boolean) { 267 | AhapModule.setLoopEnabled(this.id, value); 268 | } 269 | 270 | get playbackRate(): number { 271 | return AhapModule.getPlaybackRate(this.id); 272 | } 273 | set playbackRate(value: number) { 274 | AhapModule.setPlaybackRate(this.id, value); 275 | } 276 | 277 | get getLoopEnd(): number { 278 | return AhapModule.getLoopEnd(this.id); 279 | } 280 | set setLoopEnd(value: number) { 281 | AhapModule.setLoopEnd(this.id, value); 282 | } 283 | 284 | start(time?: number) { 285 | AhapModule.action(this.id, "start", time); 286 | } 287 | stop(time?: number) { 288 | AhapModule.action(this.id, "stop", time); 289 | } 290 | pause(time?: number) { 291 | AhapModule.action(this.id, "pause", time); 292 | } 293 | resume(time?: number) { 294 | AhapModule.action(this.id, "resume", time); 295 | } 296 | seek(time: number) { 297 | AhapModule.action(this.id, "seek", time); 298 | } 299 | unregister() { 300 | AhapModule.unregister(this.id); 301 | this.subscription.remove(); 302 | } 303 | 304 | sendParameters( 305 | params: { 306 | ParameterID: CHHapticDynamicParameterID; 307 | ParameterValue: number; 308 | /** Relative time */ 309 | Time: number; 310 | }[], 311 | time?: number 312 | ) { 313 | AhapModule.send(this.id, params, time); 314 | } 315 | 316 | scheduleParameterCurve( 317 | curve: AhapParameterCurvePattern["ParameterCurve"], 318 | time?: number 319 | ) { 320 | AhapModule.schedule(this.id, curve, time); 321 | } 322 | } 323 | 324 | const emitter = new EventEmitter(AhapModule ?? NativeModulesProxy.Ahap); 325 | 326 | function addChangeListener( 327 | listener: (event: ChangeEventPayload) => void 328 | ): Subscription { 329 | return emitter.addListener("finished", listener); 330 | } 331 | -------------------------------------------------------------------------------- /modules/ahap/ios/Ahap.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |s| 2 | s.name = 'Ahap' 3 | s.version = '1.0.0' 4 | s.summary = 'A sample project summary' 5 | s.description = 'A sample project description' 6 | s.author = '' 7 | s.homepage = 'https://docs.expo.dev/modules/' 8 | s.platform = :ios, '13.0' 9 | s.source = { git: '' } 10 | s.static_framework = true 11 | 12 | s.dependency 'ExpoModulesCore' 13 | 14 | # Swift/Objective-C compatibility 15 | s.pod_target_xcconfig = { 16 | 'DEFINES_MODULE' => 'YES', 17 | 'SWIFT_COMPILATION_MODE' => 'wholemodule' 18 | } 19 | 20 | s.source_files = "**/*.{h,m,mm,swift,hpp,cpp}" 21 | end 22 | -------------------------------------------------------------------------------- /modules/ahap/ios/AhapModule.swift: -------------------------------------------------------------------------------- 1 | import ExpoModulesCore 2 | import CoreHaptics 3 | 4 | struct CurvePoint: Record { 5 | @Field 6 | var Time: Float = 0 7 | 8 | @Field 9 | var ParameterValue: Float = 0 10 | } 11 | 12 | struct Curve: Record { 13 | @Field 14 | var ParameterID: String 15 | 16 | @Field 17 | var Time: Float = 0 18 | 19 | @Field 20 | var ParameterCurveControlPoints: [CurvePoint] 21 | } 22 | 23 | 24 | struct Send: Record { 25 | @Field 26 | var ParameterID: String 27 | 28 | @Field 29 | var Time: Float = 0 30 | 31 | @Field 32 | var ParameterValue: Double! 33 | } 34 | 35 | 36 | public class AhapModule: Module { 37 | var engine: CHHapticEngine? 38 | var players: [String: CHHapticAdvancedPatternPlayer] = [:] 39 | 40 | func startEngine() { 41 | do { 42 | if engine == nil { 43 | engine = try CHHapticEngine(audioSession: .sharedInstance()) 44 | } 45 | } catch let error { 46 | print("Error creating haptic pattern: \(error)") 47 | } 48 | } 49 | 50 | // Each module class must implement the definition function. The definition consists of components 51 | // that describes the module's functionality and behavior. 52 | // See https://docs.expo.dev/modules/module-api for more details about available components. 53 | public func definition() -> ModuleDefinition { 54 | 55 | 56 | // Sets the name of the module that JavaScript code will use to refer to the module. Takes a string as an argument. 57 | // Can be inferred from module's class name, but it's recommended to set it explicitly for clarity. 58 | // The module will be accessible from `requireNativeModule('Ahap')` in JavaScript. 59 | Name("Ahap") 60 | 61 | Events(["finished"]) 62 | 63 | // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. 64 | Function("register") { (name: String, patternDict: [CHHapticPattern.Key: Any]) in 65 | startEngine() 66 | 67 | if let engine = engine { 68 | // Create a pattern from the dictionary. 69 | let pattern = try CHHapticPattern(dictionary: patternDict) 70 | let player = try? engine.makeAdvancedPlayer(with: pattern) 71 | player?.completionHandler = { (error) in 72 | if let error = error { 73 | print("Finished with error: \(error)") 74 | } 75 | self.sendEvent("finished", ["name": name]) 76 | 77 | } 78 | players[name] = player 79 | } 80 | } 81 | 82 | // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. 83 | Function("unregister") { (name: String) in 84 | players[name] = nil 85 | } 86 | 87 | // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. 88 | Function("action") { (name: String, action: String, time: TimeInterval?) in 89 | if let engine = engine { 90 | 91 | if let player = players[name] { 92 | do { 93 | if (action == "start") { 94 | // Start the haptic engine to prepare it for use. 95 | do { 96 | try engine.start() 97 | } catch let error { 98 | print("The engine failed to start with error: \(error)") 99 | } 100 | 101 | try player.start(atTime: time ?? CHHapticTimeImmediate) 102 | } else if (action == "stop") { 103 | try player.stop(atTime: time ?? CHHapticTimeImmediate) 104 | } else if (action == "pause") { 105 | try player.pause(atTime: time ?? CHHapticTimeImmediate) 106 | } else if (action == "resume") { 107 | try player.resume(atTime: time ?? CHHapticTimeImmediate) 108 | } else if (action == "seek") { 109 | try player.seek(toOffset: time ?? CHHapticTimeImmediate) 110 | } 111 | } catch let error { 112 | print("Error starting haptic player: \(error)") 113 | } 114 | } 115 | } 116 | } 117 | 118 | // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. 119 | Function("send") { (name: String, params: [Send], time: TimeInterval?) in 120 | if let player = players[name] { 121 | do { 122 | try player.sendParameters(params.map({ send in 123 | return CHHapticDynamicParameter.init(parameterID: CHHapticDynamicParameter.ID(rawValue: send.ParameterID), value: Float(send.ParameterValue), relativeTime: TimeInterval(send.Time)) 124 | }), atTime: time ?? CHHapticTimeImmediate) 125 | } catch let error { 126 | print("Error starting haptic player: \(error)") 127 | } 128 | } 129 | } 130 | 131 | // Defines a JavaScript synchronous function that runs the native code on the JavaScript thread. 132 | Function("schedule") { (name: String, curve: Curve, time: TimeInterval?) in 133 | 134 | if let player = players[name] { 135 | // Convert curve to CHHapticParameterCurve 136 | let curve = CHHapticParameterCurve(parameterID: CHHapticDynamicParameter.ID(rawValue: curve.ParameterID), controlPoints: curve.ParameterCurveControlPoints.map( 137 | { (point: CurvePoint) -> CHHapticParameterCurve.ControlPoint in 138 | return CHHapticParameterCurve.ControlPoint(relativeTime: TimeInterval(point.Time), value: point.ParameterValue) 139 | } 140 | ), relativeTime: TimeInterval(curve.Time)) 141 | 142 | do { 143 | try player.scheduleParameterCurve(curve, atTime: time ?? CHHapticTimeImmediate) 144 | } catch let error { 145 | print("Error starting haptic player: \(error)") 146 | } 147 | } 148 | } 149 | 150 | Function("getLoopEnabled") { (name: String) -> Bool? in 151 | if let player = players[name] { 152 | return player.loopEnabled 153 | } 154 | return nil 155 | } 156 | 157 | Function("setLoopEnabled") { (name: String, loopEnabled: Bool) in 158 | if let player = players[name] { 159 | player.loopEnabled = loopEnabled 160 | } 161 | } 162 | 163 | Function("getIsMuted") { (name: String) -> Bool? in 164 | if let player = players[name] { 165 | return player.isMuted 166 | } 167 | return nil 168 | } 169 | 170 | Function("setIsMuted") { (name: String, isMuted: Bool) in 171 | if let player = players[name] { 172 | player.isMuted = isMuted 173 | } 174 | } 175 | 176 | Function("getPlaybackRate") { (name: String) -> Float? in 177 | if let player = players[name] { 178 | return player.playbackRate 179 | } 180 | return nil 181 | } 182 | 183 | Function("setPlaybackRate") { (name: String, playbackRate: Float) in 184 | if let player = players[name] { 185 | player.playbackRate = playbackRate 186 | } 187 | } 188 | 189 | Function("getLoopEnd") { (name: String) -> Double? in 190 | if let player = players[name] { 191 | return player.loopEnd 192 | } 193 | return nil 194 | } 195 | 196 | Function("setLoopEnd") { (name: String, loopEnd: Double) in 197 | if let player = players[name] { 198 | player.loopEnd = TimeInterval(loopEnd) 199 | } 200 | } 201 | 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /modules/ahap/src/Ahap.types.ts: -------------------------------------------------------------------------------- 1 | export type ChangeEventPayload = { 2 | name: string; 3 | }; 4 | 5 | export type AhapViewProps = { 6 | name: string; 7 | }; 8 | -------------------------------------------------------------------------------- /modules/ahap/src/AhapModule.ts: -------------------------------------------------------------------------------- 1 | import { requireNativeModule } from 'expo-modules-core'; 2 | 3 | // It loads the native module object from the JSI or falls back to 4 | // the bridge module (from NativeModulesProxy) if the remote debugger is on. 5 | export default requireNativeModule('Ahap'); 6 | -------------------------------------------------------------------------------- /modules/ahap/src/AhapModule.web.ts: -------------------------------------------------------------------------------- 1 | import { EventEmitter } from "expo-modules-core"; 2 | 3 | const emitter = new EventEmitter({} as any); 4 | 5 | export default { 6 | async setValueAsync(value: string): Promise { 7 | emitter.emit("onChange", { value }); 8 | }, 9 | }; 10 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "capn-ahap", 3 | "version": "1.0.0", 4 | "main": "node_modules/expo/AppEntry.js", 5 | "scripts": { 6 | "start": "expo start", 7 | "android": "expo run:android", 8 | "ios": "expo run:ios", 9 | "web": "expo start --web" 10 | }, 11 | "dependencies": { 12 | "@types/react": "~18.2.14", 13 | "expo": "~49.0.8", 14 | "expo-file-system": "^15.4.3", 15 | "expo-haptics": "^12.4.0", 16 | "expo-splash-screen": "~0.20.5", 17 | "expo-status-bar": "~1.6.0", 18 | "react": "18.2.0", 19 | "react-native": "0.72.4", 20 | "typescript": "^5.1.3" 21 | }, 22 | "devDependencies": { 23 | "@babel/core": "^7.20.0" 24 | }, 25 | "private": true 26 | } 27 | -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": ".", 4 | "paths": { 5 | "@/*": ["./src/*"], 6 | "local:*": ["./modules/*"] 7 | } 8 | }, 9 | "extends": "expo/tsconfig.base" 10 | } 11 | --------------------------------------------------------------------------------