iOS 13 brings in some handy extensions that I have quite a while now; I'd like to retain my code for iOS 11 and 12 and use built-in for iOS 13:
extension CIImage {
// if iOS 13 not available
open class var black: CIImage { return CIImage(color: .black) }
}
Related
I am experiencing issues with VNDetectBarcodesRequest on iOS 16. My code works as intended on iOS 15 but on iOS 16 it doesn't find any bar codes in an image.
I've separated my code to a playground and am experiencing the same issue here. Running the code below on Xcode 13.4.1's playground, I get the result:
"Google link: Optional("https://www.google.com")"
Running the same code on Xcode 14, I get an nil result. Running this in an iOS15 simulator with Xcode 14 gives a positive result, only on iOS16 and playground it is not reading the QR code.
To add to it, no exceptions are thrown either.
Has anybody experienced the same and managed to fix this?
This is my playground code:
import UIKit
import Vision
extension UIImage {
func qrCodeLink(completion: #escaping (String?) -> Void) {
guard let ciImage = CIImage(image: self) else {
completion(nil)
return
}
let imageRequestHandler = VNImageRequestHandler(ciImage: ciImage,
orientation: .up,
options: [:])
let request = VNDetectBarcodesRequest { (request,error) in
guard error == nil else {
completion(nil)
return
}
guard let observations = request.results as? [VNDetectedObjectObservation] else {
completion(nil)
return
}
let result = (observations.first as? VNBarcodeObservation)?.payloadStringValue
completion(result)
}
try? imageRequestHandler.perform([request])
}
}
if let google = UIImage(named: "google") {
google.qrCodeLink { link in
debugPrint("Google link: \(link)")
}
} else {
debugPrint("No google image")
}
With the above code I am using this image, which is merely a link to https://www.google.com:
Elaborating on #Paul Peelen's solution, to ensure that the workaround is only used where needed (Xcode 14 + iOS 16 + Simulator), we used:
#if targetEnvironment(simulator) && compiler(>=5.7)
if #available(iOS 16, *) {
request.revision = VNDetectBarcodesRequestRevision1
}
#endif
I think I've found the issue.
When running the request on Xcode 14 and iOS 16, the request revision runs on VNDetectBarcodesRequestRevision3 (which issn't documented yet on VNDetectBarcodesRequest page). However, using VNDetectBarcodesRequestRevision1 or VNDetectBarcodesRequestRevision2 works.
Adding the following before the perform task worked for me:
request.revision = VNDetectBarcodesRequestRevision1
When compiling for either iOS 15 or 16, I found a difference in VNDetectedBarcodesRequest behavior when scanning a barcode WITH, or a barcode WITHOUT, a border. That border seems to trigger the scanning code when to start.
WITH a border: it scans both black-background image and white-background image correctly.
WITHOUT a border: it scans the barcode image on the monitor with a black background correctly, but it fails when that image is printed on white paper and scanned. No border = no barcode.
NEW ISSUE: it returned an array of 17 identical barcode observations when it scanned that single bordered barcode.
I have a shared framework that runs in both iOS and MacOS, and I've run into a situation where in MacOS Catalina I need to make an extra check. I thought that by using the swift #available this would work:
if #available(OSX 10.15, *){
/// My Catalina Code
}
The truth is that this code passes in iOS. Would this be a bug, or is it not expected to be used this way ?
If you look through Apple documentation it should be like that.
if #available(macOS 10.15, *){
/// My Catalina Code
}
it should look like this:
if #available(macCatalyst 10.15, *) {
// use 10.15
} else {
}
if your using Catalyst.
other than that there is nothing that shows why your code snippet doesn't work.
You may need to use conditional compiling together with #available:
#if os(macOS)
if #available(macOS 15.0, *) {
//...
}
#endif
Or an ugly workaround:
if #available(macOS 15.0, iOS 9999.99, *) {
//...
}
Unable to add more than three UILabels to a UIViewController’s view in the IPad Playgrounds app. Is it me or the system?
Simplified code to show the issue. Hardware is a 2018 iPad Pro running iOS 12.3.1 Playgrounds app 3.0. Using UIViews up to five can be added successfully.
import UIKit
import PlaygroundSupport
class MyViewController : UIViewController {
let square50 = CGSize(width: 50, height: 50)
override func viewDidLoad() {
var myFrame = CGRect(origin: .zero, size: square50)
for index in 0...4 {
view.addSubview(UIView(frame: myFrame)) // fails at 6th!
(view.subviews[index] as! UIView).backgroundColor = .red
myFrame.origin.y += 80
}
}
}
PlaygroundPage.current.liveView = MyViewController()
With the index range set as shown the code worked as expected, displaying the set number of coloured rectangles. With the range increased to 0...5 the runtime stopped with the message “There was a problem encountered while running this playground. Check your code for mistakes”.
Just been able to test the code on Xcode 10.3 under OS X 10.16.6 on my iMac Retina 5k 27" late 2015. There is NO problem with the code and there is no short-range limit on the number of sub-views that can be created.
The problem rests with iOS Swift Playgrounds 3.0 running on an iPad Pro 12.9 inch 3rd-gen using iOS 12.3.1. This is therefore a bug!
My code is to display image.jpg in a window. That was written in Swift 3. Recently, I updated to Swift 4 with Xcode 10.2 . It doesn't work at all. I also rewrote it in Swift 5. It still doesn't work. I had to download the old Xcode 10 in order to run my code in Swift 3 to work again. I wonder what happened to the code.
Here is my main code to display the picture.
override func viewDidAppear() {
super.viewDidAppear()
imageView.image = NSImage(byReferencingFile: "\(ViewController.GlobaVariable.selecFile)" )
print("\(ViewController.GlobaVariable.selecFile)")
/// The print statement work but not the image.
}
let openPanel = NSOpenPanel()
openPanel.beginSheetModal(for:self.view.window!) { (response) in
if response.rawValue == NSFileHandlingPanelOKButton
{
let fileURL = openPanel.url!
//////////////////
let ph = fileURL.absoluteString
let path = (ph as NSString).substring(from: 7)
//print(path)
//////////////////////
GlobaVariable.selecFile = path
}
}
I saw in the WWDC video that there's some new swift function to detect iOS 11 availability.
How do I detect iOS11 with Swift?
Swift 3:
if #available(iOS 11.0, *) {
// Running iOS 11 OR NEWER
} else {
// Earlier version of iOS
}
More information is available in Declaration Attributes section of Apple's Swift Programming Guide.
Objective C:
if (#available(iOS 11, *)) {
// Running iOS 11 OR NEWER
} else {
// Earlier version of iOS
}