Cryptic SQLite console output in Objective-C - objective-c

When running my program to query the iPod library of my iPhone, I get the following output in the console:
CPSqliteStatementPerform: attempt to write a readonly database for UPDATE ddd.ext_container SET orig_date_modified = (SELECT date_modified FROM container WHERE pid=container_pid) WHERE orig_date_modified=0
I have disabled everything that outputs to the console so it isn't as if I am having an error with NSLog. What is going on here and how can I fix it. I'll include the overall class source code that I am calling, along with the class that does the work (sorry for posting it all:
+(NSMutableDictionary *) makeQuery {
MPMediaQuery *query = [[MPMediaQuery alloc] init]; //query iPod library
NSString *facebookIDKey = #"Facebook ID";
NSString *genericFacebookID = #"1234567890";
NSMutableDictionary *organizedSongData = [NSMutableDictionary dictionaryWithObject:genericFacebookID forKey:facebookIDKey];
NSArray *allSongs = [query collections];
//only add those songs which have not
//been played since last login
for (MPMediaItem *recent in allSongs) {
NSDate *lastPlayed = [recent valueForProperty:MPMediaItemPropertyLastPlayedDate];
int songCounter = 1;
BOOL uploadInfo = [[PlayedSinceLastLogin alloc] initWithLastPlayedDateOfSong:lastPlayed];
if (uploadInfo == YES) {
//adds songs into
[organizedSongData addEntriesFromDictionary: [MakeDicForSongInfo initWithMPMediaItem:recent andSongNumber:songCounter]];
songCounter++;
}
}
return organizedSongData;
}
Here is the actual brunt of the work, done in the MakeDicForSongInfo:
+(NSDictionary *) initWithMPMediaItem:(MPMediaItem *) song andSongNumber: (int)songCount{
//Create & initialize NSStrings for keys
//Create NSArray to hold keys
NSString *songKey = [NSString stringWithFormat: #"%i Song Title", songCount];
NSString *albumKey = [NSString stringWithFormat: #"%i Album", songCount];
NSString *artistKey = [NSString stringWithFormat: #"%i Artist", songCount];
NSString *artistIDKey = [NSString stringWithFormat: #"%i Artist Persistent ID", songCount];
NSString *lastPlayedKey = [NSString stringWithFormat: #"%i Late Played Date", songCount];
NSString *genreKey = [NSString stringWithFormat: #"%i Genre", songCount];
NSString *ratingKey = [NSString stringWithFormat: #"%i User Rating", songCount];
NSString *playCountKey = [NSString stringWithFormat: #"%i Play Count", songCount];
NSArray *propertyKeys = [[NSArray alloc] initWithObjects:songKey, albumKey, artistKey, artistIDKey,
lastPlayedKey, genreKey, ratingKey, playCountKey, nil];
//Create & initialize NSStrings to hold song property information
//Create NSArray to hold the values
NSString *songTitle = [song valueForProperty:MPMediaItemPropertyTitle];
NSString *albumName = [song valueForProperty:MPMediaItemPropertyAlbumTitle];
NSString *artistName = [song valueForProperty:MPMediaItemPropertyArtist];
NSString *artistID = [song valueForProperty:MPMediaItemPropertyArtistPersistentID];
NSString *lastPlayed = [song valueForProperty:MPMediaItemPropertyLastPlayedDate];
NSString *genre = [song valueForProperty:MPMediaItemPropertyGenre];
NSString *userRating = [song valueForProperty:MPMediaItemPropertyRating];
NSString *playCount = [song valueForProperty:MPMediaItemPropertyPlayCount];
NSArray *propertyValues = [[NSArray alloc] initWithObjects:songTitle, albumName, artistName, artistID,
lastPlayed, genre, userRating, playCount, nil];
//Create NSDictionary to store information, initializing it with
//above data, then returning the resulting dictionary
NSDictionary *songInfo = [[NSDictionary alloc] initWithObjects:propertyValues forKeys:propertyKeys];
return songInfo;
}
Could it be something in accessing all that Media information that spooks the iPhone?

Apparently this is a bug in iOS 4.3 and is addressed in this devforum at Apple:
https://devforums.apple.com/message/428584#428584

Related

Unable to convert UTF-8 text from NSDictionary in Objective-C

Im using foursquare API to get some locations around me, but when the name of that place wasn't in english, the name will be like follows:
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
i tried to convert the response to a UTF-8 but nothing changed.
Here is my code:
-(void)setUpLocations{
NSURL *url = [NSURL URLWithString: #"https://api.foursquare...."];
NSData *data = [NSData dataWithContentsOfURL:url];
NSError *error = nil;
NSDictionary *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:&error];
NSLog(#"Response: %#",[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"]);
}
And the log result is:
contact = {
};
id = 51712507498ec4e8c5ae9f48;
likes = {
count = 0;
groups = (
);
};
location = {
address = Abdoun;
cc = JO;
city = Amman;
country = Jordan;
distance = 3819;
lat = "31.95406043797281";
lng = "35.88095228186612";
};
name = "\U0645\U0633\U062c\U062f \U0627\U0644\U0633\U064a\U062f\U0629 \U0639\U0627\U0626\U0634\U0629 | Aisha Mosque";
restricted = 1;
stats = {
checkinsCount = 43;
tipCount = 2;
usersCount = 23;
};
verified = 0;
},
Any Suggestions ??
EDIT:
here is how i extract the data from the dictionary:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
namesArray = [[NSArray alloc]initWithArray:[self removeWhiteSpaces:[dic valueForKey:#"name"]]];
-(NSArray *)removeWhiteSpaces:(NSDictionary *)dic{
NSString *str = [NSString stringWithFormat:#"%#",dic];
NSString *str2 = [str stringByReplacingOccurrencesOfString:#"\n" withString:#""];
NSString *secondString = [str2 stringByReplacingOccurrencesOfString:#" " withString:#""];
NSString *thirdString = [secondString stringByReplacingOccurrencesOfString:#"(" withString:#""];
NSString *forthString = [thirdString stringByReplacingOccurrencesOfString:#")" withString:#""];
NSString *fifthString = [forthString stringByReplacingOccurrencesOfString:#"\"" withString:#""];
NSArray *items = [fifthString componentsSeparatedByString:#","];
return items;
}
And in the UITableView:
cell.textLabel.text = [NSString stringWithFormat:#"Name: %# ",[namesArray objectAtIndex:indexPath.row] ];
Update
After trying #Martin R answer i got the same results:
NSDictionary *dic = [[[[json objectForKey:#"response"]objectForKey:#"groups"]valueForKey:#"items"] copy];
NSString *value =[dic valueForKey:#"name"];
NSLog(#"%#", value);
UILabel *lbl = [[UILabel alloc]initWithFrame:self.view.frame];
lbl.numberOfLines = 0;
lbl.text = [NSString stringWithFormat:#"%#",value];;
[self.view addSubview:lbl];
and here is an image of the result
There is no problem.
NSLog() calls the description method of NSDictionary and NSArray, and that prints all non-ASCII characters as \Unnnn escape sequence.
If you extract the string values from the dictionary and print that you will see
that everything is correct.
Simple example:
NSDictionary *dict = #{ #"currency": #"€" };
NSLog(#"%#", dict);
// Output: { currency = "\U20ac"; }
NSString *value = dict[#"currency"];
NSLog(#"%#", value);
// Output: €
UPDATE: The problem seems to be in your removeWhiteSpaces: method, because
NSString *str = [NSString stringWithFormat:#"%#",dic];
already uses the description method to convert the dictionary to a string,
and the following stringByReplacingOccurrencesOfString calls are a (sorry!) very bad
method to fix that.
You should access the dictionary keys with objectForKey instead, or enumerate
the dictionary with for (NSString *key in dic) { ... } and build the desired
array.
UPDATE 2: From the JSON data (posted in chat discussion) it seem that you just need
NSArray *itemsArray = json[#"response"][#"groups"][0][#"items];
NSArray *namesArray = [itemsArray valueForKey:#"name"];
Note that "groups" is an array with one element.
Try to use this one..
[NSString stringWithUTF8String:]

Reading from SQL database into NSArray

I have an iPad that reads data from an SQL database. The following code works fine and retrieves 2 fields from each record and reads them into an NSArray.
I now need to read 5 of the fields and I can't help but think that there is a better way of doing it rather than running 5 separate queries through php (the getinfo.php file with the choice parameter set to pick the different fields).
Any pointers to a better method for doing this?
NSString *strURLClass = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=1&schoolname=",obsSchoolName];
NSArray *observationsArrayClass = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsClass = [observationsArrayClass objectEnumerator];
NSString *strURLDate = [NSString stringWithFormat:#"%#%#", #"http://wwwaddress/getinfo.php?choice=5&schoolname=",obsSchoolName];
NSArray *observationsArrayDate = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLDate]];
observationListFromSQL = [[NSMutableArray alloc]init];
NSEnumerator *enumForObsDate = [observationsArrayDate objectEnumerator];
id className, dateOfObs;
while (className = [enumForObsClass nextObject])
{
dateOfObs = [enumForObsDate nextObject];
[observationListFromSQL addObject:[NSDictionary dictionaryWithObjectsAndKeys:className, #"obsClass", dateOfObs, #"obsDate",nil]];
}
Yes, you can do that with less code by "folding" the statements into a loop, and using a mutable dictionary:
// Add other items that you wish to retrieve to the two arrays below:
NSArray *keys = #[#"obsClass", #"obsDate"]; // Key in the dictionary
NSArray *choices = #[#1, #5]; // Choice in the URL string
NSMutableArray *res = [NSMutableArray array];
NSMutableArray *observationListFromSQL = [NSMutableArray array];
for (int i = 0 ; i != keys.count ; i++) {
NSNumber *choice = choices[i];
NSString *strURLClass = [NSString stringWithFormat:#"http://wwwaddress/getinfo.php?choice=%#&schoolname=%#", choice, obsSchoolName];
NSArray *observationsArray = [[NSMutableArray alloc] initWithContentsOfURL:[NSURL URLWithString:strURLClass]];
NSEnumerator *objEnum = [observationsArrayClass objectEnumerator];
NSString *key = keys[i];
NSMutableDictionary *dict;
if (res.count < i) {
dict = res[i];
} else {
dict = [NSMutableDictionary dictionary];
[res addObject:dict];
}
id item;
while (item = [objEnum nextObject]) {
[res setObject:item forKey:key];
}
}

JSON text and variable count

I am reading like this...
NSString *fileContent = [[NSString alloc] initWithContentsOfFile:path];
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSDictionary *data = (NSDictionary *) [parser objectWithString:fileContent error:nil];
// getting the data from inside of "menu"
NSString *message = (NSString *) [data objectForKey:#"message"];
NSString *name = (NSString *) [data objectForKey:#"name"];
NSArray *messagearray = [data objectForKey:#"message"];
NSArray *namearray = [data objectForKey:#"name"];
NSDictionary* Dictionary = [NSDictionary dictionaryWithObjects:message forKeys:name];
for (NSString* Key in [Dictionary allKeys]){
NSLog(#"%# %#",Key,[Dictionary objectForKey:Key]);
}
...this JSON file...
{"message":["Untitled1a","Untitled2a","Untitled3a"],"name": ["Untitled1b","Untitled2b","Untitled3b"]}
...this is the result...
Untitled3b Untitled3a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled1b Untitled1a
2012-05-12 11:31:17.983 Quick Homework[721:f803] Untitled2b Untitled2a
...but for each pair (Untitled 1b 2b) I would like to alloc two UITextFields, witch display the correspondent text...
I tried using this method:
for (NSString *string in messagearray){
}do{
NSLog(#"happt = %i", b);
b++;
}
while(b == b);
//While loop
while (b == b ) {
NSLog(#"x = %i", b);
b++;
}
}
I would like to count the objects in the array in order to repeat an alloc code for UITextField that number of times, and display the text accordingly, but I am not able. Please help!!
Why can't you use -count?
b = [messagearray count]
To directly answer your question:
b = 0;
for (id item in messagearray)
b++;

connecting three NSStrings

Right i have three NSStrings that i want to put together to make one long nsstring (to use as a URL). I have used stringByAppedingString which lets me put two of the together but i do not know how to put three together. Basically what i want to end up with is http://graph.facebook.com/517418970/picture?type=large but i need them in three separate components so i can change the number in the URl
#implementation FacebookPicturesViewController
- (IBAction) nextImagePush {
NSString *prefix = #"http://graph.facebook.com/";
NSString *profileId = #"517418970";
NSString *suffix = #"/picture?type=large";
NSString *url = [prefix stringByAppendingString:suffix];
UIImage *img = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:url]]];
[imageView setImage:img];
imageCount++;
if (imageCount >= [imageArray count]){
imageCount = 0;
}
}
- (void) viewDidLoad {
imageArray = [[NSArray alloc] initWithObjects:#"image1", #"image2", nil];
imageCount = 0;
}
You could just do it in two steps:
NSString* partialUrl= [prefix stringByAppendingString:profileID];
NSString* fullUrl= [partialUrl stringByAppendingString:suffix];
Alternatively, you could use a format:
NSString* url= [NSString stringWithFormat:#"%#%#%#", prefix, profileID, suffix];
As a general solution for when you don't know ahead of time just how many strings you have to combine, you can stick them in an NSArray and use the array to join them together. So in this case:
NSArray *elementsInURL = [NSArray arrayWithObjects:prefix, profileID, suffix, nil];
NSString *combined = [elementsInURL componentsJoinedByString:#""];
You want + (id)stringWithFormat:(NSString *)format, …
Full docs are here
I'd handle the concatenation like this:
NSString *prefix = #"http://graph.facebook.com/";
NSString *profileId = #"517418970";
NSString *suffix = #"/picture?type=large";
NSString *URL = [[prefix stringByAppendingString:profileId]
stringByAppendingString:suffix];

How to prevent all rows of an NSTableView being selected at startup

I am new to Objective-C. I am using NSArrayController to fill NSTableView. Initially, I am getting all rows selected in the table view. I am unable to find the reason behind it.
for(int i=0;i<nCount;i++)
{
NSString *fileName_File = [[[filenames objectAtIndex:i] lastPathComponent] stringByDeletingPathExtension];
NSString *pathExtension = [[filenames objectAtIndex:i] pathExtension];
NSString *yourPath = [filenames objectAtIndex:i];
NSFileManager *fmgr = [[NSFileManager alloc] init];
NSDictionary *attrs = [fmgr attributesOfItemAtPath: yourPath error: nil];
[attrs retain];
UInt32 result = [attrs fileSize];
/*NSString * zStr1 = [[NSString alloc]initWithFormat:#"%d",i+1];
NSString * zStr2 = [[NSString alloc]initWithFormat:#"%#",fileName_File];
NSString * zStr3 = [[NSString alloc]initWithFormat:#"%#",pathExtension];
NSString * zStr4 = [[NSString alloc]initWithFormat:#"%d",result];
NSString * zStr5 = [[NSString alloc]initWithFormat:#"%#",[filenames objectAtIndex:i]];*/
CMyMediaData * MyMediaObj = [[CMyMediaData alloc]initWithString1:[[NSString alloc]initWithFormat:#"%#",#""]
andString2:[[NSString alloc]initWithFormat:#"%#",fileName_File]
andString3:[[[NSString alloc]initWithFormat:#"%#",pathExtension]uppercaseString]
andString4:[[NSString alloc]initWithFormat:#"%d",result]
andString5:[[NSString alloc]initWithFormat:#"%#",[filenames objectAtIndex:i]]
];
[attrs release];
[mMedia.mcMediaController.mcTableViewMyMedia addObject:MyMediaObj];
//[mMedia.nsMutaryOfDataObject addObject:MyMediaObj];
} this is the code to add data to nsarraycontroller object.mcMediaController is object of NSArrayController
NSArrayController has a property selectsInsertedObjects. If that is YES, inserted objects are marked selected, including the ones added by addObject:.
You can set that property to NO, or you can use the following to unset the selection after adding the items:
mMedia.mcMediaController.mcTableViewMyMedia.selectedObjects = #[];