I have recently upgraded to XCode 6.3 and I am trying to initiate an ODQuery as per the Apple Documentation and getting an error.
'Int' is not convertible to 'ODMatchType'
I am using Apple's own Documentation Open Directory Programming Guide
Here is my Swift code:
var err:NSError?
var session = ODSession.defaultSession()
var node = ODNode(session: session, name: "/Local/Default", error: &err)
var query = ODQuery(node: node, forRecordTypes: kODRecordTypeUsers, attribute: kODAttributeTypeRecordType, matchType: kODMatchContains, queryValues: "darren", returnAttributes: kODAttributeTypeStandardOnly, maximumResults: 10, error: &err)?
The issue seems to be that kODMatchContains or any other matchType that are tried are not compatible with the Swift 1.2 function?
If someone knows what is going on or if you can try the code in 6.3 yourself and get the same results, please let me know.
This has nothing to do with Swift 1.2. It was always this way in Swift. The matchType: parameter needs to be an ODMatchType. Coerce it to an ODMatchType, like this:
... matchType: ODMatchType(kODMatchContains), ...
And that line will then compile just fine (once you remove the question mark at the end).
Apparently I have to spell it out for you...
var err:NSError?
var session = ODSession.defaultSession()
var node = ODNode(session: session, name: "/Local/Default", error: &err)
var query = ODQuery(node: node, forRecordTypes: kODRecordTypeUsers, attribute: kODAttributeTypeRecordType, matchType: ODMatchType(kODMatchContains), queryValues: "darren", returnAttributes: kODAttributeTypeStandardOnly, maximumResults: 10, error: &err)
Related
I am trying to write a MIDIPlayer class which is a wrapper for an AVAudioEngine and an AVAudioUnitMIDIInstrument. I have written a loop that gets the names and ASBDs for all AudioComponents of type MusicDevice and then chooses the most desired unit according to a list which works quite similar to font substitution, with Apples DLS MusicDevice as the ultimate fallback. Here's my sample code:
import AVKit
fileprivate func setupAVAudioEngine(engine: inout AVAudioEngine, instrumentAU: inout AVAudioUnitMIDIInstrument?) {
var instrumentACD = AudioComponentDescription(componentType: kAudioUnitType_MusicDevice, componentSubType: 0, componentManufacturer: 0, componentFlags: 0, componentFlagsMask: 0)
var instrumentComponents: [(AudioComponentDescription, String)] = []
var instrumentComponent: AudioComponent? = nil
repeat {
instrumentComponent = AudioComponentFindNext(instrumentComponent, &instrumentACD)
if instrumentComponent == nil {
break
}
var compDescr = AudioComponentDescription()
var name: Unmanaged<CFString>?
AudioComponentCopyName(instrumentComponent!, &name)
AudioComponentGetDescription(instrumentComponent!, &compDescr)
let nameString = name!.takeRetainedValue() as String
instrumentComponents.append((compDescr, nameString))
name?.release()
} while true
let instrumentComponentSubstitutionList = ["MakeMusic: SmartMusicSoftSynth","Apple: AUMIDISynth","Apple: DLSMusicDevice"]
var found = false
for instrument in instrumentComponentSubstitutionList {
for member in instrumentComponents {
if member.1 == instrument {
instrumentACD = member.0
print("\(member.1) found")
found = true
break
}
if found {break}
}
}
print("Try to create InstrumentNode with ACD: \(instrumentACD)")
instrumentAU = AVAudioUnitMIDIInstrument(audioComponentDescription: instrumentACD)
print("InstrumentNode created: \(instrumentAU!.name)")
print()
engine.attach(instrumentAU!)
engine.connect(instrumentAU!, to: engine.mainMixerNode, format: nil)
}
open class MIDIPlayer {
private var audioEngine: AVAudioEngine
private var instrumentUnit: AVAudioUnitMIDIInstrument
private var mainMixer: AVAudioMixerNode
public init() {
self.audioEngine = AVAudioEngine()
self.mainMixer = audioEngine.mainMixerNode
var instrumentAU: AVAudioUnitMIDIInstrument?
setupAVAudioEngine(engine: &audioEngine, instrumentAU: &instrumentAU)
self.instrumentUnit = instrumentAU!
try! audioEngine.start()
}
public func playMIDINote(_ note: UInt8) {
print("Playing MIDI Note \(note)")
instrumentUnit.startNote(note, withVelocity: 70, onChannel: 0)
sleep(1)
instrumentUnit.stopNote(note, onChannel: 0)
}
}
let midiPlayer = MIDIPlayer()
midiPlayer.playMIDINote(60)
midiPlayer.playMIDINote(62)
midiPlayer.playMIDINote(64)
midiPlayer.playMIDINote(65)
midiPlayer.playMIDINote(67)
The code works perfectly fine in an Xcode 11.3.1 playground, howewer, when I use the exact same code outside the playground I get different kinds of errors:
When I copy the same code into a command line project and run it from XCode it still works but the console gives me the following error:
[AudioHAL_Client] AudioHardware.cpp:666:AudioObjectGetPropertyData: AudioObjectGetPropertyData: no object with given ID 0
When I run the executable without Xcode no error is reported.
When I create a single View app, put the class and its setup func in its own source file and create an instance in the applicationDidFinishLaunching method of the AppDelegate I get the following errors:
[AudioHAL_Client] HALC_ShellDriverPlugIn.cpp:104:Open: HALC_ShellDriverPlugIn::Open: opening the plug-in failed, Error: 2003329396 (what)
[AudioHAL_Client] AudioHardware.cpp:666:AudioObjectGetPropertyData: AudioObjectGetPropertyData: no object with given ID 0
These errors are written to the console even before my setup function is called. However, the code still works (I hear notes playing), but only if I change the instrumentComponentSubstitutionList so that one of the Apple AUs will be found (in other words: not the SmartMusicSoftSynth). When I keep the SoftSynth the preferred device the code crashes and I get the additional error:
[avae] AVAEInternal.h:103:_AVAE_CheckNoErr: [AUInterface.mm:461:AUInterfaceBaseV3: (AudioComponentInstanceNew(comp, &_auv2)): error -3000
Note: In the playground and the command line app the SoftSynth works.
Some observations which may or may not relate to the issue:
In this blogpost http://www.rockhoppertech.com/blog/multi-timbral-avaudiounitmidiinstrument/ Gene DeLisa mentions that the AVAudioUnitSampler is the only subclass of the abstract class AVAudioUnitMIDIInstrument. This post is from 2016, but I do not find any further information about that. But, obviously, the DLS MusicDevice as well as the 3rd party SoftSynth work – at least in some environments.
The ASBD taken from the found AudioComponents for both of the Apple Units have their componentFlags property set to 2. The documentation says: must be set to zero unless a known specific value is requested. The componentFlags property of the SoftSynth is 0.
I still have a somehow related problem when I try to capture audio from input How do I allow Xcode to access the microphone?? - related in so far that the command line app shows different behavior when run from XCode or via the terminal, and in both issues CoreAudio is involved.
My Question(s):
Why do I get these errors?
Why does the 3rd party plugIn work in the playground and the command line app but not in a single view app?
Is AVAudioEngine ready to host other Instrument Units than the monotimbral SamplerUnit?
Or do I have to step down and use the instrumentAUs directly and not the AVAudioUnitMIDIInstrument wrapper?
I am trying to find a count of entities which satisfy predicate. According to documentation and "header" files, this should work:
let fetch = NSFetchRequest<NSFetchRequestResult>(entityName: "FileRecord")
let ctx: NSManagedObjectContext = GetCtx()
let res = try ctx.count(for: fetch)
however I get compile error:
Cannot invoke 'count' with an argument list of type '(for: NSFetchRequest<NSFetchRequestResult>)'
however when I create the fetch request from FileRecord like this instead:
let fetch: NSFetchRequest<FileRecord> = FileRecord.fetchRequest()
I get the following error:
Cannot convert value of type 'NSFetchRequest<FileRecord>' to expected argument type 'NSFetchRequest<NSFetchRequestResult>'
Please anyone got an idea what can be wrong? I am a decent C++ language lawyer but I am just a novice with Swift...
EDIT: SOLVED
My example above was wrong. In reality I had code functionally identical to:
let res: UInt64 = try ctx.count(for: fetch)
since count returns Int, the function did not match. The error message was not specific enough for me to see it immediately. Thanks to all who have tried to help :)
This question and answer describe how to read data from a Mach-O section with Objective-C on modern OS X/macOS versions: Crash reading bytes from getsectbyname
The described answer works. I'm trying to implement the same thing with Swift. I can't make it work.
I have the following in "Other linker flags": -Wl,-sectcreate,__LOCALIZATIONS,__base,en.lproj/Localizable.strings,-segprot,__LOCALIZATIONS,r,r.
This Swift code gets me the a pointer to the embedded data, until I try to run the code outside Xcode and ASLR breaks it:
var size: UInt = 0
let _localizationSection = getsectdata(
"__LOCALIZATIONS",
"__base",
&size)
To get around the ASLR problem, according to the above question and answer, and based on my own testing, I should be using getsectiondata instead. It works great in Objective-C, but I'm having no luck in Swift. The following is the only thing I've managed to get past the compiler, but it returns nil:
var size: UInt = 0
var header = _mh_execute_header
let localizationSection = getsectiondata(
&header,
"__LOCALIZATIONS",
"__base",
&size)
Is taking a copy of _mh_execute_header the problem and is there any way to avoid it? I need an UnsafePointer<mach_header_64>, but using &_mh_execute_header as the first parameter to getsectiondata causes a compilation error.
I'm using Swift 3.0, and running my code on macOS 10.12.
The difference between the linked-to Objective-C code
void *ptr = getsectiondata(&_mh_execute_header, ...);
and your Swift translation
var header = _mh_execute_header
let localizationSection = getsectiondata(&header, ...)
is that the latter passes the address of a copy of the global
_mh_execute_header variable to the function, and apparently that
is not accepted. If you modify the Objective-C code to
struct mach_header_64 header = _mh_execute_header;
void *ptr = getsectiondata(&header, ...);
then it fails as well (and actually crashed in my test).
Now the problem is that _mh_execute_header is exposed to Swift
as a constant:
public let _mh_execute_header: mach_header_64
and one cannot take the address of a constant in Swift. One possible
workaround is to define
#import <mach-o/ldsyms.h>
static const struct mach_header_64 *mhExecHeaderPtr = &_mh_execute_header;
in the bridging header file, and then use it as
let localizationSection = getsectiondata(mhExecHeaderPtr, ...)
in Swift.
Another option is to lookup the symbol via dlopen/dlsym
import MachO
if let handle = dlopen(nil, RTLD_LAZY) {
defer { dlclose(handle) }
if let ptr = dlsym(handle, MH_EXECUTE_SYM) {
let mhExecHeaderPtr = ptr.assumingMemoryBound(to: mach_header_64.self)
var size: UInt = 0
let localizationSection = getsectiondata(
mhExecHeaderPtr,
"__LOCALIZATIONS",
"__base",
&size)
// ...
}
}
I have the following code in swift 2
let deviceid = UIDevice.currentDevice().identifierForVendor!.UUIDString
This fails to compile. I tried following suggestions from the auto-fix in xCode and I came up with this.
let deviceid = UIDevice.currentDevice.identifierForVendor!.UUIDString
However it still does not compile. It says value of type 'UUID' has no member UUIDString'
My advice - for these kind of issues - get straight into a playground
let deviceid = UIDevice.current.identifierForVendor?.uuidString
My class has a property
var activeSquares = Dictionary <String, SKShapeNode> ()
I try to add and update values in the dictionary using
let squareNode = SKShapeNode(rectOfSize: CGSizeMake(80, 80), cornerRadius: 8)
activeSquares.updateValue(squareNode, forKey: "someUniqueDescription")
I also get the same crash if I use
activeSquares["someUniqueDescription"] = squareNode
But it is causing a crash when compiling
1. While emitting IR SIL function #_TFC14gamename9GameScene11addedSquarefS0_FCS_6SquareT_ for 'addedSquare' at /.../gamename/gamename/GameScene.swift:30:5
<unknown>:0: error: unable to execute command: Segmentation fault: 11
<unknown>:0: error: swift frontend command failed due to signal (use -v to see invocation)
Command /Applications/Xcode6-Beta2.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swift failed with exit code 254
How do I properly use updateValue to add/update key/value pairs to my dictionary?
No sure if my solution fits here, but it could help. Seems there's something weird with subscription for NSDictionary. Not sure why, but it's defined as:
func objectForKeyedSubscript(key: NSCopying!) -> AnyObject!
so, if I'm not wrong it returns implicitly unwrapped optional, but should return optional, as far as there could be no value for a key. If you try to write:
if(dictionary["key"] != nil)
you'll get a compile error "AnyObject is not convertible to UInt8" while if you write:
if(dictionary["key"])
you don't get one.
The way I solved this issue was using optional unwrapping, so:
if(someBool && dictionary["key"]) // fine in beta 2, crash in beta 3-4
// turned to:
var hasValueForKey = false
if dictionary["key"]
{
hasValueForKey = true
}
if(someBool && hasValueForKey) // fine in beta 4
and:
var someArray : NSArray? = dictionary["key"]? as? NSArray // note ? after []
I guess there could be something with optionals and stuff for setting an object via subscript, it's defined as:
func setObject(obj: AnyObject!, forKeyedSubscript key: NSCopying!)
Maybe playing with optional unwrapping could help here as well.