swift 2.0 compile error in generated swift.h file about SecCertificateRef - swift

in our swift code somewhere there is a class with a method with this signature:
static var getCertificates : [SecCertificate] { ... }
in the generated app-swift.h this results in:
#interface TrustedCertificates : NSObject
+ (NSArray<SecCertificateRef> * __nonnull)getCertificates;
#end
and this gives the compile error:
Type argument 'SecCertificateRef' (aka 'struct __SecCertificate *') is neither an Objective-C object nor a block type
I've tried adding #import before where the .h file is included, but it doesn't solve the error.
I've also tried adding the import to the pch.h file but this also doesn't help.
Since the swift file is generated I can not start editing it there since it will be overwritten anyway.
Any idea what is missing to get it to compile?

Related

Objective-C interface Named "Category" cannot be imported into swift via the bridging header

The below swift code throws this error ('Category' is ambiguous for type lookup in this context)
// ctx is the UIContext, fetchCategories is an Obj-C function that queries CoreData
//for the Categories, the cast shouldn't even be necessary but swift will not
//recognize my obj-c interface
if let cats = self.fetchCategories(ctx) {
let array = cats as! [Category] //error happens on this line
return array
}
This is the implementation in my bridging header,
there are many other imports but I removed them for this post, so note that it is a fully functional bridging header for almost 40 other .h files
#ifndef AppDataRoom_Bridging_Header_h
#define AppDataRoom_Bridging_Header_h
#import "Category.h"
#endif /* AppDataRoom_Bridging_Header_h */
Below is the interface implementation
#interface Category : _Category <QLPreviewItem> {
UIImage *squareThumb;
}
I realize that changing the name of the Category class would be the best option since this is probably due to the naming convention being common, However when I change the code to this :
if let cats = self.fetchCategories(ctx) {
let array = cats as! [<ModuleName>.Category] //error happens on this line
return array
}
Is still says it is too ambiguous to lookup. Any ideas on other things I could try besides changing the interface name, because that really isn't an option and I will spare you all the reasons why.

Swift is using the wrong subscript overload. How can I get it to use the right one?

I'm writing UI testing code using XCTest. Here is my test method:
func testLandingUI() {
let app = XCUIApplication()
let headerExpectedMessage = "Title"
let headerLabel = app.staticTexts[headerExpectedMessage]
XCTAssert(headerLabel.exists)
}
I'm getting this error:
ExampleUITests.swift:38:19: error: value of type 'Any?' has no member 'exists'
XCTAssert(headerLabel.exists)
^~~~~~~~~~~ ~~~~~~
What's strange about this error is that I expected headerLabel to be of type XCUIElement, not Any?.
XCUIApplication.staticTexts is an XCUIElementQuery, which has a subscript method declared thusly:
open class XCUIElementQuery : NSObject, XCUIElementTypeQueryProvider {
...
open subscript(key: String) -> XCUIElement { get }
...
}
What I believe is happening is the subscript method in XCUIElementQuery is not being selected by Swift's overload resolution. Instead, it's selecting this category on NSObject:
#interface NSObject (MyCategory)
- (id)objectForKeyedSubscript:(NSString*)key;
- (void)setObject:(id)obj forKeyedSubscript:(NSString*)key;
#end
I verified that if I remove that category from my project, the error goes away. Assume that removing that category is not possible (because it's not). Is there any way to get Swift to use the correct subscript method?
Minimal test case that shows the problem: https://www.dropbox.com/s/f0fm5ennco7t2ua/SubscriptCategoryTest.zip?dl=1
(note that the error is in the UI tests, so press command-shift-U to see the error)
EDIT: It looks like the problem only shows up if the category defines setObject:forKeyedSubscript:. Interestingly, I get a slightly different error if both getter and setter are defined vs. just the setter.
Since the compiler is confused, you need to help it....
Given this example:
let example1: Any? = "1"
let example2: Any = "2"
You have two issues (it looks like you have an optional...)
if example1.exists { // won't work - I got your error message
}
if (example2 as AnyObject).exists { // works with a cast
}
I believe if you correct identify the type of the variable it will solve your problem. It is matching the NSObject category only because it didn't match something more specific.

"Ambiguous use of 'children'" when trying to use NSTreeController.arrangedObjects in Swift 3.0

I get an Ambiguous use of 'children' error in XCode 8.0/Swift 3.0 when trying to send a message to the opaque NSTreeController.arrangedObjects object.
Here is a bare playground showing the use case :
import AppKit
extension NSTreeController {
func whatever () {
let k = (self.arrangedObjects as AnyObject).children // error here
}
}
I try to use AnyObject as a bridge to the underlying ObjC object, which is supposed to be able to get through any method call, I guess.
Xcode signals that it found two candidates that could respond to a "children" message: Foundation.XMLNode and AppKit.NSTreeNode.
Of course the obvious solution (casting to NSTreeNode) is not working because arrangedObjects returns an opaque, proxy object not a real NSTreeNode
Any suggestion on how we're supposed to use NSTreeController.arrangedObjects.children in Swift 3 ?
The two candidates for the children property differ by their type:
Foundation.XMLNode:137:14: note: found this candidate
open var children: [XMLNode]? { get }
^
AppKit.NSTreeNode:12:14: note: found this candidate
open var children: [NSTreeNode]? { get }
^
You can resolve the ambiguity by casting the value of the property
to the expected type. In your case:
let k = (self.arrangedObjects as AnyObject).children as [NSTreeNode]?
Another solution: Adding an Obj-C category to NSTreeController
.h
#import <Cocoa/Cocoa.h>
#interface NSTreeController (RootNodes_m)
- (NSArray *) rootNodes;
#end
.m
#import "NSTreeController+RootNodes_m.h"
#implementation NSTreeController (RootNodes_m)
- (NSArray *) rootNodes {
NSObject * arranged = self.arrangedObjects;
if ([arranged respondsToSelector: #selector(childNodes)]) {
return [arranged performSelector:#selector(childNodes)];
}
return nil;
}
#end
Now in your code you can use it like this:
return treeController.rootNodes() as? [NSTreeNode]
I had problem with the above answer: The compiler refused to compile when "whole module optimization" was turned on. A swift extension didn't help. I'm using Xcode 8.2.1.

Swift Parse kPFCachePolicyNetworkOnly

I want to use query.cachePolicy = kPFCachePolicyNetworkOnly;
in my PFQueryTableViewController, but it tells me it dos not exisit.
I have imported Parse in my class and ParseUI trough the BridgingHeader
Here my BridgingHeader
#import <Parse/Parse.h>
#import "ParseUI.h"
#import "RSKImageCropViewController.h"
What am i doing wrong? All libarys are imported trough Cocoapods.
The enumeration types for PFQuery.cachePolicy changed with Swift.
Try typing in: PFCachePolicy.
then you will see the enumerations available for this type.
For example, your statement would be as follows:
query.cachePolicy = PFCachePolicy.NetworkOnly
or you can use the Swift abbreviated notation:
query.cachePolicy = .NetworkOnly

Trouble using opaque pointers in Objective C++

The answer to this quesion explains that opaque pointers are a good way to include C++ member variables in an Objective C++ header. I'm getting compile errors when trying to follow the example. Here's the relevant code from my header, with the corresponding compiler errors shown as comments:
struct ADSR_opaque; // error: forward declaration of 'struct ADSR_opaque'
#interface LoopyPulser : NSObject{
float _pulseRate;
UInt32 tickInterval;
UInt32 step;
InMemoryAudioFile * audioFilePlayer;
ADSR_opaque* env; // error: expected specifier-qualifier-list before 'ADSR_opaque'
Pattern * pattern;
float loopLengthRatio;
float volume;
}
Is there something simple I'm doing wrong here?
I don't have any problem with the following minimal sample:
struct ADSR_opaque;
#interface LoopyPulser : NSObject {
struct ADSR_opaque* env;
}
#end
If you include the header in plain Objective-C files (not Objective-C++), you have to add struct.
Alternatively use typedefs:
struct ADSR_opaque_;
typedef struct ADSR_opaque_ ADSR_opaque;
#interface LoopyPulser : NSObject {
ADSR_opaque* env;
// ...