Need help converting (CFPropertyListRef *)nsdictionary to swift
This is the signature for MIDIObjectGetProperties
in Swift:
func MIDIObjectGetProperties(obj: MIDIObjectRef, outProperties: UnsafeMutablePointer<Unmanaged<CFPropertyList>?>, deep: Boolean) -> OSStatus
So you need to pass in an UnsafeMutablePointer
to a Unmanaged<CFPropertyList>?
:
var midiDevice = MIDIGetDevice(0)
var unmanagedProperties: Unmanaged<CFPropertyList>?
MIDIObjectGetProperties(midiDevice, &unmanagedProperties, 1)
Now you have your properties, but they're in an unmanaged variable -- you can use the takeUnretainedValue()
method to get them out, and then cast the resulting CFPropertyList
to an NSDictionary
:
if let midiProperties: CFPropertyList = unmanagedProperties?.takeUnretainedValue() {
let midiDictionary = midiProperties as NSDictionary
println("Midi properties: \(index) \n \(midiDictionary)");
} else {
println("Couldn't load properties for \(index)")
}
Results:
Midi properties: 0
{
"apple.midirtp.errors" = <>;
driver = "com.apple.AppleMIDIRTPDriver";
entities = (
);
image = "/Library/Audio/MIDI Drivers/AppleMIDIRTPDriver.plugin/Contents/Resources/RTPDriverIcon.tiff";
manufacturer = "";
model = "";
name = Network;
offline = 0;
scheduleAheadMuSec = 50000;
uniqueID = 442847711;
}
Using a reference to CFPropertyListRef in Swift
If your usage in Objective-C is really right, the function header of your MyFunction
needs to be something like this:
extern void MyFunction(CFPropertyListRef *list, CFPropertyListFormat *fmt);
(CFPropertyListRef
actually is just a typealias of void *
in Objective-C/C. So, the compiler rarely outputs warnings for many possible type mis-uses.)
And Swift 2 imports such function as:
public func MyFunction(list: UnsafeMutablePointer<Unmanaged<CFPropertyList>?>, _ fmt: UnsafeMutablePointer<CFPropertyListFormat>)
So, assuming you have changed the function header as above,
you need to use it as follows:
var fmt: CFPropertyListFormat = .XMLFormat_v1_0
var umPlist: Unmanaged<CFPropertyList>? = nil
MyFunction(&umPlist, &fmt)
var plist = umPlist?.takeRetainedValue() //or this may be `umPlist?.takeUnretainedValue()`
Casting a CFDictionaryRef to NSDictionary?
ARC changed the way bridging works.
NSDictionary *original = [NSDictionary dictionaryWithObject:@"World" forKey:@"Hello"];
CFDictionaryRef dict = (__bridge CFDictionaryRef)original;
NSDictionary *andBack = (__bridge NSDictionary*)dict;
NSLog(@"%@", andBack);
how to do true deep copy for NSArray and NSDictionary with have nested arrays/dictionary?
A couple of years ago, I wrote a few category methods for exactly the same reason, transforming a whole tree of user defaults to mutable. Here they are - use them at your own risk! :-)
//
// SPDeepCopy.h
//
// Created by Sherm Pendley on 3/15/09.
//
#import <Cocoa/Cocoa.h>
// Deep -copy and -mutableCopy methods for NSArray and NSDictionary
@interface NSArray (SPDeepCopy)
- (NSArray*) deepCopy;
- (NSMutableArray*) mutableDeepCopy;
@end
@interface NSDictionary (SPDeepCopy)
- (NSDictionary*) deepCopy;
- (NSMutableDictionary*) mutableDeepCopy;
@end
//
// SPDeepCopy.m
//
// Created by Sherm Pendley on 3/15/09.
//
#import "SPDeepCopy.h"
@implementation NSArray (SPDeepCopy)
- (NSArray*) deepCopy {
unsigned int count = [self count];
id cArray[count];
for (unsigned int i = 0; i < count; ++i) {
id obj = [self objectAtIndex:i];
if ([obj respondsToSelector:@selector(deepCopy)])
cArray[i] = [obj deepCopy];
else
cArray[i] = [obj copy];
}
NSArray *ret = [[NSArray arrayWithObjects:cArray count:count] retain];
// The newly-created array retained these, so now we need to balance the above copies
for (unsigned int i = 0; i < count; ++i)
[cArray[i] release];
return ret;
}
- (NSMutableArray*) mutableDeepCopy {
unsigned int count = [self count];
id cArray[count];
for (unsigned int i = 0; i < count; ++i) {
id obj = [self objectAtIndex:i];
// Try to do a deep mutable copy, if this object supports it
if ([obj respondsToSelector:@selector(mutableDeepCopy)])
cArray[i] = [obj mutableDeepCopy];
// Then try a shallow mutable copy, if the object supports that
else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)])
cArray[i] = [obj mutableCopy];
// Next try to do a deep copy
else if ([obj respondsToSelector:@selector(deepCopy)])
cArray[i] = [obj deepCopy];
// If all else fails, fall back to an ordinary copy
else
cArray[i] = [obj copy];
}
NSMutableArray *ret = [[NSMutableArray arrayWithObjects:cArray count:count] retain];
// The newly-created array retained these, so now we need to balance the above copies
for (unsigned int i = 0; i < count; ++i)
[cArray[i] release];
return ret;
}
@end
@implementation NSDictionary (SPDeepCopy)
- (NSDictionary*) deepCopy {
unsigned int count = [self count];
id cObjects[count];
id cKeys[count];
NSEnumerator *e = [self keyEnumerator];
unsigned int i = 0;
id thisKey;
while ((thisKey = [e nextObject]) != nil) {
id obj = [self objectForKey:thisKey];
if ([obj respondsToSelector:@selector(deepCopy)])
cObjects[i] = [obj deepCopy];
else
cObjects[i] = [obj copy];
if ([thisKey respondsToSelector:@selector(deepCopy)])
cKeys[i] = [thisKey deepCopy];
else
cKeys[i] = [thisKey copy];
++i;
}
NSDictionary *ret = [[NSDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count] retain];
// The newly-created dictionary retained these, so now we need to balance the above copies
for (unsigned int i = 0; i < count; ++i) {
[cObjects[i] release];
[cKeys[i] release];
}
return ret;
}
- (NSMutableDictionary*) mutableDeepCopy {
unsigned int count = [self count];
id cObjects[count];
id cKeys[count];
NSEnumerator *e = [self keyEnumerator];
unsigned int i = 0;
id thisKey;
while ((thisKey = [e nextObject]) != nil) {
id obj = [self objectForKey:thisKey];
// Try to do a deep mutable copy, if this object supports it
if ([obj respondsToSelector:@selector(mutableDeepCopy)])
cObjects[i] = [obj mutableDeepCopy];
// Then try a shallow mutable copy, if the object supports that
else if ([obj respondsToSelector:@selector(mutableCopyWithZone:)])
cObjects[i] = [obj mutableCopy];
// Next try to do a deep copy
else if ([obj respondsToSelector:@selector(deepCopy)])
cObjects[i] = [obj deepCopy];
// If all else fails, fall back to an ordinary copy
else
cObjects[i] = [obj copy];
// I don't think mutable keys make much sense, so just do an ordinary copy
if ([thisKey respondsToSelector:@selector(deepCopy)])
cKeys[i] = [thisKey deepCopy];
else
cKeys[i] = [thisKey copy];
++i;
}
NSMutableDictionary *ret = [[NSMutableDictionary dictionaryWithObjects:cObjects forKeys:cKeys count:count] retain];
// The newly-created dictionary retained these, so now we need to balance the above copies
for (unsigned int i = 0; i < count; ++i) {
[cObjects[i] release];
[cKeys[i] release];
}
return ret;
}
@end
How to solve it ( EXC_BAD_ADDRESS in Objective-C )?
Some ideas:
Turn on zombies (How to enable NSZombie in Xcode). You'll get more information about the object causing the crash when you do that.
If you can make the error happen at will, set a breakpoint at the top of saveAsync
and step through it.
Change the stringWithFormat
calls somehow so they don't reference anything that might be deallocated and see if the problem goes away. If it does, you'll know what was causing it.
I find it sometimes helps to override retain
and release
in objects I'm suspicious of and either print something out or set a breakpoint so I can see who might be over-releasing an object.
Related Topics
How to Test an Optionset with a Switch Statement
Swift Objc_Getassociatedobject Always Nil
Nstableview Inside Nspopover Looks Different as Standalone
How to Detect If a Observable Has Not Emitted Any Events for Specific Time in Rxswift
How to Hash a String to Sha512 in Swift
How to Check If Core Data Is Empty
Float Is Not Convertible to 'Mirrordisposition' Swift What Is Mirrordisposition
How to Keep a Reference to Another Object in the Parameters of the Class
Save the Text in a Text Field as a Variable
Typealias of Generic Class in Swift
Swiftui MACos Scroll a List with Arrow Keys While a Textfield Is Active
Cannot Subscript a Value of Type '[String:String]' with an Index of Type 'String'
Need Help Converting (Cfpropertylistref *)Nsdictionary to Swift
Nskeyedunarchiver Fails to Decode a Custom Object in Swift
How to Trim a String in Swift Based on a Character
How to Check the Type of a Variable Against Another Variable in Swift