I have been trying to convert existing swift2.3 to swift3. I got Ambiguous use on intValue error at the following code.
jobPackageVersion.intJobPackageId = (JobPackageVersionDictionary["intJobPackageId"]! as AnyObject).intValue as NSNumber
Here is the full code
if let url = Bundle.main.url(forResource: "tblJobPackageVersion", withExtension: "csv") {
do {
let strData = try String(contentsOf: url)
let csv = CSwiftV(String: strData)
if csv.keyedRows != nil {
for dictionary in csv.keyedRows! { // [Dictionary<String, String>]
let JobPackageVersionDictionary = dictionary as NSDictionary // Cast to NSDictionary
let JobPackageVersionEntity = NSEntityDescription.entity(forEntityName: "JobPackageVersion", in: context)
let jobPackageVersion = JobPackageVersion(entity: JobPackageVersionEntity!, insertInto: context)
// Set object attributes
jobPackageVersion.intJobPackageId = (JobPackageVersionDictionary["intJobPackageId"]! as AnyObject).intValue as NSNumber
jobPackageVersion.intJobPackageVersionId = (JobPackageVersionDictionary["intJobPackageVersionId"]! as AnyObject).intValue as NSNumber
jobPackageVersion.intStatus = (JobPackageVersionDictionary["intStatus"]! as AnyObject).intValue as NSNumber
jobPackageVersion.intVersion = (JobPackageVersionDictionary["intVersion"]! as AnyObject).intValue as NSNumber
do { // Save object to database and clean up memory
try context.save()
context.refresh(jobPackageVersion, mergeChanges: false)
} catch let error as NSError { Logger.sharedInstance.logMessage("\(#function) JobPackageVersion Saving Error: \(error.userInfo)") }
} // for-loop
Logger.sharedInstance.logMessage("\(#function): Loaded \(csv.keyedRows!.count) tblJobPackageVersion records.")
} else { Logger.sharedInstance.logMessage("\(#function) CSV Parser Warning: no CSV data was parsed in tblJobPackageVersion.csv!") }
} catch { Logger.sharedInstance.logMessage("\(#function) Error reading contents of tblJobPackageVersion.csv.") }
} else { Logger.sharedInstance.logMessage("\(#function) Error locating URL for resource tblJobPackageVersion.csv") }
}
Any help would be appreciated.
Thanks.
You're trying to call intValue on an object of type AnyObject. As the error states, this is too ambiguous because both NSNumber and NSString have intValue properties. Xcode doesn't know which intValue to use, because both NSNumber and NSString fall under the AnyObject umbrella. Since Xcode is confused, you need to be more specific about what type your object is. Try something like this:
jobPackageVersion.intJobPackageId = (JobPackageVersionDictionary["intJobPackageId"]! as NSNumber).intValue
Note 1: You're probably going to get the same error with the other objects you call intValue on, but you can fix them accordingly.
Note 2: Be extremely careful about force unwrapping your objects using !. If the dictionary you're using ever returns nil your program will crash. Instead I would safely unwrap them using either an if let or guard statement depending on your use case. Something like this may work a little better:
guard let intJobPackageId = JobPackageVersionDictionary["intJobPackageId"] as? NSNumber,
let intJobPackageVersionId = JobPackageVersionDictionary["intJobPackageVersionId"] as? NSNumber,
let intStatus = JobPackageVersionDictionary["intStatus"] as? NSNumber,
let intVersion = JobPackageVersionDictionary["intVersion"] as? NSNumber
else {
print("one of the dictionary values is nil")
return
}
jobPackageVersion.intJobPackageId = intJobPackageId.intValue
jobPackageVersion.intJobPackageVersionId = intJobPackageVersionId.intValue
jobPackageVersion.intStatus = intStatus.intValue
jobPackageVersion.intVersion = intVersion.intValue
This may not be exactly what you want, but it should give you an idea on how to safely unwrap your objects so your app doesn't crash. You can play around with it and decide what's best for you.
Related
I have been changing some SWIFT code into OBJECTIVE-C, and I am stuck at certain part of the code, where I am unable to understand if it is a condition or something else.
Following is the code and I am stuck on 9th line stating :
if let channel1Buffer = buffer.floatChannelData?[0]
What I do not understand here is the above if condition is checking if "buffer.floatChannelData" is null, and then proceeding to get the first index, or is it something else.
input.installTap(onBus: 0, bufferSize:4096, format:format, block: { [weak self] buffer, when in
guard let this = self else {
return
}
print("Buffer Float Channel Data: ", buffer.floatChannelData as Any);
**if let channel1Buffer = buffer.floatChannelData?[0]** {
print("channel1Buffer: ", channel1Buffer);
/// encode PCM to mp3
let frameLength = Int32(buffer.frameLength) / 2;
print("frameLength: ", frameLength);
let bytesWritten = lame_encode_buffer_interleaved_ieee_float(this.lame, channel1Buffer, frameLength, this.mp3buf, 4096);
// `bytesWritten` bytes stored in this.mp3buf now mp3-encoded
print("\(bytesWritten) encoded");
this.file.append(this.mp3buf, length: Int(bytesWritten));
// #TODO: send data, better to pass into separate queue for processing
}
})
Let's take it part by part - buffer.floatChannelData?[0]
buffer has property named floatChannelData which is optional so it has ? at the end. then it takes that optional which accepts subscription [0] which also returns optional value. So it continues inside {} only if floatChannelData is not nil AND it's first value is not nil
Your Objc should look like
float *const *channelData = [buffer floatChannelData];
if (channelData) {
float *channel1Buffer = channelData[0]; //this might crash if channelData is empty
...
The line tries to assign the variable channel1Buffer the value of buffer.floatChannelData[0], and the code within {} is only executed if that assignment is successful. It may for instance fail if buffer.floatChannelData is nil or buffer.floatChannelData[0] is nil.
Im trying to do the following in Swift:
CFArrayRef attachmentsArray = CMSampleBufferGetSampleAttachmentsArray(sampleBuffer, 0);
if (CFArrayGetCount(attachmentsArray)) {
CFBooleanRef notSync;
CFDictionaryRef dict = CFArrayGetValueAtIndex(attachmentsArray, 0);
BOOL keyExists = CFDictionaryGetValueIfPresent(dict,
kCMSampleAttachmentKey_NotSync,
(const void **)¬Sync);
I have:
if CFArrayGetCount(attachmentsArray) != 0 {
let dict = CFArrayGetValueAtIndex(attachmentsArray, 0)
However, dict is a UnsafePointer instead of a dictionary like it should be. When I printed attachmentsArray I got
Optional({ DependsOnOthers = 0; })
I tried casting it to a CFDictionaryRef but it would fail in runtime.
How do I succeed in doing the above Obj-C code in Swift?
However, dict is a UnsafePointer instead of a dictionary like it should be.
No, not "like it should be". Look at the declaration:
func CFArrayGetValueAtIndex(theArray: CFArray!, _ idx: CFIndex)
-> UnsafePointer<Void>
It returns an UnsafePointer-to-void because that is what it is supposed to do. (In Objective-C it returns a const void *.)
When you invoke tableView.indexPathsForSelectedRows(), it returns an array of AnyObject type with the indexPaths of the rows selected in the order that user has selected them.
What I want is to sort the indexPaths in order to get ascending order. Before Swift, it could be achieved with this:
NSArray *sortedIndexPaths = [[tableView indexPathsforSelectedRows]
sortedArrayUsingSelector:#selector(compare:)];
But I have tried to implement it with Swift and it does not work :S
Anyone knows how to deal with this?
Thanks in advance!
it's simple code to sort array of NSIndexPath objects stored in paths variable .
The trick is in casting to [NSIndexPath]. Now you can have your array sorted.
let paths = tableView.indexPathsForSelectedRows() as [NSIndexPath]
let sortedArray = paths.sorted {$0.row < $1.row}
OR
if you wish to have separate function for that like:
func compare (obj0: NSIndexPath, obj1: NSIndexPath) -> Bool {
return obj0.row < obj1.row
}
then
let sortedArray = paths.sorted { compare($0, $1) }
I'm on Windows 7 at the moment so I cannot test but this is what I would expect to work. It may need a type annotation.
let paths = tableView.indexPathsforSelectedRows()
let sorted = paths.sortedArrayUsingSelector("compare:")
You can overload the < and > operators and then just call sort on it.
Define this globally
func <(left: NSIndexPath, right: NSIndexPath) -> Bool {
return left.section < right.section || left.row < right.row
}
Then you can just do this for ascending
let sortedIndexPaths = tableView.indexPathsForSelectedRows?.sort(<)
Obviously because of it returns an optional you would guard against it somehow, for example
guard let sortedIndexPaths = tableView.indexPathsForSelectedRows?.sort(<) else {
return
}
Here is Sort indexPathsForSelectedRows swift 4 code.
if var selection = tableView.indexPathsForSelectedRows
{
selection = selection.sorted{ $1.compare($0) == .orderedAscending }
}
If you have any issue ping me.
I am trying to use AXUIElementCopyAttributeValue from Swift. My best stab currently looks like this:
private func mainWindow() -> Optional<AXUIElementRef> {
let appRef = AXUIElementCreateApplication(self.pid())
var ptr: Unmanaged<AXUIElementRef>? = nil
var frontWindow: AXUIElementRef? = nil
let err = AXUIElementCopyAttributeValue(appRef, kAXMainWindowAttribute, &ptr)
if err == AXError(kAXErrorSuccess) {
frontWindow = ptr!.takeRetainedValue()
}
return frontWindow
}
Unfortunately kAXMainWindowAttribute is not in scope. This works in ObjC of course, but I can't figure out where the value is hiding when accessed from Swift. This isn't the first time I've had this problem, either, although previously I've been able to stumble around a bit and find it.
Also, I'd be happy to receive any stylistic suggestions here. I'm not convinced I'm doing this in the most natural way for Swift.
It is an old question but I still drop it here in case someone else searches for it:
let appRef = AXUIElementCreateApplication(pid)
var value: AnyObject?
AXUIElementCopyAttributeValue(appRef, kAXMainWindowAttribute as CFString, &value)
also, I assume you get the "Swift dynamic cast failed" error message because you try to cast from AXUIElement to AnyObject. You can cast it like so:
print(value as! AXUIElement)
This is not an answer yet, but perhaps might help someone get me an answer... I changed the code to this, in order to make forward progress:
func mainWindow() -> WBWindow? {
var result: WBWindow? = nil
var ptr: Unmanaged<AnyObject>?
let kAXMainWindow: CFString! = "AXMainWindow" as NSString
let appRef: AXUIElement! = AXUIElementCreateApplication(self.pid()).takeRetainedValue()
let err = AXUIElementCopyAttributeValue(appRef, kAXMainWindow, &ptr)
if err == AXError(kAXErrorSuccess) {
let val: AnyObject? = ptr?.takeRetainedValue()
if val != nil {
let value: AnyObject = val!
let description = CFCopyTypeIDDescription(CFGetTypeID(value))
println("type = \(description)")
}
else {
NSLog("got nil result")
}
// result = WBWindow(element: ptr?.takeRetainedValue() as? AXUIElement)
}
return result
}
This now builds -- yay! But, when running, the commented out line drops me into a stack:
0x1001b57ea: leaq 0x3f1a1(%rip), %rax ; "Swift dynamic cast failed"
I added the debugging code above and that produces:
type = AXUIElement
Sooooo. It's an AXUIElement that won't cast to one? Clearly I'm missing something obvious...
m_cAppIdMap is an object of a dictionary.
I want to iterate through the dictionary and to ind and remove the value pEvent.wTimerId is an unsigned short integer that is stored as key in the dictionary.
if(unsigned short* key in m_cAppIdMap) //error:Expected expression before 'unsigned'
{
(void)[self findAndRemoveEvent:pEvent];
(void)CFDictionaryRemoveValue(m_cAppIdMap,&wTimerId);
free(pEvent);
bReturn = YES;
}
I am getting an error when i try to iterate through the loop.
EDITED
-(BOOL)KillTimer:(unsigned short)wTimerId
{
stRs232Timer* pEvent;
BOOL bReturn=FALSE;
theLock = [[NSLock alloc]init];
if ([theLock tryLock]) {
// if ( m_cAppIdMap.Lookup(wTimerId,pEvent) )
// {
// (void)findAndRemoveEvent(pEvent); // remove from event queue
// (void)m_cAppIdMap.RemoveKey(wTimerId); // remove from app map
for(wTimerId in m_cAppIdMap)
{
(void)[self findAndRemoveEvent:pEvent];
(void)CFDictionaryRemoveValue(m_cAppIdMap,&wTimerId);
free(pEvent);
bReturn = YES;
}
[theLock unlock];
}
return bReturn;
}
I am getting error in this code 'selector element does not have a valid object type' . I need to search for wTimerId(key) in the m_cAppIdMap. Is it what i'm doing is correct.The commented lines above the for loop is the implementation of the same code in cpp. I coud not make the same logic over here in Objective C.
I think you meant to use for rather than if. Additionally, the fast enumeration syntax
for (x in y) can only be used on objects that implement the NSFastEnumeration protocol—typically NSArray. It looks like you're using C arrays, so this syntax won't work anyway.
you meant to write for (VARIABLE in CONTAINER) {...} -- but your sample uses if, not for.
side note: it is an error to mutate the collections you iterate over during the iteration.