* fix(apple): remove #ifdef checks in public headers
Fixes an issue where framework consumers would also have to set
WITH_RIVE_TEXT or WITH_RIVE_AUDIO
* refactor(apple): remove #if(def) from public interfaces and no-op instead
* fix(apple): fix incorrect api usage
Co-authored-by: David Skuza <david@rive.app>
Adds support for data binding to the iOS runtime.
## Changes
### RiveFile
Updated to match c++ runtime support for getting view models by index, name, and default for an artboard.
### RiveArtboard
Updated to match c++ runtime support for binding a view model instance.
### RiveStateMachine
Updated to match c++ runtime support for binding a view model instance. Additionally, this holds a strong reference to the view model instance that is currently bound (which aids in knowing which state machine should have its property listeners called after advance).
### RiveModel
Adds support for enabling / disabling autoBind functionality. This has to be done _after_ initialization, since Swift default arguments don't bridge to ObjC, and I didn't want to add n number of new initializers. When enabled, a callback will be called with the bound instance.
## New Types
Currently, type names are similar to those found within the c++ runtime. They're kind of ugly when it comes to ObjC, but the Swift names are cleaned up (e.g `RiveViewModelRuntime.Instance` instead of `RiveViewModelInstanceRuntime`).
### RiveDataBindingViewModel
The bridging type between the c++ runtime equivalent (`rive::ViewModelRuntime`) and ObjC.
### RiveDataBindingViewModelInstance
Swift: `RiveDataBindingViewModel.Instance`
The bridging type between the c++ runtime equivalent (`rive::ViewModelInstanceRuntime`) and ObjC.
### RiveDataBindingViewModelInstanceProperty
Swift: `RiveDataBindingViewModel.Instance.Property`
The superclass bridging type between the c++ runtime equivalent (`rive::ViewModelInstanceValueRuntime`) and ObjC.
### Subclasses
- Strings: `RiveDataBindingViewModelInstanceStringProperty`
- Swift: `RiveDataBindingViewModel.Instance.StringProperty`
- Numbers: `RiveDataBindingViewModelInstanceNumberProperty`
- Swift: `RiveDataBindingViewModel.Instance.NumberProperty`
- Boolean: `RiveDataBindingViewModelInstanceBooleanProperty`
- Swift: `RiveDataBindingViewModel.Instance.BooleanProperty`
- Color: `RiveDataBindingViewModelInstanceColorProperty`
- Swift: `RiveDataBindingViewModel.Instance.ColorProperty`
- Enum: `RiveDataBindingViewModelInstanceEnumProperty`
- Swift: `RiveDataBindingViewModel.Instance.EnumProperty`
- Trigger: `RiveDataBindingViewModelInstanceTriggerProperty`
- Swift: `RiveDataBindingViewModel.Instance.TriggerProperty`
### Observability
KVO has (temporarily) been disabled, "forcing" observability to be done through the explicit `addListener` and `removeListener` functions of each property type. `removeListener` exists on the superclass, however the matching `addListener` functions exist on each property type, primarily due to the fact that there is no "pretty" way of handing these functions as generics (where only the value type of the property differs for each callback) other than utilizing `id`. Listeners exist within the context of a property; however, an instance will use its (cached) properties to request that it calls its listeners.
## Details
### Caching properties
When a property getter is called on a view model instance, a cache is first checked for the property, otherwise a new one is returned and cached. This helps with ensuring we are using the same pointer under-the-hood. This isn't strictly necessary (per testing) but does allow for some niceties, such as not having to explicitly maintain a strong reference to a property if you want to just observe: `instance.triggerProperty(from: "...").addListener { ... }`.
Properties are cached for the first component when parsing the path for the property. In the instance that a path with > 1 component is provided to a property (e.g `instance.triggerProperty(from: 'nested/trigger")`, then the appropriate nested view models are created, and the property is associated with the correct view model (e.g above, the view model `nested will be cached, and the trigger property will be cached within that view model).
### Caching nested view models
Similar to caching properties, when a (nested) view model getter is called on a view model instance, a cache is first checked for the view model, otherwise a new one is returned and cached. This helps ensure that when (re)binding an instance to a (new) state machine or artboard, that all properties within that view model still have its listeners attached, regardless of how nested a path goes. This will likely help with implementing replacing instance functionality in v2.
## Testing
Unit tests have been added for data binding, attempting to capture high-level expectations rather than totally verifying the c++ runtime expectations. This includes things like: all getters returning object-or-nil, listeners being called with the correct values, autoBinding, property and view model caching, etc. The `.riv` file for unit tests is the same one that is used within the Example app.
## Example
A new `.riv` file has been added that shows basic usage of each property type (including observability). The same `.riv` file is used in the unit tests.
Diffs=
b2f1db73d7 feat(ios): add support for data binding (#9227)
Co-authored-by: David Skuza <david@rive.app>
Initially the work for https://github.com/rive-app/rive-ios/issues/352
Additionally resolves all warnings except for updating the project to recommended settings, I'll want to take a deeper look into what those changes are / will be.
Diffs=
f257ec36eb Resolve various iOS warnings (#8827)
Co-authored-by: David Skuza <david@rive.app>
This pull request adds support for both visionOS and tvOS to the Apple (colloquially referred to as iOS) runtime.
It should _not_ be a breaking change, since the only major API change is an internal one (see `RenderContext` below). I believe we should be able to make this a minor release. Developers who have subclassed `RiveView` or `RiveRendererView` should not see any changes, unless they were explicitly expecting this view to be `MTKView`, which is fully unavailable on visionOS (hence our recreation - see `RiveMTKView` below.
## Premake Scripts
The premake scripts were updated to add a few new variants for iOS:
- xros (visionOS devices; named after the internal sdk)
- xrsimulator (visionOS simulator; named after the internal sdk)
- appletvos (tvOS devices; named after the internal sdk)
- appletvsimulator (tvOS simulators; named after the internal sdk)
The majority of the work here is copy/pasting existing code, and just adding additional filters when these new options are used, primarily used to target the new SDKs / minimums for those SDKs.
## Shaders
Shaders are pre-compiled for visionOS and tvOS separately, and the correct shaders are then used later-on at compile time.
## Build scripts
Build scripts were updated to support building the new libraries, targeting the new devices, using the new options above. Additionally, they have to point to new output files.
The `build_framework` script has been updated to build the new libraries to add to the final output `xcframework`.
## Project
Example targets for both visionOS and tvOS, since these truly are the "native" apps, rather than just iPad-on-your-device. These use a new `streaming` riv by the creative team.
The tvOS example app adds additional support for remote control, since that behavior can be utilized in multiple ways during development; that is, we don't add any "default" behavior for remote controls. The visionOS app, on the other hand, works out-of-the-box with no additional changes.
## RenderContext
`RenderContext` is an internal type; it's forward-declared, so it's unusable outside of the scope of internal development. There have been some "breaking" changes here - the API has been updated to, instead of passing in `MTKView` around, using `id<RiveMetalDrawableView>`. This had to be changed, regardless, since visionOS does not have `MTKView`. The choice to use a protocol was because it forces a little more explicit initialization across platforms, rather than having a parent class that acts as an abstract class, but isn't abstract because it still needs some default values, but those values are different based on device and API availability, etc. We could've passed around `RiveMTKView` as the type, but with a protocol, there's a possibility of being able to use a type that isn't exactly a view, but might want to still act against the drawing process. Personal choice, really.
## RiveRendererView
`RiveRendererView` is now a subclass of `RiveMTKView`. `RiveMTKView`'s superclass depends on the device:
- On visionOS, this is a `UIView` with an underlying `CAMetalLayer`
- On all other platforms, `MTKView`
This new class conforms to `RiveMetalDrawableView`, which allows it to be passed to `RenderContext` types.
### RiveMTKView (visionOS)
`RiveMTKView` on visionOS is a subclass of `UIView` that is backed by a `CAMetalLayer`, providing the necessary properties of `RiveMetalDrawableView` (compile-time safety here, baby). This is quite a simple recreation of the default `MTKView`, since that type is not available on visionOS (thanks, Apple).
## Other things
Additional compile-time checks for platform OS have been added to make sure each new platform compiles with the correct APIs that can be shared, or otherwise newly implemented.
Diffs=
6f70a0e803 Add visionOS and tvOS support to Apple runtime (#8107)
Co-authored-by: David Skuza <david@rive.app>
This pull request builds on top of fallback font support on iOS by including the ability to provide fallback fonts based on the styling of the missing character. Currently, the style information only contains weight. This weight is grabbed by calling `getAxisValue`. According to Luigi, this is a linear search, so perhaps there's room for a performance optimization later on.
There is one lower-level C++ change: `gFallbackProc` returns the font for the missing character, in addition _to_ the missing character (as a second parameter). This font will be used to generate the requested styling within the iOS runtime.
This adds a new class property to `RiveFont`: `fallbackFontCallback` (whose name I'm open to changing). This is a block (i.e closure) that will be called when a fallback font is requested. It supplies the styling of the missing character so that, for example, different fonts can be used based on the weight of the missing character. For example usage, see `SwiftFallbackFonts.swift`. This provider is what's used under-the-hood, and utilizes the pre-existing `fallbackFonts` class property
The "trickiest" bit here is the caching. NSDictionary requires equatable / hashable types as keys, and we want to minimize additional generation of a Rive font, so we cache any used fonts in a wrapper type, used as the value. When new fallback fonts are provided, either directly or when a new provider block is set, the cache will be reset. Once the weight is determined, generating the right key is as simple as calling the right initializer, and when set, generating the right value is simple as calling the right initializer with the created Rive font.
Finally, `RiveFactory` was getting a little bloated, so I did a little file cleanup.
This pull requests also includes Android support from #8621
Diffs=
7986d64d83 Support supplying mobile fallback fonts by style with caching (#8396)
Co-authored-by: David Skuza <david@rive.app>
Co-authored-by: Umberto <usonnino@gmail.com>
Co-authored-by: Umberto Sonnino <umberto@rive.app>
First steps towards supporting artboard resizing in our runtimes. This PR includes:
- New Fit type `autoResizeArtboard`. After a bit of back and forth, I think this keeps the API simple.
- ScaleFactor which represents a scale value to scale the artboard by in addition to resizing (only applies with `autoResizeArtboard`). This may be useful because an artboard is created at a specific width/height, but it may be deployed to platforms where it is rendered to a much smaller or larger surface/texture. Currently the default is 1.0 (no scale), however, an alternative is to have it default to something like textureSize / artboardSize so we sort of auto normalize it.
- Implemented on iOS. Once this is finalzed, we can work with DevRels to implement across all runtimes.
- TODO : Bubble up an event when the artboard size is changed internally by the .riv
https://github.com/user-attachments/assets/20e9fdda-5c3e-4f3f-b2f5-104ff0291fbe
Diffs=
e71b4cc081 feat: add runtime layout fit type for ios, android, web (#8341)
Co-authored-by: CI <pggordonhayes@gmail.com>
Co-authored-by: David Skuza <david@rive.app>
Co-authored-by: Philip Chung <philterdesign@gmail.com>
Adds (structured) logging via the iOS `Logger` API. Under the hood, this uses `os_log` for both in-memory and on-disk logging, depending on which level is used; this means _where_ is handled by the system, we just provide the level.
The API is a little interesting; you can't have a "generic" `log` function that takes in the message. iOS requires that you use interpolation when logging.
Logging is structured so that various categories are set under one subsystem. These categories are: view model, state machine, artboard, file, and view. Each of these can log one of debug, info, default, error, and fault levels. The developer can filter which categories and levels can be logged; Xcode also supports filtering within the console.
Logging itself is split into three things: the categories, the levels, and the logging. Within each "category" of logging, there exist events that can be logged. These are enums with associated values. When using Objective-C, there are helper functions that under-the-hood call logging functions with these events. Since there are a few categories, and various events for each category, these categories are split into extensions on `RiveLogger`. At the end of the day, there exists a single log function, which ensures a log category and level are available for logging, and then a log function that is essentially a switch statement on each event, logging the (interpolated) message.
These logging events are then utilized in the files mentioned above; the categories match the files where logging has been added. Primarily setters are called, or errors that may not be handled, but may be useful. Fatal errors are also logged.
When adding new logging:
1. Check if an existing extension exists. If not, create one.
2. Create an enum of possible events.
3. Create a `log` function that takes the model, and the event.
4. Create a `_log` function that verifies that an event has been called.
## Example usage
```swift
// Somewhere early in the app lifecycle…
RiveLogger.isEnabled = true
RiveLogger.isVerbose = true // advances are considered verbose
RiveLogger.levels = [.fatal] // filter for only specific levels, such as fatal errors
RiveLogger.categories = [.stateMachine, .viewModel] // filter for only specific categories
```
Diffs=
e1fc239974 Add logging to rive-ios (#8252)
Co-authored-by: David Skuza <david@rive.app>
This builds on top of #7661 and adds an iOS / macOS API for setting fallback fonts.
At a high-level, this adds a class property to `RiveFont` for getting / setting the fallback font(s) **based on the system** (or _optionally_, a `UIFont/NSFont`)(accessible in Objective-C and Swift via `RiveFont.fallbackFonts`). This property is an array of a objects conforming to a new protocol: `RiveFallbackFontProvider` (platform-agnostic). By default, if no fallbacks are set, or an empty array is set, the default system font of regular weight will be used.
In terms of naming, the `RiveFallbackFontDescriptorDesign` and `RiveFallbackFontDescriptorWeight` types each have cases that mirror those available in 1st party Apple APIs, so that usage and expectations are similar across our APIs, as well as those provided by UIKit / AppKit.
## Example Usage
```swift
RiveFont.fallbackFonts = [
RiveFallbackFontDescriptor(systemDesign: .default, weight: .bold),
RiveFallbackFontDescriptor(systemDesign: .monospaced, weight: .ultraLight),
UIFont.systemFont(ofSize: 20, weight: .bold)
]
```
## RiveFallbackFontProvider
`RiveFallbackFontProvider` is a protocol that defines the interface for types that can be used to return system fonts, or any font that can be used as a fallback. `RiveFallbackFontDescriptor` and `UIFont/NSFont` conform to this protocol; both can be used to define fallback fonts.
## RiveFallbackFontDescriptor
`RiveFallbackFontDescriptor` is a platform-agnostic way of defining the _type_ of system font you want to request as a fallback, if necessary. It contains a couple of properties: `design` and `weight`. These are used in conjunction with each other to start with and update a system font (generated by `[UI/NS]Font.systemFont(ofSize:weight:)`, potentially matching on more than one font.
## Unit Tests
Unit tests have been written to verify that `design` and `weight` create different fonts, based on the provided values. The tests at a high-level are the same: for each case of both properties, check that there is at least one matching font. For each property, check that each font name is unique. On iOS, the font names are unique based on system design _and_ weight. I felt this was better than asserting against a specific font name, in case Apple changes that from under our feet. Additionally, what the default system fallback is set to is also tested.
## IRL Testing
This was tested by creating a riv file that contained a text run whose font was exported containing only the glyphs used, and setting the text run to some text that did not use the exported glyphs.
Tested on:
- [x] iOS (Simulator)
- [x] iPadOS
- [x] macOS
Diffs=
a4e15fb7b Add fallback font support for iOS and macOS (#7690)
Co-authored-by: David Skuza <david@rive.app>
See title. Additionally, this removes the skia build scripts and updates the major version dependency rule to v6.0.0 in the Preview app.
Diffs=
8773f56fc Update iOS contributing guide (#8018)
Co-authored-by: David Skuza <david@rive.app>
Updates the `RiveModel` API with the ability to set and get the volume for the currently set artboard. Any new artboards will default to use the last-set volume of the model. A volume default of 1.0 is set to match rive-cpp's default. `RiveArtboard` is also updated to forward volume calls to the artboard instance, exposing a new `volume` property.
There's an open question whether this belongs in `RiveViewModel`, or `RiveModel`, but I went for `RiveModel` since there's a direct reference to the artboard within the model itself, and an indirect reference through the view model (model?.artboard)
Diffs=
a31cd9761 Add ability to set iOS artboard volume through RiveModel (#7658)
Co-authored-by: David Skuza <david@rive.app>
finally found where to do this.
bit annoying but without this people that have already pulled rive-ios and want to play with the "preview app" will need to magically realize they need to up the rive-ios version. with this xcode *should* hint you need to update
Diffs=
4ed7c7a71 bump min version on swift package manager ios dependency (#7116)
Co-authored-by: Maxwell Talbot <talbot.maxwell@gmail.com>
Follow up to #7048!
I nuked the custom defines and the miniaudio include. I think this fixes the need for miniaudio and the custom defines @mjtalbot! Give it a shot 🔫
Diffs=
89053041a add out of band audio support ios - abstracted audio! (#7079)
Co-authored-by: Luigi Rosso <luigi-rosso@users.noreply.github.com>
Co-authored-by: Maxwell Talbot <talbot.maxwell@gmail.com>
Automatically fall back on atomic mode when running on non-Apple Silicon and on the iOS simulator.
Diffs=
c7e5ab376 Implement PLS atomic mode in Metal (#6610)
Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
This PR:
- Removes developer comments + Todos
- Changes the samples to use @StateObject for the RiveViewModel instances. This is the SwiftUI way to instantiate an ObservableObject. This also ensures the Rive data is only loaded when the view is displayed and not when the app is started. The `view` method may also be called multiple times for various reasons, so moving this logic to be in the view state is more efficient. @mjtalbot I think you made comments about this in the past.
By doing the above it also fixes the samples in `SwiftWidgets` that was giving issues
- For example, the sliders didn't work. It does now.
- The toggle `RSwitch` still does not work, as it's an Animation and not a StateMachine (I believe there is now logic that disables touch events if there are no active listeners, or it only does touch processing when it's a state machine).
- We should remove this file entirely or just keep the sliders. This seems to have been made before state machines were a thing, and implementing buttons etc. should rather be done through listeners and events.
### TODO
- Some samples still create the RiveViewModel in the view but rely on other state data. Need to check to see what is the correct way to lazily create those.
Diffs=
fbb092d8c chore: cleanup ios examples (#6351)
Co-authored-by: Gordon <pggordonhayes@gmail.com>
Example app downstream had troubles running the Cached Assets example. It was referencing the riv in `runtime_wasm`, so this just adds it to the project differently.
Diffs=
82f90a2de fix: cached asset example using a bad path reference (#6331)
Co-authored-by: Zachary Plata <plata.zach@gmail.com>
Issue: https://github.com/rive-app/rive-ios/issues/286
Doing a small check on the artboard query for a text run for `nullptr` before returning from the Artboard
Diffs=
35daf194f fix: add nullptr check when retrieving text run on iOS at the artboard (#6312)
Co-authored-by: Zachary Plata <plata.zach@gmail.com>
few bits to sort out
- [x] make our mix of simulator/emulator consistent, settling on emulator
- [x] passing the factory in works great for just in time asset decoding, but its not amazing when you want to decode ahead of time.
- [x] couple of places left to pass this function signature through. (Question) is there a neater way to get this done, feels a bit like we are going back to parameter explosion a bit?
- [x] should do a few examples, i think the complexity grows quite a bit in this one as you add caching, or callbacks
- [x] should get the cached images/fonts to draw on init as well, either warming up cache, or jitting
- [x] examples loading assets from the bundle (also there seem to be actual asset things too? should we use those?!)
- [x] add test
- [x] re-add "preview" project & rev the preview project once this has been deployed. (do this after new ios deploy)
- [x] fix up race condition (see comment)
https://github.com/rive-app/rive/assets/1216025/2c14330f-e8a4-481b-bc27-4807cabe3b82
(simple example, both swift ui and standard)

Diffs=
fabb7f97f Ios out of band (#6232)
Co-authored-by: Gordon Hayes <pggordonhayes@gmail.com>
Co-authored-by: Maxwell Talbot <talbot.maxwell@gmail.com>
Just a draft for testing at the moment.. if we want to include the way to set `preferredFramesPerSecond`, might make sense to expose some kind of API on `RiveView` or `RiveViewModel` to set on `CADisplayLink` when we create it for the animation loop.
In particular, the change to `Info.plist` below is what enables the display link to go to 120fps.
One caveat is that in setting `.preferredFramesPerSecond`, this API is marked as deprecated by Apple.. and still need to understand what the alternative is
https://developer.apple.com/documentation/quartzcore/cadisplaylink/1648421-preferredframespersecond
Diffs=
97b7622bc Enable CADisplayLink to run at a user-defined preferredFramesPerSecond (#6111)
Co-authored-by: Zachary Plata <plata.zach@gmail.com>
Instead, fall back on Skia with a warning.
Diffs=
e0c21beec Don't crash the iOS simulator when requesting Rive Renderer (#6110)
Co-authored-by: Chris Dalton <99840794+csmartdalton@users.noreply.github.com>
This is similar to the Android PR that added build variants to make it easier to build the example apps, see: https://github.com/rive-app/rive/pull/6088
With this PR we're now making use of additional targets that shares code with the parent examples (iOS and macOS respectively). Then there are two new schemes that you can select when playing `preview` and `preview (macOS)`, which will use the above mentioned targets that uses the hosted Rive dependency instead of the local one.
This works well, but is not as smooth of an implementation as Android, where it was simply switching out a build flag. With this implementation we'll also need to semi-manually bump the hosted version - see the additional docs in `CONTRIBUTING`.
There might be a way that we could make this smoother. It'll only be a headache for examples that make use of new features. Where after we release, we'd then need to do another PR that updates the minimum version for the `preview` targets. We could likely look into automating this by scripting the change in the Xcode config.
Diffs=
d78a6561a feat: add preview target to ios and macos runtime example (#6096)
Co-authored-by: Gordon <pggordonhayes@gmail.com>
Adds event bindings for iOS/macOS
**Caveat:** tl;dr We may have to explicitly make app owners open URLs for `OpenUrlEvent`, rather than doing it implicitly
Recently, there was a [request for a specific change](https://github.com/rive-app/rive-ios/pull/267) to mark `RiveRuntime` package as using application-extension-safe in terms of API usge. This allows RiveRuntime to be used in places other than apps in the Apple ecosystem, which they needed, so that Apple doesn't flag their apps negatively in App Store submissions. Because we mark this setting in build settings for our package, this means we can't use a specific API to access `UIApplication`, which is needed to open URLs from our side (i.e. `UIApplication.shared.open(url)`), thus not allowing us to _directly_ open URLs on `OpenUrlEvent`. Couldn't find a way around this unfortunately, so the onus on opening the URL will be on the consumer when they listen for this event.
Diffs=
b47ff1523 feature: Add Rive Event bindings to iOS runtime (#5899)
Co-authored-by: Zachary Plata <plata.zach@gmail.com>
Redoing the PR from: https://github.com/rive-app/rive/pull/5683
Wasn't recognizing latest commits for some reason, Github was having some PR status issues yesterday so might've been from that
Diffs=
fe466871e Add text binding ios (#5687)
Co-authored-by: Zachary Plata <plata.zach@gmail.com>
draft because i need to get a todo list together.
Adds macos as a target for our ios runtime! Also adds a macos target for our example (which is a different app completely, very minimalistic right now).
<img width="331" alt="CleanShot 2023-05-17 at 20 32 45@2x" src="https://github.com/rive-app/rive/assets/1216025/7a6cadce-9763-41a3-b1a0-6d067dfc3eca">
macos, macos rosetta, macos (designed for ipad), and ios all co existing in peace, from the same runtime project

todo:
- [x] update build scripts to build supporting macos (gotta do this)
- [x] run formatter
- [x] test out builds in forked version of ios? (gotta do this)
- [ ] one more stab at catalyst? (i think we can try that later...)
- [ ] do we need a more comprehensive example setup for macos (I think we can do this later & try to pull zach's examples in)
- [ ] I think we should restructure the ios project, but i think we can do that after this as well (i just think the folder structure/project structure can do with some work, now that we add macos (and should make room for tvos as well)
- [x] probably got tests to fix
- [ ] there's probably a bunch of looking at errors in the debugger and figuring those out, but i would hope that we can deploy with some warnings here too.
catalyst problem:
we get this error:
and the problem is basically that we can target a specific library for macos, but we need one for macos and one for macos catalyst. they share the same architecture, so i dont think we can lipo them into one file...
we could change the compiled binaries before creating the frameworks I guess though? .. maybe something to try..
`/Users/maxwelltalbot/development/rive/rive/packages/runtime_ios/dependencies/debug/librive_skia_renderer_macos.a(cg_factory.o), building for Mac Catalyst, but linking in object file built for macOS, file '/Users/maxwelltalbot/development/rive/rive/packages/runtime_ios/dependencies/debug/librive_skia_renderer_macos.a' for architecture arm64` basically
Diffs=
a9f8a1c5d Macos take2 (#5258)
Set of ios changes:
- Fixes a couple of memory leaks
- Implements ref counting for our graphics context, so we can ditch it if noone's using it
- few leftover notes about things i've not quite "solved" we still keep a hold of too much url data, but i think i want to get this change in. its been too long
Diffs=
1ddbb679a Ios memory shared context (#5169)