Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
I have some data that contains UTF8 characters. If I do following I can able to see characters correctly in console:
NSString *responseData = [[NSString alloc]
initWithData:urlData
encoding:NSUTF8StringEncoding];
NSLog(#"Response = %#", responseData);
Output
{"success":1,"row":1,"no":"001","title":"Arendi iOS","subject":"Konu 1","describtion":"Aciklama 1 ıİöÖçÇüÜğĞ","attachment":"Eklenti 1","status":1}
After this step I am doing this:
SBJsonParser *jsonParser = [SBJsonParser new];
NSDictionary *jsonData = (NSDictionary*)[jsonParser objectWithString:responseData error:nil];
NSLog(#"jsonData = %#",jsonData);
Output:
jsonData = {
attachment = "Eklenti 2";
describtion = "Aciklama 2 \U0131\U0130\U00f6\U00d6\U00e7\U00c7\U00fc\U00dc\U011f\U011e";
no = 002;
row = 2;
status = 1;
subject = "Konu 2";
success = 1;
title = "Arendi Android";
}
After that I am doing this:
NSString *description = (NSString*)[jsonData objectForKey:#"description"];
But it gives me null. How can I print this characters correctly?
Not sure whether it is a simple typo but I couldn't help noticing that you had a field named "description" here.
jsonData = {
attachment = "Eklenti 2";
describtion = "Aciklama 2 \U0131\U0130\U00f6\U00d6\U00e7\U00c7\U00fc\U00dc\U011f\U011e";
no = 002;
row = 2;
status = 1;
subject = "Konu 2";
success = 1;
title = "Arendi Android";
}
However in the final output, you were trying to get the value of a property named "description". If key is defined as "describtion", you can't find it by "description" and parser will return "null" as expected.
Hope it helps.
Related
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Hello there im stuck on this thing where i need to cycle through a certain dir that i need to get all the file names from and get there paths as a variable.
I know how to create a loop, but to get the directory's contents, I do not.
Any help is appreciated, thanks!
Try like this:
// If your folder is a document.
NSString *docsDir = [NSHomeDirectory() stringByAppendingPathComponent: #"Documents"];
// else you can give your folder path as well, if you know
// for example like this NSString *docsDir = #"user/desktop/testFolder"
NSFileManager *localFileManager = [NSFileManager defaultManager];
NSDirectoryEnumerator *dirEnum = [localFileManager enumeratorAtPath:docsDir];
NSString *file = nil;
NSData *fileContents = [NSData data];
while ((file = [dirEnum nextObject]))
{
NSLog(#"your file name%#",file); // This will give your filename
// Now for getting file path follow below.
// here we are adding path to filename.
NSString *fileNamePath = [docsDir stringByAppendingPathComponent:file];
NSLog(#"your fileNamePath%#",fileNamePath); // This will give your filename path
fileContents = [NSData dataWithContentsOfFile:fileNamePath]; // This will store file contents in form of bytes
}
Hope it helps:)
I'm trying to create a basic quiz app where the questions will not repeat. I've looked at several examples and believe I should be storing the questions in an array and then removing one from the array each time its used. I've tried the following code.
- (void)viewDidLoad
{
//The array of questions
NSMutableArray *questionArray = [[NSMutableArray alloc] initWithObjects:
[NSMutableArray arrayWithObjects:#"First Question",#"Answer A", nil],
[NSMutableArray arrayWithObjects:#"Second Quesiton",#"AnswerA",#"AnswerB", nil],
nil];
//remove used question from array
for (int i = questionArray.count; i>=0; --i) {
_questions = [questionArray objectAtIndex:arc4random() % questionArray.count];
[questionArray exchangeObjectAtIndex:i withObjectAtIndex:_questions];
}
//use array object
self.lblQuestion.text = [_questions objectAtIndex:0];
[self.btnA setTitle:[_questions objectAtIndex:1] forState:UIControlStateNormal];
[super viewDidLoad];
}
I'm getting the following warning:
Incompatible pointer to integer conversion sending NSMutableArray*_strong to parameter of type 'NSUInteger'
I take it this means I shouldn't be using another array to store the random question as I can't use this to remove the question from the array. However I don't know how else to do this?
Am I completely misunderstanding how I should go about this?
Since your goal here is to get non-repeating questions...
I believe that instead of removing the question you have already used, you should SHUFFLE your array at the beginning and then loop through the array one index at a time using a simple counter.
I hope you can find this piece of code helpful -- give it a shot:
-(NSMutableArray *)shuffleArray:(NSMutableArray *)anArray
NSUInteger count = [anArray count];
for (NSUInteger i = 0; i < count; ++i)
{
int nElements = count - i;
int n = (arc4random() % nElements) + i;
[anArray exchangeObjectAtIndex:i withObjectAtIndex:n];
}
return anArray;
}
-(void)viewDidLoad
{
//The array of questions
NSMutableArray *questionArray = [[NSMutableArray alloc] initWithObjects:
[NSMutableArray arrayWithObjects:#"First Question",#"Answer A", nil],
[NSMutableArray arrayWithObjects:#"Second Quesiton",#"AnswerA",#"AnswerB", nil],
nil];
//Shuffle the question array -- Now all indexes are shuffled and Random
questionArray = [self shuffleArray:questionArray];
//Every time you want to move to the next question, all you have to do is connect a button to the nextIndex action and let it do all the work!
//Use the nextIndex method to initialise -- we call it manually the first time so things would get going and something is displayed -- you can remove the line below if you want it to initialise on first button click! Your call the shots sir!
[self nextIndex];
[super viewDidLoad];
}
//Edit -- This method shows how to change question array index using a method
int currentIndex = 0;
-(IBAction)nextIndex
{
if ( currentIndex == [questionArray count] )
{
currentIndex = 0; //Resets the var when getting to the final Index
//The above line will result in a question loop -- meaning if you arrive at the last question, the next question will be the first! Pacman mode!
//If you want to stop at the last question just change the above line to return; and you're all set!
}
//Set _questions object to the current Index Array element
_questions = [questionArray objectAtIndex:currentIndex];
//Increment currentIndex for next use
currentIndex++;
//use the array object to set your objects' values
self.lblQuestion.text = [_questions objectAtIndex:0];
[self.btnA setTitle:[_questions objectAtIndex:1] forState:UIControlStateNormal];
}
You will end up having totally different questions that are shuffled every time.
I hope you find this helpful.
noobie question.. What is the best way to check if the index of an NSArray or NSMutableArray exists. I search everywhere to no avail!!
This is what I have tried:
if (sections = [arr objectAtIndex:4])
{
/*.....*/
}
or
sections = [arr objectAtIndex:4]
if (sections == nil)
{
/*.....*/
}
but both throws an "out of bounds" error not allowing me to continue
(do not reply with a try catch because thats not a solution for me)
Thanks in advance
if (array.count > 4) {
sections = [array objectAtIndex:4];
}
If you have an integer index (e.g. i), you can generally prevent this error by checking the arrays bounds like this
int indexForObjectInArray = 4;
NSArray yourArray = ...
if (indexForObjectInArray < [yourArray count])
{
id objectOfArray = [yourArray objectAtIndex:indexForObjectInArray];
}
Keep in mind NSArray is in sequential order from 0 to N-1 items
Your are trying to access item which has exceeded limit and a array is nil then compiler would throw out of bound error.
EDIT : #sch's answer above shows how can we check if NSArray has required ordered item present in it or not.
You can use the MIN operator to fail silently like this [array objectAtIndex:MIN(i, array.count-1)], to either get next object in the array or the last. Can be useful when you for example want to concatenate strings:
NSArray *array = #[#"Some", #"random", #"array", #"of", #"strings", #"."];
NSString *concatenatedString = #"";
for (NSUInteger i=0; i<10; i++) { //this would normally lead to crash
NSString *nextString = [[array objectAtIndex:MIN(i, array.count-1)]stringByAppendingString:#" "];
concatenatedString = [concatenatedString stringByAppendingString:nextString];
}
NSLog(#"%#", concatenatedString);
Result: "Some random array of strings . . . . . "
I'm trying to compare two strings
NSString strOne = #"Cat, Dog, Cow";
NSString strTwo = #"Cow";
How do I determine if strOne contains strTwo
Try using rangeOfString:
NSRange result = [strOne rangeOfString:strTwo];
From the documentation:
Returns an NSRange structure giving the location and length in the receiver of the first occurrence of aString. Returns {NSNotFound, 0} if aString is not found or is empty (#"").
For anyone needing the code to check is a string exists within a string, here's my code thanks to fbrereto. This example checks to see if any string contained in an array of strings (stringArray) can be found within a string (myString):
int count = [stringArray count];
for (NSUInteger x = 0; x < count; ++x) {
NSRange range = [self.myString rangeOfString:[stringArray objectAtIndex:x]];
if (range.length > 0) {
// A match has been found
NSLog(#"string match: %#",[stringArray objectAtIndex:x]);
}
}
I believe this is the correct syntax for checking if the range exists (correcting response from Kendall):
range.location != NSNotFound
Gradually straying off topic, but I always explode my strings, which would mean just exploding it using your search string as a key and you can use the array count to see how many instances you have.
Just incase anyone is coming from a code language that uses "explode" to blow a string up into an array like me, I found writing my own explode function tremendously helpful, those not using "explode" are missing out:
- (NSMutableArray *) explodeString : (NSString *)myString key:(NSString*) myKey
{
NSMutableArray *myArray = [[NSMutableArray alloc] init];
NSRange nextBreak = [myString rangeOfString:myKey];
while(nextBreak.location != NSNotFound)
{
[myArray addObject: [myString substringToIndex:nextBreak.location]];
myString = [myString substringFromIndex:nextBreak.location + nextBreak.length];
nextBreak = [myString rangeOfString:myKey];
}
if(myString.length > 0)
[myArray addObject:myString];
return myArray;
}
works like this:
[self explodeString: #"John Smith|Age: 37|Account Balance: $75.00" key:#"|"];
which will return this array:
[#"John Smith", #"Age: 37", #"Account Balance: $75.00"];
This lets you quickly pull out a specific value in a tight space, Like if you have a client and you want to know how much money he has:
[[self explodeString: clientData key: pipe] objectAtIndex: 1];
or if you wanted specifically the dollar amount as a float:
[[[self explodeString: [[self explodeString: clientData key: pipe] objectAtIndex: 1] key: #": "] objectAtIndex: 2] floatValue];
anyway I find arrays way easier to work with and more flexible, so this is very helpful to me. Additionally with a little effort you could make an "explodable string" data type for your private library that lets you treat it like a string or return an index value based on the key
ExplodableString *myExplodableString;
myExplodableString.string = #"This is an explodable|string";
NSString *secondValue = [myExplodableString useKey: #"|" toGetValue: index];
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 4 years ago.
Improve this question
I'd appreciate some feedback on a particular approach I'm thinking of using. The scenario is below.
I have an object (lets call it MObject) that has a number of properties, say, x and y coordinates, height and width. The properties are named according to the KVC guidelines (MObject.x; MObject.height, etc). My next task, is to read in an XML file that describes this MObject. Unfortunately, the XML elements are named differently -- X and Y, Height and Width (note the capitalization).
Ideally, the XML elements would match up with MObject's properties. In this case, I could use KVC and avoid a whole whack of code:
for (xmlProperty in xmlElement)
{
[MObject setValue:xmlProperty.value forKey:xmlProperty.name].
}
One way of approaching this would be to make use of case-insensitive keys. Where would I start with that? Are there any other, better solutions?
Suggestions very much appreciated.
Don't override -[NSObject valueForKey:] and -[NSObject setValue:forKey:] if you can at all help it.
Your best bet would be to convert the keys you get from the XML file on the fly. Use a separate method to do the conversion and you can also maintain a cache of names to property keys, so you only need to do each conversion once.
- (NSString *)keyForName:(NSString *)name {
// _nameToKeyCache is an NSMutableDictionary that caches the key
// generated for a given name so it's only generated once per name
NSString *key = [_nameToKeyCache objectForKey:name];
if (key == nil) {
// ...generate key...
[_nameToKeyCache setObject:key forKey:name];
}
return key;
}
- (void)foo:xmlElement {
for (xmlProperty in xmlElement) {
[myObject setValue:xmlProperty.value forKey:[self keyForName:xmlProperty.name]].
}
}
You can use NSString's lowercaseString to convert the XML key name to lowercase, if that helps.
Override -valueForUndefinedKey: and -setValue:forUndefinedKey:
If you find a key with a different capitalization use it, otherwise call up to super.
Override -valueForKey: and -setValue:forKey:.
You should probably only accept keys (element/attribute names) you recognize, and call up to super for other keys.
So I implemented Chris Hanson's suggestion and here's what I ended up with. I put this in my Utils class. It keeps a dictionary for each class that we lookup. It could probably use a little refactoring but it has worked very well for me so far.
static NSMutableDictionary *keyCache;
+ (NSString *)keyForClass:(Class)klass column:(NSString *)column {
if (!keyCache) { keyCache = [NSMutableDictionary dictionary]; }
NSString *className = NSStringFromClass(klass);
NSMutableDictionary *tableKeyCache = [keyCache objectForKey:className];
if (!tableKeyCache) {
tableKeyCache = [NSMutableDictionary dictionary];
unsigned int numMethods = 0;
Method *methods = class_copyMethodList(klass, &numMethods);
NSMutableArray * selectors = [NSMutableArray array];
for (int i = 0; i < numMethods; ++i) {
SEL selector = method_getName(methods[i]);
[selectors addObject:NSStringFromSelector(selector)];
}
[tableKeyCache setValue:selectors forKey:#"allSelectors"];
free(methods);
[keyCache setValue:tableKeyCache forKey:className];
}
NSString *keyToReturn = [tableKeyCache valueForKey:column];
if (!keyToReturn) {
for (NSString *columnKey in [tableKeyCache valueForKey:#"allSelectors"]) {
if ( [column caseInsensitiveCompare:columnKey] == NSOrderedSame) {
[tableKeyCache setValue:columnKey forKey:column];
keyToReturn = columnKey;
break;
}
}
}
if (!keyToReturn) { // Taking a guess here...
NSLog(#"Selector not found for %#: %# ", className, column);
keyToReturn = [Utils keyForClass:[klass superclass] column:column];
}
return keyToReturn;
}