The markdown parsing is broken/disabled for release notes. Sorry about that, I'm chasing the source of a crash that's been bringing this website down for the last couple of days.
### Increased Compatibility with Sony Cameras
CascableCore 12 greatly expands support for Sony cameras. USB remote control via **PC Remote (USB)** has been added for the following already-supported models:
- α7 II, α7 III
- α7R II, α7R III
- α7S, α7S II
- α6000, α6300, α6500
In addition, USB remote control via **PC Remote (USB)** and network remote control via **Control with Smartphone**, and **PC Remote (WiFi)** (where available) has been added for these newly-supported models:
- α7 IV
- α7R IV
- α7S III
- α7C
- α9, α9 II
- α1
- α6100, α6400, α6600
- ZV-E10, ZV-1
- RX100 V, RX100 VI, RX100 VII
### Other Camera Compatibility
- Added support for the OM System OM-1. This camera is identified as an Olympus camera (`CBLCameraFamilyOlympus`) by CascableCore.
### New API: Camera-Initiated Transfer
Shot preview (`id <CBLCameraShotPreviewDelivery>`) has been removed and replaced by a more powerful API that's more suited to the fact that original images can be transferred as well as previews.
The new API uses the terminology of "camera-initiated transfers", and is designed to handle both previews of shots added to a memory card as well as the transfer of full image files — including cameras set to "Host Only" saving – i.e., the full image needs to be transferred to the host to avoid data loss. The new API can handle simple cases ("I just want a preview") and more complex ones ("I want a preview, and if the image would otherwise be lost, the original image too").
This new API is defined in `CBLCameraInitiatedTransfer.h`. The flow is as follows:
- The client receives a callback from the camera notifying it of a new camera-initiated transfer request. This will be an object of type `id <CBLCameraInitiatedTransferRequest>`, which contains some metadata about the incoming image, whether or not transferring it is required to avoid data loss (i.e., "Host Only" saving), and which representations the request contains.
- The client then executes the request, informing it which representations are wanted. Current representations are "preview" and "original". The image transfer is then performed, optimising data transfer if possible (for instance, if the client only requests the preview representation of a RAW image, CascableCore will try to avoid transferring the entire RAW image).
- When the request is complete, a result object of type `id <CBLCameraInitiatedTransferResult>` will be delivered. The result object contains additional metadata about the transferred image, as well as helpers for writing representations to disk, getting them as in-memory data, and getting preview images.
Previous uses of the shot preview API can be migrated to camera-initiated transfers with no loss in functionality by transferring preview representations (`CBLCameraInitiatedTransferRepresentationPreview`), then using either `-generatePreviewImage:` or `-generateDataForRepresentation:completionHandler:` on the result.
### New API: Stepped Properties
CascableCore now supports "stepped properties" — properties that don't have a list of valid values, and are instead changed by adjusting the property "up" or "down" in steps.
This change has been implemented in a backwards-compatible way, and with no code changes stepped properties will appear read-only (i.e., will have an empty `validSettableValues` value).
To implement stepped properties, see the new `valueSetType` property on `id <CBLCameraProperty>`. If that returns `CBLPropertyValueSetTypeStepping`, you can use the `incrementValue:` and `decrementValue:` methods to change that property's value.
### Other API Changes
- Added the `CBLPropertyIdentifierImageDestination` property. Values are typically along the lines of "Host", "Camera", and "Camera & Host". Common values are of type `CBLPropertyCommonValueImageDestination`.
- Added the error code `CBLErrorCodeIncorrectCommunicationMode`, of which connections will fail on a Sony USB camera not in PC Remote mode.
- Added the error code `CBLErrorCodeObjectTooLarge`, which can be returned when requesting very large assets as in-memory data objects from an `id <CBLCameraInitiatedTransferResult>` object.
### Known Issues
- There is no video timer on some Sony cameras when being controlled via USB. Video recording still works, if available.
- Live view zoom is not yet implemented for newly-supported Sony cameras.
- Extremely new cameras (such as the α7 IV) support touch AF via remote control, but this is not yet supported in CascableCore.
### Video Recording
Added an initial, basic API for working with video recording. This API has currently been implemented for Canon EOS and Nikon cameras.
To see if a camera supports video recording, check for `CBLCameraSupportedFunctionalityVideoRecording`. To switch a camera into a mode that allows video recording, use `CBLCameraAvailableCommandCategoryVideoRecording`.
Once the camera is in a mode in which video recording can go ahead, start and stop video recording with `-startVideoRecording:` and `-endVideoRecording:`. Whether or not the camera is currently recording video can be observed with `-isRecordingVideo`.
Video recording has ramifications across the entire API surface of a camera, and particularly changes a number of assumptions you may have been making when working with Canon and Nikon cameras. In particular:
- A number of APIs are unavailable while video is recording, including all filesystem access. See the new error code `CBLErrorCodeVideoRecordingInProgress`.
- Canon EOS and Nikon cameras can now be placed into a mode where taking photos isn't allowed. Previously, these cameras always allowed both stills shooting and filesystem access.
- Older Canon EOS cameras don't allow video recording while WiFi is active. If you try to start recording video via a WiFi connection, the `CBLErrorCodeDisallowedOnCurrentTransport` error will be returned.
- Some cameras require moving a physical switch to move the camera in or out of video mode. If that's the case, attempting to switch the available command categories to or from `CBLCameraAvailableCommandCategoryVideoRecording` may produce the error `CBLErrorCodeRequiresPhysicalInteraction`. If this happens, instruct the user to flip the relavent switch manually. The `-currentCommandCategories` property is observable with Key-Value Observing, and will change automatically when the video mode is changed by the user.
#### New API
- Added `CBLCameraSupportedFunctionalityVideoRecording` to enable checks to see if video recording is supported by a particular camera.
- Added `CBLCameraAvailableCommandCategoryVideoRecording` to put a camera into video recording mode.
- Added the `-isRecordingVideo` and `-currentVideoTimerValue` properties to `id <CBLCamera>`, which are observable with Key-Value Observing.
- Added `-startVideoRecording:` and `endVideoRecording:` to `id <CBLCamera>` to start and stop video recording.
- Added the error codes `CBLErrorCodeVideoRecordingInProgress`, `CBLErrorCodeRequiresPhysicalInteraction`, `CBLErrorCodeDisallowedOnCurrentTransport`, `CBLErrorCodeRequiresLiveView`, `CBLErrorCodeCardError`, and `CBLErrorCodeStorageFull`.
#### Breaking API changes:
- `CBLCameraAvailableCommandCategoryRemoteShooting` has been renamed to `CBLCameraAvailableCommandCategoryStillsShooting`.
- A number of existing situations where a camera would return a `CBLErrorCodeNotAvailable` error code have been changed so a more accurate error code is returned instead. Particularly, `CBLErrorCodeRequiresLiveView` and `CBLErrorCodeVideoRecordingInProgress` have replaced a number of more generic existing error paths.
#### Known Issues
- Some older Canon cameras will automatically terminate live view when exiting video mode. If this happens, re-start live view.
- Newer Nikon cameras have separate properties for video exposure settings, which aren't currently exposed by CascableCore. They will be added in a future release.
### Camera Compatibility
- Added support for the Canon EOS R3.
- Added `CBLCameraSupportedFunctionalityRemoteControlWithoutLiveView` to the Canon EOS 5D Mark II. [CORE-363]
- Greatly improved file transfer performance from a number of Nikon cameras. [CORE-354]
### Bug Fixes
- CascableCore will no longer attempt to deliver shot preview callbacks for video or other non-image file types from Canon or Nikon cameras.
- Improved the accuracy of the `focused` and `active` properties of `id <CBLCameraLiveViewAFArea>` objects from Canon cameras.
- Fixed some missing autoexposure mode localized display values for certain Nikon cameras. [CORE-347]
### Camera Compatibility
- Added support for "focusless half-press" for the EOS M6 Mark II (i.e., photos can be taken without autofocus even if the camera is set to autofocus). [CORE-353]
### Bug Fixes
- Fixed an issue that would cause live view to get into an odd state on the Nikon D800 after taking a photo. [CORE-337]
### New Features
- Added full support for Canon's Fv mode, including a new common value for flexible priority autoexposure modes (`CBLPropertyCommonValueAutoExposureModeFlexiblePriority`). [CORE-341]
- Autoexposure results now report whether autoexposure is clipped (i.e., values are blinking) on Canon cameras. [CORE-342]
### Bug Fixes
- Fixed an issue that could cause "Automatic" shutter speed and aperture values to be represented incorrectly on some Canon cameras. [CORE-341]
- Fixed an issue that could cause incorrect autoexposure results on Canon EOS R5 and R6 cameras. [CORE-342]
- Added support for live view on older Nikon cameras, including the D800 and D810. [CORE-337]
- Fixed `CBLImageQualityTIFF` not being represented properly on some Nikon cameras. [CORE-337]
- Fixed the disconnection callback never being fired on USB-connected cameras on macOS Monterey. [CORE-345]
- Nikon cameras are no longer explicitly put into "Application Mode" when connected to via USB. [CORE-345]
### New Features
- Nikon cameras can now be operated with full remote control functionality over USB on iOS 15.0 and higher. [CORE-207]
- Added support for live view zoom (`CBLCameraSupportedFunctionalityZoomableLiveView`) on newer Nikon cameras, including the Z series. [CORE-50]
### Changes
- Added support for "focusless half-press" for the EOS M50 (i.e., photos can be taken without autofocus even if the camera is set to autofocus). [CORE-326]
### Bug Fixes
- Fixed a bug that could cause the EOS M5 and EOS M6 Mark II to not correctly start live view. [CORE-302, CORE-325]
- Fixed a bug where certain Canon cameras would be extremely slugglish to respond to events when connected via USB on iOS. [CORE-326]
### Bug Fixes
- Fixed an issue that could cause user authorisation for USB cameras on iOS 14+ to not be obtained correctly. [CORE-313]
- Fixed an issue that caused the exposure mode property to be incorrectly reported from Phase One cameras in some instances. [CORE-318]
This version of CascableCore contains a significant number of large breaking changes.
### New Property API
CascableCore's old API for dealing with camera settings has been replaced with a more modern one. The significant change here is that we are no longer trying to unify every single camera property under a single "universal" system, which was getting out of hand (just take a look at the old `CBLAutoExposureMode` enum!).
Instead, properties are presented as an opaque list of values, which have display values for presentation to the user. By and large, what these values represent are implementation details of the camera themselves, and should be presented to the user as-is — the display values should be recognisable to the user.
However, it is of course useful to either know what the camera is doing, or to target a particular camera setting. For this case, we have "common values" — values that are both common to most cameras, and useful to be able to target when getting and setting values. You can't get or set common values directly, but rather you can ask a property value "Do you match this common value?" or "Give me a value to set that matches this common value.".
For example, in example below, we print out the camera's current white balance:
```
id <CBLCameraProperty> whiteBalance = [camera propertyWithIdentifier:CBLPropertyIdentifierWhiteBalance];
NSLog(@"The camera's white balance is: %@", whiteBalance.currentValue.localizedDisplayValue);
```
However, since we don't know what particular strings the connected camera might report, we can't programatically tell what the white balance actually is. For this, we need to use the common value:
```
id <CBLCameraProperty> whiteBalance = [camera propertyWithIdentifier:CBLPropertyIdentifierWhiteBalance];
BOOL isTungsten = (whiteBalance.currentValue.commonValue == CBLPropertyCommonValueWhiteBalanceTungsten);
```
And additionally, we can set a particular white balance if the camera is able:
```
id <CBLCameraProperty> whiteBalance = [camera propertyWithIdentifier:CBLPropertyIdentifierWhiteBalance];
id <CBLPropertyValue> flashWhiteBalanceValue = [whiteBalance validValueMatchingCommonValue:CBLPropertyCommonValueWhiteBalanceFlash];
if (flashWhiteBalanceValue != nil) {
[whiteBalance setValue:flashWhiteBalanceValue completionQueue:dispatch_get_main_queue() completionHandler:^(NSError *error) {
NSLog(@"Set white balance value with error: %@", error);
}];
}
```
The main differences between the new API and old one are:
- The property system is always interacted with via objects representing that property, rather than directly with the camera.
- Property values are always `id <CBLPropertyValue>` objects, rather than `id`.
- Property values and valid settable values are opaque, and don't have constants defined for them (many enums have been removed).
- Common settings you're likely to want to query programmatically can be translated using "common values".
You can see the new `CBLCameraPropertyAPI.h` file to see the whole API and its documentation.
### Changed Live View API
Live view frames can now contain pixel data that isn't JPEG data. The API has been updated to reflect this, and the `rawImageData` property has been renamed to `rawPixelData` to make sure uses of this property are dealt with. You can use the new `rawPixelFormat` property to query the pixel format at a basic level, and `rawPixelFormatDescription` at a detailed level.
This change makes no difference to the `image` property if you're relying on CascableCore to parse live view frame images.
On supported cameras, live view can be cropped using `-setLiveViewCrop:completionCallback:` and `-resetLiveViewCrop:` if the camera supports the new `CBLCameraSupportedFunctionalityCroppableLiveView` functionality. Instead of calling the old zoom methods, live view can effectively zoomed in by cropping the image — the crop is applied on the camera side, before the image is transmitted, so the image delivered by the camera is the same size as before. This allows the implementation of pinch-to-zoom for live view.
### Manual Discovery API
In situations where automatic camera discovery over the network is not desirable or available, CascableCore now has a "manual discovery" API that lets your users say "Hey, there's a Canon camera at this IP address" and have you do something about it.
To use this API, first you need a camera descriptor. There are descriptors for specific IP addresses and for cameras at the suggested gateway (i.e., cameras that create their own WiFi networks):
```
CBLCameraDescriptor *gatewayNikon = [CBLCameraDescriptor descriptorForCameraFamilyAtSuggestedGateway:CBLCameraFamilyNikon];
CBLCameraDescriptor *ipCanon = [CBLCameraDescriptor descriptorForCameraFamily:CBLCameraFamilyCanon atIPAddress:@"10.0.1.123"];
```
Once you have a descriptor, you must attempt to resolve it into a camera. To do this, get the manual discovery object then use it to resolve the camera. It's a good idea to make sure that manually resolving the camera family you're interested in is possible, since not all cameras can be manually resolved:
```
id <CBLCameraManualDiscovery> manualDiscovery = [[CBLCameraDiscovery sharedInstance] manualDiscovery];
if (![manualDiscovery.supportedCameraFamilies containsObject:@(descriptor.cameraFamily)]) {
NSLog(@"Can't resolve this kind of camera!");
return;
}
[manualDiscovery attemptToDiscoverCamera:descriptor completionHandler:^(id <CBLCamera> camera, NSError *error) {
// Use the camera.
}];
```
It's important to note that in some cases, manual discovery can succeed even if the given descriptor doesn't point to a valid camera. This can happen if it's impossible to tell if a camera exists before actually connecting to it. In such circumstances, the camera object will fail to connect. This can take a little while if the underlying protocol has a long timeout.
Additionally, although the manual discovery object is fetched from `CBLCameraDiscovery`, it is *completely* separate from the automatic discovery provided by that class. You don't need to use automatic discovery at all, and a camera resolved using manual discovery will *not* be added to the automatic discovery's list of cameras (unless automatic discovery is running and the camera is separately discoverable).
Finally, manual discovery is much more error-prone than automatic discovery given that you could be trying to connect to a camera that doesn't exist, is already connected to by something else, etc. Make sure you have robust error handling around connection to and unexpected disconnection from cameras.
### Plugin API
CascableCore now allows camera support to be added by including separate framework binaries into the client application. These will then be discovered and initialised automatically at runtime by CascableCore with no intervention from the client app.
New APIs have been added to `CBLCameraDiscovery` to allow control over plugins. The `-loadedPluginIdentifiers` property allows clients to see which plugins are available, and `-enabledPluginIdentifiers` to see which ones are enabled (plugins are enabled by default). Plugins can be enabled or disabled with `-setEnabled:forPluginWithIdentifier:`. This allows you to, for instance, only have the fake camera enabled in the iOS Simulator.
For information on the plugin API itself, see the new `CBLCorePluginEntryPoint.h` file.
At this point, the only publicly available plugin is a "Fake Camera" plugin that allows you to work with CascableCore without having a physical camera connected. For information on this, see that project's page.
### Other API Changes
- Added the `-originalBackingImageUrl` property to `id <CBLCameraShotPreviewDelivery>`. In some circumstances, CascableCore will choose to store the source data for the shot preview on disk instead of in RAM to conserve resources. If this is the case, the value of this property will be non-nil and you can access the original image at the given location while the shot preview delivery object is active.
- Added `+[CBLNetworkConfigurationHelper ipv4AddressFromNetServiceData:]` for converting binary address data into an IP address.
- Due to the fact that additional cameras can be added by plugins, `CBLCameraFamily` is no longer an enum.
- Added `-requestProgress` to `id <CBLCameraShotPreviewDelivery>`, which can be used to observe shot preview progress for some cameras.
- Various APIs have been tidied up for use in Swift.
### Bug Fixes
- Canon cameras now correctly call the live view termination handler if live view is terminated by disconnecting from the camera.
### Known Issues
- Live view cropping and the "ready for capture" property are currently only supported by Phase One cameras. This functionality will come to other cameras soon.