I need to access Swift Package Manager's Bundle.module equivalent in objective-c. I've tried the Bundle.module in Objective-c but no luck. This is how we access in Swift:
public let settingsURL = Bundle.module.url(forResource: “settings”, withExtension: “plist”)
Any guess what my be the equivalent in objective-c?
Here is the Apple Documentation page.
Solution
Oh!? Sometimes things get so weird between these two beautiful languages. I found the solution:
NSString *path = [SWIFTPM_MODULE_BUNDLE pathForResource:#"settings" ofType:#"plist"];
So simple right? :)
For more information, please check the related proposal (SE-0271).
For Objective-C, the build system will add a preprocessor define
called SWIFTPM_MODULE_BUNDLE which can be used to access the bundle
from any .m file.
Related
Is it at all possible to have Xcode create a .playground file for Objective-C instead of Swift? Are there any available Xcode plugins that allow that?
You can quickly test code snippets using a test case in a new project. Just create a new project and go to the Navigator in the left pane and hit the Test Navigator button. Then follow this guide
The setup code will look a little different than a swift playground, but it still allows you to prototype and play around.
There is a very good library developed by Krzysztof Zabłocki in Github entitled KZPlayground that support both code in Playgrounds for Objective-C and Swift and a lot of cool features.
I hope this can help you.
If the only purpose is to test out Objective-C snippets, i would really recommend you an OS X command line Tool project.
There are enough moving parts in a playground, and all of those would have to be reimplemented for Objective-C. Reliable playgrounds also depend on definite initialization which Objective-C does not have.
For instance consider:
var d: NSData // this is not initialized, so I can't use it
vs.
NSData *d; // this is also not initialized, but now I can use it
If I am the person storing the description of your NSData for the sidebar, now I know that I am not supposed to do
describe(d)
in the Swift case, but for the Objective-C case, I don't have equal knowledge and I run the risk of saying
[d description]; // even though d is a random pointer now.. oops, I just crashed!
In short, I don't think any such thing exists, and making one work would also involve some trickery
I am a novice in Objective-C and I am trying to understand how pre-defined methods work. I went through the documentation of XCode and the *.h files where the method is defined. However I am eager to read the *.m file or any other document that can help me understand how the method works.
For instance - isEqualToString:(NSString *) checks if two strings (of the type NSString) are equal or not. I am not satisfied with this description. I am eager to see how the method works internally or what is the algorithm it follows. Where can I find this information?
Thank you for your help.
isEqualToString:(NSString *) is a method defined in the NSString class. Apple provides you with the framework, but they do not provide the implementation of those methods. Therefore, you can't see the source behind the standard framework's libraries.
Edit: you can create a binary and use this app to check the assembly code: http://itunes.apple.com/us/app/hopper-disassembler/id422856039?mt=12
Unfortunately, a lot of the implementation (.m) files for Apple's frameworks aren't provided publicly. You have a couple alternatives:
As Matthias suggested in a comment, use the debugger and inspect the assembler code generated for that method.
Browse through the repositories for the GNUstep project, which has some equivalents to Apple classes.
I have an NSString (which is a path to a file) in my code that I would like to somehow obfuscate or encrypt,
but still be able to call up the file path easily when needed.
I searched for an answer to this, but everything I've seen either deals specifically with iOS or seems overly complicated.
I would simply like to use it with something such as this:
- (void)method {
NSString *obfuscate = #"/path/to/something/secret"; // encrypt or obfuscate
[self manageFiles:obfuscate]
- (void)manageFiles(NSString *)obfuscate {
NSFileManager *files = [[NSFileManager alloc] init];
if ([files fileExistsAtPath:obfuscate])
... .
— any help is appreciated, thank you.
(This is an old question, but I'm replying anyway)
There's no such way to in Obj-C. Obj-C is dynamic enough that any of these methods can be trapped and intercepted. Do not ship anything in a application that absolutely needs to be secret. If your application is run on a jailbroken phone, or if it is made available on piracy sites, than it has already been exposed and it's memory contents dumped. All these above methods copy the decoded data to main memory where it is exposed.
See:
https://www.youtube.com/watch?v=Ii-02vhsdVk
None of these methods above is actually secure. Again, do not embed these sorts of things in your applications with an assurance they are actually secure.
What I have done in the past to obfuscate a string was something to this extent:
-(NSString*)myString {
NSString *string = nil;
string = [#"ozzzzzzzzzzzzhazzzzzzzizzzzzz" stringByReplacingOccurrencesOfString:#"z" withString:#""];
return string;
}
What it would do is remove all the occurences of the letter z, leaving you with ohai as a string. Not sure if this will suffice for your case, but it has worked for me.
Hope this helps!
While playing with RubyCocoa, I keep progressing with my idea for my application. Because my application will be going to use configuration files, I would like to know how I discover the relative path to store these inside my application structure (or if a better idea emerges, please elaborate also the "why").
Also good for me to know is to discover environment variables, such as operating system version, the amount of memory that is available and such. Hyperlinks would be awesome too.
Please notice I use RubyCocoa and thank you for your feedback, comments and answers!
To access inside the application bundle, you use NSBundle. See NSBundle reference. In Obj-C, you use +[NSBundle mainBundle] to get the main bundle of the app. Then you use -[NSBundle pathForResource:ofType:] to get the file. I don't know RubyCocoa syntax, but I assume you know how to translate to it :)
If by the configuration file you mean a user-configurable things, remember you can't write inside the app bundle at runtime. Instead one uses NSUserDefaults. See User Defaults Guide.
Here's some Cocoa code I use to write all the environment variables to the console. Again, I don't use RubyCocoa, so you'll have to translate:
NSProcessInfo *myProcessInfo = [NSProcessInfo processInfo];
NSDictionary *env = [myProcessInfo environment];
for (id key in env)
{
NSLog (#"key: %#, value: %#", key, [env objectForKey: key]);
}
I am trying to use an external Obj-C class in my MacRuby project, but I can't figure out how to import it. Specifically, I want to use ObjectiveResource inside a MacRuby 0.5 project (since ActiveResource doesn't work - yet).
I have gotten as far as the 'framework' command in MacRuby, but it only seems to apply to actual frameworks.
Questions: where should I install the objective-resource directory? how do I pull these classes inside my ruby code?
Thanks for any help!
You can access the class directly using ClassName.new.
If you have a class named Utilities in your project and it has a method named greeting:, you would call it like so.
util = Utilities.new
puts util.greeting("Good morning")
There is no require or framework declarations required. Amazingly simple isn't it. I discovered this watching the Peepcode screencast on MacRuby.
Also, if you are interested in calling Ruby code from Objective-c, here is an extract from the MacRuby mailing list:
Once the MacRuby runtime is initialized, you can access all your Objective-C objects from Ruby. For example, if you have an Objective-C class named Foo, you can do `Foo.new', etc.
Another possibility is to pass your Objective-C objects to a Ruby method by using [NSObject performRubySelector:].
ruby:
class Foo
def test(o)
o.something
end
end
objc:
MyObject *o = [MyObject new]; // where o responds to -something
MacRuby *runtime = [MacRuby sharedRuntime];
id foo_obj = [runtime evaluateString:#"new Foo"];
[foo_obj performRubySelector:#selector(test:) withArguments: o, NULL];
Check out the whole API here: http://www.macruby.org/trac/browser/MacRuby/trunk/include/ruby/objc.h
Thread: http://lists.macosforge.org/pipermail/macruby-devel/2010-April/004715.html
(Edit) That said, perhaps the easiest way is to add a header file for your ruby file, containing your methods equivalents.
Suppose that you have this ruby class:
class Foo
def bar(moo)
"a string like #{moo}"
end
end
so the equivalent header file will be something like that:
#interface Foo : NSObject
- (NSString *)bar:(NSString *)moo
#end
Now, just #import the header and use your ruby classes as standard Obj-C ones from within your Obj-C code:
NSString *aString;
Foo *myFoo;
aString = [myFoo bar:#"me"];
It may seem weird, but it works. Essentially, the idea is to shut the compiler's mouth and let it compile your code without complaining about missing methods. Then, at runtime, it will just work (I suppose thanks to the dynamic nature of Obj-C itself). By the way, to mimic the ruby typeless behavior, id is your friend in writing methods signatures in the header file.
Did you look at this example of creating an ObjC bundle?