Need help converting (CFPropertyListRef *)nsdictionary to swift - swift

I need a little help converting this
MIDIDeviceRef midiDevice = MIDIGetDevice(i);
NSDictionary *midiProperties;
MIDIObjectGetProperties(midiDevice, (CFPropertyListRef *)&midiProperties, YES);
NSLog(#"Midi properties: %d \n %#", i, midiProperties);
to swift. I have this but I am getting hung up on casting the CFPropertList.
var midiDevice = MIDIGetDevice(index)
let midiProperties = NSDictionary()
MIDIObjectGetProperties(midiDevice, CFPropertyListRef(midiProperties), 1);
println("Midi properties: \(index) \n \(midiProperties)");
Any help would be great.
Thanks

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;
}

Related

Swift, dictionary parse error

I'm using an API to get weather condition and the retrieved dict is
dict = {
base = stations;
clouds = {
all = 92;
};
cod = 200;
coord = {
lat = "31.23";
lon = "121.47";
};
dt = 1476853699;
id = 1796231;
main = {
"grnd_level" = "1028.63";
humidity = 93;
pressure = "1028.63";
"sea_level" = "1029.5";
temp = "73.38";
"temp_max" = "73.38";
"temp_min" = "73.38";
};
name = "Shanghai Shi";
rain = {
3h = "0.665";
};
sys = {
country = CN;
message = "0.0125";
sunrise = 1476827992;
sunset = 1476868662;
};
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
wind = {
deg = "84.50239999999999";
speed = "5.97";
};
}
If I want the value of humidity, I just use
let humidityValue = dict["main"]["humidity"] and it works.
But the problem is I also want to get the value of description in weather
when I used let dscptValue = dict["weather"]["description"]
it retrieved nil.
How's that? and I notice there are two brackets around weather .I'm not sure whether it is the same with the statement without brackets.
weather = (
{
description = "light rain";
icon = 10d;
id = 500;
main = Rain;
}
);
How to get the value of description?
weather keys contains Array of Dictionary not directly Dictionary, so you need to access the first object of it.
if let weather = dict["weather"] as? [[String: AnyObject]], let weatherDict = weather.first {
let dscptValue = weatherDict["description"]
}
Note: I have used optional wrapping with if let for preventing crash with forced wrapping.
Weather is an array of dictionaries.
dict["weather"][0]["description"]
may give you the expected result.

Could not find an overload for 'subscript' that accepts the supplied arguments in case of nsmutable array

I am new to Swift, can u plz suggest me why these errors are happening
{
var profArr : NSMutableArray = NSMutableArray()
for index in 1...<profArr.count
{
var joomlaID : NSString = [dbManager?.getZoomlaID(profArr[index]["firmUserId"] as String)];
// while using this in loop getting **could not find overload** error.
}
func getZoomlaID (firmUser : NSString) -> NSString
{
var zoomlaId : NSString
var dbPath: AnyObject? = NSUserDefaults.standardUserDefaults().valueForKey("dbPath")
var db = FMDatabase(path: dbPath as! String)
db?.open()
if var rsltSet : FMResultSet! = db!.executeQuery("Select JoomlaUserID From org_firm_users where FirmUserID like ('\(firmUser)')", withArgumentsInArray: nil) //Here again getting error Unprintable ASCII character.
{
while (rsltSet.next())
{
print(rsltSet.resultDictionary())
zoomlaId = (rsltSet.resultDictionary() as NSDictionary).valueForKey("JoomlaUserID") as! NSString
}
}
else
{
println("select failed: \(db.lastErrorMessage())")
}
db?.close()
return zoomlaId
}
}
in the line for index in 1...<profArr.count you are adding an unwanted .< to loop declaration, it should be something like this: for index in 1..profArr.count
... means from-to inclusive and .. means from-to non-inclusive.
e.g. 1..3 means 1,2,3 but 1..3 means 1,2

How to get AudioComponent's Description Type letter code?

I'm trying to understand AudioComponents before instanciate them and understand/use AudioUnits...
I create an AudioComponentDescription by using wildcards:
var inDesc = AudioComponentDescription(componentType: OSType(),
componentSubType: OSType(),
componentManufacturer: OSType(),
componentFlags: UInt32(0),
componentFlagsMask: UInt32(0))
I look how many AudioComponent there is:
AudioComponentCount(&inDesc) // returns 98 in a playground (ok)
I focus the first AudioComponent by using "nil" as first parameter in AudioComponentFindNext:
var currentComp = AudioComponentFindNext(nil, &inDesc)
Looking at its name:
func getAudioComponentName (componentInit:AudioComponent) -> CFString {
var componentProp:AudioComponent = componentInit
var componentNameProp:CFString = "" as CFString
var unmanagedCurrentCompName:Unmanaged<CFString>?
AudioComponentCopyName(componentProp, &unmanagedCurrentCompName)
componentNameProp = unmanagedCurrentCompName!.takeRetainedValue()
return componentNameProp
}
var currentComponentName:CFString = "" as CFString
currentComponentName = getAudioComponentName(currentComp) // returns "Apple PAC3 Transcoder" (ok)
At this point, the following tries will not be "ok".
I want to know much more about this "Apple PAC3 Transcoder" and its description:
// Creating an empty AudioComponentDescription
var currentComponentDescription = AudioComponentDescription()
// Gettings currentComp's description (type)
AudioComponentGetDescription(currentComp, &currentComponentDescription)
var compDescType:OSType = currentComponentDescription.componentType // returns 1633903715
At the last line of code, how could I get the letter code described in AUComponent.h:
enum
{
kAudioUnitType_Output = 'auou',
kAudioUnitType_MusicDevice = 'aumu',
kAudioUnitType_MusicEffect = 'aumf',
kAudioUnitType_FormatConverter = 'aufc',
kAudioUnitType_Effect = 'aufx',
kAudioUnitType_Mixer = 'aumx',
kAudioUnitType_Panner = 'aupn',
kAudioUnitType_Generator = 'augn',
kAudioUnitType_OfflineEffect = 'auol',
kAudioUnitType_MIDIProcessor = 'aumi'
};
for further compatibility I prefer to not have to reproduce this "enum" in my code.
componentType is an OSType which is 4 ASCII character codes packed into 32 bits.
1633903715 in hexadecimal is 0x61636463
0x61636463 in ascii is 'acdc' (0x61 = 'a', 0x63 = 'c', etc...)

How do you add an attribute to an Unicode string in Swift?

How do you add attribute to a UNICODE string in Swift?
NSMakeRange seems to expect String in bytes for a variable byte length UNICODE string.
Any way to solve this? Thanks in advance.
var s:NSMutableAttributedString = NSMutableAttributedString(string: "வாங்க வாங்க வணக்கமுங்க")
s.string[0...2]
s.addAttribute(NSForegroundColorAttributeName, value:UIColor(red:0.0, green:1.0, blue:0.0, alpha:1.0), range:NSMakeRange(0,3))
UPDATED EXAMPLE:
let text = "வாங்க வாங்க வணக்கமுங்க"
var startOfWord = advance(text.startIndex, 4)
var endOfWord = advance(startOfWord, 3)
var highlightRange = startOfWord..<endOfWord
text[startOfWord..<endOfWord]
let attrText = NSMutableAttributedString(string:text)
attrText.addAttribute(NSForegroundColorAttributeName, value:UIColor(red:0.0, green:1.0, blue:0.0, alpha:1.0), range:highlightRange)
How do construct NSRange from swift Range?
I created a small extension for String which works for both Index based and Int based Ranges.
extension String {
func NSRangeFromRange(swiftRange: Range<Index>) -> NSRange {
let start = swiftRange.startIndex.samePositionIn(utf16)
let end = swiftRange.endIndex.samePositionIn(utf16)
return NSRange(location: utf16.startIndex.distanceTo(start), length: start.distanceTo(end))
}
func NSRangeFromRange(swiftRange: Range<Int>) -> NSRange {
let indexRange = Range(start: startIndex.advancedBy(swiftRange.startIndex), end: startIndex.advancedBy(swiftRange.endIndex))
return NSRangeFromRange(indexRange)
}
}
Note: The function is on the String class because we need the strings UTF16View to convert between the Unicode-aware Range<Index> and the non-Unicode-aware NSRange.
I hope the below function may help you
func findAndAddAttributeString(str: String, query : String) {
let strASNSString = str as NSString
println("employeeIdAsNSString, \(strASNSString)")
var attributeDictionary = NSMutableDictionary(objects: [UIColor.grayColor(), UIFont.systemFontOfSize(17)], forKeys: [NSForegroundColorAttributeName, NSFontAttributeName])
println("attributeDictionary, \(attributeDictionary)")
var attributedEmployeeId = NSMutableAttributedString(string: strASNSString, attributes: attributeDictionary)
println("attributedEmployeeId = \(attributedEmployeeId)")
var error:NSError?
var regex = NSRegularExpression.regularExpressionWithPattern(query, options: NSRegularExpressionOptions.CaseInsensitive, error: &error)
println("regex = \(regex)")
var range = NSMakeRange(0, strASNSString.length)
println("range = \(range)")
regex.enumerateMatchesInString(strASNSString, options: nil, range: range, usingBlock:{ (textCheckingResult, MatchingFlags, unsafePointer) in
println("textCheckingResult \(textCheckingResult.rangeAtIndex(0))")
var subStringRange = textCheckingResult.rangeAtIndex(0)
attributedEmployeeId.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: subStringRange)
})
}
You can convert a swift String to Swift NSString by
var strAsNSString = "வாங்க வாங்க வணக்கமுங்க" as NSString
And then you can create NSMutableAttributedString.
Something like this might work:
let text = "வாங்க வாங்க வணக்கமுங்க"
var startOfWord = advance(text.startIndex, 5)
var endOfWord = advance(startOfWord, 5)
var range = startOfWord..<endOfWord
Even if some more work is required to figure out how far to advance (if you are looking for just one known word you can directly get it with NSRangeFromString)

Multidimensional array makes Xcode6 crash

I have an application which retrieves a JSON file. Here you are a piece of my code:
Array definition
var photos: NSArray = []
How I populate the array:
ezJson().createRequest("http://myapiurl/load", type: "GET", params: nil, completion: {(returnedObject : AnyObject?, error : NSError?)in
if returnedObject{
self.photos = returnedObject as NSArray
self.tableView.reloadData()
}
})
println(self.photos)
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
},
{
created = {
date = "2014-06-13 18:38:38";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description2;
id = 4;
name = 539b290ed8577;
}
println(self.photos[0])
{
created = {
date = "2014-06-13 18:35:46";
timezone = "Europe/Madrid";
"timezone_type" = 3;
};
description = description1;
id = 3;
name = 539b286277617;
}
The problem is, I don't know how to get a particular item. I've tried:
println(self.photos[0]) // it works
println(self.photos[0]["name"] // Xcode crash "Command /Applications/Xcode6-Beta.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254"
println(self.photos[0].name) // returns nil
How can I access to the name parameter ?
It seems that you are casting a String to NSArray. This won't give you the effect that you want.
First of all, if you want to acces your elements by name, you want an NSDictionary.
Then it propably still won't work, as there is no implicit conversion between the types so you will have to either parse it yourself or use some JSON library.
Last : your JSON is incorrect.