Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 600 Vote(s) - 3.5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Shortcuts in Objective-C to concatenate NSStrings

#1
Are there any shortcuts to (`stringByAppendingString:`) string concatenation in Objective-C, or shortcuts for working with `NSString` in general?

For example, I'd like to make:

NSString *myString = @"This";
NSString *test = [myString stringByAppendingString:@" is just a test"];

something more like:

string myString = "This";
string test = myString + " is just a test";
Reply

#2
The only way to make `c = [a stringByAppendingString: b]` any shorter is to use autocomplete at around the `st` point. The `+` operator is part of C, which doesn't know about Objective-C objects.
Reply

#3
NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
Reply

#4
NSString *label1 = @"Process Name: ";
NSString *label2 = @"Process Id: ";
NSString *processName = [[NSProcessInfo processInfo] processName];
NSString *processID = [NSString stringWithFormat:@"%d", [[NSProcessInfo processInfo] processIdentifier]];
NSString *testConcat = [NSString stringWithFormat:@"%@ %@ %@ %@", label1, processName, label2, processID];
Reply

#5
This is for better logging, and logging only - based on dicius excellent multiple argument method. I define a Logger class, and call it like so:

[Logger log: @"foobar ", @" asdads ", theString, nil];

Almost good, except having to end the var args with "nil" but I suppose there's no way around that in Objective-C.

Logger.h

@interface Logger : NSObject {
}
+ (void) log: (id) first, ...;
@end

Logger.m

@implementation Logger

+ (void) log: (id) first, ...
{
// TODO: make efficient; handle arguments other than strings
// thanks to @diciu

[To see links please register here]

NSString * result = @"";
id eachArg;
va_list alist;
if(first)
{
result = [result stringByAppendingString:first];
va_start(alist, first);
while (eachArg = va_arg(alist, id))
{
result = [result stringByAppendingString:eachArg];
}
va_end(alist);
}
NSLog(@"%@", result);
}

@end

In order to only **concat** strings, I'd define a Category on NSString and add a static (+) concatenate method to it that looks exactly like the log method above except it returns the string. It's on NSString because it's a string method, and it's static because you want to create a new string from 1-N strings, not call it on any one of the strings that are part of the append.
Reply

#6
When building requests for web services, I find doing something like the following is very easy and makes concatenation readable in Xcode:

NSString* postBody = {
@"<?xml version=\"1.0\" encoding=\"utf-8\"?>"
@"<soap:Envelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">"
@" <soap:Body>"
@" <WebServiceMethod xmlns=\"\">"
@" <parameter>test</parameter>"
@" </WebServiceMethod>"
@" </soap:Body>"
@"</soap:Envelope>"
};
Reply

#7
Well, as colon is kind of special symbol, but *is* part of method signature, it is possible to exted the `NSString` with category to add this **non-idiomatic** style of string concatenation:

[@"This " : @"feels " : @"almost like " : @"concatenation with operators"];

You can define as many colon separated arguments as you find useful... ;-)

For a good measure, I've also added `concat:` with variable arguments that takes `nil` terminated list of strings.

// NSString+Concatenation.h

#import <Foundation/Foundation.h>

@interface NSString (Concatenation)

- (NSString *):(NSString *)a;
- (NSString *):(NSString *)a :(NSString *)b;
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c;
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d;

- (NSString *)concat:(NSString *)strings, ...;

@end

// NSString+Concatenation.m

#import "NSString+Concatenation.h"

@implementation NSString (Concatenation)

- (NSString *):(NSString *)a { return [self stringByAppendingString:a];}
- (NSString *):(NSString *)a :(NSString *)b { return [[self:a]:b];}
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c
{ return [[[self:a]:b]:c]; }
- (NSString *):(NSString *)a :(NSString *)b :(NSString *)c :(NSString *)d
{ return [[[[self:a]:b]:c]:d];}

- (NSString *)concat:(NSString *)strings, ...
{
va_list args;
va_start(args, strings);

NSString *s;
NSString *con = [self stringByAppendingString:strings];

while((s = va_arg(args, NSString *)))
con = [con stringByAppendingString:s];

va_end(args);
return con;
}
@end

// NSString+ConcatenationTest.h

#import <SenTestingKit/SenTestingKit.h>
#import "NSString+Concatenation.h"

@interface NSString_ConcatenationTest : SenTestCase

@end

// NSString+ConcatenationTest.m

#import "NSString+ConcatenationTest.h"

@implementation NSString_ConcatenationTest

- (void)testSimpleConcatenation
{
STAssertEqualObjects([@"a":@"b"], @"ab", nil);
STAssertEqualObjects([@"a":@"b":@"c"], @"abc", nil);
STAssertEqualObjects([@"a":@"b":@"c":@"d"], @"abcd", nil);
STAssertEqualObjects([@"a":@"b":@"c":@"d":@"e"], @"abcde", nil);
STAssertEqualObjects([@"this " : @"is " : @"string " : @"concatenation"],
@"this is string concatenation", nil);
}

- (void)testVarArgConcatenation
{
NSString *concatenation = [@"a" concat:@"b", nil];
STAssertEqualObjects(concatenation, @"ab", nil);

concatenation = [concatenation concat:@"c", @"d", concatenation, nil];
STAssertEqualObjects(concatenation, @"abcdab", nil);
}
Reply

#8
Two answers I can think of... neither is particularly as pleasant as just having a concatenation operator.

First, use an `NSMutableString`, which has an `appendString` method, removing some of the need for extra temp strings.

Second, use an `NSArray` to concatenate via the `componentsJoinedByString` method.
Reply

#9
How about shortening `stringByAppendingString` and use a **#define**:

#define and stringByAppendingString

Thus you would use:

NSString* myString = [@"Hello " and @"world"];

Problem is that it only works for two strings, you're required to wrap additional brackets for more appends:

NSString* myString = [[@"Hello" and: @" world"] and: @" again"];

Reply

#10
Here's a simple way, using the new array literal syntax:

NSString * s = [@[@"one ", @"two ", @"three"] componentsJoinedByString:@""];
^^^^^^^ create array ^^^^^
^^^^^^^ concatenate ^^^^^
Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through