I've been searching a solution for this problem, but it seems I'm the only one on the Internet who has encountered a problem like this.
I'm using the keychain wrapper class provided by Apple to store the user and password as it should be stored. When I want to get the user value back, is as easy as doing:
NSString *user = [keychain objectForKey:(id)kSecAttrAccount];
Retriveing the password should be as straightforward as the username:
NSString *pass = [keychain objectForKey:(id)kSecValueData];
But after that, trying to print them with an NSLog, nothing is shown on console AFTER the pass. For example:
NSLog(#"user: <%#>, pass: <%#>, something after the pass", user, pass);
The output of this NSLog is:
user: <123456>, pass: <5433
Invoking [pass length] gives me always a number greater than the actual length of the pass (in this example, 10, when I would say its length is actually 4).
I have no idea of what's going on. I made a workaround to patch this problem while I try to find a proper solution (looking every character's integer value and allowing only the ones which are numbers, letters and some symbols).
Thank you in advance!
The problem here is that you are trying to store a CFDataRef object as an NSString object, and then print it is a string using %#. It is a data object, not a string. If you'd like to see it as a string, you must first convert it into a string. Try something like the code below to convert it into a string before you try to log it:
NSData *passData = [keychain objectForKey:(id)kSecValueData];
NSString *pass = [[NSString alloc] initWithBytes:[passData bytes] length:[passData length] encoding:NSUTF8StringEncoding];
kSecValueData is of type: typedef const void * CFTypeRef;
You shouldn't typecast it to a NSString.
Try directly posting it into the NSLog like this.
NSLog(#"user <%#> pass <%#>", [keychain objectForKey:(id)kSecAttrAccount], [keychain objectForKey:(id)kSecValueData]);
Goodluck!
Related
So I'm reading the most recent tweet from a twitter bot and assigning it to a string, but sometimes it tweets directly to users. Here's an example of what that might look like.
NSString tweet = #("#user hey heres my message: BLah blah with symbols!");
//part I want to keep is: " BLah blah with symbols!"
//or it could end up being
NSString tweet = #("#otheruser my msg is: Wow heres some more blah: and a second colon");
//part I want to keep is: " Wow heres some more blah: and a second colon"
I want to always remove the first part that talks to the user, while keeping the message on the end. There are too many different messages to use "stringByReplacingOccurrencesOfString"
I don't want to use "exlude-replies" from the twitter API because this bot is very popular and that would require fetching up to 100 since "count" applies before
any idea how I could do this? I think it has something to do with regular expressions, but I haven't ever used them before or been able to get one working how I want. I would really appreciate the help from anyone whos comfortable with regex
edit: also if a regex won't work for this case, id accept an explanation of the limitation preventing that :)
The easiest solution that I can think of is to create an NSMutable array, by using the NSString function componentsSeparatedBy:#":", and simply remove the first element.
NSMutableArray *tweetArray = [[NSMutableArray alloc] initWithArray: [tweet componentsSeparatedByString:#":"]];
[tweetArray removeObjectAtIndex:0];
Your issue with a colon appearing at random afterwards can be fixed by joining the pieces back together again.
tweet = [tweetArray componentsJoinedByString:#":"];
Edit: Fix an error pointed out by user 'maddy'
You'll have to stick this code in an if statement so that it does not execute in tweets that have a colon normally. You can use the fact that it always begins with #user however.
if ([tweet characterAtIndex:0] == '#' && [tweet characterAtIndex:1] != ' '){
NSMutableArray *tweetArray = [[NSMutableArray alloc] initWithArray: [tweet componentsSeparatedByString:#":"]];
[tweetArray removeObjectAtIndex:0];
tweet = [tweetArray componentsJoinedByString:#":"];
}
You can also use this.
NSString *myString = #"#username is me: by using this as sample text";
NSRange range = [myString rangeOfString:#":"];
NSString *newString= [myString substringFromIndex:range.location];
NSLog(#"New String is : %#", newString);
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
I need to gather data from a website based on the user's input.
searchString is the user inputted value, such as "search this string".
NSString *withoutSpaces = [searchString stringByReplacingOccurrencesOfString:#" " withString:#"%20"];
Here, I need to replace spaces with %20
Next, I need to put the new string without spaces (replaced with %20) into another string.
NSString *unescapedSearchString = [NSString stringWithFormat:
#"website.com/query?=%22%#%22", withoutSpaces];
The site I need is not really "website.com", but that's just an example. I also need the %22 to remain at the beginning and end.
As you can see, I need the %# to format the new withoutSpaces user input into the website URL.
I did a search and found examples but I could not find any with formatting such as in my case using %#.
What's the best way to "escape" the characters and keep my formatted string? Currently, when I try to access data from the website, it comes back as null. However, when I try a string without the %# formatting and an actual value, I successfully retrieve the data from a website.
Any help is greatly appreciated.
You should do things this way:
NSString *searchString = ... // the raw search string with spaces and all
NSString *quoted = [NSString stringWithFormat:#"\"%#\"", searchString];
NSString *escaped = [quoted stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
NSString *urlString = [NSString stringWithFormat:#"website.com?query=%#&value=all", escaped];
BTW - the URL seems a little off. There should be a variable name before the = and after the ?.
I'm having an issue with grabbing the App Store ID from my plist, and using it with Appirater. I NSLogged the URL that was being used when the user pushes "Rate Now", and the App Store ID is way different from the App Store ID I set in Info.plist. No idea where it is getting these numbers from -- they are a different set of 9 numbers each time. This is really strange.
The code in Appirater.m that deals with grabbing the App Store ID and using it in the link looks like this: NSString *const kAppiraterAppIdBundleKey = #"AppStoreId";
NSString *templateReviewURL = #"itms-apps://ax.itunes.apple.com/WebObjects/MZStore.woa/wa/viewContentsUserReviews?type=Purple+Software&id=APP_ID";
....
+ (NSString*)appStoreAppID {
NSString* value = [[[NSBundle mainBundle] infoDictionary] objectForKey:kAppiraterAppIdBundleKey];
NSAssert1(value, #"Error - you have not specified %# property in your info.plist", kAppiraterAppIdBundleKey);
return value;
}
//...
+ (void)rateApp {
//...
NSString *reviewURL = [templateReviewURL stringByReplacingOccurrencesOfString:#"APP_ID" withString:[NSString stringWithFormat:#"%d", [self appStoreAppID]]];
//...
}
I added a field in the plist called "AppStoreId", and entered the 9 digit code. I made it a string type. Now, the code runs perfectly when I replace "APP_ID" with the actual 9 digit code in that iTunes link above, but when I keep it as APP_ID, I get the error "Cannot connect to the iTunes Store.", and the NSLog output has 9 random numbers in the link, and again, they are different each time.
This is probably an easy fix, but I can't seem to figure it out.
Random numbers? You're using:
[NSString stringWithFormat:#"%d", [self appStoreAppID]]
where appStoreAppID is an NSString.
So you're replacing "APP_ID" with the pointer to the NSString, not the contents of the NSString.
Just use %# instead of %d.
I want a input from user their name and output that input name in NSLog using NSString.
I don't know which % sign and how to output that.
Can i use scanf() function for that?
Please help me , i am just beginner of Objective-C.
You can use %# for all objects including NSString. This will in turn call the objects description method and print the appropriate string. Most objects have a rather useful representation already there (e.g. NSArray objects return the descriptions of all their contents).
Mark Dylan is the name which would be stored in the Name variable.
NSString* Name = #"Mark Dylan";
This code will allow you to ask their name and scan it into memory which will be stored in the Name variable.
NSLog(#"What is your name?");
scanf("%#", &Name);
If you want to print out the variable you can use;
NSLog(#"Your name is %#", Name);
%# is what you want. It fit for object like NSString, [YourViewController class]
To get input from the user use a UITextField or a NSTextField. To output a string to the log file you can use NSLog, ie:
NSString* userName = #"Zawmin";
NSLog(#"name = %#", userName);
NSLog accepts a format string, so you can do something like this:
#include <stdio.h>
#include <Foundation/Foundation.h>
// 1024 characters should be enough for a name.
// If you want something more flexible, you can use GNU readline:
// <http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html>
#define MAX_NAME_LENGTH 1024
// Get name from user input
char name[MAX_NAME_LENGTH];
name[0] = '\0'; // just in case fgets fails
fgets(name, MAX_NAME_LENGTH, stdin);
// Put name into NSString object and output it.
NSString *name = [NSString stringWithUTF8String:name];
NSLog(#"%#", name);
%# works for all Objective-C objects.
If you want to output a C-string (char* or const char*), use %s. Never put a non-literal string as the first argument to NSLog as this opens security holes.