Does AHEasing run in Swift? - ios

I'm trying to use AHEasing in my Swift project. I've installed it via cocoapods and included this line in my bridging header:
#import <AHEasing/CAKeyframeAnimation+AHEasing.h>
I am able to access the function in CAKeyframeAnimation+AHEasing.h just fine, but when I try
var alphaAnimation = CAKeyframeAnimation.animationWithKeyPath("alpha", function: QuadraticEaseInOut, fromValue: 1.0, toValue: 0.0)
I get the error
Cannot invoke 'animationWithKeyPath' with an argument list of type '(String, function: (Double) -> Double, fromValue: Double, toValue: Double)'
After a little digging, I confirmed that QuadraticEaseInOut is indeed being converted to a (Double) -> Double closure, while the type for that parameter, AHEasingFunction, is being converted into a CFunctionPointer<((Double) -> Double)>.
Is there a way to convert between these 2 types? Has anyone successfully used AHEasing in Swift? Is there another work around that I'm not seeing?

I've heard reports from some people that this is a Swift 1.2 issue, that is no longer a problem in Swift 2.
Either way, I just worked around the problem by implementing the functionality that I needed from AHEasing entirely in Swift.

Related

Accelerate framework - vDSP_zvmags - Swift 4.2

In Swift 4.0 Xcode 9.4.1 using the vDSP_zvmags function and passing an inout float array variable works however in Swift 4.2 Xcode 10.1 complains that one cannot pass an array parameter when a expecting a float type.
//Class variable
private var magnitudes: [Float]!
self.magnitudes = [Float](repeating: 0.0, count: self.halfSize)
vDSP_zvmags(&(self.complexBuffer!), 1, &self.magnitudes!, 1, UInt(self.halfSize))
Error message:
Cannot convert value of type '[Float]' to expected argument type 'Float'
&self.magnitudes! is underlined in red.
Can someone shed some light as to why it is acceptable in Swift 4.0 and not acceptable in Swift 4.2? The function does not appear to have changed between the 2 functions, I have checked in Apple's documentation and looked at the vDSP library doc.
If the class variable is initialized on declaration to empty float array the error disappears.

Xcode 10 Swift build error: "Converting non-escaping value to 'T' may allow it to escape"

I'm using the Swift-VectorBoolean library, which is currently on Swift 3.2, not yet updated for Swift 4.2, but should still work on Xcode 10. Running this on Xcode 9, it works fine. On Xcode 10, it gives an error that I'm not sure how to fix. This is the function in question:
typealias MyPathApplier = #convention(block) (UnsafePointer<CGPathElement>) -> Void
// Note: You must declare MyPathApplier as #convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.
private func myPathApply(_ path: CGPath!, block: MyPathApplier) {
let callback: #convention(c) (UnsafeMutableRawPointer, UnsafePointer<CGPathElement>) -> Void = { (info, element) in
let block = unsafeBitCast(info, to: MyPathApplier.self)
block(element)
}
path.apply(info: unsafeBitCast(block, to: UnsafeMutableRawPointer.self), function: unsafeBitCast(callback, to: CGPathApplierFunction.self))
}
The error is on that last line, path.apply, highlighting the first unsafeBitCast:
Converting non-escaping value to 'T' may allow it to escape
I'm not sure how to modify this code to remove the error, or if this is an issue with Xcode 10. It should be able to compile Xcode 3.2 code.. even updating the code base to Swift 4 in Xcode 9, it still has the same issue.
EDIT: Changing this with the answer from #Vyacheslav allows it to compile, but it gets a runtime error:
"Fatal error: Can't unsafeBitCast between types of different sizes"
There is a comment provided above the function which I didn't include in the sample above:
// Note: You must declare MyPathApplier as #convention(block), because
// if you don't, you get "fatal error: can't unsafeBitCast between
// types of different sizes" at runtime, on Mac OS X at least.
I still don't understand what needs to change here to ensure it builds, and we also don't get a runtime error.
Use
private func myPathApply(_ path: CGPath!,
block: #escaping #convention(block) (UnsafePointer<CGPathElement>) -> Void) {
}
#noescape is now by default

Cannot invoke initializer for type 'SCNMatrix4'

I'm working on ARKit and trying to initialize SCNMatrix but its throwing following error:
Code snippet:
if let frame = self.sceneView.session.currentFrame {
let mat = SCNMatrix4(frame.camera.transform)
return (dir, pos)
}
Error:
Cannot invoke initializer for type ‘SCNMatrix4’ with an argument list
of type ‘(matrix_float4x4)’ Overloads for ‘SCNMatrix4’ exist with
these partially matching parameter lists: (float4x4), (double4x4)
Does anyone face something similar kind of issue?
You're using an old Xcode beta. Swift bridging for SIMD matrix types changed in Xcode 9.0 beta 2. (As of this writing, beta 3 is current.)
With said changes, matrix_float_4x4 and float4x4 are the same type, so your code should work fine.

Cannot assign value of type '(UIImage?, PHAsset?)' to type UIImage? Swift 2.2

I updated to XCode 7.3 - swift 2.2 and I received a compile time error as mentioned in the title. It had no issues in swift 2.1. As per basics of swift, '?' variables can be compared to nil. I googled for possible solutions, but could not find the appropriate solution.
I think the problem was not in swift update but in ALCameraViewController update. Now it takes completion with two parameters
public typealias CameraViewCompletion = (UIImage?, PHAsset?) -> Void
So you need to change this
(image) -> Void in ...
to this
(image, asset) -> Void in ...
Actually now in your code Swift treats image as tuple of two values so also you can change all calls to image in your code with calls to image.0 that will address first closure parameter that is your UIImage?

How to have multiple definitions for a function in swift [duplicate]

I am starting to learn Swift, and have been following the very good Stanford University video lectures on YouTube. Here is a link if you are interested or it helps (although it isn't required to understand my problem):
Developing iOS 8 Apps with Swift - 2. More Xcode and Swift, MVC
While following the lectures I got to a point where (as far as I could tell) my code was identical to the code in the video but on my system I got a compiler error. After a lot of trial and error I have managed to reduce my code to two examples, one of which generates an error, the other or which doesn't, but I have no idea what is actually causing the error or how to resolve it.
The code which creates the error is:
import UIKit
class BugViewController: UIViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
This creates the following compiler error:
Method 'perform' with Objective-C selector 'perform: ' conflicts with previous declaration with the same Objective-C selector
By simply removing the sub-classing of UIViewController the code compiles:
import UIKit
class BugViewController
{
func perform(operation: (Double) -> Double) {
}
func perform(operation: (Double, Double) -> Double) {
}
}
Some other information which may or may not be relevant:
I have recently upgraded to Yosemite.
When I installed Xcode, I ended up with a Beta version (Version 6.3 (6D543q)) because (if I remember correctly) this was the version I needed to run on my version of OS X.
I am half hoping this is a bug in the compiler because otherwise this doesn't make any sense to me. Any help very gratefully received!
I myself am also taking the Standford course and I got stuck here for a long time too, but after some searching, I found something from here: Xcode release notes and it mentioned something below:
Swift 1.2 is strict about checking type-based overloading of #objc
methods and initializers, something not supported by Objective-C.
// Has the Objective-C selector "performOperation:".
func performOperation(op: NSOperation) { /* do something */ }
// Also has the selector "performOperation:".
func performOperation(fn: () -> Void) {
self.performOperation(NSBlockOperation(block: fn))
}
This code would work when invoked from Swift, but could easily crash
if invoked from Objective-C. To solve this problem, use a type that is
not supported by Objective-C to prevent the Swift compiler from
exposing the member to the Objective-C runtime:
If it makes sense, mark the member as private to disable inference of #objc.
Otherwise, use a dummy parameter with a default value, for
example: _ nonobjc: () = (). (19826275)
Overrides of methods exposed
to Objective-C in private subclasses are not inferred to be #objc,
causing the Swift compiler to crash. Explicitly add the #objc
attribute to any such overriding methods. (19935352)
Symbols from SDKs are not available when using Open Quickly in a
project or workspace that uses Swift. (20349540)
what i did was just adding "private" in front of the override method like this:
private func performOperation(operation: Double -> Double) {
if operandStack.count >= 1 {
displayValue = operation(operandStack.removeLast())
enter()
}
}
Objective-C does not support method overloading, you have to use a different method name. When you inherited UIViewController you inherited NSObject and made the class interopable to Obj-C. Swift on the other hand does support overloading, that's why it works when you remove the inheritance.
As it has already been answered, ObjC doesn't support method overloading (two methods with the same name) and In swift 2 under Xcode 7 there are two options to solve this kind of problems. One option is to rename the method using the attribute: #objc(newNameMethod:)
func methodOne(par1, par2) {...}
#objc(methodTwo:)
func methodOne(par1) {...}
another option to solve this problem in Xcode 7+ is by applying #nonobjc attribute to any method, subscript or initialiser
func methodOne() {...}
#nonobjc
func methodOne() {...}
The problem is UIViewController is an #objc class. When inheriting from UIViewController, BugViewController is also a #objc class.
This means it must conform to the rules of Objective-C selectors (the name of a method). The methods func perform(operation: (Double) -> Double) and func perform(operation: (Double, Double) -> Double) both have the same selector #selector(perform:). This is not allowed.
To resolve this, use different names: like func perform1(operation: (Double) -> Double) and func perform2(operation: (Double, Double) -> Double).
I think the best way to handle this is to give your perform() methods more descriptive names. What do these methods do? How do they change the state of the view controller? Look at the other UIViewController methods to get a feel for the style of method naming, or read Method Names Should Be Expressive and Unique Within a Class
From https://developer.apple.com/library/ios/releasenotes/DeveloperTools/RN-Xcode/Chapters/xc6_release_notes.html under "Xcode 6.3 Release Notes" -> "Swift Language Changes" you find
Swift now detects discrepancies between overloading and overriding in the Swift type system and the effective behavior seen via the Objective-C runtime.
I got the same error due to having having two methods with the same Obj-C signature:
static func prepareForUpSyncing(obj : NSManagedObject!) -> Bool
static func prepareForUpSyncing(objs : [NSManagedObject]!) -> Bool
I didn't want to mark one of them as #nonobjc due to possibility of unforseen consequences at runtime. (Someone can correct me if there is no possibility)
Resolved it by using Swift's external parameter name feature (I made external name same as local name) to the second method, which effectively changes the Obj-c method signature:
static func prepareForUpSyncing(objs objs : [NSManagedObject]!) -> Bool {

Resources