Recover Past NSLogs - ios

A tester that uses my application encountered a seemingly un-reproducable bug a few days ago. I believe the NSLogs that my application records can possibly provide information surrounding the issue, but the Xcode Organizer console only logs the 260 or so previous lines. Is there some log file located on the device that offers a more extended amount of NSLogs? The tester has a jailbroken device so accessing the root directory shouldn't be an issue.

Why don't you use PList to store the logs?
I have developed some location based apps. I always have to drive around a certain areas to test the accuracy of the Location Update, Region Monitoring and etc. I store those logs into a PList and I will analyse the logs on the PList after I completed a run.
Example Code:
-(void)addLocationToPList{
NSString *plistName = [NSString stringWithFormat:#"Location.plist"];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *fullPath = [NSString stringWithFormat:#"%#/%#", docDir, plistName];
NSMutableDictionary *savedProfile = [[NSMutableDictionary alloc] initWithContentsOfFile:fullPath];
if (!savedProfile){
savedProfile = [[NSMutableDictionary alloc] init];
self.shareModel.myCurrentLocationArray = [[NSMutableArray alloc]init];
}
else{
self.shareModel.myCurrentLocationArray = [savedProfile objectForKey:#"locationArray"];
}
if(self.shareModel.myBestLocationDictFromTracker)
{
[self.shareModel.myCurrentLocationArray addObject:self.shareModel.myBestLocationDictFromTracker];
[savedProfile setObject:self.shareModel.myCurrentLocationArray forKey:#"locationArray"];
}
if (![savedProfile writeToFile:fullPath atomically:FALSE] ) {
NSLog(#"Couldn't save Location.plist" );
}
}
I call the above function to add the location to a PList whenever there is a location update. You may use it in anyway you want based on what you really need to log.
I think it is much better than the Organizer Console log as you can extract the PList Out and keep a copy on your Mac for future analysis and etc. I am using iFunBox to access/extract the PList.

Related

How to upload .xml file in IOS app using Objective-C?

In my IOS app I have one abc.xml file through which I get data and display it on screen (I have already done with that, no issue for doing this), my problem is,on button click I want to upload any .xml file to my app (I have some .xml file in my ipad) and want to replace that .xml file with abc.xml file, (then i will fetch data through that newly uploaded file)
It is just like "choose file" option in web
can we do this in iOS app using Objective-C?
iOS uses .plist setting configuration files. I don't know how well this would work, but you could try something a little like this...
NSMutableDictionary *abcDict = [NSMutableDictionary dictionaryWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"abc" fileType:#"xml"]];
NSString *someString = (NSString*)[abcDict valueForKey:#"someString"];
NSNumber *someNumber = (NSNumber*)[abcDict valueForKey:#"someNumber"];
NSDictionary *someDictionary = (NSDictionary*)[abcDict valueForKey:#"someDict"];
NSArray *someArray = (NSArray*)[abcDict valueForKey:#"someArray"];
BOOL *someBoolean = [((NSNumber*)[abcDict valueForKey:#"someBool"]) booleanValue]
Just change your code depending on your data type. BOOL is a bit weird, but everything else is written just like that. Use the right key names, and if XML doesn't work, try plugging a .plist file into your app!
If i understood what you want, this should make the trick.
NSURL *url = [NSURL URLWithString:linkURL];
NSData *urlData = [NSData dataWithContentsOfURL:url];
if ( urlData )
{
BOOL success = [db writeToFile:#"locationOfTheFile" atomically:YES];
if (success) {
//all went well
}else{
//error
}
}
edit:
if the file is at the root of your app, you can get the path with this.
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory , NSUserDomainMask, YES);
NSString *documentsDir = [paths objectAtIndex:0];
BOOL success = [db writeToFile:[documentsDir stringByAppendingPathComponent:#"fileName"];

Detect if another application was installed/uninstalled in a jailbroken iDevice

I want to detect when another application was installed/uninstalled and save the time to a database at the moment of execution.
I know this is possible in Android using broadcastreceiver and I want to know if this can be done in iOS using a jailBroken device because I believe this is not possible in a non-jailBroken device.
I hope someone could help me. Thank you.
Recently was having the same problem.
You need to write SpringBoard tweak. In it you observe notification SBInstalledApplicationsDidChangeNotification from local notification center (CFNotificationCenterGetLocalCenter or [NSNotificationCenter defaultCenter]). User info dictionary will contain:
SBInstalledApplicationsRemovedBundleIDs key contains array of bundle IDs of uninstalled applications.
SBInstalledApplicationsModifiedBundleIDs key contains array of bundle IDs of updated applications.
SBInstalledApplicationsAddedBundleIDs key contains array of bundle IDs of installed applications.
Obviously that way you can log every time applications are installed/uninstalled/updated.
You can check if an application is installed by using its bundle id
BOOL isInstalled = [[LSApplicationWorkspace defaultWorkspace] applicationIsInstalled:#"com.app.identifier"];
if (isInstalled) {
// app is installed }
else {
// app is not installed
}
EDIT:
If you want to check if an application got installed you can maybe count the items inside user of com.apple.mobile.installation.plist it holds all the information about installed apps.
You can write the number of apps inside a plist then later check back and compare the results?
// get apps count
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:#"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"];
int numberOfApps = [[dict objectForKey: #"User"] count];
NSLog(#"Count: %i",numberOfApps);
// Save apps count inside a plist
NSString *path = #"/var/mobile/AppsCount.plist";
NSFileManager *fm = [NSFileManager defaultManager];
NSMutableDictionary *data;
if ([fm fileExistsAtPath:path]) {
data = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
}
else {
// If the file doesn’t exist, create an empty dictionary
data = [[NSMutableDictionary alloc] init];
}
[data setObject:[NSNumber numberWithInt:numberOfApps] forKey:#"savedAppsCount"];
[data writeToFile:path atomically:YES];
[data release];
And then to compare old counts with the new apps count:
// get current number of apps
NSString *path = #"/var/mobile/AppsCount.plist";
NSDictionary *dict = [[NSDictionary alloc] initWithContentsOfFile:#"/var/mobile/Library/Caches/com.apple.mobile.installation.plist"];
int numberOfApps = [[dict objectForKey: #"User"] count];
// retrieve old app count and compare to new ones
NSMutableDictionary *retrieveCounts = [[NSMutableDictionary alloc] initWithContentsOfFile:path];
int oldAppCount = [[retrieveCounts objectForKey:#"savedAppsCount"] intValue];
if (oldAppCount < numberOfApps) {
NSLog(#"NEW APP GOT INSTALLED");
}
else if (oldAppCount > numberOfApps) {
NSLog(#"AN APP GOT UNINSTALLED");
}
else {
NSLog(#"NOTHING GOT INSTALLED OR UNINSTALLED");
}
[retrieveCounts release];
But that doesn't give you the time, it just checks if a new app got installed
There might be a better way of doing that, but that's what came into my mind.
Hope it helps.

local memory as well as webservice

even after so many research i haven't found a solution for this question. I am currently working on a app which uses 3 view controllers for Registration with a log out button. the last view controller has the Register button which saves all the details of registration in a web service. But if the user has filled the two view forms and logs out. The two view filled forms field should be saved in the local memory and wen the user logs it again the pre filled forms should load the fields saved in internal memory just to continue the Registration for webservice. Any idea how to implement this sort of functionality
As others have said, NSUserDefaults will suffice for what you need.
NSUserDefaults *registrationInfo = [NSUserDefaults standardUserDefaults];
Guessing you have text fields with the info you need. So pull out the text and save to a key like this.
[registrationInfo setObject:self.someTextFieldName.text forKey#"firstTextField"];
After repeating this for every text field(use different key names though), call this [registrationInfo synchronize];
To pull the data out, you open the defaults again just like the first line. And to retrieve a specific key: NSString *firstTextField = [registrationInfo objectForKey:#"firstTextField"];
To make this easier, you can also put all of your strings in an array or dictionary, and then add that as an object in your defaults. Then you only have to set/get once.
If you have large amount of data to save use CoreData else you NSUserDefaults to save it.
I suggest you to use PLIST There are mainly three steps to do this.
1) Generate .plist file.
NSError *error1;
BOOL resourcesAlreadyInDocumentsDirectory;
BOOL copied1;
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath1 = [documentsDirectory stringByAppendingString:#"/epub.plist"];
resourcesAlreadyInDocumentsDirectory = [fileManager fileExistsAtPath:filePath1];
if(resourcesAlreadyInDocumentsDirectory == YES) {
} else {
NSString *path1 = [[[NSBundle mainBundle] resourcePath] stringByAppendingFormat:#"/epub.plist"];
copied1 = [fileManager copyItemAtPath:path1 toPath:filePath1 error:&error1];
if (!copied1) {
NSAssert1(0, #"Failed to copy epub.plist. Error %#", [error1 localizedDescription]);
}
}
2) Try to read(open) it.
NSMutableDictionary* dict = [[NSMutableDictionary alloc] initWithContentsOfFile:filePath1];
3) write data to plist file.
[dict setObject:[NSNumber numberWithInt:value] forKey:#"value"];
[dict writeToFile:path atomically:YES];
This is a simple way to use it. I suggest to use .plist file in place of NSUserDefaults.

Optimum way to make an auto back up of photos on server?

What I've known:
How make requests to server for uploading I will use AFNetworking
How access photos and videos with help of ALAssetsLibrary
I think I must use CoreData to keep info about:last syncing, photos already uploaded, etc. I worked already with coreData it will no be a problem.
My problems are logic, flow how can achieve this auto back up and of course to be optimum(minimum requests, short way). What steps must follow to achieve this scope?
Any thoughts?
I think CoreData is too heavy in this situation. You may want to use plist to store your info data .here are some steps to follow .
After loading image from server, create a dictionary to store the message you want and create another dictionary to store these messages , and use image's url as the key of this dictionary. It might look like this:
imageUrl = {
lastSyncTime = xxxxxxxxxx,
photoUploaded = 0,
}
Create a plist file to save this dictionary:
- (NSString *)filePath:(NSString *) fileName{
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
return [documentsDirectory stringByAppendingPathComponent:fileName];
}
[yourImageDictionary writeToFile:[self filePath:#"imageInfo.plist"] atomically:YES];
Read or write your plist file anytime you want:
if ([[NSFileManager defaultManager] fileExistsAtPath:[self filePath:#"imageInfo.plist"]]) {
NSDictionary *imageInfo = [NSDictionary dictionaryWithContentsOfFile:[self filePath:#"imageInfo.plist"]];
}

Using directory to store information and keep this information in a App Update

I have an app that stores images from the user in the app/documents folder, I'm doing the following code determine the path to save it:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *imageFilename = [[[[NSNumber alloc] initWithInteger:self.nextID] stringValue] stringByAppendingFormat:#".jpg"];
NSString *dirPath = [docs stringByAppendingFormat:#"/Photos/"];
imagePath = [dirPath stringByAppendingString:imageFilename];
it gives me a path similar to (in simulator):
/var/mobile/Applications/C9C43CFD-6A5F-40CF-8BAE-20496B5A544A/Documents/Photos/1.jpg
I save this path to show this image when I need.
My problem is, when I sent an update in the app store, after update the app it cant show the images anymore.
My understand is the Documents folder cant change when update the app in AppStore.
My probably reason for that it the name between Applications folder and Documentar has changed, is it true when update a app version from AppStore?
Does anyone has any idea? is there any way to test this app update local?
Thanks
You need to save the relative path after the Documents directory, not the absolute path. The app's directory can change during an update but the structure inside the app's sandbox won't change.
Also, there is a slightly better way to build your path:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docs = [paths objectAtIndex:0];
NSString *imageFilename = [NSString stringWithFormat:#"%d.jpg", self.nextID];
NSString *dirPath = [docs stringByAppendingPathComponent:#"Photos"];
imagePath = [dirPath stringByAppendingPathComponent:imageFilename];
When the app is updated from the App Store, the contents of the Documents directory are unchanged. The app bundle and all its contents are replaced with the new version, but the Documents folder is a safe place to store content between app versions.

Resources