iCarousel in swift version 1.2 error (candidate is not Objc but protocol requires it) - objective-c

I get the following error in swift 1.2 : 'RootViewController' does not conform to protocol 'iCarouselDataSource'
In the below class, when I tryed to implement the third party library iCarousel:
class RootViewController: UIViewController,iCarouselDataSource,iCarouselDelegate
{...}
The auto-fix tool puts an #objc mark in this method that conform the protocol:
#objc func carousel(carousel: iCarousel!, viewForItemAtIndex index: Int, var reusingView view: UIView?) -> UIView?
{}
But then another error appears : Method cannot be marked #objc because the type of the parameter 3 cannot be represented in Objective-C
I appreciate any help or clue, thanks !

Remove var from reusingView, ex:
func carousel(carousel: iCarousel!, viewForItemAtIndex index: Int, reusingView view: UIView!) -> UIView! {
var newView = view
if newView == nil {
//create new view
}
//update data
return newView
}

Related

Unable to cast element in ForEach Loop to NSManagedObject Subclass SwiftUI

I got a ListView in SwiftUI and want to generate RowViews depending on a given property.
Therefore I want to check the property of the element in the ForEach loop.
Xcode does not recognize the type of the element, thats why i want to cast the element to the correct Class which is an NSManagedObject Subclass.
I created the NSManagedObject Subclass from the xcdatamodeld (Editor -> Create NSManagedObject Subclass...).
The NSManagedObject Subclass is created in objective-c and I added the .h file to the bridging header.
I have no problem working with the NSManagedObject Subclass in the rest of the project.
I can even create an property of that Type in the same Struct like so:
struct MyListView: View {
var test : MyNSManagedObjectSubclass //Xcode does recognize it here
For some reason Xcode wont recognize the NSManagedObject Subclass inside the ForEach Loop.
code looks like:
struct MyListView: View {
var test : MyNSManagedObjectSubclass //Xcode does recognize it here
#EnvironmentObject private var fetchResultsContainer : FetchedResultsContainer
var body: some View {
NavigationView{
VStack{
ForEach(fetchResultsContainer.results , id: \.identifier) { result in
if let castedResult = result as! MyNSManagedObjectSubclass { //Xcode does not recognize it here
if castedResult.property{
ResultRowView(input: result)
}
}
}
}
}
}
}
FetchedResultsContainer:
#objc class FetchedResultsContainer : NSObject, ObservableObject{
#objc #Published var results: [MyNSManagedObjectSubclass]()
#objc static let sharedInstance: FetchedResultsContainer = {
let instance = FetchedResultsContainer()
return instance
}()
}
I feel like im missing something obvious, as im still quite new to Swift and SwiftUI.
Appreciate your help.
Ok after taking a step back and simply coding it again from scratch it simply worked an no casting was needed...
List(fetchResultsContainer.results, id: \.identifier) { result in
if (result.property == 0) {
//do something
}
}
My assumption that the casting was not working was not correct.
I probably checked result.property == false, with property being of type NSNumber and it gave out some strange compile errors that led me on the wrong path.

Conforming to a Obj-C protocol in Swift [duplicate]

Ok here is the big problem. I had a library written in ObjC(this). There we had a defined protocol. When I tried to use it in swift file I get constantly:
Type "XXX" does not conform to protocol "XXX"
To simplify things I made up a test project - it should be created as Swift project.
Then create ObjC header file(I called it StupidProtocol.h) with following protocol inside(please note each name and value to exactly match the given including uppercase/lowercase):
#protocol MyProtocol <NSObject>
- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;
#end
In bridging header:
#import "StupidProtocol.h"
And then back in Swift file:
class ViewController: UIViewController, MyProtocol
{
func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
return ""
}
}
And baam we got this error again even though auto-complete finishes the getAxisLabel function for me.
I strongly suspect that the problem is with argument "value" and it's function parameter "Value".
Any help will be highly appreciated.
EDIT
Please note that this library is not technically mine, so I cannot change it. I need a way to use it in Swift without changing it's original declaration. My example is only to simplify my problem.
WHAT I TRIED
I have tried following scenarios with no success:
'has different arguments name from those required by protocol' error
func getAxisLabel(axis: AnyObject!, Value value: CGFloat) -> String! {
return ""
}
'has different arguments name from those required by protocol' error
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! {
return ""
}
'type does not conform to protocol'
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> NSString! {
return ""
}
SOLUTION
See accepted answer
I don't know if this is a bug or not. The Objective-C protocol method
- (NSString *)getAxisLabel:(id)axis Value:(CGFloat)value;
(with uppercase "V" in Value:) is mapped to Swift as
func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String!
(with lowercase "v" in value:), but none of
func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! { }
func getAxisLabel(axis: AnyObject!, Value: CGFloat) -> String! { }
is accepted by the compiler to satisfy the protocol requirement.
As a workaround, you can annotate the method with an explicit
Objective-C selector name:
class ViewController: UIViewController, MyProtocol
{
#objc(getAxisLabel:Value:)
func getAxisLabel(axis: AnyObject!, value: CGFloat) -> String! {
return ""
}
}

Swift 2.1: Property cannot be marked dynamic?

How do I fix this compilation error?
dynamic var users = [User]()
Property cannot be marked dynamic because its type cannot be represented in Objective-C
I need dynamic so that certain view controllers can observe (via KVO) users and update their views when users changes.
Just as the error mentions
error, not #objc : NSObject:
class A{
}
func something(){
dynamic var a = [A]()
}
should be changed to:
#objc class A:NSObject{
}
func something(){
dynamic var a = [A]() //works, all good
}

How do you define/declare a swift method for an objc protocol that has a reference return type?

I created an objc protocol:
#protocol CGEventTapHandler
- (CGEventRef)onCGEvent:(CGEventTapProxy)proxy type:(CGEventType)type event:(CGEventRef)event;
#end
Then in my swift class I get the signature:
func onCGEvent(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent!) -> Unmanaged<CGEvent>!
Now it gets confusing. I get a number of errors.
First error is:
...: Protocol requires function 'onCGEvent(_:type:event:)' with type '(CGEventTapProxy, type: CGEventType, event: CGEvent!) -> Unmanaged<CGEvent>!'
...: Candidate is not '#objc', but protocol requires it
So I add '#objc' to the signature then I get:
...: Method cannot be marked #objc because its result type cannot be represented in Objective-C
Edited per request:
class ViewController: NSViewController, CGEventTapHandler {
func onCGEvent(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent!) -> Unmanaged<CGEvent>! {
}
}
Not absolutely certain where your error lies, so here is a tutorial that works.
Start with a fresh, new, Swift project targeted to OS X.
Create an Objective-C Protocol
File name: CGEventTapHandler.h. When prompted to create the Bridging-Header, approve.
#import <CoreGraphics/CoreGraphics.h>
#protocol CGEventTapHandler
- (CGEventRef)onCGEvent:(CGEventTapProxy)proxy type:(CGEventType)type event:(CGEventRef)event;
#end
Register Protocol
File name: ...-Bridging-Header
#import "CGEventTapHandler.h"
Adopt Protocol
In you client class, adopt CGEventTapHandler:
import Cocoa
class ViewController: NSViewController, CGEventTapHandler {
func onCGEvent(proxy: CGEventTapProxy, type: CGEventType, event: CGEvent!) -> Unmanaged<CGEvent>! {
return nil
}
}
Compiled, linked, built and ran. No warnings, no errors.

Unable to set the delegate to class in Swift

This is their example function
[GTMagBarDevice sharedDevice].delegate = self;
I tried rewriting it in swift like this
GTMagBarDevice.sharedDevice().delegate = self;
But I am receiving an error "type view controller does not conform to protocol GTMagBarDeviceDelegate"
Any ideas?
Update
I have implemented all the required functions, this is what it says in the .h file i am bridging
#protocol GTMagBarDeviceDelegate <NSObject>
#required
- (void)magbarDevice:(GTMagBarDevice*)device accessoryConnected:(BOOL)state;
- (void)magbarDevice:(GTMagBarDevice*)device componentFailed:(int)components;
And this is the implantation
func magbarDevice(magbarDevice: GTMagBarDevice, accessoryConnected isAccessoryConnected: Bool) {
}
func magbarDevice(magbarDevice: GTMagBarDevice, componentFailed components: Int) {
}
You need to implement the methods that the protocol you are conforming to requires.
It looks like your function signatures are incorrect. Try these instead:
func magbarDevice(device: GTMagBarDevice!, accessoryConnected state: Bool) {
}
func magbarDevice(device: GTMagBarDevice!, componentFailed components: Int32) {
}