I am creating an ios application with xcode 4.6.1 which uses core data to save data in the database, i have provided the deployment target as ios 4.3 and the base sdk is set to latest 6.1.
The place where i am stuck is when i run the application on ios 4.3 i see that my sqlite file is created but contains no tables in it. I have wrote no special code here and every thing is by default taken care in the app delegate, i came across few post where other developers have said to
NSURL *modelURL =[[NSBundle mainBundle] URLForResource:#"StudentData" withExtension:#"momd"];
_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
use "mom" above but i even did that and it seems that every time in ios 4.3 this issue pops up, i have also tried and reset my simulator lots of time but nothing seems to be working and i do require ios4.3 support so please let me know what's going on here and what do i need to do.
I also tried printing
NSLog(#"%#",[self managedObjectModel]);
but it's not nil
Please note their is no mistake in the name of the files here.
Thanks
NSBundle *modelWrapper = [NSBundle bundleWithPath:[[NSBundle mainBundle] pathForResource:#"StudentData" ofType:#"momd"]];
NSString *modelPath = [modelWrapper pathForResource:#"StudentData" ofType:#"mom"];
managedObjectModel = [[NSManagedObjectModel alloc]initWithContentsOfURL:[NSURL fileURLWithPath:modelPath]];
By default in Mac OS you don't have write permission.
From terminal go to the path where you have stored your StudentData file and then write this command chmod 777.
It will allow you to write data in files.
Well, i got this working what i did was ran the application and saw that it created the sqlite file but with no tables but when i tried to insert the data in the database with ios 4.3 then the data got inserted and tables were created surprisingly it did not make any sense to me but i got this working without changing anything in the code.
Related
I have been working on an application involving client-server communication. Everything was working fine until iOS 7.1. Now that Xcode 6 GM Seed in launched, I tried to build and run the project on iOS8 simulator. However, all NSURLConnections seem to time out now. I can not get any response from the server. This works on iOS 7 simulator and Xcode 6.
I tried using the NSURLSession hoping that would resolve the issue. But it hasnt.
Any help will be highly appreciated!! If anyone else has faced this issue, please let me know if you have any workaround to this.
UPDATE:
This is the code I have used:
NSString *authStr = [NSString stringWithFormat:#"%#:%#", username, password];
NSData *authData = [authStr dataUsingEncoding:NSUTF8StringEncoding];
NSString *authValue = [NSString stringWithFormat: #"Basic %#",[authData base64EncodedStringWithOptions:0]];
[inURLRequest setValue:authValue forHTTPHeaderField:#"Authorization"];
Please note that the inURLRequest is already iniatlized with the desired URL.
After this just use the inURLRequest to fire the transaction as usual. For eg., in case of NSURLSession, create a download task using this request object and call resume API on it.
Well, I have found a fix for this issue.
The app had basic authentication in place for each REST webservice. This means that we used to get an authentication challenge for each webservice where we sent the credentials back with the challenge.
I changed this to send the credentials in the request header (in encrypted format) as a header field.
I am not sure how this was working in iOS 7 and not in iOS 8. But this seems to have fixed my problem :).
If you are streaming data to the NSURLConnection make sure you write new data exactly once when the stream event hasSpaceAvail has arrived - I found I had connection issues when I had wrong handling of the hasSpaceAvail event.
do not write more than once in response to the event
do not write zero times (or else you won't get another hasSpaceAvail event)
I am writing an application to remove a piece of software and its files from OS X. I can delete everything else except the .app and a folder in /Applications. I am using AuthetificationExecuteWithPriviledges, I know that it is deprecated, so could that be giving me admin issues when attempting to move the .app to the trash bin? When I step through the process I see an NSCocoaErrorDomain, with code 513. I did a quick search for it, and saw it is related to a permissions error. My other theory is that my path to the application is incorrect. I am using:
NSString *ibmNotesApplication = #"/Applications/IBM Notes.app";
If you are wondering why I am trying to delete Lotus Notes, it is because the Notes uninstaller provided by IBM doesn't have all of the functionality I would like. So, I am writing one that removes notes and all files related to it so we can have a fresh install.
Here is a snippet of code where I move an item in the array to the trash bin.
if ([filemanager fileExistsAtPath:object])
{
NSURL *objectURL = [NSURL fileURLWithPath:object];
NSURL *trashedObject;
NSError *error;
//Moves item to trash bin and update log
if([filemanager trashItemAtURL:objectURL resultingItemURL:&trashedObject error:&error])
{
NSLog(#"Trashed %# to %#",objectURL, trashedObject);
self.textfield.stringValue = [NSString stringWithFormat:#"%#%#%#%#%#%#", self.textfield.stringValue, #"Trashed ", objectURL, #" to ", trashedObject, #"\n"];
}
As you mentioned in the question, the function AuthorizationExecuteWithPrivileges is a deprecated function and has been for quite a while now. I suggest you start by following Apple's advice of factoring out the privileged process into a separate privileged helper tool, which is launched with the help of launchd.
You can follow the example code here.
If the permission problem still exists, then at least you've gone about refactoring your code to the right way of doing things, knowing that it will be supported for future versions of the OS.
Using the following steps, I'm able to embed an info.plist into a command-line tool.
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/CodeSigningGuide/Procedures/Procedures.html
I know how to retrieve the plist file from a .bundle, but I'm not sure how to do the same in a single-file tool like I've got.
I've embedded the info.plist into the command-line tool so that I can store the version in it. Does anyone know how I can retrieve it at run-time so I can determine what version is running?
Thanks
__info_plist is a "magic" section name that makes the following Just Work:
NSBundle *bundle = [NSBundle mainBundle];
id version = [bundle objectForInfoDictionaryKey: (NSString*) kCFBundleVersionKey];
NSLog(#"mainBundle.version = %#", version);
If you need to read a bundle embedded in a different executable than the one currently running, this answer by Bavarious from the comments has a more comprehensive list of approaches.
I currently have an app in the store which is SQLite-backed and does not use Core Data. In the past when I have wanted to release an update that had SQLite changes, the update would include some code that would detect the version of the app, and programmatically update the tables if necessary. Now I am working on an update that uses Core Data. I don't care about any of the old data that is currently live, and I know how I can delete all the old SQLite tables programmatically. Are all the Core Data model files included in the update binary, or do I have to programmatically generate some or all of the Core Data model? Will the .xcdatamodeld be included with the binary? Any other pitfalls I should be wary of?
Thanks for your help
With core data it can be quite tricky when updating to a new version. I have experienced many times that even the slightest changes in the core data model cause weird app behaviour (understandable to some extend). The easiest way to avoid any unwanted sideeffects is to just change the name. Here the code
- (NSPersistentStoreCoordinator *) persistentStoreCoordinator {
// D_IN;
if (persistentStoreCoordinator != nil) {
return persistentStoreCoordinator;
}
persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel: [self managedObjectModel]];
// Allow inferred migration from the original version of the application.
NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
[NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
[NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
NSURL *storeUrl = [NSURL fileURLWithPath: [[self applicationDocumentsDirectory] stringByAppendingPathComponent: #"myData073.sqlite"]];
NSError *error = nil;
if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl
options:options error:&error]){
NSLog(#"Unresolved error %#, %#", error, [error userInfo]);
}
// D_OUT;
return persistentStoreCoordinator;
}
So all you really have to do is to change the name myData073.sqlite to for example myData074.sqlite
The data model description file is not really part of the binary, but the model behind it with all the classes and access methods surely is. You do not need to worry about that. ps even during development I change the name frequently, otherwise one might waste lots of time looking for coding errors that are not really there...
An App Store update replaces the entire app bundle, so everything in your app bundle, including any Core Data model, will be included. You can test this by installing an Ad Hoc or developer build over an App Store build on your own device (without deleting first). In the compiled App, the model files are compiled or processed, and have different extensions (.momd, .mom). So you'll see those instead of .xcdatamodeld or .xcdatamodel.
Other pitfalls: Now, the Core Data data file is not part of your bundle. If you want the updated app to start with an empty database, you don't have to do anything special. But if you want to install/update with a prepopulated database, you have to figure out a way to get that database into a read-write location on the device. Basically, you generate a Core Data file, included it in the app bundle as part of your Xcode project, then at first launch, programmatically copy it somewhere in your Documents or Library folders (using the correct Cocoa API for finding these).
Pitfall #2: modifying an empty core data file with SQLLite on the Mac is suggested on some web sites, but specifically dis-recommended by Apple. Instead, you might write an iOS app that puts data into core data and run it in the simulator. How do I initialize a store with default data?
As user387184 indicated, your next update that changes the model on an existing Core Data database can get tricky. Try to get the model as right as you can the first time.
In my application, I am storing user preferences (which are applicable for all users) into a plist file,
which is attached as a form of bundle.
The problem is, it runs fine in admin mode, but when I run the application, it's not writing the file. Do I need to set some attribute to write to the plist in local mode? Or is it not possible at all?
My code for writing the file is below:
-(void)SavePrefrence:(NSString *)fileName PrefrenceOption:(NSMutableDictionary *)pDict{
NSString *filePath = [[[NSBundle mainBundle] pathForResource:fileName ofType:#"plist"] retain];
NSDictionary *pTemp = [[NSDictionary alloc]initWithDictionary:pDict];
bool bRet = [pTemp writeToFile:filePath atomically:YES];
if(bRet==YES){
NSLog(#"File Saved ");
}
else {
NSLog(#"File not saved ");
}
}
This is the code which calls it:
-(void)SaveListSettings:(NSMutableDictionary *)pListSettings{
[ self SavePrefrence:#“MyList" PrefrenceOption:pListSettings];
if(pListInfo)
[pListInfo release];
[self LoadListProfile];
}
The application bundle will, by default, only be writable by the owner (if it's installed by dragging into the Applications folder, this'll be whoever installed it; if it's installed by a .pkg, it should probably be root). The way you're doing this, if I follow it properly, requires a user to have write access to the app's Contents/Resources folder, which is a really bad idea (not that it's unheard of -- see the University of Utah's documentation about "Poorly-Made Applications" for examples). Actually, saving preferences inside the application is a bad idea anyway; that's what the various Library/Preferences folders are for (~/Library/Preferences for personal settings, /Library/Preferences for system-wide settings. But, of course, /Library/Preferences is only writable by admins (for very good reasons). I don't really know of a good way to handle this, as system-wide settings modifiable by non-admins is not exactly normal.
You could use an installer which asks for an admin password and then create "/Library/Application Support/MyApp" and then either make this world writable, or make a sub-folder inside it which is world-writeable. Now MyApp running under a non-admin account can still write to this shared folder.
If you don't want to make the folder world-writeable then include a helper app to the bundle to do the writing and make the helper setuid root by using an installer which asks for an admin password...
BTW: Both of those options will fail Mac App Store rules. Maybe you can use '/Users/Shared', but I don't know if it is allowed by MAS, and anyway it is far from standard. Which would leave you with storing it on a web server...