Problems with Zbar (ZbarSymbolSet) and Xcode8 - ios10

I'm having difficulty with the use of ZBar library as soon as I opened the project in Swift 2.2 with Xcode 8. I've always used a bridge to run this library but on xcode I immediately a red extension of ZbarSymbolSet.
Use of undeclared type 'ZbarSymbolSet'
//Extension for Zbar
extension ZBarSymbolSet: SequenceType {
public func generate() -> NSFastGenerator {
return NSFastGenerator(self)
}
}

for Swift 3:
extension ZBarSymbolSet: Sequence {
public func makeIterator() -> NSFastEnumerationIterator {
return NSFastEnumerationIterator(self)
}
}
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
// ADD: get the decode results
let results: NSFastEnumeration = info[ZBarReaderControllerResults] as! NSFastEnumeration
var symbolFound : ZBarSymbol?
for symbol in results as! ZBarSymbolSet {
symbolFound = symbol as? ZBarSymbol
break
}
let resultString = symbolFound!.data
print(resultString)
}

Related

SWIFTUI warning imagePickerController nearly matches - happens only in existing swift project file

I'm upgrading an existing app with some swift views. Now I'm getting the warning:
Instance method 'imagePickerController(:didFinishPickingMediaWithInfo:)' nearly matches optional requirement 'imagePickerController(:didFinishPickingMediaWithInfo:)' of protocol 'UIImagePickerControllerDelegate'
at the function:
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let image = info[.originalImage] as? UIImage {
self.onImagePicked(image)
}
self.onDismiss()
}
Additionally I get the error message:
Cannot infer contextual base in reference to member 'originalImage'
The funny thing is, if I copy the code in a new project everything is fine (no warning, no error). In order to check whether I may have some effects from other views/methods within the existing project, I copied my existing project and deleted all other files, except the one with the imagepicker - still the warning and the error.
Is there any setup or other issue which might be the reason? Any help is more than appreciated - working on that the third day now ....
The whole code is:
import SwiftUI
public struct ImagePickerView: UIViewControllerRepresentable {
private let sourceType: UIImagePickerController.SourceType
private let onImagePicked: (UIImage) -> Void
#Environment(\.presentationMode) private var presentationMode
public init(sourceType: UIImagePickerController.SourceType, onImagePicked: #escaping (UIImage) -> Void) {
self.sourceType = sourceType
self.onImagePicked = onImagePicked
}
public func makeUIViewController(context: Context) -> UIImagePickerController {
let picker = UIImagePickerController()
picker.sourceType = self.sourceType
picker.delegate = context.coordinator
return picker
}
public func updateUIViewController(_ uiViewController: UIImagePickerController, context: Context) {}
public func makeCoordinator() -> Coordinator {
Coordinator(
onDismiss: { self.presentationMode.wrappedValue.dismiss() },
onImagePicked: self.onImagePicked
)
}
public class Coordinator: NSObject, UINavigationControllerDelegate, UIImagePickerControllerDelegate {
private let onDismiss: () -> Void
private let onImagePicked: (UIImage) -> Void
init(onDismiss: #escaping () -> Void, onImagePicked: #escaping (UIImage) -> Void) {
self.onDismiss = onDismiss
self.onImagePicked = onImagePicked
}
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
if let image = info[.originalImage] as? UIImage {
self.onImagePicked(image)
}
print("vor dismiss")
self.onDismiss()
}
public func imagePickerControllerDidCancel(_: UIImagePickerController) {
self.onDismiss()
}
}
}
The project Format is Xcode 12.0-compatible, iOS Deployment Target is 14.0,
The project includes originally also watch
Got the answer, can't explain but instead of
public func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey: Any]) {
it works fine with
func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : Any]) {
The problem is solved, however, if anyone could explain - more than welcome

imagePickerController didFinishPickingMediaWithInfo not being called

I am trying for the first time to use an external library, WDImagePicker. Below is the WDImagePicker code relevant to my problem.
#objc public protocol WDImagePickerDelegate {
#objc optional func imagePicker(imagePicker: WDImagePicker, pickedImage: UIImage)
#objc optional func imagePickerDidCancel(imagePicker: WDImagePicker)
}
#objc public class WDImagePicker: NSObject, UIImagePickerControllerDelegate, UINavigationControllerDelegate, WDImageCropControllerDelegate {
public var delegate: WDImagePickerDelegate?
private var _imagePickerController: UIImagePickerController!
public var imagePickerController: UIImagePickerController {
return _imagePickerController
}
override public init() {
super.init()
self.cropSize = CGSize(width: 320, height: 320)
_imagePickerController = UIImagePickerController()
_imagePickerController.delegate = self
_imagePickerController.sourceType = .photoLibrary
}
public func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject]) {
print("this line never runs\n\n")
}
}
In the controller I wrote myself, I have this method, which presents cropImagePicker's imagePickerContoller; however even though the delegate of this controller is cropImagePicker, cropImagePicker's ImagePickerControllerDelegate methods never get called (I tested all of them).
#IBAction func cameraButtonPressed() {
let cropImagePicker = WDImagePicker()
cropImagePicker.cropSize = CGSize(width: 50, height: 50)
cropImagePicker.delegate = self
cropImagePicker.resizableCropArea = false
cropImagePicker.imagePickerController.delegate = cropImagePicker
self.present(cropImagePicker.imagePickerController, animated: true, completion: nil)
}
Why is this happening? Could it be because of the swift 3 changes I had to make to the library? And most importantly, how can I get around this? All input is appreciated.

Swift 2.0: Protocol Extension Class Method returning Self

In order to extend some functionalities of my NSManagedObject subclasses, I have defined a series of protocols:
protocol ManagedObjectFindable {
static func find(format:String, arguments: [AnyObject]?, inContext context:NSManagedObjectContext, entityName:String?) -> Self?
}
protocol UniquelyIdentifiable: ManagedObjectFindable {
var identifier: NSNumber? { get }
static func findWithIdentifier(identifier: Int, inContext context:NSManagedObjectContext) -> Self?
}
So then every NSManagedObject that has identifier in its data model entity can conform to UniquelyIdentifiable.
For that purpose I am utilising Swift 2.0 Protocol Extensions, where:
extension UniquelyIdentifiable {
static func findWithIdentifier(identifier: Int, inContext context:NSManagedObjectContext) -> Self? {
return self.find("identifier == %lld", arguments: [NSNumber(longLong: Int64(identifier))], inContext: context, entityName:nil)
}
}
Where find is defined as:
extension NSManagedObject: ManagedObjectFindable {
/** returns single entity if found, nil otherwise */
class func find(format:String, arguments: [AnyObject]?, inContext context:NSManagedObjectContext, entityName:String? = nil) -> Self? {
let objectEntityName:String
if let name = entityName {
objectEntityName = name
} else {
objectEntityName = String(self)
}
let fetchRequest = NSFetchRequest()
fetchRequest.entity = NSEntityDescription.entityForName(objectEntityName, inManagedObjectContext: context)
fetchRequest.fetchLimit = 1
fetchRequest.predicate = NSPredicate(format: format, argumentArray: arguments)
var persistentEntityº:NSManagedObject?
context.performBlockAndWait {
do {
let fetchResults = try context.executeFetchRequest(fetchRequest)
if (fetchResults.count != 0){
persistentEntityº = fetchResults.first as? NSManagedObject
}
} catch {}
}
if let persistentEntity = persistentEntityº {
return _safeObjectSelfCast(persistentEntity)
} else {
return nil
}
}
}
func _unsafeObjectSelfCast<T>(obj: AnyObject!) -> T { return obj as! T }
func _safeObjectSelfCast<T>(obj: AnyObject) -> T? { return obj as? T }
Now these methods correctly return Self? and compiler is silent on the coding time, however when compiling it gives me that error Method 'findWithIdentifier(_:inContext:)' in non-final class must return 'Self' to conform to protocol 'UniquelyIdentifiable'
Now the thing is that if instead of implementing that method in a protocol extension I would just extend my NSManagedObject subclass, it will go fine, but that kills the purpose of protocol extensions, when you are completely duplicating the same code across dozens of your NSManagedObject subclasses.
Any workaround, or I am really missing something?
Short answer:
Change Self? in extension to the NSManagedObject?.
Long answer: Self in protocol requirement acts as a placeholder for the class that will implement that protocol. So if you have
protocol SomeProtocol {
func returnSomething() -> Self
}
That means that if you implement it on Int, function returnSomething() should return Int, and if you implement it on Double it should return Double.
Since you are implementing UniquelyIdentifiable on NSManagedObject and your protocol has Self? requirement, you should return NSManagedObject?.

PFObject subclass gets "Cannot convert value of type 'Match' to expected argument type '#noescape (AnyObject) throws -> Bool'" error

I'm getting the following error when calling indexOf on an array of a subclass of PFObject.
Cannot convert value of type 'Match' to expected argument type
'#noescape (AnyObject) throws -> Bool'
my class:
class Match: PFObject, PFSubclassing {XXXX}
The method where the error is happening:
func imagePickerController(picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [String : AnyObject])
{
//dismiss the image picker
self.dismissViewControllerAnimated(true) { () -> Void in
//wait for the dismissal in case there is an error to show
let recordedVideofileURL = info[UIImagePickerControllerMediaURL] as? NSURL
if let recordedVideofileURL = recordedVideofileURL
{
//upload the file to S3
do
{
let uploadRequest = try S3UploadManager.uploadFile(self.match!.localPathToVideo()!)
self.match!.saveEventually({ (success: Bool, error: NSError?) -> Void in
if (success)
{
// The object has been saved.
self.matchesController.loadObjects()
//set up progress tracking for the upload
uploadRequest.uploadProgress = {[weak self](bytesSent:Int64, totalBytesSent:Int64, totalBytesExpectedToSend:Int64) -> Void in
if let match = self?.match
{
>>>>>>error here var index = self?.matchesController.objects?.indexOf(match)
}
}
}
})
}
catch
{
// TODO: handle error
}
}
}
}
From what i read only, this error happens when the object contained in the array does not conform to the Equatable extension. But PFObject inherits from NSObject which conform to that extension. So I'm at a loss...
Any pointers appreciated
Found the solution. It turns out that the objects method on the PFQueryTableViewController returns [AnyObject], so I need to cast it to [Match]
let objects = self?.matchesController.objects as! [PFObject]
and then it works...
I'm still new at swift and Parse, but this seem wrong for objects method to return [AnyObject]? especially given the comment in the doc
/*!
#abstract The array of instances of <PFObject> that is used as a data source.
*/
public var objects: [AnyObject]? { get }

Get a unique String for a given AnyObject?

In Objective-C, this was as simple as:
[NSString stringWithFormat:#"%p", objRef]
How can I do this in Swift?
func hashString (obj: AnyObject) -> String {
return String(ObjectIdentifier(obj).uintValue)
}
let id = hashString(obj)
Swift 3.0
return String(UInt(ObjectIdentifier(obj))
Swift 4.1
return String(UInt(bitPattern: ObjectIdentifier(obj)))
How about a direct translation:
func pointerToString(objRef: NSObject) -> String {
return NSString(format: "%p", objRef)
}
A more native way (in decimal, not hex):
func pointerToString(objRef: AnyObject) -> String {
return withObjectAtPlusZero(objRef, { ptr in
"\(UnsafePointer<RawByte>(ptr) - nil)"
})
}
func pointerToString(objRef: AnyObject) -> String {
let ptr: COpaquePointer =
Unmanaged<AnyObject>.passUnretained(objRef).toOpaque()
return "\(UnsafePointer<RawByte>(ptr) - nil)"
}
Update: Pointers stringify correctly now, so you can just do
func pointerToString(objRef: AnyObject) -> String {
let ptr: COpaquePointer =
Unmanaged<AnyObject>.passUnretained(objRef).toOpaque()
return "\(ptr)"
}
Swift 4.1
String(UInt(bitPattern: ObjectIdentifier(obj)))
#aleclarson's answer update
func hashString(obj: AnyObject) -> String {
return String(UInt(bitPattern: ObjectIdentifier(obj)))
}
let id = hashString(obj)
what you could do to resolve the error is pretty much this:
func pointerToString<T> (ptr: CMutablePointer<T>) -> String {
// ...
}
but printing the actual pointer is not really possible in Swift.
You can't. A native String in Swift is an object with a different and opaque memory layout than the contents of whatever memory is located at the CMutablePointer address. So you can't assign one to another. An alternative is to assign/copy an NSString that has been initialized with the contents of the memory at the pointer address.