I have a struct, House
, that I want usable in both Objective-C and in Swift (additionally, I just wanted to test the bounds of what I could and couldn't import from C to Swift).
House
is defined as follows:
typedef struct {
NSUInteger number;
CFStringRef street CF_REFINED_FOR_SWIFT;
CFStringref city CF_REFINED_FOR_SWIFT;
StateCode stateCode; // an enum, whose definition isn't relevant to this question
NSUInteger zip;
} House;
To avoid using Unmanaged<T>
in Swift, street
and city
each have accessor methods that bridge the underlying CFStringRef
to NSString*
. The accessors for city
are practically identical, so I'll omit them here and only provide the accessors for street
.
House.h
NSString* HouseGetStreet(const House* h) CF_SWIFT_NAME(getter:House.street(self:));
void HouseSetStreet(House* h, NSString* newStreet) CF_SWIFT_NAME(setter:House.street(self:newStreet:));
House.m
NSString* HouseGetStreet(const House* h) {
return [(__bridge NSString*)h->street copy];
}
void HouseSetStreet(House* h, NSString* newStreet) {
CFStringRef* currentStreet = &h->street;
CFStringRef street2 = (__bridge CFStringRef)street; // don't retain yet
if (*currentStreet != street2) {
CFRelease(*currentStreet);
*currentStreet = CFRetain(street2); // now we retain
} else {
return;
}
}
When defining only the getter method, Swift imports the street
property as a Swift.String
and everything works fine. But when I define the setter methods, Swift acts like the street
property doesn't even exist and I can't get or set the field from Swift code.