How can I configure Xcode to put '{' where I want it in generated files - objective-c

I know this is a fairly contentious issue amongst programmers, but when developing I like my IDE to position the opening curly bracket underneath the method/interface/control declaration, for illustrative purposes: -
This is how Xcode automatically generates skeleton methods with the { at the end: -
-(void) isTrue:(BOOL)input {
if(input) {
return YES;
}
else {
return NO;
}
}
This is how I like to lay out my code (which I believe is called the Allman style): -
-(void) isTrue:(BOOL)input
{
if(input)
{
return YES;
}
else
{
return NO;
}
}
I'm just wondering if there's any configuration switch in Xcode to enable this style of development? It's really annoying when typing out if/else statements as it tends to auto-complete the else clause with the { at the end of the line which just looks silly if you like developing with them underneath.
Or am I being unreasonable? Is Objective-C supposed to adhere to a standard defined by Apple?

Take a look at:
Xcode: Adjusting indentation of auto-generated braces?
Apple Xcode User Defaults
XCCodeSenseFormattingOptions = {
BlockSeparator = "\\n";
PreMethodDeclSpacing = "";
};
This should at least solve your problem after if, for, or while statements.

After digesting the helpful information from WhirlWind above (thanks), the resulting snippet (just cut and paste into terminal) is:
defaults write com.apple.Xcode
XCCodeSenseFormattingOptions -dict
BlockSeparator "\\n"
PreMethodDeclSpacing ""
Stupid backslash quoting. When typed at the terminal, there should be TWO exactly TWO backslashes in the block separator.

Even with those settings, it does not appear to work with the templates. If you set this and then type "init" in a .m file you get:
- (id)init
{
self = [super init];
if (self) {
<#initializations#>
}
return self;
}
Note the "if (self) {" line.

I believe that "defaults write com.apple.Xcode" doesn't work on the latest versions of Xcode (7.x)
Here are the solutions I know:
Snippet Edit -- this little program will allow to edit default Xcode's code snippets. So, you will be able to open braces from new line in your if, for, while, etc. However, this doesn't allow to change the block indentation.
Uncrustify -- this might solve your problem too, but it doesn't look like being easy to set up. And it only formats the code after it is already written, instead of formatting 'on the go'.

Related

Why can't I put the { of an anonymous class at a new line in Kotlin?

This question may be stupid but... why? Personally I like the Microsoft style where { is at the same column as the matching }. In all languages I have used, it did not matter where { was placed.
But in Kotlin, only this works.
image_view.viewTreeObserver.addOnGlobalLayoutListener{
};
And this causes an error.
image_view.viewTreeObserver.addOnGlobalLayoutListener
{
};
https://kotlinlang.org/docs/reference/grammar.html#semicolons
Because your second example has the same meaning as
image_view.viewTreeObserver.addOnGlobalLayoutListener;
{
};
a property access followed by an empty lambda.
Braces in the same column and indented with the line above is not Microsoft style - it's known as the Allman style. It's a style I wish people would use, but sadly K&R's ancient style was pushed by Sun (Java) as the "official" style and Kotlin has followed suit.
You can do this:
image_view.viewTreeObserver.addOnGlobalLayoutListener()
{
}
to stop Kotlin complaining.
For further information on styles, see:
https://en.wikipedia.org/wiki/Indentation_style

Theos - MobileSubstrate: if/else using default values

I'm writing a tweak to edit the statusbar clock strings. I'm struggling to find a way to call the native settings if the tweak is 'disabled'. I thought that calling %orig would work. But it only works after a respring, I want to avoid a respring if possible!
here's the applicable code:
%hook SBStatusBarStateAggregator
-(void)_resetTimeItemFormatter {
%orig;
// Hook _timeItemDateFormatter iVar
NSDateFormatter *newDateFormat = MSHookIvar<NSDateFormatter *>(self, "_timeItemDateFormatter");
// set new clock format if ST is enabled
if(STTime && STIsEnabled)
{
[newDateFormat setDateFormat:STTime];
} else {
// USE THE DEFAULT FORMAT
}
}
%end
I'm aware that this is probably not the correct usage of case for %orig. So for my 'else' what shall I use? I don't know what the 'default' format is going to be!
Any help appreciated.
LM

How to enforce parameters of anonymous blocks to be unused in Objective-C?

I've run into a situation while using a library called TransitionKit (helps you write state machines) where I am want to supply entry and exit actions in the form of a callback.
Sadly, the callbacks include two completely useless parameters. A typical block has to look like this:
^void (TKState *state, TKStateMachine *stateMachine) {
// I TOTALLY don't want parameters `state` or `stateMachine` used here
};
(this is an anonymous code block. Read up on blocks here if you're unclear)
As I've noted in the comment, I really don't want those parameters even mentioned in the body there. I've tried simply removing the parameter names like suggested in this question like so:
^void (TKState *, TKStateMachine *) {
// I foobar all I like here
};
but sadly the code won't compile then :(.
How can I enforce this non-usage of parameters in code?
This is what I could come up with. Quite a hack and relies on the GCC poison pragma, which is not standard but a GNU extension - although, given that you are probably compiling this with clang anyway, it should not be a problem.
#define _state state
#define _stateMachine stateMachine
#pragma GCC poison state stateMachine
Then this compiles:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something();
}
But this doesn't:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something(state, stateMachine);
}
You could just have a function that took one kind of block, and returned another, like this:
#class TKState, TKStateMachine; // here so this will compile
typedef void (^LongStateBlock)(TKState *state, TKStateMachine *stateMachine);
static inline LongStateBlock Adapter(void(^block)()) {
void(^heapBlock)() = [block copy]; // forces block to be on heap rather than stack, a one-time expense
LongStateBlock longBlock = ^(TKState *s __unused, TKStateMachine *sm __unused) {
heapBlock();
};
// this is the non-ARC, MRR version; I'll leave ARC for the interested observer
[heapBlock release];
return [[longBlock copy] autorelease];
}
And in practice:
// this represents a library method
- (void)takesLongStateBlock:(LongStateBlock)longBlock
{
// which hopefully wouldn't look exactly like this
if (longBlock) longBlock(nil, nil);
}
- (void)yourRandomMethod
{
[self takesLongStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
NSLog(#"Gratuitous parameters, AAAAHHHH!");
}];
[self takesLongStateBlock:Adapter(^{
NSLog(#"So, so clean.");
})];
}
The whole thing is gisted, and should compile inside any class. It does what you expect when you call -yourRandomMethod.
AFAIK there is no way to do what you want when you are creating a block, you can only miss the parameter names when you are declaring a block variable(a reference to a block, to avoid misunderstandings)
So here you can miss the param names:
void (^myBlock)(SomeClass *);
But not when you create a block:
myBlock = ^(SomeClass *o)
{
};
I'd write
^void (TKState *unused_state, TKStateMachine *unused_stateMachine) {
// Anyone using unused_state or unused_stateMachine gets what they deserve.
};
Of course someone can use the parameters. But then whatever you do, they can change the code. If someone is intent on shooting themselves in the foot, there is no stopping them.

Standards for comments in NSLocalizedString

How do people write their comments for their NSLocalizedStrings? Is there a standard guideline that we should follow? For example if I have:
NSLocalizedString(#"Tap your account to sign in", #"");
and my comment is "Text that asks user to sign in by tapping on the account", is this a bit ambigous? Should I leave the comment out if it's pretty much self-explanatory?
Another question is, what if I have a bunch of ProgressHUD that has a text set to LoggingIn, what would be an easy way to sync across my app project that this needs to be localized into NSLocalizedString (#"Logging In", #"some description"); Is there a tool for performing such tasks?
The second parameter is a comment that will automatically appear in the strings file if you use the genstrings command-line utility, which can create the strings file for you by scanning your source code.
The comment is useful for your localizers. For example:
NSLocalizedString(#"Save",#"Title of the Save button in the theme saving dialog");
When you run genstrings, this will produce an entry in the Localizable.strings file like this:
/* Title of the Save button in the theme saving dialog */
"Save" = "Save";
In your specific example, it's fairly obvious what the comment means, but not the context. You should probably add some context like so:
NSLocalizedString(#"Tap your account to sign in", #"Instruct user to tap their account to sign in (Facebook account, main game preferences)");
That way the localizer knows exactly what button you're referring to.
This becomes even more important for buttons labelled "Share" or some other non-specific label:
NSLocalizedString(#"Share", #"Label for sharing button on main image editing screen");
(This is a modified version of my answer to this similar question).
Rob Keniger is right. I also would like to add this:
Second param can be used as .. default value!!
(NSLocalizedStringWithDefaultValue does not work properly with genstring, that's why I proposed this solution)
Here is my Custom implementation that use NSLocalizedString that use comment as default value:
1 . In your pre compiled header (.pch file) , redefine the 'NSLocalizedString' macro:
// cutom NSLocalizedString that use macro comment as default value
#import "LocalizationHandlerUtil.h"
#undef NSLocalizedString
#define NSLocalizedString(key,_comment) [[LocalizationHandlerUtil singleton] localizedString:key comment:_comment]
2. create a class to implement the localization handler
#import "LocalizationHandlerUtil.h"
#implementation LocalizationHandlerUtil
static LocalizationHandlerUtil * singleton = nil;
+ (LocalizationHandlerUtil *)singleton
{
return singleton;
}
__attribute__((constructor))
static void staticInit_singleton()
{
singleton = [[LocalizationHandlerUtil alloc] init];
}
- (NSString *)localizedString:(NSString *)key comment:(NSString *)comment
{
// default localized string loading
NSString * localizedString = [[NSBundle mainBundle] localizedStringForKey:key value:key table:nil];
// if (value == key) and comment is not nil -> returns comment
if([localizedString isEqualToString:key] && comment !=nil)
return comment;
return localizedString;
}
#end
3. Use it!
Make sure you add a Run script in your App Build Phases so you Localizable.strings file will be updated at each build, i.e., new localized string will be added in your Localized.strings file:
My build phase Script is a shell script:
Shell: /bin/sh
Shell script content: find . -name \*.m | xargs genstrings -o MyClassesFolder
So when you add this new line in your code:
self.title = NSLocalizedString(#"view_settings_title", #"Settings");
Then perform a build, your ./Localizable.scripts file will contain this new line:
/* Settings */
"view_settings_title" = "view_settings_title";
And since key == value for 'view_settings_title', the custom LocalizedStringHandler will returns the comment, i.e. 'Settings"
VoilĂ  :-)

Registering for Display Reconfiguration Callbacks

I'm putting together a Mac OS X Application and I'm trying to register to receive Display Reconfiguration notices, but I'm very lost right now. I've been reading Apple's documentation and some forums posts, etc., but everything seems to assume a better knowledge of things than I apparently possess. I understand that I have to request the callback inside a run loop for it to work properly. I don't know how to set up a basic run loop for it, though. I also feel like the example Apple has in their documentation is missing stuff they are expecting me to already know. To display my ignorance here is what I feel like things should look like.
NSRunLoop *rLoop = [NSRunLoop currentRunLoop];
codeToStartRunLoop
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack, NULL);
The actual code I got was from Apple's Example, but it tells me that flags is an undeclared identifier at this point and won't compile. Not that it would work right since I don't have it in a run loop. I was hoping to find a tutorial somewhere that explains registering for system callback in a run loop but have not been successful. If anyone could point me in the right direction I'd super appreciate it.
(I'm sure that you'll be able to tell from my question that I'm very green. I taught myself Objective-C out of a book as my first programming language. I skipped C, so every once in a while I hit a snag somewhere that I can't figure out.)
If you're writing a Mac OS X application, the AppKit has already set up a run loop for you, so you don't need to worry about that part. You really only need to create your own run loop in Cocoa when you are also creating your own thread.
For the "undeclared identifier" part, it looks like it's due to a typo/syntax mistake:
void MyDisplayReconfigurationCallBack (CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo);
// Semicolon makes this an invalid function definition^^
{
// This is an anonymous block,* and flags wasn't declared in it
if (flags & kCGDisplayAddFlag) {
// etc.
}
Also, unlike some other languages, you can't declare or define functions inside of other functions, methods, or blocks* -- they have to be at the top level of the file. You can't put this in the same place where you call CGDisplayRegisterReconfigurationCallback.
Just as an sample (I have no idea what the rest of your code really looks like):
// MyClassThatIsInterestedInDisplayConfiguration.m
#import "MyClassThatIsInterestedInDisplayConfiguration.h"
// Define callback function at top level of file
void MyDisplayReconfigurationCallBack (
CGDirectDisplayID display,
CGDisplayChangeSummaryFlags flags,
void *userInfo)
{
if (flags & kCGDisplayAddFlag) {
NSLog (#"Display Added");
}
else if (kCGDisplayRemoveFlag) {
NSLog (#"Display Removed");
}
}
#implementation MyClassThatIsInterestedInDisplayConfiguration
- (void) comeOnBabyAndDoTheRegistrationWithMe {
// Register callback function inside a method
CGDisplayRegisterReconfigurationCallback(MyDisplayReconfigurationCallBack,
NULL);
}
#end
*The basic C curly-brace-delimited thing, not the new cool Obj-C ad hoc function thing.