How do I return a structure? - objective-c

I have this code that does not works since user is always null. It's weird since if I debug before returning data it's ok but after returning data is always null. How can I fix this? I really appreciate any comments, suggestions, or tips....
Notes: xcode 5 iOS 7
definition of data types
typedef struct {
char *locale;
} W_user;
.m test file
W_user *user;
-(void)test{
// user is always null
user = W_generateUserDefault();
}
methods
W_user *W_new() {
W_user *user = malloc(sizeof(W_user));
memset(user, 0x00, sizeof(W_user));
return user;
}
W_user *W_generateUserDefault() {
W_user *user = W_new();
user->locale = "es";
// but here user contains data
return user;
}

Try to change the test to this:
-(void)test{
// user is always null
W_user *user = W_generateUserDefault();
}
However, that's strange, because local variables hide global ones, not visa-versa.
Also, are you sure that you aren't debugging it in release mode? Try NSLog the user value to make sure it's nil.

Related

XCode UITesting check if a text field exists

I can't find any way to check if a text field exists without trying to get it which then fails the tests and shows an error if it can't be found. No matches found for TextField
Current code
XCUIElement *usernameTextField = app.textFields[#"username"];
Reason/detail
I've got a Objective C UITest in XCode which logs into my app in setUp and logs out in tearDown however sometimes my app is already logged in when the test starts (if the simulator has been used for anything else in the meantime). I'd like to be able to check to see if the username textfield exists in my setUp and then if it doesn't I can skip the login or call my logout function and continue as normal.
Not sure about Obj-C but here's how it would work in Swift.
let usernameTextField = app.textFields["username"]
if usernameTextField.exists {
do something
} else {
do something else
}
Here is the code in Swift, which can easily be converted to Obj-C:
// given:
// usernameTextField exists
// The username that is possibly entered there is "username".
// then:
if usernameTextField.value as! String == "username" {
// logged in
} else {
// not logged in
}

Force asynchrounous Firebase query to execute synchronously?

I'm designing an app that uses firebase to store user information. Below, I'm trying to write a method that queries the database, obtains the stored password, and checks it against the inputted password, returning a boolean based on whether or not they match.
-(BOOL) ValidateUser: (NSString*)username :(NSString*)password {
//initialize blockmutable true-false flag
__block bool loginFlag = true;
//initialize blockmutable password holder
__block NSString* passholder;
//check if user exists in database
//get ref to firebase
Firebase * ref = [[Firebase alloc] initWithUrl:kFirebaseURL];
//delve into users
Firebase * usersref = [ref childByAppendingPath:#"users"];
//search based on username
FQuery * queryRef = [[usersref queryOrderedByKey] queryEqualToValue: username];
//EXECUTION SKIPS THIS PORTION OF CODE
//get snapshot of things found
[queryRef observeEventType:FEventTypeChildAdded withBlock:^(FDataSnapshot *querySnapshot){
NSLog(#"%#", querySnapshot);
if no match found
if (querySnapshot.childrenCount == 0)
{
return false
loginFlag = false;
}
//otherwise store password of thing found
else
{
passholder = querySnapshot.value[#"hashed_password"];
NSLog(#"%#", passholder);
}
}];
//CODE SKIPS TO HERE
NSLog(#"%#", passholder);
//check inputted password against database password
if (![password isEqualToString:passholder])
{
//if they don't match, return false
loginFlag = false;
}
return loginFlag;
}
The problem, however, is that the method terminates and returns true before the firebase query runs. Essentially, the method executes, checks placeholder values against the inputted password, returns the value for the bool, AND ONLY THEN retrieves the password(within the block). I'm not sure how to force the block to run synchronously in order to actually return the correct boolean.
Is there any way to alter the flow of the method in order to actually have it return the correct boolean value? I'm at a loss.
Thanks so much
PS: I'm aware that Firebase supports a dedicated login functionailty (AuthUser and all that); however, this project is more of a proof of concept and so we're utilizing simple, unencrypted passwords stored in the main firebase.
To force your function to wait for some asynchronous action to complete, check out semaphores. Here's another StackOverflow question which tackles it: objective c - How do I wait for an asynchronously dispatched block to finish?

qvariant_cast causing segfault

Within qt's item/view framework, I'm trying to save a QColorDialog as user data and then retrieve that dialog as the editor, as well as during paint, in a tableview.
In my class constructor I do
QStandardItem *item = new QStandardItem();
QColorDialog *colorDlg = new QColorDialog(QColor(0,0,255), this);
item->setData(QVariant::fromValue(colorDlg), ColorDialogRole);
mTableModel->setItem(0,2,item);
then, inside my delegate's paint function I have
void ReportFigureTableDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
QVariant vColorDlg= index.data(ReportFigure::ColorDialogRole);
if(vColorDlg.isValid())
{
////////////////////////////////////////////////
// Program segfaults on the next line ... why?
////////////////////////////////////////////////
QColorDialog *colorDlg = qvariant_cast<QColorDialog*>(vColorDlg);
if(colorDlg != NULL)
{
painter->save();
QStyleOptionViewItem opt = option;
initStyleOption(&opt, index);
painter->fillRect(opt.rect, colorDlg->selectedColor());
painter->restore();
}
else
QStyledItemDelegate::paint(painter, option, index);
}
else
QStyledItemDelegate::paint(painter, option, index);
}
During runtime, the table shows up the first time (although with the wrong color ... different issue I assume). I double click to edit the cell and it brings up the dialog as expected. When I close, though, it segfaults on the indicated line. I don't understand why since I think I'm doing all the necessary checks.
You set the data on a QStandardItem object. Meanwhile you are retrieving the data on a QModelIndex object. Now why is the variant valid is a mystery. Maybe because ReportFigure::ColorDialogRole is equal to a build-in Qt role while it should be at least Qt::UserRole.
Anyway In the paint() method you can access the previously set item using
QStandardItem *item = mTableModel->itemFromIndex(index);

respondsToSelector: equivalent for CoreFoundation?

I have a CFArrayRef which mostly has CFDictionaryRef, but sometimes it'll contain other things. I'd like to access a value from the dictionary in the array if I can, and not crash if I can't. Here's the code:
bool result = false;
CFArrayRef devices = CFArrayCreateCopy(kCFAllocatorDefault, SDMMobileDevice->deviceList);
if (devices) {
for (uint32_t i = 0; i < CFArrayGetCount(devices); i++) {
CFDictionaryRef device = CFArrayGetValueAtIndex(devices, i);
if (device) { // *** I need to verify this is actually a dictionary or actually responds to the getObjectForKey selector! ***
CFNumberRef idNumber = CFDictionaryGetValue(device, CFSTR("DeviceID"));
if (idNumber) {
uint32_t fetched_id = 0;
CFNumberGetValue(idNumber, 0x3, &fetched_id);
if (fetched_id == device_id) {
result = true;
break;
}
}
}
}
CFRelease(devices);
}
return result;
Any suggestions for how I can ensure that I only treat device like a CFDictionary if it's right to do so?
(I'm dealing with some open source code that isn't particularly well documented, and it doesn't seem to be particularly reliable either. I'm not sure if it's a bug that the array contains non-dictionary objects or a bug that it doesn't detect when it contains non-dictionary objects, but it seems to me that adding a check here is less likely to break other code then forcing it to only contain dictionaries elsewhere. I don't often work with CoreFoundation, so I'm not sure if I'm using the proper terms.)
In this case, since it looks like you are traversing the I/O Registry, you can use CFGetTypeId():
CFTypeRef device = CFArrayGetValueAtIndex(devices, i); // <-- use CFTypeRef
if(CFGetTypeID(device) == CFDictionaryGetTypeID()) { // <-- ensure it's a dictionary
...
}
If you really need to send messages to NSObject's interface from your C code, you can (see #include <objc/objc.h> and friends, or call to a C helper function in a .m file), but these strategies are not as straight forward as CFGetTypeID(), and much more error-prone.

Why am I getting an EXEC_BAD_ACCESS when setting the info pointer of a FSFileOperationClientContext?

I am using FSCopyObjectAsync to copy files in a Cocoa app. Problem is, whenever I try to set the info field (an object of type void *) the application crashes because of an EXEC_BAD_ACCESS. I'm not sure what I'm doing wrong.
Here's my code:
// Start the async copy.
FSFileOperationClientContext *clientContext = NULL;
if (spinner != nil) {
clientContext->info = (__bridge void *)(spinner); // <- Problem here!
}
status = FSCopyObjectAsync(fileOp,
&source,
&destination, // Full path to destination dir.
CFSTR("boot.iso"), // Copy with the name boot.iso.
kFSFileOperationDefaultOptions,
copyStatusCallback,
0.5, // How often to fire our callback.
clientContext); // The progress bar that we want to use to update.
CFRelease(fileOp);
I'm using ARC, and it works if I comment out the lines dealing with clientContext and pass NULL in the last argument of FSCopyObjectAsync, but that severely cripples my application's functionality. It's definitely the assignment, therefore, that's causing the problem.
You are creating a NULL pointer without allocating it and then trying to reference it. Change the code so you allocate it on stack and pass its address like below.
// Start the async copy.
FSFileOperationClientContext clientContext;
if (spinner != nil) {
clientContext.info = (__bridge void *)(spinner);
}
status = FSCopyObjectAsync(fileOp,
&source,
&destination, // Full path to destination dir.
CFSTR("boot.iso"), // Copy with the name boot.iso.
kFSFileOperationDefaultOptions,
copyStatusCallback,
0.5, // How often to fire our callback.
&clientContext); // The progress bar that we want to use to update.
CFRelease(fileOp);