I'm sure this is something stupid I'm doing wrong but why is the swift parser telling me I can't convert the expression's type () when clearly the definition of AudioQueueDispose returns an OSStatus type? I've put off asking this question for a while cos I know it's going to be something dumb I'm just overlooked.
I put this in to Xcode playground for simplicity...
import UIKit
import AudioToolbox
import AVFoundation
var audioQueue:AudioQueue
var status : OSStatus = OSStatus(noErr)
status = AudioQueueDispose(audioQueue, inImmediate: false)
I think the error message was very misleading especially with the little arrow pointing to the '=' sign implying it was an issue with the return type. Anyway, the actual problem is to do with using 'false', which is a swift type 'Bool', whereas the function expects at type 'Boolean' which is in fact a UInt8. So the above can be fixed by writing...
status = AudioQueueDispose(audioQueue, 0)
Perhaps someone can offer a better solution which does not involve using integers?
For now I'm just defining a couple of constants..
let FALSE:Boolean = 0
let TRUE:Boolean = 1
Related
import CryptoKit
func getAlgorithm(algo: String) {
var algorithms = ["md5":Insecure.MD5.hash,
"sha1":Insecure.SHA1.hash,
"sha256":SHA256.hash,
"sha384":SHA384.hash,
"sha512":SHA512.hash]
return algorithms[algo]
}
var algorithm: () = getAlgorithm(algo: "sha256")
link to screenshot
The error: "Generic parameter 'D' could not be inferred" is happening on line 4, I am not really familiar with generics. That's why I'm asking this question here. Could any of you please explain what's wrong with this code? That would be greatly appreciated.
I wan't to be able to specify a hashing algorithm and use it multiple times instead of having to do a switch statement and having to call the function there. (For efficiency reasons)
I'm working, tentatively, with the AudioToolbox API using Swift 2.0 and Xcode 7b6. The API uses a lot of c-language constructs, including function pointers. This is my first time working with commands like withUnsafeMutablePointer and unsafeBitCast. I am looking for a reality check to make sure that I am not way off base in what I am doing.
For example, to open a file stream, you use the following function:
func AudioFileStreamOpen(
_ inClientData: UnsafeMutablePointer<Void>
, _ inPropertyListenerProc: AudioFileStream_PropertyListenerProc
, _ inPacketsProc: AudioFileStream_PacketsProc
, _ inFileTypeHint: AudioFileTypeID
, _ outAudioFileStream: UnsafeMutablePointer<AudioFileStreamID>) -> OSStatus
Just the type signature of the function makes me start to sweat.
At any rate, the inClientData parameter needs to be an UnsafeMutablePointer<Void>, and the pointer will point to an instance of the same class I am working in. In other words, it needs to be a pointer to self. My approach is to call the function using withUnsafeMutablePointer like this:
var proxy = self
let status = withUnsafeMutablePointer(&proxy) {
AudioFileStreamOpen($0, AudioFileStreamPropertyListener
, AudioFileStreamPacketsListener, 0, &audioFileStreamID)
}
My first question is whether or not I'm using withUnsafeMutablePointer correctly here. I wasn't sure how to get a pointer to self - just writing &self doesn't work, because self is immutable. So I declared proxy as a variable and passed a reference to that, instead. I don't know if this will work or not, but it was the best idea I came up with.
Next, AudioFileStreamPropertyListener and AudioFileStreamPacketsListener are C callback functions. They each get passed the pointer to self that I created using withUnsafeMutablePointer in AudioFileStreamOpen. The pointer is passed in as an UnsafeMutablePointer<Void>, and I need to cast it back to the type of my class (AudioFileStream). To do that, I believe I need to use unsafeBitCast. For example, here is AudioFileStreamPropertyListener:
let AudioFileStreamPropertyListener: AudioFileStream_PropertyListenerProc
= { inClientData, inAudioFileStreamID, inPropertyID, ioFlags in
let audioFileStream = unsafeBitCast(inClientData, AudioFileStream.self)
audioFileStream.didChangeProperty(inPropertyID, flags: ioFlags)
}
That compiles fine, but again I'm not sure if I'm using unsafeBitCast correctly, or if that is even the correct function to be using in this kind of situation. So, is unsafeBitCast the correct way to take an UnsafeMutablePointer<Void> and cast it to a type that you can actually use inside of a C function pointer?
It's interesting that the inClientData "context" param is bridged as UnsafeMutablePointer, since I doubt the AudioToolbox APIs will modify your data. It seems it would be more appropriate if they'd used COpaquePointer. Might want to file a bug.
I think your use of withUnsafeMutablePointer is wrong. The pointer ($0) will be the address of the variable proxy, not the address of your instance. (You could say $0.memory = [a new instance] to change it out for a different instance, for example. This is a bit confusing because its type is UnsafeMutablePointer<MyClass> — and in Swift, the class type is itself a pointer/reference type.)
I was going to recommend you use Unmanaged / COpaquePointer, but I tested it, and realized this does exactly the same thing as unsafeAddressOf(self)!
These are equivalent:
let data = UnsafeMutablePointer<Void>(Unmanaged.passUnretained(self).toOpaque())
let data = unsafeAddressOf(self)
And these are equivalent:
let obj = Unmanaged<MyClass>.fromOpaque(COpaquePointer(data)).takeUnretainedValue()
let obj = unsafeBitCast(data, MyClass.self)
While the Unmanaged approach makes logical sense, I think you can see why it might be prefereable to use unsafeAddressOf/unsafeBitCast :-)
Or, you might consider an extension on Unmanaged for your own convenience:
extension Unmanaged
{
func toVoidPointer() -> UnsafeMutablePointer<Void> {
return UnsafeMutablePointer<Void>(toOpaque())
}
static func fromVoidPointer(value: UnsafeMutablePointer<Void>) -> Unmanaged<Instance> {
return fromOpaque(COpaquePointer(value))
}
}
Then you can use:
let data = Unmanaged.passUnretained(self).toVoidPointer()
let obj = Unmanaged<MyClass>.fromVoidPointer(data).takeUnretainedValue()
Of course, you will need to ensure that your object is being retained for the duration that you expect it to be valid in callbacks. You could use passRetained, but I would recommend having your top-level controller hold onto it.
See some related discussion at https://forums.developer.apple.com/thread/5134#15725.
I'm trying to write a general argmin function in Swift. Here is my code:
func argmin<X, Y:Comparable, R:SequenceType, where X== R.Generator.Element>
(f:(X)->Y, domain:R)->X{
var gen = domain.generate()
var best = gen.next()!
var minval = f(best)
while let this = gen.next() {
let value = f(this)
if value < minval {
best = this
minval = value
}
}
return best
}
I get the error message "Expected identifier to name generic parameter" when I try to compile this definition. I have no idea what this means. It sounds like an error one would get on calling the function, not defining it, but even then, I wouldn't understand it.
I'm just starting to learn Swift. Can you explain this message? (BTW, I know this function will blow up if called with an empty sequence. I'm not worrying about that yet.)
You have to remove this comma:
func argmin<X, Y:Comparable, R:SequenceType, where X== R.Generator.Element>
^
Placed that, it tells the compiler there's another generic parameter. The error message just says that - maybe in a cryptic way, but once you know, it's clearer what it means
I've tried dozens of things to get this right and just can't come up with anything that works. Can anyone tell me what's wrong with the following Swift code:
let incomingRequest: CFHTTPMessageRef? = CFDictionaryGetValue(self.incomingRequests as CFMutableDictionaryRef, unsafeAddressOf(incomingFileHandle!)) as CFHTTPMessageRef
The code above gives the error message: 'UnsafePointer<Void>' is not convertible to 'CFHTTPMessageRef'
I guess what I don't understand is how do I convert an 'UnsafePointer' returned by a Core Foundation function to the pointer type it should be (i.e. CFHTTPMessageRef in this case). How do I find documentation on how to do this. I've read everything I can find, but nothing so far explains how to recast return values to what they should have been in the first place. This has to be documented somewhere, doesn't it?
EDIT
Here's the code I'm having trouble with:
let incomingRequest = CFDictionaryGetValue(self.incomingRequests as CFMutableDictionaryRef, unsafeAddressOf(incomingFileHandle!))
unsafeBitCast(incomingRequest, CFHTTPMessageRef.self)
if (incomingRequest != nil) {
let success: Boolean = CFHTTPMessageAppendBytes(incomingRequest as CFHTTPMessageRef, unsafeAddressOf(data!.bytes) as UnsafePointer<UInt8>, data!.length)
if success { // Do something... }
The CFHTTPMessageAppendBytes call still gives a "Type 'UnsafePointer' does not conform to protocol 'AnyObject'". And the following 'if' check for 'success' complains that "Type 'Boolean' doesn not conform to protocol 'BooleanType'". What the heck is that about? Boolean isn't a Boolean type?
I find the strict type checking of Swift extremely frustrating. So far it is far more difficult to code in than Obj-C, C, or any of the other languages I've used. I'm sure it's because I just don't get it, or haven't found the right documentation, but this is really driving me crazy.
Use unsafeBitCast. As following example:
import Foundation
var x = "1"
var dict : NSMutableDictionary = [x: "2"]
var y = CFDictionaryGetValue(dict as CFMutableDictionaryRef, unsafeAddressOf(x))
let str: NSString = unsafeBitCast(y, NSString.self)
str == "2"
FYI: There is one quora related with unsafeBitCast. http://www.quora.com/Why-does-Swift-not-allow-implicit-type-conversion
I am quite new to swift and got a pretty weird compiler error:
Command
/Applications/Xcode6-Beta5.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/swiftc
failed with exit code 254
The Error occours when I ad the following lines to my code:
var response = HoopsClient.instance().collections["posts"]
response = response["_id"]
when I remove the second line everything compiles fine. I don't get it ^^
edit: The reason is probably that "response" is of type "AnyObject" according to the compiler... but shouldn't that be detected by xcode or give me a runtime error instead of this compiler error?
Try casting response as the type you're expecting. From what you're trying to do, instance().collections I would assume that it should return some type of dictionary.
var response = HoopsClient.instance().collections["posts"] as NSDictionary
That way, response now can handle subscripts so you could now (in theory) do:
response = response["_id"]
However
The error you get is regarding bad access to an array. This makes me think that instance().collections actually returns an array of some sort, containing Post objects.
Arrays in Swift can only handle Integer subscripts. If you want to access the information of a Post in the array, you can do something like this:
for post: Post in response {
println(post._id)
}
I know this is a long shot, but hope it helps.
Swift tends to throw error when it cant infer the type of an object, what you could probably do is add a conditional cast as follows
Im assuming that HoopsClient.instance().collections["posts"] is either a Dictionary or an Array
var response = HoopsClient.instance().collections["posts"]
if response is NSArray {
let item = response.objectAtIndex(0)
let reponseId: Post = item
}
if response is NSDictionary {
let item = response.objectForKet("_id")
let reponseId: Post = item
}
Any way, in my experience you should try to cast your variables when assigning from types that return AnyObject, xcode doesn't handle very well type inferring and when it's unable to infer the type the interface starts to throw error, like text editor uncoloring the code.