dyld: Symbol not found: _OBJC_CLASS_$_NSHTTPURLResponse - ios7

I wrote a Swift App with Xcode6 Beta 2 that does some networking using CFNetwork classes such as NSURLRequest and NSHTTPURLResponse.
The App works just fine with iOS 8, still, when I try to run it on an iOS 7 device or in the simulator running iOS 7, I get the following error when starting the App:
dyld: Symbol not found: _OBJC_CLASS_$_NSHTTPURLResponse
Referenced from: /Users/patrick/Library/Developer/CoreSimulator/Devices/B0A61F43-A67C-4803-8F5D-77C3972107BE/data/Applications/E0C7C89F-9EEE-4893-BE5B-FCC224F2855D/CheckYourWeather.app/CheckYourWeather
Expected in: /Applications/Xcode6-Beta2.app/Contents/Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator7.1.sdk/System/Library/Frameworks/CFNetwork.framework/CFNetwork
in /Users/patrick/Library/Developer/CoreSimulator/Devices/B0A61F43-A67C-4803-8F5D-77C3972107BE/data/Applications/E0C7C89F-9EEE-4893-BE5B-FCC224F2855D/CheckYourWeather.app/CheckYourWeather
I've done some research and found out that it's a linking problem. Still, I know that the classes I'm using are already available in iOS 7.
I also tried to add the CFNetwork.framework to the frameworks in the project settings and set it to optional, which only caused the App to crash during runtime.
The confusing part for me is: I wrote a Test App and just pasted my code I used in the main app into it and it worked just fine. Therefore the code is probably not the problem.
Deleting the App from the Simulator/Device, make a clean on the project and deleting Xcode's DerivedData haven't solved the problem.
Update:
Here's the code that causes the crash:
extension NSURLRequest {
class func plainPostRequest(url: NSURL, httpBody: String) -> NSURLRequest {
let urlRequest = NSMutableURLRequest(URL: url)
urlRequest.HTTPMethod = "POST"
urlRequest.HTTPBody = httpBody.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)
urlRequest.setValue("text/plain", forHTTPHeaderField: "Content-Type")
return urlRequest
}
}
But that's just an example. Any use of CFNetwork classes causes the App to crash during start.

This is a known bug with the iOS 8 SDK. As a workaround, move Foundation.framework before CFNetwork.framework in the list of frameworks to link to in the project settings.

For me just moving the Foundation.framework before CFNetwork.framework doesn't work. I need to close and reopen the project for it to work.

I was able to fix the problem by creating a new project and copying all my classes and assets there. Unfortunately I couldn't find out what the actual source of the problem was.
Any alternative solutions are greatly appreciated!

Moving Foundation.framework would not help so after further investigation the further method helped me.
I was able to resolve the problem by adding main.m file at Build Phases -> Compile Sources
Apparently it couldn't find the main.m file.

Related

Cocoapod fails to build on Travis-CI - "expected a type"

Objective: Build a cocoapod with CI support through travis-ci and coveralls.
Sub Objective: Keep git repo cleared of Pods/, while still including Podfile and Podfile.lock
Referenced repo: SRRandomUser
note: while indeed there exists a simple workaround solution (just removing Pod/ from my .gitignore, I ask this question because it will likely be helpful to understand this issue for future work.
Here is the situation I find myself in:
Using FSNetworking for network requests.
One of its classes, FSNData, has a class method withImage:jpegQuality:fileName: that accepts a UIImage and CGFloat as parameters.
Building this file without adding #import for UIKit and CoreGraphics results in a compiler error of expected a type with reference to the UIImage and CGFloat parameters
Locally, this is not a problem because I can add the module #imports, however since I am not committing the entirety of the Pods/ directory, these changes don't get pushed
Travis received the build and attempts to build, but since the FSNData doesn't have CoreGraphics or UIKit imported, when Travis goes to build the project, it throws the error in SRRandomUserGenerator since that class is #importing the affected FSNData class:
✗ Compile SRRandomUserGenerator.m (73 ms)
In file included from /Users/travis/build/spacedrabbit/SRRandomUser/Random Strangers/SRRandomUser/SRRandomUser/SRRandomUserAPIManager.h:10:
In file included from /Users/travis/build/spacedrabbit/SRRandomUser/Random Strangers/SRRandomUser/../../Pods/Headers/Public/FSNetworking/FSNConnection.h:36:
/Users/travis/build/spacedrabbit/SRRandomUser/Random Strangers/SRRandomUser/../../Pods/Headers/Public/FSNetworking/FSNData.h:42:18: error: expected a type
+ (id)withImage:(UIImage*)image jpegQuality:(CGFloat)quality fileName:(NSString*)fileName;
^
/Users/travis/build/spacedrabbit/SRRandomUser/Random Strangers/SRRandomUser/../../Pods/Headers/Public/FSNetworking/FSNData.h:42:46: error: expected a type
+ (id)withImage:(UIImage*)image jpegQuality:(CGFloat)quality fileName: (NSString*)fileName;
^
2 errors generated.
So, my questions are:
How do I either silence that warning so that the build runs anyhow or
How do I get that Pod to include the correct frameworks for building?
Many thanks in advance, SO.
I would recommend trying to search for the framework you need via Cocoapods.org. If you're using Cocoapods it usually means that it's been linked to your project (so there's really no way to silence the error, especially in this case where it seems that the framework you're using depends on other frameworks)

Warnings on XCAbstractTest.h, XCTestCase.h, and XCTestSuite.h

I recently turned on stricter warnings for a project, and Xcode started throwing warnings on some of Apple's classes. I'm not sure if this is an Apple bug, or if I'm doing something wrong. I'm using Xcode 6.1.1 on Yosemite.
TL;DR: adding some strict warning flags to your project starts throwing warnings in various XC*Test*.h headers. The issue is intermittent, but the steps below have reproduced the issue on multiple computers.
Steps to reproduce:
Create a new Xcode project via File → New → Project.
Choose iOS → Application → Single View Application.
For Product Name, type MyApp. Choose Objective-C and Universal. Save the project.
Build the project with CommandB. Run the tests with CommandU. Observe that they both finish with no errors or warnings.
Click on the Project to go to the Project Settings.
Click on the blue MyApp Project (as opposed to MyApp or MyAppTests targets).
Click on the Build Settings tab.
Search for Other Warning Flags.
Enter the following string for the Other Warning Flags for the app:
-Weverything -Wno-objc-missing-property-synthesis -Wno-objc-property-synthesis -Wno-direct-ivar-access -Wno-assign-enum -Wno-float-equal -Wno-sign-compare -Wno-switch-enum -Wno-gnu -Wnewline-eof
Build the app again. You should see three or four warnings about treating #import as #import, which is expected given the warnings you just enabled.
Clean the project with CommandShiftK
Build again. You may see extra warnings. If not, then you need to…
Delete the DerivedData folder, at least for this project. It is located at /Library/Developer/Xcode/DerivedData/MyApp-*, where * is some random identifier string. You may also need to delete /Library/Developer/Xcode/DerivedData/ModuleCache.
Clean and build again. And again. It may take a few times. Eventually...
You will see code and documentation warnings on XCAbstractTest.h, XCTestCase.h, and XCTestSuite.h. Screenshot:
As you can see, these warnings would be quite valid on my own code, but this is Apple’s framework code. Is there any way to stop these weirdly intermittent warnings from appearing? Or is it an Apple bug that the file gets warnings at all? I’m leaning Apple bug, because plenty of other Apple headers use #import instead of #import, and none of them is throwing warnings.
Update: I filed a radar: http://www.openradar.me/20038246
Update 2: I was able to glean some more information that may be helpful:
The issue appears to be at least partly related to where Derived Data is stored. See this screen recording, courtesy of Sam Marshall for details: http://cl.samdmarshall.com/a4Hy
Note that, when I reproduce the same steps as in Sam's video on my computer, I am not able to get rid of the extra warnings. They always come back. Possible differences between my and Sam's setups:
Sam is on Xcode 6.1, while I am on 6.1.1.
Sam is on Mavericks, while I am on Yosemite (10.10.2).
When I build in Xcode 6.3b2, I get an additional warning about "building module 'UIKit'". See screenshot: http://cl.ly/a3sK
Update 4: Radar was closed as a duplicate of an issue.
Update 5: I have a workaround, which is to disable the problem warnings on the Tests target only. Here’s a partial diff. Xcode won’t add the $(inherited) automatically, so you’ll have to add it yourself.
+ WARNING_CFLAGS = (
+ "$(inherited)",
+ "-Wno-documentation-unknown-command",
+ "-Wno-auto-import",
+ "-Wno-incomplete-module",
+ );

PhoneGap / iOS7 / XCode 5 / Mavericks: compiles but doesn't really work

I have used Phonegap several times but since the upgrade to Mavericks / Xcode5 everything has changed.
If I try to create a helloworld project, everything looks good: it compiles and launches the simulator or installs the app on my phone. The problem is if I try to add any Phonegap functionality, the it just won't work.
UPDATE: this is how I'm creating the project:
cordova create helloworld
cordova platform add ios
I have tried directly opening helloworld.xcodeproj in Xcode, using the "cordova run ios", "cordova prepare", "cordova build" commands but none of them seems to make any difference (some of these create and copy a lot of files, but there is no difference regarding the access to "device" variable)
The only way of debugging I have managed to use is to show alerts and try/catch blocks like this:
try {
alert(device);
// var text = '';
// var i = 0;
// for (var attribute in window) {
// text = text + '\n' + attribute;
// i++;
// }
// alert("total " + i + " keys: " + text);
} catch (err) {
alert(err);
}
Trying to read from "device" variable results in the following:
The text on this error suggests that one should use the following command
phonegap plugin add thePlugin
That indeed works: it adds the desired feature on the config.xml file, but the problem persits, so it does not look like an issue related to permissions. The same thing occurs when installing and trying to use other plugins, such as accelerometer or notifications.
I really liked Phonegap because it made things easier, but now it seems the opposite. One optoin is to use an older version of Phonegap and/or Xcode, but that's not what I'm looking for.
So, what is my configuration?
Mavericks 10.9.1
Xcode 5.0.2 (5A3005)
Phonegap / cordova 3.3.0
iOS 7.0.4 (iPhone 5) --> or the emulator
Any clues?
Thanks
I finally managed to solve this issue.
The solution is simple, yet it was difficult to detect.
Every time you add a plugin using the following command: cordova plugin add thePlugin you then need to run the cordova prepare command again. This is tricky, because if you take a look at the code after adding the plugin there is some setup/changes made. But these changes aren't enough, so cordova prepare might first seem redundant, but solves the issue.
So:
create the project
add as many plugins as you might use
start developing either:
(a) directly on the generated YOURAPP.xcodeproj file, and NEVER run
the cordova prepare commmand again, otherwise you will delete all your
changes
(b) work on the "general" www folder of your project and then run cordova prepare everytime you need to create a new version. Note:
you'll need to close the xcodeproj file in order to see any changes
I tend to think that alternative "(a)" should be the optimal, just make sure you don't overwrite your files or keep your files properly versioned

XCode 5 unit testing: starts my app

When I run my tests in XCode 5, the main window of my OS X app appears on the screen for a couple of seconds while running the tests. Why? Even if I uncomment all my tests it still opens my main window.
You are running application test, not logic test. This means an instance of your app will be started and then run the unit tests. This allow you to perform some integration test that require your app is running.
Here is the guide to setup application test and logic test.
If you want to change it to logic test (so it run faster and don't need to start your app first):
go to build settings for your unit test target
search Bundle
remove Bundle Loader and Test Host
Thats right, you have to delete the "Bundle Loader" and "Test Host" from your build settings.
But you have to add the necessary implementation files to your unit test target. The necessary files are what you want to use in your unit test cases. You need to do this because in logic tests XCode wont compile the whole application. So some of your files will be missing.
This is en error message if you have left out a file:
Undefined symbols for architecture i386:
"_OBJC_CLASS_$_Module", referenced from:
objc-class-ref in Lobic Network.o
objc-class-ref in Logic_Unit.o
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)
You can add the missing files by selecting the implementation file and bringing up the file inspector. There will be a section named "Target Membership" and there you can set the files target membership to your unit test also.
With XCTest, application files DO NOT need to be included within XCTest targets. The XCTest bundle is linked against the application which makes those files available during runtime.
To make this work, ensure the compiler option "Symbols hidden by default" is set to NO Within the Application target.
Here is a blog post with screenshots for clarity:
http://zmcartor.github.io/code/2014/02/24/slim-xctest-targets
The advantage of this approach is test target builds much much faster.
In XCode 7, removing Host Application does not work for me. Indeed I use the following to avoid app runs.
Setup Test Scheme Arguments
in main.m
static bool isRunningTests()
{
NSDictionary* environment = [[NSProcessInfo processInfo] environment];
NSString* testEnabled = environment[#"TEST_ENABLED"];
return [testEnabled isEqualToString:#"YES"];
}
modify main()
int main(int argc, char * argv[]) {
#autoreleasepool {
if (isRunningTests()) {
return UIApplicationMain(argc, argv, nil, nil);
} else {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
}
}
If the tests are for code that can run on desktop and mobile, you can run them without a simulator or hosting them within your app.
The trouble is that you cannot use the scheme chooser for your normal target (desktop or iOS) to run the test.
The following worked for me in Xcode6.
File > New Target...
Select Cocoa Testing Bundle from the OS X category.
Take care to select None from the target drop-down.
Click Finish. Add the relevant files to the new target as described above.
Now create a scheme to run the test.
Click the schemes chooser top-right and choose New Scheme..., click the drop-down and navigate down the list to the new target. Now you can choose the scheme from the schemes chooser, and use ⌘U to run the tests.
I just wasted a morning on this.
Project was created in XCode 4 and used SenTesting.
Tried migrating tests on XCode 5/XCTTest
Had same issue - app ran in simulator and test never started
after trying everything (change from app to logic tests, change to XCTest, remove SenTesting)
gave up created a clean XCode 5 project.
Added all my files in and tests ran ok.
May still have issues with Storyboard as these were built with XCode 4.
Drastic but it works so keep it as last resort.
On XCode5, the app does start. This answer shows how to change its delegate when running unit tests so that it exits right away: https://stackoverflow.com/a/20588035/239408

CFURLResourceIsReachable failed because it was passed this URL which has no scheme

I have a Cocoa program with deployment target 10.7, using the latest (10.8) SDK, I run it on 10.7.5 with XCode 4.6.2. In it I work with NSURLs with no problem whatsoever, everything works fine. One method I use is the NSURL method:
[newURL checkResourceIsReachableAndReturnError:&error]
with newURL a pointer to aNSURL. So far so good.
However, when I compile and run this, on a mac mini with Mountain Lion installed the following warning appears:
CFURLResourceIsReachable failed because it was passed this URL which has no scheme
and some other things now go wrong as well, such as
[dict setObject:url forKey:[url path]],
with dict a NSMutableDictionary and url a NSURL, the url simply is not added anymore to the dict. Strange isn't it? Did I miss a change in how NSURLs work from OS X 10.7 to 10.8?
Apologies if this already has been discussed here (I could not find it), thanks for looking at this question,
Marijn