Best ios questions in November 2010

libXcodeDebuggerSupport.dylib is missing in iOS 4.2.1 development SDK

25 votes

Note: getting this on Xcode 4.3.2? Check out the answer to this question.

Note: creating a symbolic link to use the 4.2 lib seems to work fine

cd /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1\ \(8C148\)/Symbols/
sudo ln -s ../../4.2\ \(8C134\)/Symbols/Developer

After upgrading from 4.2.0 (beta, I believe) to 4.2.1, the libXcodeDebuggerSupport.dylib file is missing, which results in:

warning: Unable to read symbols for /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib (file not found).

which I guess isn't good. Looking at the directory in question I note:

.../DeviceSupport/4.2 (8C134)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib

but

.../DeviceSupport/4.2.1 (8C148)/Symbols/System/
.../DeviceSupport/4.2.1 (8C148)/Symbols/usr/

the above two dirs make up all the content in the 4.2.1 folder. No "Developer" folder. Checking the /usr/ dir there, I find no libXcodeDebuggerSupport.dylib file in the lib dir either, so ln -s'ing isn't an option.

Worth mentioning: after the upgrade, I plugged the iPad in and had to click "Use for development" in Xcode organizer. Doing so, I got a message about symbols missing for that version, and Xcode proceeded to generate such, then failed. I restored the iPad and did "Use for development" again, and nothing about missing symbols appeared...

Update: deletion of /Developer and reinstallation of Xcode from scratch does not fix this issue.

Update 2: I just realized that after the reinstall of Xcode,

.../DeviceSupport/4.2 (8C134)/Symbols

is now a symbolic link,

lrwxr-xr-x  1 root  admin        36 Dec  3 17:17 Symbols -> ../../Developer/SDKs/iPhoneOS4.2.sdk

And the directory in question has the appropriate files. Maybe this is simply a matter of linking the 4.2.1 dir in the same fashion? I'll try that and see if Xcode freaks out. If someone who has this file could provide a md5 sum that would be splendid. This is what it says for me:

$ md5 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2\ \(8C134\)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib 
MD5 (/Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2 (8C134)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib) 
    = 08f93a0a2e3b03feaae732691f112688

If the MD5 sum is identical to the output of

$ md5 /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1\ \(8C148\)/Symbols/Developer/usr/lib/libXcodeDebuggerSupport.dylib 

then we're all set.

What I just did to solve this problem was:

cd /Developer/Platforms/iPhoneOS.platform/DeviceSupport/4.2.1 (8C148)/Symbols

and created the symlink was missing:

ln -s ../../4.2\ \(8C134\)/Symbols/Developer/ Developer

It solves my problem.

iOS Tests/Specs TDD/BDD and Integration & Acceptance Testing

23 votes

What are the best technologies to use for behavior-driven development on the iPhone? And what are some open source example projects that demonstrate sound use of these technologies? Here are some options I've found:

UPDATE: Wow, Kiwi rocks! I've found gold!


Unit Testing

Test::Unit Style

  1. OCUnit/SenTestingKit as explained in iOS Development Guide: Unit Testing Applications & other OCUnit references.
  2. CATCH
  3. GHUnit
  4. Google Toolbox for Mac: iPhone Unit Testing

RSpec Style

  1. Kiwi (which also comes with mocking & expectations)
  2. Cedar
  3. Jasmine with UIAutomation as shown in dexterous' iOS-Acceptance-Testing specs

Acceptance Testing

Selenium Style

  1. UIAutomation

  2. UISpec with UISpecRunner

  3. FoneMonkey

Cucumber Style

Frank vs. iCuke (based on the Cucumber meets iPhone talk)

Additions

Conclusion

Well, obviously, there's no right answer to this question, but here's what I'm choosing to go with currently:

For unit testing, I used Cedar with XCode 3 and love it! I chose Cedar because RSpec seemed like the way to go. (But, why is RSpec better than Test::Unit?) Now, although I prefer the RSpec style of unit testing to that of Test::Unit, I'm going to try out OCUnit/SenTestingKit because Apple develops it, and so it has a promising future and integrates better with XCode 4 (Like, you can have your tests run automatically in Xcode when you build your application target, whereas with Cedar, tests must run on a second target.).

For acceptance testing, I'm going to try on UIAutomation because Apple develops it, and so it has a promising future. It also works on the device and from Instruments, which allows for other cool features, like showing memory leaks. I'll just write the Gherkin as comments unless I figure out how to drive UIAutomation from the Gherkin. Also, with UIAutomation, I don't think you can run Objective-C code, but with Frank & iCuke you can. So, I'll just test the lower-level Objective-C stuff with unit tests. Or, worst case, create UIButtons only for the test build that when clicked, will run Objective-C code.

Which solutions do you recommend?

Related Questions

tl;dr

At Pivotal we wrote Cedar because we use and love Rspec on our Ruby projects. Cedar isn't meant to replace or compete with OCUnit; it's meant to bring the possibility of BDD-style testing to Objective C, just as Rspec pioneered BDD-style testing in Ruby, but hasn't eliminated Test::Unit. Choosing one or the other is largely a matter of style preferences.

In some cases we designed Cedar to overcome some shortcomings in the way OCUnit works for us. Specifically, we wanted to be able to use the debugger in tests, to run tests from the command line and in CI builds, and get useful text output of test results. These things may be more or less useful to you.

Long answer

Deciding between two testing frameworks like Cedar and OCUnit (for example) comes down to two things: preferred style, and ease of use. I'll start with the style, because that's simply a matter of opinion and preference; ease of use tends to be a set of tradeoffs.

Style considerations transcend what technology or language you use. xUnit-style unit testing has been around for far longer than BDD-style testing, but the latter has rapidly gained in popularity, largely due to Rspec.

The primary advantage of xUnit-style testing is its simplicity, and wide adoption (amongst developers who write unit tests); nearly any language you could consider writing code in has an xUnit-style framework available.

BDD-style frameworks tend to have two main differences when compared to xUnit-style: how you structure the test (or specs), and the syntax for writing your assertions. For me, the structural difference is the main differentiator. xUnit tests are one-dimensional, with one setUp method for all tests in a given test class. The classes that we test, however, aren't one-dimensional; we often need to test actions in several different, potentially conflicting, contexts. For example, consider a simple ShoppingCart class, with an addItem: method (for the purposes of this answer I'll use Objective C syntax). The behavior of this method may differ when the cart is empty compared to when the cart contains other items; it may differ if the user has entered a discount code; it may differ if the specified item can't be shipped by the selected shipping method; etc. As these possible conditions intersect with one another you end up with a geometrically increasing number of possible contexts; in xUnit-style testing this often leads to a lot of methods with names like testAddItemWhenCartIsEmptyAndNoDiscountCodeAndShippingMethodApplies. The structure of BDD-style frameworks allows you to organize these conditions individually, which I find makes it easier to make sure I cover all cases, as well as easier to find, change, or add individual conditions. As an example, using Cedar syntax, the method above would look like this:

describe(@"ShoppingCart", ^{
    describe(@"addItem:", ^{
        describe(@"when the cart is empty", ^{
            describe(@"with no discount code", ^{
                describe(@"when the shipping method applies to the item", ^{
                    it(@"should add the item to the cart", ^{
                        ...
                    });

                    it(@"should add the full price of the item to the overall price", ^{
                        ...
                    });
                });

                describe(@"when the shipping method does not apply to the item", ^{
                    ...
                });
            });

            describe(@"with a discount code", ^{
                ...
            });
        });

        describe(@"when the cart contains other items, ^{
            ...
        });
    });
});

In some cases you'll find contexts in that contain the same sets of assertions, which you can DRY up using shared example contexts.

The second main difference between BDD-style frameworks and xUnit-style frameworks, assertion (or "matcher") syntax, simply makes the style of the specs somewhat nicer; some people really like it, others don't.

That leads to the question of ease of use. In this case, each framework has its pros and cons:

  • OCUnit has been around much longer than Cedar, and is integrated directly into Xcode. This means it's simple to make a new test target, and, most of the time, getting tests up and running "just works." On the other hand, we found that in some cases, such as running on an iOS device, getting OCUnit tests to work was nigh impossible. Setting up Cedar specs takes some more work than OCUnit tests, since you have get the library and link against it yourself (never a trivial task in Xcode). We're working on making setup easier, and any suggestions are more than welcome.

  • OCUnit runs tests as part of the build. This means you don't need to run an executable to make your tests run; if any tests fail, your build fails. This makes the process of running tests one step simpler, and test output goes directly into your build output window which makes it easy to see. We chose to have Cedar specs build into an executable which you run separately for a few reasons:

    • We wanted to be able to use the debugger. You run Cedar specs just like you would run any other executable, so you can use the debugger in the same way.
    • We wanted easy console logging in tests. You can use NSLog() in OCUnit tests, but the output goes into the build window where you have to unfold the build step in order to read it.
    • We wanted easy to read test reporting, both on the command line and in Xcode. OCUnit results appear nicely in the build window in Xcode, but building from the command line (or as part of a CI process) results in test output intermingled with lots and lots of other build output. With separate build and run phases Cedar separates the output so the test output is easy to find. The default Cedar test runner copies the standard style of printing "." for each passing spec, "F" for failing specs, etc. Cedar also has the ability to use custom reporter objects, so you can have it output results any way you like, with a little effort.
  • OCUnit is the official unit testing framework for Objective C, and is supported by Apple. Apple has basically limitless resources, so if they want something done it will get done. And, after all, this is Apple's sandbox we're playing in. The flip side of that coin, however, is that Apple receives on the order of a bajillion support requests and bug reports each day. They're remarkably good about handling them all, but they may not be able to handle issues you report immediately, or at all. Cedar is much newer and less baked than OCUnit, but if you have questions or problems or suggestions send a message to the Cedar mailing list (cedar-discuss@googlegroups.com) and we'll do what we can to help you out. Also, feel free to fork the code from Github (github.com/pivotal/cedar) and add whatever you think is missing. We make our testing frameworks open source for a reason.

  • Running OCUnit tests on iOS devices can be difficult. Honestly, I haven't tried this for quite some time, so it may have gotten easier, but the last time I tried I simply couldn't get OCUnit tests for any UIKit functionality to work. When we wrote Cedar we made sure that we could test UIKit-dependent code both on the simulator and on devices.

Finally, we wrote Cedar for unit testing, which means it's not really comparable with projects like UISpec. It's been quite a while since I tried using UISpec, but I understood it to be focused primarily on programmatically driving the UI on an iOS device. We specifically decided not to try to have Cedar support these types of specs, since Apple was (at the time) about to announce UIAutomation.

Compensating compass lag with the gyroscope on iPhone 4

14 votes

I've been experimenting with the compass and gyroscope on iPhone 4 and would like some help with an issue I'm having. I want to compensate for the slowness of the compass by using data from the gyroscope.

Using CMMotionManager and its CMDeviceMotion object (motionManager.deviceMotion), I get the CMAttitude object. Correct me if I'm wrong (please), but here is what I've deduced from the CMAttitude object's yaw property (I don't need pitch nor roll for my purposes):

  • yaw ranges from 0 to PI when the phone is pointing downwards (as indicated by deviceMotion.gravity.z) and swinging counterclockwise and 0 to -PI when swung clockwise
  • when the device is pointing upwards, yaw ranges from -PI to 0 and PI to 0, respectively
  • and from the compass data (I'm using locationManager.heading.magneticHeading), I see that the compass gives values from 0 to 360, with the value increasing when swinging clockwise

All right, so using all of this information together, I'm able to get a value I call horizontal that, regardless of whether the device is pointing up or down, will give values from 0 to 360 and increase when the device is swung clockwise (though I am still having trouble when deviceManager.gravity.z is around 0 -- the yaw value freaks out at this gravity.z value).

It seems to me that I could "synchronize" the horizontal and magneticHeading values, using a calculated horizontal value that maps to magneticHeading, and "synchronize" the horizontal value to magneticHeading when I feel the compass has "caught up."

So my questions:

  • Am I on the right track with this?
  • Am I using the gyro data from CMDeviceMotion properly and the assumptions I listed above correct?
  • Why might yaw freak out when gravity.z is around 0?

Thank you very much. I look forward to hearing your answers!

Just trying to answer... correct me if i'm wrong..

1.Yes you are on the right track

2.gravity in CM is already "isolated" from user gravity (gravity value caused by user acceleration) thats why there is two gravity, the "gravity" and "userAcceleration" its on apple CM documentation // Note : not entirely isolated //

3. if you have a gravity 0 it mean that the coresponding axis is perpendicular with gravity. gravity.z is the iPhone screen thats why it -9.82m/s2 if you put on the desk with screen upright, actualy it hard to get 0 or maximum value of the gravity due to the sensor noise (it's normal, all sensor has a noise expecially cheap sensor).

what i do on my apps is I will switch my reference axis to other axis (in your case may be x or y) for certain limits, how the strategy is depend on the purpose or which side is your reference.

the other thing is, gyro is fast but its not stable, you need to re-calibrate the value for several interval. In my case every 5 second. I've experiment with gyro for calculating angle between two plane, i try with exacly 90 degree ruler and it will give an error about 0.5 degree every second try and keep increasing, but thats is mine, maybe others have a better method for avoid the error.

below is my steps "

  1. Init
  2. Read gravity XYZ -> Xg Yg Zg
  3. Check if Xg < 0.25 If TRUE try Yg then Zg // Note 1 = 1g = 9.82 m/s^2
  4. Read the compass and gyro
  5. Configure and calibrate the gyro using the compass and calulate based on which axis i use in point 3.
  6. If 5 second is pass then recalibrate, read the compass
  7. If the the difference with gyro reading is > 5 degree skip recalibartion the gyro.
  8. If the the difference with gyro reading is < 5 degree calibrate the gyro using compass value

Note: for number 7 : is to check if the phone affected with magnetic field or near huge steel such or high voltage electrical line or in noisy and heavy equipment in factory plant.

Thats all... Hope this could help you... And sorry for my english..

iOS simulator - How can I make default simulator as iPhone

10 votes

I downloaded latest XCode with iOS 4.2 version. When I'm testing any app in simulator, its running in ipad simulator by default. How can I make my simulator default to iPhone.

Solution#1

You can remove the iPad from the organizer. I haven't tried it, since I use both iPhone and iPad.


Solution#2

Create a keyboard shortcut to switch to to the iPhone simulator

top menu > Project > Set Active Executable > Targetname - iPhone Simulator

See these screenshots

Menu that we want to target with a keyboard shortcut How to setup the keyboard shortcut

NSComparisonResult and NSComparator - what are they?

5 votes

What NSComparisonResult and NSComparator actually are?

I've seen one of the type definitions, something like that:

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);

Is it some kind of function object? If yes, does it make any difference from a function pointer?

Also, I can't even guess what the ^ symbol means.

^ signifies a block type, similar in concept to a function pointer.

typedef NSComparisonResult (^NSComparator)(id obj1, id obj2);
//          ^                      ^                ^
//   return type of block      type name       arguments

This means that the type NSComparator is a block that takes in two objects of type id called obj1 and obj2, and returns an NSComparisonResult.

Specifically NSComparator is defined in the Foundation Data Types reference.

And to learn more about C blocks, check out this ADC article Blocks Programming Topics.

Example:

NSComparator compareStuff = ^(id obj1, id obj2) {
   return NSOrderedSame;
};

NSComparisonResult compResult = compareStuff(someObject, someOtherObject);