I'm trying to use CoreBluetooth's retrievePeripheral :
- (void)retrievePeripherals:(NSArray *)peripheralUUIDs;
The documentation says peripheralUUIDs should be a NSArray of CFUUIDRef. In the Apple sample project temperatureSensor, it is called as :
[centralManager retrievePeripherals:[NSArray arrayWithObject:(id)uuid]];
(uuid being a CFUUIDRef)
When I use the exact same code in XCode 4.5.1, IOS6, I'm getting a error :
Cast of C pointer type 'CFUUIDRef' (aka 'const struct __CFUUID *') to Objective-C pointer type 'id' requires a bridged cast
I would say (though I'm far from sure) that the reason it works in TemperatureSensor and not in my project is because TemperatureSensor seems not to use ARC whereas my project does.
Xcode suggests 2 ways of solving the problem : adding a __bridge or using CFBridgingRelease(). I tried them both and I'm under the impression that the function does not work [Edit] because the delegate methode didRetrievePeripheral: never gets called [/Edit] (my understanding is that these operation would change the C-style structs into objective-C-objects thus creating a NSUUID, and the method can't use it, but, again I'm really not sure)
So what should I do ? I've been searching on google for examples of retrievePeripherals using ARC, but without success.
In the temperature sensor change this line and run
LeDiscovery.m
-(void) startScanningForUUIDString:(NSString *)uuidString
{
[centralManager scanForPeripheralsWithServices:nil options:0];
}
change the word nil and assume 0.
If you want more check this link.
I hope its useful for you.
Turns out the problem was much simpler than that. I copied/pasted some code from TemperatureSensor, specifically the DidRetrievePeripheral. But it turns out, there's an error in this code (it's DidRetrievePeripheralS), so the delegate method never gets called. I think the bug is already reported.
Thanks/sorry
Related
I'm following an apple document, but unfortunately the examples are written on objective-c, but I have confidence with Swift language and can not understand the meaning of some things, in particular, in this example:
void RunLoopSourcesPerformRoutine (void *info){
RunLoopSource* obj = (RunLoopSource*)info;
[obj sourceFired];
}
this line: RunLoopSource* obj = (RunLoopSource*)info;
the parameter: void *info indicates that info is a pointer to void, then I can put the address of any type of data structure, following various apple documents I saw that the translation of this : void *info into swift language is :
info: UnsafeMutableRawPointer?
Now, the RunLoopSource* obj = (RunLoopSource*)info; line indicates that obj is a variable of type: RunLoopSource, and to this is assigned the value of (RunLoopSource *) info, but precisely What does it mean this statement? : (RunLoopSource *) info, and how it translates in swift language ?
Swift really hates pointer. These 2 lines of code can be converted to Swift as
func RunLoopSourcesPerformRoutine(info: UnsafeMutableRawPointer) {
let obj = info.assumingMemoryBound(to: RunLoopSource.self)
obj.pointee.sourceFired()
}
This specific expression is a "typecast": it's saying that info, which is declared to be a pointer-to-unknown-anything (void *) is actually known by the programmer to be a pointer to a RunLoopSource. This forcibly changes the type of the expression to make the compiler happy as it is assigned to obj.
It is equivalent to using as! in Swift and is idiomatic when you know the semantics of a void * but the syntax doesn't capture it.
(This attempts to answer your question as stated but I'm not sure if you are looking for more information. If so, please clarify and me or someone more expert in unsafe pointers in Swift can help out.)
What you are dealing with (void *info) is a C pointer-to-void, which arrives into Swift as a form of UnsafeRawPointer. This means that type info has been cast away and that memory is being managed elsewhere.
In order to work with this thing as what you believe it to be, i.e. a RunLoopSource, you need to characterize it explicitly as a RunLoopSource. In C, you would cast, as in the example code you posted: (RunLoopSource*)info. In Swift, you rebind.
Observe that in your case this whole thing has been made just a little more complicated by the fact that this UnsafeMutableRawPointer has been wrapped in an Optional, and will have to be unwrapped before you can do anything at all.
Assuming, then, in your case, that info is really an UnsafeMutableRawPointer? bound to a RunLoopSource, you can say:
let rlsptr = info!.assumingMemoryBound(to: RunLoopSource.self)
let rls = rlsptr.pointee
Now rls is a RunLoopSource and you can work with it however you like. Keep in mind, however, that the memory is unmanaged, so you should work with it only here and now.
EDIT By the way, Apple has a really nice document on this entire matter: https://swift.org/migration-guide/se-0107-migrate.html
I'm running into an issue with my swift 2 conversion of an Apple provided example for displaying an AVMutableComposition. This is a really useful project if you're trying to visualize your AVComposition to see what might be going on under the hood.
Update: I added print statements to each function to see the order they are being called, and who is calling them, in comparison to the Obj-C project.
Two Issues that I'm seeing that seem pretty important:
synchronizePlayerWithEditor() is not getting called after buildTransitionComposition(_:andVideoComposition:andAudioMix:)
observeValueForKeyPath(_:...) is NOT being called in the same order as the Obj-C project
Posting the snippet here to get the calling function as it's kind of useful
Obj-C
NSLog(#"%d %s %#", __LINE__, __PRETTY_FUNCTION__, [[NSThread callStackSymbols] objectAtIndex:1]);
Swift
func functionnYouWantToPrintCaller(yourNormalParameters..., function:String = __FUNCTION__){...}
print("\(__LINE__) \(__FUNCTION__) \(function)
Here is Apple's AVCompositionDebugViewer project I'm working from: https://developer.apple.com/library/mac/samplecode/AVCompositionDebugViewer
My github repo:
https://github.com/justinlevi/iOSAVCompositionDebugViewerSwift
I think the issue might be stemming from something in the keyValueObservation code although I'm not entirely sure at this point.
The issue ended up being in SimpleEditor.swiftbuildCompositionObjectsForPlayback` method. There were some global variables that were being defined incorrectly.
Everything seems to be working as expected now.
https://github.com/justinlevi/iOSAVCompositionDebugViewerSwift
The code I have currently functions correctly, however, at present it throws a warning. As the app is to be shipped soon and this particular component is responsible for key functionality I figured it would be worth asking.
The code is as follows (modified slightly):
REC_AppAuthPage *thisView = ((UINavigationController*)self.window.rootViewController).visibleViewController;
[thisView receiveSomeString:someString];
'REC_AppAuthPage' is a UIViewController class.
The warning being thrown is:
"Incompatible pointer types initializing 'REC_AppAuthPage *' with an expression of type 'UIViewController *'"
My question is, is it okay to ignore the warning and release or does something need to be changed? If so what?
Cheers
Add a specific cast to the assignment:
REC_AppAuthPage *thisView = (REC_AppAuthPage *)((UINavigationController*)self.window.
rootViewController).visibleViewController;
I have used JSONKit library to parse dictionary and get JSON string. All is well and good with normal devices (iOS7). But when i run application in iOS 7-64 bit simulator it was crashed at below method:
- (NSString *)JSONString;
And the crash message shows on this line of JSONKit.m class
Tried to find out it but not able to sort out.
And i ended up with our native NSJSONSerialization class.
Did any one sort out this?
As far as I know there are more than one patch versions that tried to fix the 64 bit crash issue you mention here, e.g. JSONKit 64bit crash fix by heroims.
They all tried to fix that troublesome line for getting tagged pointers, "the very first thing that a pointer to an Objective-C object "points to" is a pointer to that objects class":
*((void **)objectPtr)
I wrote a simple code to emulate the crash,
NSDictionary *dic = #{#"hi":#(4)};
void *keys[2], *objects[2];
CFDictionaryGetKeysAndValues((CFDictionaryRef)dic, (const void **)keys, (const void **)objects);
void *objectPtr = objects[0];
void *another = *((void **)objectPtr);//Only works for 32 bit machine
NSLog(#"%#",[another description]);
My guess is that for 64bit compiler, apple changed the tagged pointer implementation for NSNumber, which causes the crash. Check the discussion for tagged pointers here stackoverflow.com/questions/5819387/why-is-nsnumber-immutable
If I change NSDictionary *dic = #{#"hi":#(4)}; to NSDictionary *dic = #{#"hi":#"hello"}; it won't crash.
The patch I mentioned here just used object_getClass, which seems to defeat the original purpose, "Why not just use object_getClass()?..." (the comments right above)
So like you said now I also end up using NSJSONSerialization class.
There is an patched version of JSONKit here that fixes the 64 bit issues among others.
Apologies if this is too vague... this is my first post here and I'm well and truly stumped on this issue!
I've been attempting to transition an iOS Xcode project using Audio Units to ARC, but it appears to have broken the functionality of the audio unit processing class. Some symptoms... When I attempt referencing 'self' in AUProcessor.mm, the AUProcessor class is referred to as 'const*', whereas in the pre-ARC version, there was no 'const*' mentioned.
This pointer to 'self' produces the following error:
callbackStruct.inputProcRefCon = self;
[error] Assigning to 'void *' from incompatible type 'AUProcessor *const __strong'.
I can remove the error by adding (__bridge void*) ahead of self, which allows the project to compile. However, the Audio Unit processor doesn't work in the app.
I can't see anything elsewhere in the code that is significantly different from the pre-ARC version in terms of how the class is referenced.
Let me know if more context is required.
Thanks in advance!!
(BTW, thank you to all contributors to these forums... they are truly a wonderful resource for keen yet inexperienced programmers!)
Typically, (__bridge void*) would be the correct cast here. This means "take a pointer to this object without applying any memory management; I promise I'll hold onto it for as long as it's needed." (That last part is just implied, but if you don't, you'll crash.)
Are you certain that self continues to exist for as long as this audio unit? If nothing has a strong reference to self, then it will disappear and inputProcRefCon will become a dangling pointer.
When you say "doesn't work in the app," what do you mean? Does it crash? Does the callback not happen? When the callback happens, does it not have the right data?
I managed to resolve my issue by excluding the troublesome class from ARC using the compiler flag -fno-objc-arc.
Its not a very satisfying conclusion but at least my app is working again... Looks like I'm going to need to learn more about memory management!
The code below is working for me with the MusicPlayer API. I don't know that it is correct but I am not getting any errors or memory leaks. Hope it helps!
// assign the callback:
MusicSequenceSetUserCallback( sequence, MyEventCallback, (__bridge_retained void *)self );
//the callback method:
void MyEventCallback(void *inClientData,
MusicSequence inSequence,
MusicTrack inTrack,
MusicTimeStamp inEventTime,
const MusicEventUserData *inEventData,
MusicTimeStamp inStartSliceBeat,
MusicTimeStamp inEndSliceBeat)
{
struct MyMusicEventUserData* userEventData = ( MyMusicEventUserData *)inEventData;
[(__bridge MusicPlayerController*)inClientData MIDIEvent:userEventData
eventTime:inEventTime
startSliceBeat:inStartSliceBeat
endSliceBeat:inEndSliceBeat];
}