We are using the below code to get reference to the bundle we add for our resources like xib and images however I am not sure what would be the code to access them in swift.
NSString *resourceBundlePath = [[NSBundle mainBundle] pathForResource:#"DTPinLockController" ofType:#"bundle"];
NSBundle *resourceBundle = [NSBundle bundleWithPath:resourceBundlePath];
Can anyone convert this to swift 1.2 code?
Constructors in Swift are a little different than Objective-C. Try this:
let path = NSBundle.mainBundle().pathForResource("DTPinLockController", ofType: "bundle")!
let bundle = NSBundle(path: path)
And for loading a UIViewController afterwards in a NIB inside that bundle:
let controller = UIViewController(nibName: "MyViewController", bundle: bundle) as! MyViewController
Take a look at the Apple documentation for the full reference. There's a selector at top that lets you switch between Swift and Objective-C.
Related
This question already has answers here:
How do I call Objective-C code from Swift?
(17 answers)
Closed 8 years ago.
I want to incorporate a .rtfd (...or html) file into a NSAttributedString.
I've created some class helper methods within a NSAttributedString(category) written in Objective-C.
My Question: how do I access these Objective-C methods from Swift?
The following is how I would do it in Objective-C:
NSURL *rtfURL = [[NSBundle mainBundle] URLForResource: #"Recursion" withExtension:#"rtfd"];
NSAttributedString *attrString = [NSAttributedString attributeStringFromRTFURL:rtfURL];
Here's the Objective-C class method:
+ (NSAttributedString *)attributeStringFromRTFURL:(NSURL *)rtfURL {
NSAttributedString *stringWithRTFAttributes =
[[NSAttributedString alloc] initWithFileURL:rtfURL
options:#{NSDocumentTypeDocumentAttribute:NSRTFDTextDocumentType}
documentAttributes:nil
error:nil];
return stringWithRTFAttributes;
}
Here's what I have in the .swift file:
let rtfURL = NSBundle.mainBundle().URLForResource("Recursion", withExtension: "rtfd")
let attrString = [NSAttributedString attributeStringFromRTFURL:rtfURL];
Question: What's the Swift equivalent of [NSAttributedString attributeStringFromRTFURL:rtfURL];?
Note: I'm seeking the syntax of calling a class vs instantiated method.
I believe I've been too subjective. With a bit of fresh air...
There are two (2) possible solutions:
1) Use the Swift extension for NSAttributedString rather than focus on the current Objective-C category {NSAttributedString+Extra}. Or...
2) Follow the other examples and access an instance vs class of NSAttributedString via Swift syntax.
I'm currently following #2. <-- I got it working!
I'm seeking the syntax of calling a class vs instantiated method
The syntax for calling a class method is the same as that for an instance method. The only difference is that you use the class name instead of an instance of the class as the recipient of the message:
var foo = NSString.string() // same as Obj-C: NSString *foo = [NSString string]
When I try with the following coding for custom cell, Its showing error.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *simpleTableIdentifier = #"SimpletablcellCell";
SimpletablcellCell *cell = (SimpletablcellCell *)[tableView dequeueReusableCellWithIdentifier:simpleTableIdentifier];
if (cell == nil)
{
NSArray *nib = [[NSBundle mainBundle] loadNibNamed:#"SimpletablcellCell" owner:self options:nil];
cell = [nib objectAtIndex:0];
}
cell.nameLabel.text = [ar objectAtIndex:indexPath.row];
cell.thumbnailImageView.image = [UIImage imageNamed:[ar1 objectAtIndex:indexPath.row]];
cell.prepTimeLabel.text = [ar objectAtIndex:indexPath.row];
return cell;
}
Error msg
'NSInternalInconsistencyException', reason: 'Could not load NIB in bundle: 'NSBundle </Users/apple/Library/Application Support/iPhone Simulator/6.0/Applications/FE02B3A1-C40C-4FAC-BBA6-B245350F3754/SImpleTab.app> (loaded)' with name 'SimpletablcellCell''
*** First throw call stack:
(0x1c8f012 0x10cce7e 0x1c8edeb 0x22ffac 0x23198d 0x3418 0xcef4b 0xcf01f 0xb780b 0xc819b 0x6492d 0x10e06b0 0x228bfc0 0x228033c 0x228beaf 0x1038cd 0x4c1a6 0x4acbf 0x4abd9 0x49e34 0x49c6e 0x4aa29 0x4d922 0xf7fec 0x44bc4 0x44dbf 0x44f55 0x4df67 0x2d40 0x117b7 0x11da7 0x12fab 0x24315 0x2524b 0x16cf8 0x1beadf9 0x1beaad0 0x1c04bf5 0x1c04962 0x1c35bb6 0x1c34f44 0x1c34e1b 0x127da 0x1465c 0x29fd 0x2925)
libc++abi.dylib: terminate called throwing an exception
Please check, what is wrong with this code?
Does a .nib / .xib exist in your project named SimpletablcellCell? You might have a typo in the name, please check carefully.
Make sure the file is part of your target. You can check this by opening the right-side menu in Xcode. Example:
If the cell exists, is it being copied in the build process? Check the "Copy bundle resources" phase in your project target build settings and make sure it is being copied. If not, add the file manually to this phase.
I had this problem when using Cocoapods for a private pod library of mine.
I had incorrectly included my xib files in s.source_files like so
s.source_files = 'MyLibrary/**/*.{h,m,xib}' //DOES NOT WORK
The solution was to use the resources attribute:
s.resources = 'MyLibrary/**/*.{xib}' //PROBLEM SOLVED
s.source_files = 'MyLibrary/**/*.{h,m}'
...
Then there is the problem that occurs if your podspec is looking for the xib as specified by s.resources above, but the xib is not in that path.
Once I mistakingly added a xib to my root project directory (where your AppDelegate is) and so Cocoapods would not copy it to any clients using the pod.
I fixed this by either changing the s.resources path or moving the xib so that it would be in the s.resources path.
If you are registering the nib using:
let nib: UINib = UINib(nibName: "myNib", bundle: nil)
tableView.registerNib(nib, forCellReuseIdentifier: "myCell")
make sure it is done in the viewDidLoad() function. I had placed it in the init() function and received this error. Once moved to viewDidLoad(), it worked well.
This error can occur when you rename some files outside XCode. To solve it you can just remove the files from your project (Right Click - Delete and "Remove Reference") You re-import the files in your project and everything will be ok !
Make sure your custom cell is added to the target you are building. Register that cell without fail.
There should be no IBOutlet errors in xib. Also, connect the view to the file owner.
The common error could be the name of the nib you are loading is incorrect.
i create a view based project named myclass.
and i add another UIviewcontroller subclass to it, named as webdata.
In the webdataviewcontroller.m i get image from the webserver.
I need to display this image on imageview in myclassViewController.m from webdataViewController.m
for this my code in webdataViewController.m is
docDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
imagepath = [NSString stringWithFormat:#"%#/image.png",docDir];
logopath = [NSString stringWithFormat:#"%#/logo.png",docDir];
myclassViewController *obj = [[myclassViewController alloc]init];
obj.homeimage.image = [UIImage imageWithContentsOfFile:imagepath];
but image is not displayed,i try to print image in console
NSLog(#"image to display %#",obj.homeimage.image);
NSLog(#"image to display %#",[UIImage imageWithContentsOfFile:imagepath]);
but i get like this
image to display (null)
image to display <UIImage: 0x6f614b0>
why i get null for obj.homeimage.image,i did n't get can any one please help me.
Thank u in adavance.
(Let me add comment if question is not understandable)
Are you sure that obj.homeimage is not nil? If it is nil then obj.homeimage.image = ... will result to setting image property to nil object, that is "nothing".
Why don't you give us the code for myclassViewController ?
Also you have a lot of mistakes in capitalization, etc. It makes it hard to read your code and it's messy.
myClassViewController should be MyClassViewController
webdataViewController should be WebDataViewController
You should camel case variable names
homeimage should be homeImage
imagepath should be imagePath
You said you subclassed myclassViewController, I think by that you meant you added it as a subview. If so when you execute the code:
myclassViewController *obj = [[myclassViewController alloc]init];
you are creating a NEW myclassViewController, not referencing the parent view controller. You need a pointer to the the instance of the myclassViewController that added webdataViewController as a subview, and add the image to it's property. Also I'm guessing here lies your problem, you are creating a new empty instance of myclassViewController therefore you have not initialized your ivars. (Unless you did so in your -init method, but I would doubt that). So you alloc-ed and init-ed a new myclassViewController but none of it's variables are initialized so you are just messaging nil objects probably. Which is why your code isn't crashing yet still not responding. Once again this is a guess, but it probably is the problem.
I can edit with more information if you give the code for myclassViewController.
I have an iPhone iOS4.1 application that uses localized strings. I have just started building unit tests using the SenTestingKit. I have been able to successfully test many different types of values.
I am unable to correctly test any of my code that uses NSLocalizedString calls, because when the code runs in my LogicTests target, all of my NSLocalizedString calls only return the string key.
I have added my Localizable.strings file to the LogicTests target.
My question is: How must I configure my LogicTests target so that calls to NSLocalizedString will return the localized string and not the string key.
This problem was driving me crazy, but I was able to get NSLocalizedString to behave.
zoul was right, if you print the mainBundle to the console in a logic test, it's not the same bundle that contains your Localizable.strings file. You need to conditionally redefine NSLocalizedString whenever you run your unit tests. I did it in the following steps:
We need a way to tell when we're in our logic tests target, so add something like LOGIC_TESTS to your logic tests target's Preprocessor Macros build setting.
There's only 1 place in my code where I need to redefine NSLocalizedString, so I was able to place the following code in the header corresponding to that class. If you're having this problem in multiple places, I'd suggest putting the following code in a header and #include-ing it where you need it (I tried using a .pch file but it doesn't work in Logic Tests). Anyway, place this somewhere in the header of class(es) that use NSLocalizedString:
#ifdef LOGIC_TESTS
#undef NSLocalizedString
#define NSLocalizedString(key, comment) [[NSBundle bundleWithIdentifier:#"YOUR_IDENTIFIER"] localizedStringForKey:(key) value:#"" table:nil]
#endif
Replace YOUR_IDENTIFIER with the Bundle Identifier of your app's bundle (found in your Info.plist file, key is CFBundleIdentifier). This assumes that you've defined LOGIC_TESTS as a preprocessor macro only in your Logic Tests target.
edit: Curiously, once I removed some debugging code this solution stopped working. It looks like you have to trick Xcode into loading the bundle as well. The following does it:
NSString *path = #"path_to_main_bundle";
NSBundle *bundle = [NSBundle bundleWithPath:path];
NSLog(#"bundles: %#", [NSBundle allBundles]);
Where path_to_main_bundle is == [[NSBundle mainBundle] bundlePath] when you run your main target. Just log it once in gdb or using NSLog on your app delegate to grab the path. It should look something like /Users/YOUR_USER_NAME/Library/Application Support/iPhone Simulator/4.1/Applications/UUID_LOTS_OF_LETTERS_AND_NUMBERS_HERE/App.app.
I placed that code in the setUp call for one of my logic test classes. And no, I have no idea why I have to log allBundles to make it work, so anyone who has a clue, please let me know!
I was able to use NSLocalizedString using the following code in the setup for my unit test
- (void)setUp
{
[super setUp];
NSString *bundlePath = [[NSBundle bundleForClass:[self class]] resourcePath];
[NSBundle bundleWithPath:bundlePath];
}
I encounter the same problem, and, thanks #kevboth, I tackle it by adding two lines to YourUnitTests-Prefix.pch:
#undef NSLocalizedString
#define NSLocalizedString(key, comment) [[NSBundle bundleForClass:[self class]] localizedStringForKey:(key) value:#"" table:nil]
A shortcut for Swift:
This is a simple version which can be extended to different use cases (e.g. with the use of tableNames).
public func NSLocalizedString(key: String, referenceClass:AnyClass) -> String
{
let bundle = NSBundle(forClass: referenceClass)
return NSLocalizedString(key, tableName:nil, bundle: bundle, comment: "")
}
This global method can be placed in a single .swift file or somewhere else outside the class scope.
Use it like this:
NSLocalizedString("YOUR-KEY", referenceClass: self)
Maybe NSLocalizedString will only work inside the application tests? This is a macro that invokes localizedStringForKey:value:table: on the main bundle. Maybe +[NSBundle mainBundle] returns something iffy in the testing target?
The cleanest solution seems to me just to include a Localizable.strings in your octest bundle.
Swift 4.1 - Xcode 9.3
Localizable.strings (en)
"TEXT_TO_LOCALIZE" = "Hello!";
Localizable.strings (es)
"TEXT_TO_LOCALIZE" = "Hola!";
XCTestCase
class AppTestCase: XCTestCase {
func testLocalize() {
let localizedText = "TEXT_TO_LOCALIZE".localized(for: reference)
print(localizedText) // "Hello!" or "Hola!"
}
}
extension String {
public func localized(for aClass: AnyClass) -> String {
let bundle = Bundle(for: aClass)
return NSLocalizedString(self, tableName: nil, bundle: bundle, comment: "")
}
}
extension XCTestCase {
var reference: AnyClass {
return type(of: self)
}
}
I am having trouble in accessing which is in the UITableViewCell, that i have placed in my main .xib file.
That Label is connected to IBOutlet servicesCell.
And the Label inside the table view cell is connected through IBOutlet serviceLabel.
At runtime i am not getting the text which i am assining to that label.
Following is my sample code for that.
static NSString *ServiceIdentifier = #"ServiceIdentifier";
UITableViewCell *cell1 = [tableView dequeueReusableCellWithIdentifier:ServiceIdentifier];
if(cell1 == nil) {
[[NSBundle mainBundle] loadNibNamed:#"servicesCell" owner:self options:nil];
cell1 = servicesCell;
}
// label access
serviceLabel = (UILabel *)[cell1 viewWithTag:1];
serviceLabel.numberOfLines = 3;
serviceLabel.lineBreakMode = UILineBreakModeWordWrap;
[serviceLabel setTextAlignment:UITextAlignmentLeft];
[serviceLabel setText:#"Testing String"];
Anyone have any idea then please help..
Thanks in advance..
You say that your Cell is in your main XIB file, but I take it the cell is actually in "servicesCell.xib", correct?
I assume you started with "Loading Custom Table-View Cells from Nib Files". This code is similar to Apple's example, so I assume you started there. If you just copied this code from somewhere without understanding it, go read that doc first.
You should walk through this code in the debugger and make sure that everything is set to what you think it should be set to. The most common cause of "nothing happens" is that you're sending messages to nil, and so I bet one of your variables here is actually nil. Looking at this code, the most likely culprits are failure to actually wire something in IB (this is the most common cause of nil objects when working with NIBs; double check that you really did it), or that you have not assigned your label the expected tag of 1.
Place the UITableViewCell in it's own nib.