I have following line of code and I want to convert into HexDecimal value.
NSString *hexDecimal = #"€";
I want the result to be hexDecimalValue = 0x20ac.
NSScanner can do this. Here an example method:
- (NSNumber *)scanHex:(NSString *)aString {
NSScanner *sc=[NSScanner scannerWithString:aString];
if(![sc scanString:#"&#x" intoString:NULL]) return nil;
unsigned long long val;
if(![sc scanHexLongLong:&val]) return nil;
return [NSNumber numberWithUnsignedLongLong:val];
}
This method will return nil if aString does not have the &#x you list, or if that is not followed by a valid hex string. Otherwise it returns a NSNumber object with the desired value.
Looks like you have HTML/XML escaped entities. What you really want to use is the Core Foundation function CFStringTransform.
For that you'll want to have an NSMutableString and bridge it to CFMutableString.
The secret sauce is that this CF function wraps the ICU (International Components for Unicode) library's string transform.
The ICU docs will give you more possible transforms. But for this, you want Hex-Any as your transform if I recall correctly.
Related
I have converted an NSArray to NSString using below code
Suppose i have an array with some data in it.
NSString *sample=[array description];
NSLog(#"%#",sample);
which prints:
(
{
URL = "1a516af1a1c6020260a876231955e576202bbe03.jpg##37911944cc1ea8fd132ee9421a7b3af326afcc19.jpg";
userId = 0;
wallpaperId = 31;
},
{
URL = "a9356863fa43bc3439487198283321622f88e31f.jpg##f09c743ebdc26bb9f98655310a0529b65a472428.jpg";
userId = 0;
wallpaperId = 30;
}
)
It looks like array but it is actually a string.
Now I am wondering, how can I reconvert back to NSArray?
Help appreciated.
And please this not a duplicate question, I couldn't found the same anywhere on SO.
You cannot rely on the results of description as it is not a convert to string operator, but merely a debugging aid. There is nothing to stop it changing between O/S releases and there is no equivalent fromDescription method.
The conventional way of serializing an Objective-C collection to and from a string is to use JSON, so look at the NSJSONSerialization class.
the
NSString componentsseparatedbystring
method will return an array of components separated by a string
I wan't to "know" how to put a string at a location in another string. I already know because I figured out another way to do this. But I wan't to know the real way, does it even exist?
I'm also asking this question for future questions on how to put this string at a location in another string the "false" way (in case it can't be done the real way)
What I mean about putting a (sub)string at a location of string is for example to put
this string:#"Hello" at location:5 inString:#"123456789"
I want the results to be:#"12345Hello6789"
Can this be done the real way? something like this fake code:
[str stringByPuttingString:#"s" atLocation:5];//this code does not exist
I figured out other ways to get this done, can we get it to shorter code?
-(NSString *)putString:(NSString *)str atLocation:(int)location ofString:(NSString *)mainString {
NSRange range = NSMakeRange(location, 0);
return [mainString stringByReplacingCharactersInRange:range withString:str];
}
and
-(NSString *)putString:(NSString *)str atLocation:(int)location ofString:(NSString *)mainString {
NSString *first = [mainString substringToIndex:location];
NSString *last = [mainString substringFromIndex:location];
return [NSString stringWithFormat:#"%#%#%#", first, str, last];
}
The first one feels best, any other ideas or real ideas?
Jonathan,
in future cases of this "problem".
Why not just use an NSMutableString?
NSMutableString *string = [NSMutableString stringWithString:#"123456789"];
[string insertString:#"Hello" atIndex:5];
NSLog(#"%#", string);
Outputs:
12345Hello6789
You can use NSMutableString to accomplish this task. Specifically, see the reference to the insertString:atIndex: method which will do exactly what you want, i.e. insert a string into another string at a specified location. API LINK
you can implement this by using NSMutableString method insertString:atIndex:
Inserts into the receiver the characters of a given string at a given location.
- (void)insertString:(NSString *)aString atIndex:(NSUInteger)anIndex
Parameters
aString
The string to insert into the receiver. aString must not be nil.
anIndex
The location at which aString is inserted. The location must not exceed the bounds of the receiver.
Taken from apple developer classes ref
NSMutableString *chars=[ [NSMutableString alloc] initWithString:#""] ;
NSString *temp=[[self convertDecimalToChar:(digitizer%10)] copy]; //temp is good
[chars stringByAppendingString:temp]; //chars is empty
Any idea whats wrong here ?
Thank you.
This line:
[chars stringByAppendingString:temp];
Is supossed to return a string combining both strings.
- (NSString *)stringByAppendingString:(NSString *)aString
If you want to just append a string to your string, do this:
[chars appendString:temp];
Find the documentation here:
NSmutableString
The stringByAppendingString method is on the non-mutable NSString class, where non-mutable means you cannot modify it.
Therefore, as with most other NSString methods, it returns a new NSString object, in this case containing the original string plus whatever you passed in the parameter.
However given you are actually manipulating an NSMutableString object, which is mutable, you probably want the appendString: method instead:
[chars appendString:temp];
If you take a look at the documentation of this method, you need to do:
chars = [chars stringByAppendingString:temp];
It is returning a new NSString combining the two NSString, not actually changing the receiver.
I'm using a 3rd party library for an iOS project I work on, and I'm down to one warning left in the project, namely on this line of code
[NSNumber numberWithUnsignedLongLong:'oaut']
And the warning is
Multi-character character constant
I suck at C, so I don't know how to fix this, but I'm sure the fix is relatively easy. Help?
EDIT: More context.
#implementation MPOAuthCredentialConcreteStore (KeychainAdditions)
- (void)addToKeychainUsingName:(NSString *)inName andValue:(NSString *)inValue {
NSString *serverName = [self.baseURL host];
NSString *securityDomain = [self.authenticationURL host];
// NSString *itemID = [NSString stringWithFormat:#"%#.oauth.%#", [[NSBundle mainBundle] bundleIdentifier], inName];
NSDictionary *searchDictionary = nil;
NSDictionary *keychainItemAttributeDictionary = [NSDictionary dictionaryWithObjectsAndKeys: (id)kSecClassInternetPassword, kSecClass,
securityDomain, kSecAttrSecurityDomain,
serverName, kSecAttrServer,
inName, kSecAttrAccount,
kSecAttrAuthenticationTypeDefault, kSecAttrAuthenticationType,
[NSNumber numberWithUnsignedLongLong:"oaut"], kSecAttrType,
[inValue dataUsingEncoding:NSUTF8StringEncoding], kSecValueData,
nil];
if ([self findValueFromKeychainUsingName:inName returningItem:&searchDictionary]) {
NSMutableDictionary *updateDictionary = [keychainItemAttributeDictionary mutableCopy];
[updateDictionary removeObjectForKey:(id)kSecClass];
SecItemUpdate((CFDictionaryRef)keychainItemAttributeDictionary, (CFDictionaryRef)updateDictionary);
[updateDictionary release];
} else {
OSStatus success = SecItemAdd( (CFDictionaryRef)keychainItemAttributeDictionary, NULL);
if (success == errSecNotAvailable) {
[NSException raise:#"Keychain Not Available" format:#"Keychain Access Not Currently Available"];
} else if (success == errSecDuplicateItem) {
[NSException raise:#"Keychain duplicate item exception" format:#"Item already exists for %#", keychainItemAttributeDictionary];
}
}
}
EDIT 2: They were attempting to meet the requirements of this by creating that NSNumber:
#constant kSecAttrType Specifies a dictionary key whose value is the item's
type attribute. You use this key to set or get a value of type
CFNumberRef that represents the item's type. This number is the
unsigned integer representation of a four-character code (e.g.,
'aTyp').
In C and Obj-C the single-quote ' is used only for single-character constants. You need to use the double-quote: "
Like so:
[NSNumber numberWithUnsignedLongLong:"oaut"]
That covers the warning, but there's also a semantic issue here. Although a single character constant, such as 'o', can be treated as an integer (and can be promoted to an unsigned long long), a "string" (char * or char []) cannot, which means you can't use "oaut" as an argument to numberWithUnsignedLongLong:
Update:
I guess the four-character code is supposed to be treated as an integer, i.e., the 8 bits of each char put in place as if they together were a 32-bit int:
char code[] = "oaut";
uint32_t code_as_int = code[0] | (code[1] << 8) | (code[2] << 16) | (code[3] << 24);
[NSNumber numberWithUnsignedLongLong:code_as_int]
although I'm not sure which endianness would be expected here, nor why this is calling for an unsigned long long, unless just to be certain there are enough bits.
Rudy's comment, now that I think of it, is correct -- multi-character constants are allowed by some compilers for exactly this purpose (it is "implementation-defined" behavior).
'oaut' (single quotes) is a character, so the compiler tries to interpret it as a multi-byte character but can't make any sense of it. That explains the error message.
I guess that if you gave a proper string, like #"oaut", you'd get another error message, since numberWithUnsignedLongLong: expects an unsigned long long, not a string or a character. Are you trying to pass a variable with the name "oaut"? If so, use
[NSNumber numberWithUnsignedLongLong: oaut];
If not, then please explain what "oaut" is.
Edit
'oaut' may actually be the original value. There are/were multi-character character constants in C. Using a (4 byte) char, used as int and promoted to unsigned long long would then be possible. This must be old code. It seems such code was accepted by CodeWarrior.
Assuming that really a multi-char char const was meant, 'oaut' looks like a "magic number" and this value was chosen because it is the beginning of "oauth". I guess it should either be value 0x6F617574 or 0x7475616F.
#Josh Caswell 's answer is partially right, the simplest and "official" solution is:
[NSNumber numberWithUnsignedInt:'oaut']
unsigned int's length is 32-bit in both 32-bit and 64-bit cpu, there's a practical example from Apple: https://developer.apple.com/library/ios/samplecode/CryptoExercise/Listings/Classes_SecKeyWrapper_m.html
I have been able to find methods like -[NSString stringWithCString:encoding:] but they do not seem to play well when the cstring is a pointer.
First up, don't use initWithCString, it has been deprecated.
Couple of ways you can do this:
const *char cString = "Hello";
NSString *myNSString = [NSString stringWithUTF8String:cString];
If you need another encoding like ASCII:
const *char cString = "Hello";
NSString *myNSString = [NSString stringWithCString:cString encoding:NSASCIIStringEncoding];
If you want to see all the string encodings available, in Xcode, hold command + option then double click on NSASCIIStringEncoding in the above code block.
You will be able to see where Apple have declared their enumeration for the string encoding types. Bit quicker than trying to find it in the documentation.
Some other ones you might need:
NSASCIIStringEncoding
NSUnicodeStringEncoding // same as NSUTF16StringEncoding
NSUTF32StringEncoding
Checkout Apple's NSString Class Reference (encodings are at the bottom of the page)
With modern Objective-C (since Xcode 5 at least) you can just do:
char const* cString = "Hello";
NSString *myNSString = #(cString);
stringWithCString:encoding: creates an NSString from a given C string. To create a C string from an NSString, use either the UTF8String method (generally preferred) or cStringUsingEncoding: (if you need an encoding other than UTF-8).