Converting NSString to CString in Xcode Playground - xcode

When I attempt:
import Cocoa
var ns: NSString = "whatever"
var cs: CString = ns.UTF8String
println(cs)
in an Playground it reports this exception when executing the var cs: CString = ns.UTF8String statement:
fatal error: Can't unwrap Optional.None
Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).
The process has been left at the point where it was interrupted, use "thread return -x" to return to the state before expression evaluation.
* thread #1: tid = 0xbf05a5, 0x000000010401b02d libswift_stdlib_core.dylib`Swift._StringCore._growBuffer (#inout Swift._StringCore)(Swift.Int, minElementWidth : Swift.Int) -> Swift.COpaquePointer + 813, queue = 'com.apple.main-thread', stop reason = EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0)
* frame #0: 0x000000010401b02d libswift_stdlib_core.dylib`Swift._StringCore._growBuffer (#inout Swift._StringCore)(Swift.Int, minElementWidth : Swift.Int) -> Swift.COpaquePointer + 813
frame #1: 0x000000010401643f libswift_stdlib_core.dylib`Swift._StringCore.append (#inout Swift._StringCore)(Swift._StringCore) -> () + 607
frame #2: 0x0000000104016fa5 libswift_stdlib_core.dylib`Swift.+ #infix (Swift.String, Swift.String) -> Swift.String + 117
...truncated...
However the same code works as expected when compiled into an app. It looks like a Playground bug but does anyone know a workaround to convert an NSString to Cstring in the Playground?

I was able to get it to work in the playground by making cs a CString optional.
import Cocoa
var ns: NSString = "whatever"
println(ns)
var cs: CString? = ns.UTF8String
println(cs)
and if you need to unwrap the optional
if let str = cs{
println(str)
}

Related

Error while trying to get PID with FindWindowA and GetWindowThreadProcessId

I'm trying to get the PID of a program in rust using the Windows crate, with the FindWindowA and GetWindowThreadProcessId functions. My problem is that GetWindowThreadProcessId fails with error 1400.
fn main(){
unsafe{
let process_name: PCSTR = windows::s!("ac_client.exe");
let window = windows::Win32::UI::WindowsAndMessaging::FindWindowA(None, process_name);
let error = windows::Win32::Foundation::GetLastError();
println!(" {:?}", error); //0
let mut pId= 0;
windows::Win32::UI::WindowsAndMessaging::GetWindowThreadProcessId(window, Some(&mut pId));
let error = windows::Win32::Foundation::GetLastError();
println!("{:?}", error); // 1400
}
}
error 1400: ERROR_INVALID_WINDOW_HANDLE Invalid window handle.
It seems that you used a wrong window handle. I suggest you could try to check the window handle. And you should make sure that the thread is valid before you call the GetWindowThreadProcessId.

Using Error Handling in DDMathParser

I am using DDMathParser library in my project and I want to use error handling. I want the error to be displayed to user if he inputs wrong expression. What would be my catch block to detect and display related error and its position. Following is my sample code:
do{
var X = "(3 + 4" //Missed Closed Parenthesis
let evaluator = Evaluator()
let expression = try Expression(string: X)
let value = try evaluator.evaluate(expression)
}
catch
{
}
According to DDMathParser it should be Grouping error and by using Range with it it should specify its location where parenthesis got missed or any other error type occurred. Here is its Documentation
You have to cast the error as a GroupedTokenError to access the specific DDMathParser error messages.
do {
let X = "(3 + 4"
let evaluator = Evaluator()
let expression = try Expression(string: X)
let value = try evaluator.evaluate(expression)
} catch let error as GroupedTokenError {
print(error._code) // 1
print(error.kind) // MissingCloseParenthesis
print(error.range) // 6..<6
} catch let error as NSError {
print(error.debugDescription)
}
Note that you also have to add a generic error catching block for non-DDMathParser errors (in my example a generic ErrorType will be bridged to an NSError to display the contents the Cocoa way).

CoreAnimation uncommitted CATranaction NSComboBox

I am populating an NSComboBox with some data from the function below. After it is populated and I try to scroll through the items I get the CATransaction warning. Can anyone shed some light on why this is happening and what I can do to fix it? I have figured out that it may have something to do with changing the UI of the combobox on a thread other than the main thread but after that I am stuck.
func getAllRecords()
{
CATransaction.begin()
let url = NSURL(string: "http://URL.php")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!)
{
(data, response, error) in
var d = NSString(data: data, encoding: NSUTF8StringEncoding)
var arr = d!.componentsSeparatedByString("<") // spliting the incoming string from "<" operator because before that operator is our required data and storing in array
var dataWeNeed:NSString = arr[0] as! NSString // arr[0] is the data before "<" operator and arr[1] is actually no use for us
if let data = NSJSONSerialization.JSONObjectWithData(dataWeNeed.dataUsingEncoding(NSUTF8StringEncoding)!, options: NSJSONReadingOptions.MutableContainers, error: nil) as? NSArray
{
for dd in data
{
var name : String = dd["Name"]! as! String
var email : String = dd["Email"]! as! String
//println("Name: \(name)")
//println("Email: \(email)")
self.userComboBox.addItemsWithObjectValues([name])
}
}
}
task.resume()
CATransaction.commit()
}
Here is the warning I am getting from the debug area.
2015-06-14 13:54:04.756 Green Time Clock[2150:738395] Unexpected outstanding background CATransaction
CoreAnimation: warning, encountered thread with uncommitted CATransaction; created by:
0 QuartzCore 0x00007fff9ab4d6c2 _ZN2CA11Transaction4pushEv + 312
1 QuartzCore 0x00007fff9ab689a8 _ZN2CA11Transaction15ensure_implicitEv + 276
2 QuartzCore 0x00007fff9ab4d842 _ZN2CA11Transaction9set_valueEj12_CAValueTypePKv + 40
3 QuartzCore 0x00007fff9ab4f452 +[CATransaction setDisableActions:] + 38
4 AppKit 0x00007fff921a1b8c -[NSView(NSInternal) _updateLayerGeometryFromView] + 389
5 AppKit 0x00007fff921c7d09 -[NSView setFrameSize:] + 1129
6 AppKit 0x00007fff921c789a -[NSControl setFrameSize:] + 77
7 AppKit 0x00007fff922e3891 -[NSTableView setFrameSize:] + 256
8 AppKit 0x00007fff922e35f9 -[NSTableView _tileAndRedisplayAll] + 180
9 Green Time Clock 0x00000001000042d6 _TFFC16Green_Time_Clock14ViewController13getAllRecordsFS0_FT_T_U_FTGSQCSo6NSData_GSQCSo13NSURLResponse_GSQCSo7NSError__T_ + 2886
10 Green Time Clock 0x0000000100004463 _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT__ + 51
11 Green Time Clock 0x0000000100001e31 _TPA__TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFo_iTGSQS__GSQS0__GSQS1____iT__ + 81
12 Green Time Clock 0x0000000100004493 _TTRXFo_iTGSQCSo6NSData_GSQCSo13NSURLResponse_GSQCSo7NSError___iT__XFo_oGSQS__oGSQS0__oGSQS1___dT__ + 35
13 Green Time Clock 0x00000001000044fa _TTRXFo_oGSQCSo6NSData_oGSQCSo13NSURLResponse_oGSQCSo7NSError__dT__XFdCb_dGSQS__dGSQS0__dGSQS1___dT__ + 90
14 CFNetwork 0x00007fff8c09cba2 __49-[__NSCFLocalSessionTask _task_onqueue_didFinish]_block_invoke + 157
15 Foundation 0x00007fff9a75f7e8 __NSBLOCKOPERATION_IS_CALLING_OUT_TO_A_BLOCK__ + 7
Not sure what root issue is, I found that warning when updating string value to a NSTextView object and resolved it with following code just now.
Just make sure the updating process is handled in main thread.
// Link: NSTextStorage limitation on size and frequency of updates
dispatch_block_t block = ^ {
NSAttributedString *attributeString = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:#"%#\n", strLog]];
NSTextStorage* store = [_textViewOutputLog textStorage];
[store beginEditing];
[store appendAttributedString:attributeString];
[store endEditing];
[_textViewOutputLog scrollRangeToVisible:NSMakeRange([[_textViewOutputLog string] length], 0)];
};
if ([NSThread isMainThread]) {
block();
} else {
dispatch_async(dispatch_get_main_queue(), block);
}

Differences between Playground and Project

In the course of answering another question, I came across a weird bug in Playground. I have the following code to test if an object is an Array, Dictionary or a Set:
import Foundation
func isCollectionType(value : AnyObject) -> Bool {
let object = value as! NSObject
return object.isKindOfClass(NSArray)
|| object.isKindOfClass(NSDictionary)
|| object.isKindOfClass(NSSet)
}
var arrayOfInt = [1, 2, 3]
var dictionary = ["name": "john", "age": "30"]
var anInt = 42
var aString = "Hello world"
println(isCollectionType(arrayOfInt)) // true
println(isCollectionType(dictionary)) // true
println(isCollectionType(anInt)) // false
println(isCollectionType(aString)) // false
The code worked as expected when I put it into a Swift project or running it from the command line. However Playground wouldn't compile and give me the following error on the downcast to NSObject:
Playground execution failed: Execution was interrupted, reason: EXC_BAD_ACCESS (code=2, address=0x7fb1d0f77fe8).
* thread #1: tid = 0x298023, 0x00007fb1d0f77fe8, queue = 'com.apple.main-thread', stop reason = EXC_BAD_ACCESS (code=2, address=0x7fb1d0f77fe8)
* frame #0: 0x00007fb1d0f77fe8
frame #1: 0x000000010ba46e12 libswiftCore.dylib`Swift._EmptyArrayStorage._withVerbatimBridgedUnsafeBuffer (Swift._EmptyArrayStorage)<A>((Swift.UnsafeBufferPointer<Swift.AnyObject>) -> A) -> Swift.Optional<A> + 50
The build platform was OS X in all three cases. Does anyone know how to get Playground to play along?
Xcode 6.3.2. Swift 1.2. OS X 10.10.3 Yosemite
Not really the cause of that bug (it does look weird) but...
You will need to use optional chaining since value can be AnyObject:
import Foundation
func isCollectionType(value : AnyObject) -> Bool {
if let object = value as? NSObject {
return object.isKindOfClass(NSArray)
|| object.isKindOfClass(NSDictionary)
|| object.isKindOfClass(NSSet)
}
return false
}
var arrayOfInt = [1, 2, 3]
var dictionary = ["name": "john", "age": "30"]
var anInt = 42
var aString = "Hello world"
isCollectionType(arrayOfInt)
isCollectionType(dictionary)
isCollectionType(anInt)
isCollectionType(aString)
Also worth noting, NSArray and Array are different things:
NSArray is an immutable class:
#interface NSArray : NSObject <NSCopying, NSMutableCopying, NSSecureCoding, NSFastEnumeration>
whilst Array is a struct:
struct Array<T> : MutableCollectionType, Sliceable, _DestructorSafeContainer
With this in mind it might be surprising that isCollectionType(arrayOfInt) returns true - but there is a conversion happening.

Cocoa app crashes with EXC_BAD_ACCESS, but only on Mac OS X 10.6.6

I received a couple of crash reports from users running Mac OS X 10.6.6. My app crashes with the error below:
Exception Type: EXC_BAD_ACCESS (SIGSEGV)
Exception Codes: KERN_INVALID_ADDRESS at 0x0000000060443800
Crashed Thread: 0 Dispatch queue: com.apple.main-thread
Application Specific Information:
objc_msgSend() selector name: release
Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 libobjc.A.dylib 0x97d98edb objc_msgSend + 27
1 com.apple.LaunchServices 0x9038dc62 __LSSharedFileListItemDeallocate + 126
2 com.apple.CoreFoundation 0x9489d101 _CFRelease + 353
3 com.apple.CoreFoundation 0x948c75b2 __CFArrayReleaseValues + 210
4 com.apple.CoreFoundation 0x9489d101 _CFRelease + 353
5 ...myapp.AppName 0x00005d67 +[ABTools isLoginItem] + 1597
The code that breaks is trying to determine if the application has installed a login item. The 3rd to last line releasing the array fails (on 10.6.6, works on 10.5.8).
Can anybody see why that would happen? I looked at that code for way too long and I don't see it.
Thanks!
Mark
+ (BOOL) isLoginItem {
BOOL isLoginItem = NO;
UInt32 seedValue;
NSString *appName = [NSString stringWithFormat:#"%#.app", [[NSBundle mainBundle] objectForInfoDictionaryKey:#"CFBundleName"]];
NSString *appPath = [[NSBundle mainBundle] bundlePath];
LSSharedFileListRef loginItems = LSSharedFileListCreate(NULL,kLSSharedFileListSessionLoginItems,NULL);
if (!loginItems) {
return isLoginItem;
}
CFURLRef url = (CFURLRef)[NSURL fileURLWithPath:appPath];
NSArray *loginItemsArray = (NSArray *)LSSharedFileListCopySnapshot(loginItems, &seedValue);
if (!loginItemsArray) {
return isLoginItem;
}
for (id item in loginItemsArray)
{
if (LSSharedFileListItemResolve((LSSharedFileListItemRef)item,0,(CFURLRef*)&url,NULL) == noErr
&& [[(NSURL *)url path] isEqualToString:appPath]) {
isLoginItem = YES;
}
if (url) CFRelease(url);
}
if (loginItemsArray) [loginItemsArray release]; // THIS FAILS ON Mac OS X 10.6.6
if (loginItems) CFRelease(loginItems);
return isLoginItem;
}
In general, changes in .x.y releases should not cause previously working apps to crash. I suggest you file a bug at bugreport.apple.com.
Not sure about the problem that you are having, but I have used this code for my app and it is working perfectly Enabling launch on startup

Resources