I'm developing Locked Camera Capture Extension.
I noticed UIViewController's view.frame size on extension is smaller than app's one. It seems extension's View.frame is same as safe-area's frame.
WWDC24 session Build a great Lock Screen camera capture experience doesn't mention this issue. It looks like bug for me or is it intended specification to avoid complexity for users ?
Post
Replies
Boosts
Views
Activity
I'm developing LockedCameraCapture extension.
My extension can capture photo, save to system photo library and load from system photo library. That's pretty nice extension.
I want to fix interface orientation to portrait for particular screen(capture screen). But I want some other screen to landscape orientation(photo viewing screen).
So, I'm using "supportedInterfaceOrientations" property and "setNeedsUpdateOfSupportedInterfaceOrientations" method for interface orientation flexibility.
This code implies the screen only supports portrait orientation.
override var supportedInterfaceOrientations: UIInterfaceOrientationMask {
.portrait
}
And I call this code to enable orientation setting.
// UIViewController # viewDidLoad
setNeedsUpdateOfSupportedInterfaceOrientations()
My App work as expected, but my CaptureExtension doesn't work.
My extension's capture screen can rotate Landscape and that's not intended behavior.
My App try to call via tel: scheme for USSD, it worked on iOS 15.3 and earlier but doesn't work on iOS 15.4 beta.
let number = "10*10#" // Doesn't work.
// let number = "1234" // This is Okay.
guard let url = URL(string: "tel:" + number),
UIApplication.shared.canOpenURL(url) else {
fatalError()
}
UIApplication.shared.open(url, options: [:]) { success in
print("success: \(success)") // This is true
}
canOpenUrl() returns true, which means now we can call open() method.
But nothing happens when we call open(url: options: completion:).
First, I code ATT authorization struct below which uses brand new Swift concurrency.
struct ATT {
private init() {}
static func permissionRequest() async -> Bool {
switch ATTrackingManager.trackingAuthorizationStatus {
case .notDetermined:
await ATTrackingManager.requestTrackingAuthorization()
return ATTrackingManager.trackingAuthorizationStatus == .authorized
case .restricted, .denied:
return false
case .authorized:
return true
@unknown default:
fatalError()
}
}
}
And Video authorization as well.
struct Video {
private init() {}
static func permissionRequest() async -> Bool {
switch AVCaptureDevice.authorizationStatus(for: .video) {
case .authorized:
return true
case .denied, .restricted:
return false
case .notDetermined:
await AVCaptureDevice.requestAccess(for: .video)
return AVCaptureDevice.authorizationStatus(for: .video) == .authorized
@unknown default:
fatalError()
}
}
}
Next, I request two permissions in serial, and works as I expected.
Remember uninstalling the app to reset those permissions status.
@IBAction func onClickButton(_ sender: Any?) {
Task {
_ = await ATT.permissionRequest() // okay
_ = await Video.permissionRequest() // okay
}
}
Lastly, I replace those order, and ATT alert is not showing this time.
That’s not what I expected.
Why ?
@IBAction func onClickButton(_ sender: Any?) {
Task {
_ = await Video.permissionRequest() // okay
_ = await ATT.permissionRequest() // not showing
}
}
And I noticed this would happen again when I called this from viewDidLoad()
override func viewDidLoad() {
super.viewDidLoad()
Task {
_ = await ATT.permissionRequest() // not showing
}
}
Seems like this behavior is since iOS 15 beta 3.
I wrote a minimum app to check "Add to Siri" feature. but I found that we can not removed a voice shortcut just in particular case.
Tap add to Siri button to add voice shortcut first time.
Now we can see iOS 15's new user interface to add shortcut to Siri. Just tap Done button.
The button says "Added to Siri". And I confirmed that we can execute my feature by my voice correctly. Then tap the button again.
Next, I want to remove shortcut, so tap remove button.
Then the button says "Add to Siri" which implies the shortcut has not registered to system any more. That's nice. Tap the button once again.
Lastly, I want to remove shortcut again, but unexpectedly nothing happened and modal screen remains to keep showing when we tap the remove button. Seems like bug?
in Code
I set INUIAddVoiceShortcutButtonDelegate to my Instance.
and it has two callback method.
func present(_ addVoiceShortcutViewController: INUIAddVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton)
func present(_ editVoiceShortcutViewController: INUIEditVoiceShortcutViewController, for addVoiceShortcutButton: INUIAddVoiceShortcutButton)
One is called when my shortcut is not registered to system yet. and another's called when it's registered already.
And my code set editVoiceShortcutViewController.delegate just latter one.
I think this is the reason why my button has NO-response. But I don't know how to prevent being called former callback.
Is this my own coding issue or Bug of iOS 15 beta 3 ?
The session says that "when someone taps Add to Siri, the shortcut is added instantly, using your suggested invocation phrase". (at 21 min in Video)
Now we can see that new UI at iOS 15 beta 2.
But on iPadOS 15 beta 2, it looks like unexpected behavior.
It looks like INUIEditVoiceShortcutViewController shows in UISplitViewController, but we expect that in UIViewController itself.
And when we tap "Back" button, INUIEditVoiceShortcutViewController shows on left side of window.
It's Okay when the window has narrow width. This is what i expected.
Is there any way to implement "Add to Siri" feature or is it an iPadOS bug ?
I call PHPhotoLibrary requestAuthorization which is iOS 14 new API, then choose "SelectPhotos" at permission alert, now I can see modal where we can select photos.
After choose some photos, We have three choices here, one is tap "done", tap "cancel" or flick modal to dismiss.
When we tap done, we get .limited status in authorizationStatus handler. that's okay.
When we tap cancel, we get .limited but we expect .notDetermined status.
When we flick to dismiss, we get nothing, but actual authorization status has changed to unexpected .authorized status.
Is this Apple's intent ?