-3

how to get rid of the compiler warning in XCode 5.1

in Stringtable is of course a string with a format specifier (updated: now in front of code)

"fmtDetail" = "Count: %d";

int number = 0;
//Compiler warning: Data argument not used by format string
NSString *text = [NSString stringWithFormat:NSLocalizedString(@"fmtDetail", nil), number];

//this gets no warning
NSString *fmtDetail = NSLocalizedString(@"fmtDetail", nil);
NSString *text2 = [NSString stringWithFormat:fmtDetail, number];
Karsten
  • 1,869
  • 22
  • 38
  • 1
    Post your localized `fmtDetail` string. – Joe Jan 27 '14 at 12:49
  • Actually I cannot reproduce your issue. I do not get a " Data argument not used by format string" warning with your first example, not even with `-W everything`. - But your second example gives a "format string is not a string literal" warning. – Martin R Jan 27 '14 at 12:55
  • Are you actually getting the localized version of the string? Ie: `NSLog (@"format string is '%@'",fmtDetail);` – Rok Jarc Jan 27 '14 at 13:09
  • 1
    … but I tested your code only with Xcode 5.0.2. Perhaps this is a Xcode 5.1 problem. – Martin R Jan 27 '14 at 13:13
  • 1
    This actually is not a bad question. Poor phrasing seems to be the reason for downvotes. It looks this was an issue even before Xcode 5: [nslocalizedstring with stringwithformat](http://iphonedevsdk.com/forum/iphone-sdk-development/57875-nslocalizedstring-with-stringwithformat.html) I would still use the `%d` within key: to remind me that this is formatted string and in case the string is not present in one of the localizations... – Rok Jarc Jan 27 '14 at 13:20
  • 1
    As it turns out, this is a *feature* of the new compiler that comes with Xcode 5.1 beta, not a *bug*... – Martin R Jan 27 '14 at 15:44

2 Answers2

2

It is not the compiler warning that is poor - you should correct your code.

There seems to be an %d (or similar) missing in the @"fmDetail".

Or you should get rid of the number argument - that is not used.

Depends on what you are actually trying to do...

NSString *text = [NSString stringWithFormat:NSLocalizedString(@"fmtDetail%d", nil), number];

NSString *text = [NSString stringWithFormat:NSLocalizedString(@"fmtDetail %d", nil), number];

NSString *text = [NSString stringWithString:NSLocalizedString(@"fmtDetail", nil)];

Second note: this @"fmtDetail%d" should match the key in the plist dictionary (translated strings). It could also be simly @"theDeatils" - the string that returned from your plist is the one that should actually hold formatting data for the string.

Why would one want to use the %d in the key? Because NSLocalizedString returns the key as the result if it doesn't find string with appropriate key.

EDIT: MartinR found the real reason for why this warning appears. Just a note that might be useful: since localizing strings usually means translation into many languages (duh) you might need to use numbered placeholders - not all languages share the same basic sentence structure.

Community
  • 1
  • 1
Rok Jarc
  • 18,765
  • 9
  • 69
  • 124
  • The argument to `stringWithFormat:` must be a literal string. – jlehr Jan 27 '14 at 12:54
  • Why? Please see http://stackoverflow.com/a/14984616/653513 - true usually the key would be without formatting arguments - due to better readability – Rok Jarc Jan 27 '14 at 12:57
  • 1
    The first argument of `NSLocalizedString` is just a key. It does not matter if you call is "fmtDetail%d" or "fmtDetail". Important is only what it expands to, which is "Count = %d" in this case. - (Actually the code from question compiles just fine, I do not get that warning.) – Martin R Jan 27 '14 at 13:02
  • True - i added that while you were writing the comment :) - one could still use this % parameters - it's not really wrong. Specially in the case when the string one is looking for is missing in plist. – Rok Jarc Jan 27 '14 at 13:02
  • But there is nothing to fix in his code (unless I am overlooking something). There is no "%d" missing, "fmtDetail" *does* match the key in the plist, and the number argument *is* used. – Martin R Jan 27 '14 at 13:06
  • Yeah, i'm reading it all over again and something doesn't make sense. – Rok Jarc Jan 27 '14 at 13:07
  • 1
    @rokjarc, why do you say that stringWithString is deprecated? I searched the docs and could not find anything to that effect. I even put a call to it in my code and compiled it, and did not get a warning to that effect. – Duncan C Jan 27 '14 at 13:43
  • @DuncanC: hmm, looking at the documentation there really is no sign of this method being deprecated. I'm sure i was getting the warnings when using `NSString *aString = [NSString stringWithString:@"something"];` to change to `NSString *aString = @"something";` - maybe this goes just for creating literals. I will remove that statement, thanx! – Rok Jarc Jan 27 '14 at 13:51
  • 1
    @rokjarc: I have tested this with Xcode 5.1 (beta) now and the result is that you were exactly on the right track! - It seems that with `stringWithFormat:NSLocalizedString(key, ...)`, Xcode 5.1 now expects that the key uses the same format specifier as the expansion. This is actually an improvement, because the compiler can now check the types and number of arguments even for localised formats. This was not possible before. – Martin R Jan 27 '14 at 15:29
  • @MartinR: thanks for investigating and sharing this. I'm at the windows machine at the moment so i didn't have a chance to test. Could you add this as an answer? It could be useful to a lot of people. – Rok Jarc Jan 27 '14 at 16:07
2

This seems to be not a bug, but a new feature of the compiler that comes with Xcode 5.1 (beta). It expects now that in

[NSString stringWithFormat:NSLocalizedString(key, ...), arguments... ]

the key itself is a valid format for the given arguments. (In other words, the key uses the same format specifiers as its value from the strings file). For example:

// Source code:
[NSString stringWithFormat:NSLocalizedString(@"Count = %d", nil), number]
// Localizable.strings:
"Count = %d" = "Die Anzahl ist %d";

This is an advantage because the compiler can now check that the number and types of the format specifiers match the actual arguments even with localizable format strings. That was not possible before (as far as I know).

For example, this will cause a warning in Xcode 5.1 beta, but not in Xcode 5.0.2:

[NSString stringWithFormat:NSLocalizedString(@"fmtDetail %f", nil), 13];
// warning: format specifies type 'double' but the argument has type 'int' [-Wformat]

(And as @rokjarc already had pointed out, using a valid format string as key makes sense anyway, because NSLocalizedString() returns the key if no matching string is found in the Localizable.strings file.)

Martin R
  • 529,903
  • 94
  • 1,240
  • 1,382