cannot find protocol declaration for 'CAAnimationDelegate' - ios

My code was fine before, but it tips me :
cannot find protocol declaration for 'CAAnimationDelegate';did you mean 'UIApplicationDelegate'?
when I run it today.
I have tried import QuartzCore/CAAnimation.h but doesn't work.

CAAnimationDelegate is a new protocol that was added in the iOS 10 SDK. That means it is there if you build with Xcode 8, but not there if you build with Xcode 7.
When you build with Xcode 8, you'll get a warning to say:
Assigning to 'id<CAAnimationDelegate> _Nullable' from incompatible type 'WhateverUIViewController *const __strong'
If you add the CAAnimationDelegate, your code won't build in Xcode 7 anymore. If you need to build with both Xcode's, you need to use ifdefs:
#if __IPHONE_OS_VERSION_MAX_ALLOWED < 100000
// CAAnimationDelegate is not available before iOS 10 SDK
#interface WhateverUIViewController ()
#else
#interface WhateverUIViewController () <CAAnimationDelegate>
#endif

CAAnimationDelegate is not a protocol. There is no need to tell your class is going to implement the CAAnimationDelegate.
First you need to import QuartzCore/QuartzCore.h.Then, You just pass your class's (in which you want to implement the animation delegate methods) object as delegate to your CAAnimation object. It will automatically calls animationDidStart while starting the animation and calls animationDidStop method while finishing the animation.

Related

Cannot use all methods in Objective-C class in Swift

I am trying to make use of an Objective-C API in Swift. I can only seem to call the shareMyInstance() method from Swift, and not the initOpenApi() method for some reason. I'm not sure if there is some sort of scope identifier present in the interface, but I can't make use of initOpenApi, even though both are in the header. I also cannot see the method bodies, but I don't believe that affects the scope of the function.
This is locking me into using Objective-C, because for some reason I can access all of the functions from Objective-C, but only 3 of the 4 from Swift.
Header file (LCOpenSDK_Api.h):
#ifndef LCOpenSDK_LCOpenSDK_Api_h
#define LCOpenSDK_LCOpenSDK_Api_h
#import <Foundation/Foundation.h>
#interface LCOpenSDK_Api: NSObject
+ (LCOpenSDK_Api*) shareMyInstance;
- (id) initOpenApi:(NSString*)addr port:(NSInteger)port CA_PATH:(NSString*)caPath;
- (NSInteger)request:(void*)req resp:(void*)resp timeout:(NSInteger)timeout;
- (void)uninitOpenApi;
#end
#endif
My code (.swift):
import Foundation
#objc(LeChangePlayerView)
class LeChangePlayerView: UIView {
//...
#objc
override init(frame: CGRect) {
super.init(frame: frame)
var lc = LCOpenSDK_Api.shareMyInstance()!; //Fine
//Need this function!
lc.initOpenApi("openapi.easy4ip.com", 443, "") //Value of type 'LCOpenSDK_Api' has no member 'initOpenApi'
}
The only possible other explanation is that there is a different header file with the same name, but different interface, but this is highly unlikely because shareMyInstance, request and unitOpenApi are all available, and going to the definition from within the swift file using Xcode points to the same file. It is a dynamic framework, and as of right now, I can only view the headers, not the method implementations. I'm not sure if there's a solution to this, but this is another problem I could use help with. Could they have locked the original source code somehow, as well as made that specific method private?
Although initOpenApi is an instance method, Swift recognises it as an initialiser as it starts with the word init. Initialisers are translated from Objective-C into Swift-style initialisers.
In Objective-C you would say something like [[LCOpenSDK_Api alloc] initOpenAPI:#"openapi.easy4ip.com", port: 443, CA_PATH: #""]
In Swift the word init is stripped and there is no need to explicitly allocate a new instance:
let lc = LC_OpenSDK_Api(openApi:"openapi.easy4ip.com:, port: 443, CA_PATH:"")
However, you need to refer to the documentation from the framework to determine if you want to access the singleton instance LC_OpenSDK_Api.shareMyInstance or whether you want to create a specific instance as I showed above.

Disambiguate overriden method written in ObjC used in Swift

Complete code: https://github.com/minbi/ambiguous-swift
Is there a way to disambiguate use of an ObjC method from Swift 3?
I need to make the modification in ObjC so that the usage in Swift is as seamless as possible.
Objective C bridged to Swift
#interface A
+ (instancetype)singletonA;
#end
#interface B: A
+ (instancetype)singletonB;
#end
Usage in Swift 3.
I don't understand why this would be ambiguous. Doesn't the fact that I call the method from B "disambiguate the usage even a little?
var b: B! = B.singleton()
Error
Ambiguous use of 'singleton()'
Apparently this is a known bug. Swift does not handle overriding methods or properties well.
"Ambiguous use of 'propertyName'" error given overridden property with didSet observer

No visible #interface for UIPresentationController declares the selector initWithPresentingViewController:presentedViewController

I was watching WWDC 2014 video A Look Inside Presentation Controllers
I downloaded the source code (written in Objective-C) for the session, try to build it and I got this error:
No visible #interface for UIPresentationController declares the
selector initWithPresentingViewController:presentedViewController.
Is the method suppose to be in the UIPresentationController?
I found the answer from the documentation of UIPresentationController the method is supposed to be
- (instancetype)initWithPresentedViewController (UIViewController *)presentedViewController presentingViewController:(UIViewController*)presentingViewController; not -(instancetype)initWithPresentingViewController:(UIViewController *)presentingViewController presentedViewController:(UIViewController *)presentedViewController.
As soon as I changed that it fixed the problem
No visible #interface for 'GIDSignIn' declares the selector 'signInWithConfiguration:presentingViewController:callback:'
Google SDK is updated there for in v6.2.x version signInWithConfiguration:presentingViewController:callback: is using but in updated version v7.0.0 using signInWithPresentingViewController:completion: — check this blow link - and check what version you are using .
https://developers.google.com/identity/sign-in/ios/quick-migration-guide

Creating an app with deployment target of iOS 7.1 and optional iOS 8-only features

I'm creating an app that works with CloudKit framework (iOS 8-only) but still want to keep compatibility with iOS 7.1, with no CloudKit functionality, of course. Apple documentation recommends checking for optional classes like this:
if ([CKRecordID class]) {
// iOS 8 code
} else {
// iOS 7 code
}
This works. On the other hand, if I write
#interface Foo : NSObject
#property (nonatomic) CKRecordID *recordID;
#end
anywhere in the code, the app will crash on iOS 7 when loading the Foo class. How can I define properties with those optional classes?
You could use the forward declaration
#class CKRecordID;
but you will need runtime checks for the iOS version, such as
[[NSProcessInfo processInfo] operatingSystemVersion]
Other solutions for detecting the iOS version are shown here or here.
But how about two different builds for different iOS versions?
You can make your property recordId of type id or NSObject.
And when you need to access this property (after checking that your runtime is iOS8+), you cast it to CKRecordID class.

Objective-C compiler is leaving out a protocol definition

I'm writing a couple classes that make use of the Objective-C runtime library. This includes retrieving Protocol definitions at runtime based on their name. However, it appears that Protocols that are not explicitly adopted by a class or referenced in code using #protocol(ProtocolName) are excluded from compilation and not available at runtime.
Example:
#protocol MyProtocol <NSObject>
-(void)doSomething;
#end
//Somewhere else in code
Protocol *protocol = NSProtocolFromString(#"MyProtocol");
// ^ value of "protocol" will be nil when I run the application!
//However, if I use do the following:
Protocol *whyDoIHaveToDoThis = #protocol(MyProtocol);
Protocol *protocol = NSProtocolFromString(#"MyProtocol");
// ^ value of "protocol" will now be a pointer as expected when I run the application!
Does anyone know why this is, and even better, how to force the compiler to include Protocol definitions that are not in use at compile time, but which I will later want available at runtime?
You can force the compiler to include the protocol by making a dummy method that's not called that uses it. I've done this before:
void preserveProtocolFromBeingTrimmed()
{
(void)#protocol(BrightnessProtocol);
}
I see that Apple uses this in their FxBrightness plug-in from the FxPlug SDK.

Resources