PojectName-Swift.h Not found while using Both Swift and ObjC codebase - objective-c

I had a perfectly working ObjC project integrated with Apple WatchKit App with Multiple Targets. Only one of the Targets is linked with the WatchKit App.
I am moving my classes to swift and hence there are ModuleName-Swift.h files being used in my code.
Followed steps given in ModuleName-Swift.h file not found in xcode8 and I have ensured to add the “$(PROJECT_NAME)-Swift.h” under Projects > Build Settings > Objective-C Generated Interface header name.
But when I go to the build settings - it shows as Objective-C generated interface header name for the project target and Swift_ObjC_Interface_header_name for WatchKitApp Target
Error thrown by compiler : ProjectName-Swift.h file Not found
Is this causing the error? Not sure what I am Missing.
This is how I've linked the -swift.h files in Other targets

The issue was:
There were Unit test cases that were failing, disrupting further Compiling of the Project
Quick Fix:
The ObjectiveC Classes had Unit test cases associated with it.
Some of the Unit tests were failing due to changes to the main code base.
I had to uncheck the the following under Edit Schemes > Build so that they don't Build while running the WatchKit App.
I agree I will have to update the test cases to work with the Updated app, But the issue of Watch App not working is Fixed! :)

Related

Unknown class in Compiled Swift Framework embedded in Objective-C Project

I have a framework binary built with Swift that I'm trying to incorporate into an Objective-C project. However the class in the framework isn't available.
In the swift framework, the class is defined like this:
#objcMembers
#objc public final class Messaging: NSObject, UINavigationControllerDelegate, LogsManagerDelegate {
...
}
I drag the archived and exported framework directly into the project to use and make sure the Defines Module is set to Yes in the Build Settings.
In the Objective-C I try to use the framework:
#import ContactAtOnceMessaging;
#implementation MessagingExperience
Messaging *messaging; // Unknown type name 'Messaging'
...
#end
If I drag the code for the framework directly into the project, Messaging is a known class so I know the Swift is okay.
I also tried changing the import to the following, but that didn't work.
#import "ContactAtOnceMessaging/ContactAtOnceMessaging-Swift.h"
I also tried using CocoaPods to import the framework and that hasn't helped.
What am I doing wrong?
I can confirm that I experienced the same problem as you. I was also able to resolve it. I'm not sure if the original problem was caused by an anomaly somewhere in my configuration. I did, however, test the following procedure and found it to work reliably with Xcode 9.3.
I first made a test Swift framework named Dynamic-Framework-Tester, in an Xcode project, and set it to be copied to an absolute path on every build.
I then performed the following steps to setup my Objective-C project:
Made a new project with Objective-C as the language.
Dragged the framework from its absolute path into the project without choosing "Copy items if needed".
Deleted the framework from Linked Frameworks and Libraries because it will get added automatically in step (4).
Added the framework to Embedded Binaries.
In build settings, set Always Embed Swift Standard Libraries to Yes.
Added my custom framework path to the Framework Search Paths setting in the build settings.
In the Objective-C project, I imported the framework using
#import Dynamic_Framework_Tester;
and called a method exposed in the framework from Objective-C.
Using a simulator, I was able to update the framework and have the changes applied on subsequent runs of the app.

Test target can't find app's Objective-C Generated Interface Header

I have an app target which includes a mix of Objective-C and Swift code. The Swift code uses Objective-C code and vice versa.
The app target is compiling fine, but when I try and compile my test target, it can’t find the “Objective-C Generated Interface Header”. Although the app target compiles fine, when it comes to compiling the app source code in the test target, the #import “MyApp-Swift.h” file results in a “file not found” error from the compiler.
If I check in the DerivedData folder, I can see the MyApp-Swift.h file inside the DerivedSources folder for the app MyApp.build folder, but not for Tests.build (which has no DerivedSources folder).
Does anyone know how to resolve this issue please?
Ensure that the app source files are only included in the app target and not in the test target as well.
Although it used to be necessary to include the app source in both the app and test targets, this is no longer the case.

No such module <product module name> in XCode Unit test

I have a mixed objective-c and Swift project and I try to write Unit tests for it.
My project name is: Alphaproject
my product module name is: Alphaproject
I set to YES Defines Module in my main Target (Alphaproject)
and set to YES EnableTestability for Debug only in this same Target.
In my Test class, I try to import my product module name:
#testable import Alphaproject
Additional notes:
all my projects files are only part of the main target
my test files are only part of the test target
My scheme for Test is set to Build Debug configuration.
I also tried to clean the Build folder (ALT + Clean)
The project doesn't have any error when compiling or trying to run tests except this "No such module Alphaproject"
Any other ideas?
OK! The problem was coming from the fact that I had arm64 in my Debug configuration for Valid Architectures.
As the main target also doesn't contain arm64 in Valid Architectures, It couldn't apparently find the module...
I think apple can make better work on displaying a proper error here. (Apple, if you read me, please)
In my case, the initial Xcode project was Objective-C, and I added testing targets that were Swift-based, and the import <Product Moodule Name> failed. I ensured that Defines Module was set to YES in Build Settings, but still got the error as indicated. The fix for me was to add a Bridging Header into the Objective-C main project.

Dependency Management for iOS Library

First off: Why is dependency management for obj-c projects such a pain?!
I am writing a wrapper for my RESTful service in objective-c. The server is a simple sinatra app running locally on 'http://localhost:4567'.
I've included RestKit by following the steps outlined here.
I know RestKit is 'installed' correctly into my project because when I do #import <RestKit/RestKit.h> the project builds just fine.
Now, I'm testing my library using SenTesting.Framework. I have a class in my main library that looks like this:
#import "CITWCore.h"
#import <RestKit/RestKit.h>
#implementation CITWCore
- (id)init
{
self = [super init];
if (self) {
RKObjectManager *manager = [RKObjectManager objectManagerWithBaseURL:#"http://localhost:4567"];
// Initialization code here.
}
return self;
}
#end
And my unit test class:
#import "CITWCoreTests.h"
#implementation CITWCoreTests
- (void)testItCreatesAnInstance
{
CITWCore *newCoreObject = [[CITWCore alloc]init];
STAssertNotNil(newCoreObject, #"new object should not be nil");
}
#end
When I run the tests using ⌘U the test fails with this message:
error: testExample (CITWCoreTests) failed: -[__NSCFString isIPAddress]: unrecognized selector sent to instance 0xa115880
The error is being triggered by line 292 in RKClient.m
if ([newBaseURLString isEqualToString:#"localhost"] || [hostName isIPAddress]) {
There is a header file in the RestKit project called "NSString+RestKit.h" which contains the -isIPAddress method declaration, and as far as I can tell it is getting included, so I have no idea why the compiler/run-time does not know about that particular method. Is there something wrong with the way I've configured my testing target? How can I create an instance of RKObjectManager and get this test to pass?
More abstractly: How are people managing dependencies like this? I'm looking at things like VenderKit, but it seems lacking in documentation and I don't think I have the proper understanding of how compilers and linkers work to go to that big of an abstraction. What are some general guidelines when linking static libraries into my project, which is itself a static library?
Double check that your project build settings for "Other Linker Flags" has "-all_load" and "-ObjC" on your build target. While you are in there, check that you created the "Header Search Paths" entry ("$(SOURCE_ROOT)/RestKit").
The "Installing-RestKit-in-Xcode-4.x" page that you linked to, is slightly out of date with a) Xcode and b) RestKit HEAD (the build process was simplified recently. FMI see the mailing list.
If you want to see a project correctly setup (I just created it recently, with the newest Xcode and Restkit) take a look at https://github.com/lottadot/lottadot-restkit-ios-rails3-1-advanced
My guess is if you clone that project, edit it's configuration and remove "-all_load" you will see the exact same error, when you run it.
In this case, you need to find the file (or image/library) which defines/exports -[NSString isIPAddress]. Then you would need to add that file to your compile phase (if it is a source file), or link the library to your final binary (if it is a library or object file). In addition to linking it to your app, you will also need to compile and or link it into your unit test executable.
I know RestKit is 'installed' correctly into my project because when I do #import the project builds just fine.
#importing will not necessarily link or compile all of the necessary dependencies. You may have to do this manually. Xc4 may detect the dependency automatically, and build and link it for you if the option is enabled -- but it does not always get it right (it's good for basic dependencies).
Why is dependency management for obj-c projects such a pain?!
It's really not, IMO. Specifying files to compile and libraries to link with is something you'll need to get used to when compiling C family languages. Unless you want to be more specific about this criticism…
How are people managing dependencies like this?
Add the dependent projects to your Xcode projects. Configure them as build dependencies -- this will ensure they build before your app is built, and that the builds are up to date. For static libraries (targeting iOS), save the link stage for the final executables. In more complex scenarios, you will want to use xcconfig files in order to easily define build settings for any/all dependencies.
One simple solution is to use cocoapods, which is good dependency management tool similar to maven in Java world.
CocoaPods is quite a powerful and maturing dependency management tool that can manage libraries, the libraries these depend on (transitive dependencies) as well as compiler and header flags.
It works by linking your project to another workspace that includes the libraries in source form, where the main target emits a static lib. This gives a good compromise between speed and being able to see the source-code.

Is it possible to unit test a static library project using XCode's SenTestingKit?

I've created an iOS unit test target for doing logic tests following the steps provided in Apple's documentation.
However my build fails and i get the following error:
Undefined symbols:
"_OBJC_CLASS_$_MyClass",
referenced from:
objc-class-ref-to-MyClass in LogicTests.o ld: symbol(s) not
found collect2: ld returned 1 exit
status
Ordinarily, if I wanted to use my static library within an application I would include the library.a file, and the headers(including the MyClass.h file...). Is something additional required to run logic tests on a static library WITHIN that same project if my test cases are utilizing MyClass.h ?
Tjhanks
Due to the nature of static libraries, you can't perform application tests, which by the sound of it is what you are trying to do. However, you can perform logic tests.
You were correct in your observation about unit testing in the client application.
The Xcode template optionally includes unit tests, but if you go to the build settings for that unit test you will see it doesn't specify a test host or bundle loader. This is because of the nature of static libraries. They are not applications, they are libraries - so you can do logic tests, you cannot do application tests.
Application tests you may wish to perform on your static library may include the following scenario:
My library creates an SQLite database at runtime, I wish to
perform a unit test to check everything is inserting and/or updating
as expected.
In order to test this with unit tests, one must create another application which includes or otherwise is dependant of your library. This application then includes your library and application tests may then be set up there.
Apple has a sample up (UnitTests) that shows how to do this:
https://developer.apple.com/library/ios/#samplecode/UnitTests/Introduction/Intro.html#//apple_ref/doc/uid/DTS40011742
I actually just solved it. I had to copy all of the .m files in my project to the LogicTest target's 'Compile Sources'. As well as add the frameworks the sources reference to the 'Link Binary With Libraries' section of the target.
I hope this helps others
Yes, Xcode 4.2 has a template for Cocoa Touch Static Library with tests.