Why should your constant implementation file be added to your frameworks target? - iphone

I was reading an old post on here: Constants in Objective-C which talks about how to set up a file for your constants when doing iPhone dev in objective C. One of the responses (which got a lot of helpful votes) says that "Constants.m should be added to your application/framework's target so that it is linked in to the final product."
My question is, how do you do this, and what is accomplished by this? Does this make it so you don't have to import the constants file in the files you need to use it for?
Also, does the same method talked about in the response apply to integer constants, etc?
Thanks.

It makes it so that the constant values are available in the linked binary. Your header file will be included by reference (since you #import it) but the compiler needs to know that you want that .m file to be part of the final binary.
In XCode 4, choose your project from the top of the Project Navigator (the file tree view tab on the left). Select your target from the list of targets that appears in a new column to the right of the Project Navigator. Select the Build Phases tab on the right. Open up the Compile Sources item. Here are all of the files that are being compiled to build your binary. Make sure your constants file is in here. If it is not, find it in the Project Navigator and drag it into the Compile Sources pane.

In Xcode 4, beside the method Seamus mentioned, you can also select that .h file, open right view (at the top-right conner, there're three), in the first tab there's target membership, select the target you want to add it to and you're set.
You have to make sure you #import and also the file has to be in build target. #import make sure your complier know where to look for, include the file in target make sure when complier go and look, there's that file (The file won't be include in your build if it's not part your building target even it's in your project).

Related

Sharing classes between iphone and the apple watch

I was hoping someone could shed some light on this. I've tried researching but couldn't really find anything...
Is there a way to share a class between the iPhone application and the apple watch extension?
Let's say in the watch extension I have a class myClass; I am unable to use this class within the phone application. Is there anyway to get around this?
iPhone application and the apple watch extension are basally different targets in your project. For each file (except the .h file), you can specify which target you want to include it to.
There are at least two ways to do this.
1) From the top menu select View -> Utilities -> File Inspector. The right panel will show up and you should find the Target Membership section with checkboxes next to the available targets for you project. Check the targets you want to include this file to. In this case, the iPhone app and the WatchKit extension.
2) You can also click on the project to go to the project settings. Select the target you want. (i.e. iPhone app or WatchKit extension), click on the Build Phases tab. In the Compile sources, you can click on the "+" icon to add more files to build for the target. (i.e. myClass.m in your case)
Hope this helps!
Another possible solution (and what eventually solved my problem) is making sure your Watch Target also knows where your bridging file lives!
Open your project settings and select your WatchKit extension.
In Build Settings, search for the keyword "bridging"
Make sure the Objective-C Bridging Header file is set
There are two ways to do this.
Create a framework with your shared code in there and link that framework to your WatchKit extension and your iPhone app. This is the cleanest and recommended way.
Add the source file (and dependancies) for MyClass to both your iPhone and WatchKit extension targets.
In case you wish to share Obj-C classes from iPhone app in Swift code in Watch App Extension:
Include all the .m files that you wish to share from iPhone app, in
the Target for WatchKit Extension app (i.e. in Target Membership).
Create a bridging header (a new .h file) file (typically named
[projectName]-Bridging-Header.h). You can optionally name it as
[projectName]-Watch-Bridging-Header.h (or anything else that is
suitable).
Include all the .h files corresponding to .m included in the WatchKit
Extension target as imports in the bridging-header file (e.g.
#import "MyLogger.h").
You are ready to use the Obj-C classes in WatchKit Extension App code
now.

SDWebImage/UIImageView+WebCache.h file not found while archiving [duplicate]

I am fairly new to ios development - trying to use sdwebimage in my iphone project. I believe I completed all basic setups as required. But when I build, I get this error: No such file file or directory near this line:
#import "UIImageView+WebCache.h"
Yes I have added Target Dependencies
I have added libSDWebImage.a in Link Binary With Libraries
I have -all_load -ObjC in Other Linker Flags
I also tried the -force_load ${BUILT_PRODUCTS_DIR}/libSDWebImage.a (64bit mac)
My Use Header Search Paths is : $(BUILT_PRODUCTS_DIR)
I cleaned the project and rebuilt - but no use.
Build keeps failing. Again, XCode4 code completion "resolves" when I type #import "UI & hit "ctrl+space" which means the lib is visible to xcode. Any pointers will be super helpful. Thanks.
To add the needed header files to the build path do the following.
Select your project file
Select your target
Select Build settings
In the search box enter 'header search paths'
For the Release add "$(SOURCE_ROOT)/SDWebImage" (thats with quotes).
This will work when importing like this #import <SDWebImage/UIImageView+WebCache.h>
I also use SDWebImage.
In my experience I didn't do anything with the linker flags etc.
You only have to add the classes in your project and simply import the "UIImageView+WebCache.h" in your class' header like this:
#import "UIImageView+WebCache.h"
and if you want to use it on an UIImageView object, just use the method
setImageWithURL:placeholderImage:
you can refer to their github for more info
I just ran into this problem and have solved it.
The issue is that when you "drag" the SDWebImage xcode project to your project, Xcode only create a reference to point to those files needed. When you are in debug mode it's fine, it knows where to find those file. However, when you want to archive it (packing everything to be self-contained), it couldn't find it from your search path.
Although you have added $(BUILT_PRODUCTS_DIR) to your search path, but if the actual files that you downloaded are not physically located in your $(BUILT_PRODUCTS_DIR), then Xcode won't find them. This was the problem for me since my SDWebImage files were still sitting in my download folder.
What you want to do is:
1.Move the SDWebImage folders to a place where you won't accidentally delete it. Notice once you've done that, the SDWebImage project file will become red since it's physical location is moved. And it's wired that I could not delete that reference in Xcode, what I ended up doing is add that file again (choosing from the location where I just move it too). You will end up with a red SDWebImage.xcodeproj in your project navigator which you can not delete. It's very annoying but it won't affect anything.
2. If the location you move the SDWebImage stuff to is not in your $(BUILT_PRODUCTS_DIR), then you either move that inside $(BUILT_PRODUCTS_DIR) or as I do, add the path to Target -> Build Settings -> Search Paths -> User Header Search Paths.
Archive and it should work now.
I faced this same problem and was about to go crazy. Like Ravi, I followed the static installation instructions as closely as possible.
I saw the auto suggest for UIImageView+WebCache.h when I was typing #import, but it keeps throwing file not found.
In the end, it was this. In header search paths,
“$(BUILT_PRODUCTS_DIR)” - Wrong.
$(BUILT_PRODUCTS_DIR) - Right.
Embarrassed but now it's working right =)
I've been dealing with this problem for the past hour and noticed something that hasn't been mentioned: Make sure that when you up update header search paths that the "Recursive" option is selected! Otherwise the compiler will not check subfolders.
Worked for me...
I was dealing with the same problem, my two frameworks were not getting found. I tried all the suggested ways in order to resolve the error but it couldnt help. Atlast I deleted the frameworks from my project structure and reloaded them from the original project file and it worked!! Please try this if it helps, It worked for me...
I had a similar issue after pod update. If you are using CocoaPods version higher than 1.0.0 and more than one target in your project, you have to add all the targets into the Podfile.

How do I keep files not associated with the project in XCode 4 without generating a warning

I recently upgraded to XCode 4 and adjusting. I have a folder called "Unused" in which I keep some .h and .m files. They are basically code which are no longer associated with the project and I keep them because they serve as a reference. The compiler doesn't look what it sees in there so I change the .h and .m files to .h.txt and .m.txt. However, I get this warning:
warning: no rule to process file '$(PROJECT_DIR)/Classes/AddViewController.m.txt' of type text for architecture i386
Does anyone have any solution for this?
Thanks.
Select the target in XCode, then in the Build Phases tab, under Compile Sources, remove the unused files that you don't want. XCode will only compile the files listed.
If you don't want the files to link, you can select the relevant file on the left side project navigator, then go to your right side bar and select the File inspector (left most icon on top right bar), then scroll down to "Target Membership" and unclick the checkbox so the file is not associated with any of your targets.

How to add new iPhone target

I'm trying to add a new target to my Xcode project so that I can run the same app, but with subtle difference.
Please can someone guide me through the setup of a new target since it is my first time and I'm not sure how to go about doing it.
In particular, I'm interested how I make the new target run the code in the original app. When I tried creating a new target it just made a new app delegate, and viewController file.
Sorry if this is simple, I'm just quite confused.
EDIT:
Please note that I'm after after instructions based in Xcode 4.
In xcode 4, make sure you're in the folder view where you have the project. Select the blue project button, then next to that you can see Targets, Select the target you have there, right click & select duplicate target.
Now you have two build targets.
To apply subtle differences in your app, make a global C flag. in Build settings there is a paragraph named GCC 4.2 - Language, it has a property named Other C Flags. Add your flag here like so:
-DOTHER_VER
Now in your code you can check for this using:
#ifdef OTHER_VER
// some code.
#else
// the subtle difference.
#endif
After you create your new target from settings of your project, you can create an identifier class to check the target. If you use macros everywhere in your code, it'll not be readable and feasible. You can check this tutorial-blog to learn how to do it, besides you may see some best practices there.

Rename a class in Xcode: Refactor... is grayed out (disabled). Why?

Why is Refactor... grayed out (disabled) in Xcode?
I'd like to rename a class.
Select the class's symbol in its header file - i.e. the bit just after #interface. Then the refactoring stuff should be enabled.
If you are using Objective-C++ (i.e. mix Objective-C with C++ code) then refactoring is disabled in xcode since it does not support refactoring of C++ code.
Refactor might also be disabled if affected files (most likely the file with your class in it) are not saved.
I've been using Xcode for 5 years now, and refactoring has never worked correctly (even xcode 4.6 has major bugs where it WILL corrupt your source code!).
The workaround has always been (still works 100%, even in cases where Apple's code fails)
use shift-command-f to find all uses of the file
select "replace" in the search settings
"replace-all"
do the following for the .h file, and REPEAT IT FOR THE .m FILE (if you have one):
right click the original file, and select "show in finder"
delete the file from xcode (select "delete references only" when asked)
rename the .h (and .m if you have one) in Finder
in Xcode, select "Product -> (hold down Alt) -> Clean Build Folder"
quit xcode (you can usually get away with not doing this - but NOTE: there are some other MAJOR bugs in Xcode where it crashes itself if you don't do this)
re-open xcode
drag/drop the .h and .m back into Xcode
wait a few seconds (some of Xcode's core methods are asynchronous - allowing it to corrupt your project)
finally, when it seems to be doing nothing (and your hard disk isn't making any noise any more): cmd-b to re-build
I have a 100% success rate with this method. I just tried refactoring with Apple's "Refactor -> Rename" in latest xcode and it failed - again!
(this time with the incorrect error: "Unable to determine the language of", one of those error messages where Apple put the wrong text in place)
I'm going to my project at finder, then change files name by get info.
After that, at xcode -> Project Navigator I delete the files.
At end, I click right on the class and Add files to ..., and add these files again.
It worked for me.
For me I realized Refactor was disabled because the Xcode project I had opened was referencing a Base SDK that was missing. Edit Project Settings and in the Build tab set the Base SDK to one that you have (like for me this was iOS 4.2). This enabled Refactor for me.
Also, it could happen that you renamed the filename for the class, either outside xcode or by ctrl-clicking the filename and then renaming it.
xcode refuses to refactor if filename does not match with the class name.
Go to your class' header file and find the line that looks similar to this:
#interface YourClassName
Right click on the class symbol (e.g. YourClassName) and you should be able to select Refactor -> Rename...
I just tried this and it works in Xcode 5.
This may be a bit late, but I stumbled across this post because I was unable to refactor my "ViewController.swift" file to "WhateverViewController.swift". I tried selecting the file in the Project Navigator and then selecting "Editor -> Refactor" from the top menu, but 'rename' is always greyed out.
Instead, what worked was selecting the ViewController name from the editor. So if you have:
class ViewController: UIViewController {
// Code here...
}
Highlight the "ViewController" word and then select Refactor from the menu or right-click and select Refactor -> rename.
Hopefully that helps...
Had this problem as well. I ran through trying to find missing SDKs, saving files, and looking for Objective-C++ code as mentioned above, and all it took to fix my machine was rebooting XCode.
Seems a little buggy still.
BTW, this was for XCode 4.0.1
Refactoring works If you first change the file name in the project navigator.