I want to use same database object at Delegate file & Controller File of Custom Created databse header file which Contains object of type Sqlite3 & thee methods
like OpenDB & CreateTable & InserData.
i m right now just beginner in iphone programming so, pls Help me
app delegate file is like a global file , you just import the your Custom created database header file in app delegate , and create the object of Custom created database header file , assuming the file name is dbOperations.h
in app delegate
import it and create its object, then , do property , synthesize and that's all.
in any view controller you just need to import your "appDelegate.h" file and make its object in view did load like
objAppdelegate = [[UIApplication sharedApplication]delegate];
and you may access your all methods and members of dbOperations.h file by
objAppdelegate.objdbOperations .
whatever you put in appdelegate will remain shared and common to entire app , all viewControllers and all classes.
your createDatabase method should be like this, and call this method when your application did finished loading method of appDelegate file.
-(void)checkAndCreateDatabase
{
appDelegate = (SexarobicsAppDelegate *)[[UIApplication sharedApplication]delegate];
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir =[documentPaths objectAtIndex:0];
NSString *databasePath = [documentsDir stringByAppendingPathComponent:#"database.sqlite"];
//NSLog(#"%#", databasePath);
NSFileManager *fileManager = [NSFileManager defaultManager];
if(![fileManager fileExistsAtPath:databasePath])
{
NSString *databasePathFromApp = [[[NSBundle mainBundle] resourcePath] stringByAppendingPathComponent:#"database.sqlite"];
[fileManager copyItemAtPath:databasePathFromApp toPath:databasePath error:nil];
}
//Open DB Connection
if(sqlite3_open([databasePath UTF8String], &database) != SQLITE_OK)
sqlite3_close(database);
return;
}
and firing sql query like this fashion, in above code #"database.sqlite" is your db file name.
-(void)getData
{
selectStmt = nil;
// fire query and perform those related operations
// Release the compiled statement from memory
sqlite3_finalize(selectStmt);
selectStmt = nil;
}
Related
I'm getting this crash log when I create a new version of my Core Data Model and then restart the app:
*** -[NSRelationshipDescription name]: message sent to deallocated instance 0x1d032e240
It seems the model migration doesn't work whereas I'm using the NSMigratePersistentStoresAutomaticallyOption and NSInferMappingModelAutomaticallyOption store options...
Can someone help me?
Thanks!
EDIT: the changes I've made to my model are just the addition of a new attribute (Boolean as NSNumber) to en existant entity
EDIT: here is the Core Data initialization code:
- (BOOL) loadCatalog
{
// Unload any existing store
[self _unloadCurrentStore];
// Create a new managed object context
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_managedObjectContext.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
_managedObjectContext.persistentStoreCoordinator = _persistentStoreCoordinator;
// Create the persistent store
NSURL *storeURL = [[AppDelegate sharedDelegate].catalogDirectoryURL URLByAppendingPathComponent:#"Store.sqlite"];
NSDictionary *storeOptions = #{ NSMigratePersistentStoresAutomaticallyOption : #YES,
NSInferMappingModelAutomaticallyOption : #YES };
return ([_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:storeOptions error:nil] != nil);
}
So I have 2 views, one of them is a UITableVew where a user can populate cells by adding them. The second view is the information when they add them (Name, date, company and a place to scan a barcode.). Well when they scan that image, they can see the image of what they scanned (Done with Zbar barcode scanner). So the main question is how can I exactly save different images in each different cell that the user adds?
Code:
Zbar:
- (IBAction)cameraButtonTapped:(id)sender
{
// Check for camera
if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera] == YES) {
// Create image picker controller
UIImagePickerController *imagePicker = [[UIImagePickerController alloc] init];
// Set source to the camera
imagePicker.sourceType = UIImagePickerControllerSourceTypeCamera;
// Delegate is self
imagePicker.delegate = self;
// Show image picker
[self presentModalViewController:imagePicker animated:YES];
}
}
- (void) imagePickerController: (UIImagePickerController*)reader
didFinishPickingMediaWithInfo: (NSDictionary*) info
{
// ADD: get the decode results
id<NSFastEnumeration> results =
[info objectForKey: ZBarReaderControllerResults];
ZBarSymbol *symbol = nil;
for(symbol in results)
// EXAMPLE: just grab the first barcode
break;
// EXAMPLE: do something useful with the barcode data
resultText.text = symbol.data;
// EXAMPLE: do something useful with the barcode image
resultImage.image =
[info objectForKey: UIImagePickerControllerOriginalImage];
// ADD: dismiss the controller (NB dismiss from the *reader*!)
[reader dismissModalViewControllerAnimated:YES];
}
-(UIView*)CommomOverlay{
UIView *view = [[UIView alloc] initWithFrame:CGRectMake(0,0,320,480)];
UIImageView *TopBar = [[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,58)];
[TopBar setImage:[UIImage imageNamed:#""]];
[view addSubview:TopBar];
UILabel *Toplabel = [[UILabel alloc] initWithFrame:CGRectMake(10, 9, 300, 30)];
[Toplabel setFont:[UIFont fontWithName:#"Heiti TC light" size:22]];
[Toplabel setTextAlignment:UITextAlignmentCenter];
[Toplabel setBackgroundColor:[UIColor clearColor]];
[Toplabel setTextColor:[UIColor lightGrayColor]];
[Toplabel setNumberOfLines:1];
[Toplabel setText:#"Turn your device sideways to scan"];
[TopBar addSubview:Toplabel];
UIImageView *FrameImg = [[UIImageView alloc] initWithFrame:CGRectMake(40,50,240,370)];
[FrameImg setImage:[UIImage imageNamed:#"scanImage.png"]];
[view addSubview:FrameImg];
return view;
}
- (IBAction) scanButtonTapped
{
// ADD: present a barcode reader that scans from the camera feed
ZBarReaderViewController *reader = [ZBarReaderViewController new];
reader.readerDelegate = self;
reader.supportedOrientationsMask = ZBarOrientationMaskAll;
ZBarImageScanner *scanner = reader.scanner;
// TODO: (optional) additional reader configuration here
// EXAMPLE: disable rarely used I2/5 to improve performance
[scanner setSymbology: ZBAR_I25
config: ZBAR_CFG_ENABLE
to: 0];
// present and release the controller
reader.cameraOverlayView = [self CommomOverlay];
[self presentModalViewController: reader
animated: YES];
}
I did think using core data but i cant find a tutorial anywhere. Then I thought saving it in the apps Documents folder and i think that would be the bes way for me. I am new to this so descriptive code would help :)
Update:
- (IBAction)save:(id)sender {
NSManagedObjectContext *context = [self managedObjectContext];
UIImage *image = resultImage.image;
NSData *imageData = UIImagePNGRepresentation(image); //convert image into .png format.
NSFileManager *fileManager = [NSFileManager defaultManager];//create instance of NSFileManager
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //create an array and store result of our search for the documents directory in it
NSString *documentsDirectory = [paths objectAtIndex:0]; //create NSString object, that holds our exact path to the documents directory
NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"/%#KYRO Receipts Images/Barcode.png", resultImage]]; //add our image to the path
[fileManager createFileAtPath:fullPath contents:imageData attributes:nil]; //finally save the path (image)
NSLog(#"image saved");
if (self.device) {
// Update existing device
[self.device setValue:self.nameOfItem.text forKey:#"name"];
[self.device setValue:self.dateOfPurchase.text forKey:#"date"];
[self.device setValue:self.companyOfItem.text forKey:#"company"];
} else {
//
NSManagedObject *newDevice = [NSEntityDescription insertNewObjectForEntityForName:#"Receipt" inManagedObjectContext:context];
[newDevice setValue:self.nameOfItem.text forKey:#"name"];
[newDevice setValue:self.dateOfPurchase.text forKey:#"date"];
[newDevice setValue:self.companyOfItem.text forKey:#"company"];
}
NSError *error = nil;
// Save the object to persistent store
if (![context save:&error]) {
NSLog(#"Can't Save! %# %#", error, [error localizedDescription]);
}
[WTStatusBar setStatusText:#"Saving data..." animated:YES];
[self performSelector:#selector(setTextStatusProgress3) withObject:nil afterDelay:0.1];
[self.navigationController popViewControllerAnimated:YES];
[self.presentingViewController dismissViewControllerAnimated:YES completion:nil];
}
If you're already using Core Data, then depending on the size of the images you could either convert them to NSData and save them directly within Core Data (if they're small) or you can save them within the documents directory and save the file name within Core Data.
Since a full Core Data tutorial is beyond the scope here, I'll just go over saving the image to the documents directory under a unique name. Note that some of the code below was adapted from "iOS Programming: The Big Nerd Ranch Guide".
// Method to save your image file. Returns the file name for you to save in Core Data or elsewhere.
- (NSString *)saveImage:(UIImage *)image {
// Generate a unique key to name the image file
CFUUIDRef newUniqueID = CFUUIDCreate(kCFAllocatorDefault);
CFStringRef newUniqueIDString = CFUUIDCreateString(kCFAllocatorDefault, newUniqueID);
NSString *imgkey = (__bridge NSString *)newUniqueIDString;
// Get a path for the image file in the documents directory
NSString *imagePath = [self imagePathForKey:imgkey];
// Convert the UIImage into NSData and save it to the documents directory
NSData *imageData = UIImageJPEGRepresentation(img, 0.5);
[imageData writeToFile:imagePath atomically:YES];
// Clean up
CFRelease(newUniqueIDString);
CFRelease(newUniqueID);
return imgkey;
}
// Method to provide the image path for saving/retrieving the image
- (NSString *)imagePathForKey:(NSString *)key {
NSArray *documentDirectories = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentDirectory = [documentDirectories objectAtIndex:0];
return [documentDirectory stringByAppendingPathComponent:key];
}
The following method retrieves the image:
- (UIImage *)imageForKey:(NSString *)imgkey {
result = [UIImage imageWithContentsOfFile:[self imagePathForKey:imgkey thumbnail:FALSE]];
if (!result) {
// File not found - add code here as needed (to return default image or whatever)
}
return result;
}
Note that if you are planning to display multiple images in the table at the same time, you must be careful to ensure they are small, otherwise you may run into memory issues. In this case you would want to convert them into a thumbnail form for the table view, then display the full size image only in the detail view (how to generate a thumbnail would be a separate question).
I have a Core Data Object Which is Composed of Different Types NSString, Float,NSDATA,....
<Shoplog: 0x9c78d20> (entity: Shoplog; id: 0x9c77050 <x-coredata://828289C5-E1B8-48A6-B2A0-F68B7DF21F2E/Shoplog/p5> ; data: {
categoryname = Ines;
comments = nil;
date = nil;
email = "iloveyou#gmail.com";
image = <ffd8ffe0 00104a46 49460001 01000001 00010000 ffe10058 45786966 00004d4d 002a0000 00080002 01120003 00000001 0001>;
phone = 800;
price = 9988;
shop = "";
websiteurl = "http://www.google.com";
})
The issue is i want to Export this NSManaged Object into an NSArray or NSDictionary in order to write it to a file , in order to send it by mail to another User , & Open it from His App.
So Whenever i am Trying to use this Code
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *filePath = [documentsDirectory stringByAppendingPathComponent:#"Shoplog.slog"];
[savedData writeToFile:filePath atomically:YES];
It Gives me a very small File 135bytes no matter how big is the Selected NSManagedObject i get the same Size .
i need help to understand what is going on wrong ?
I think about 1 Solutions :
1- Transfer the NsManagedObject to NSMutableArray using KVC Method
Although i still Believe there is a smarter Solution for this Problem , so if someone can help i will be Grateful.
Thank you
I have my Answer in the Following Link , It is Very Easy to Implement, Just follow the Steps
Serializing (Archiving/Unarchiving) an NSManagedObject Graph
I am loading a NSManagedObjectModel model with the initWithContentsOfURL: constructor like this:
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:#"MyDocument" withExtension:#"momd"];
NSManagedObjectModel *mom = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
However this only gives me access to the latest/current version of a model. Is it posible to load previous versions with the same momd file? how?
Actually you can load an older version with:
- (NSManagedObjectModel *)managedObjectModelForVersion:(NSString *)version
{
NSURL *modelURL = [[NSBundle mainBundle] URLForResource:[NSString stringWithFormat:#"AppModel.momd/AppModel %#",version] withExtension:#"mom"];
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
return model;
}
Just replace AppModel with your model name.
I'm using this to get myself out of a sticky manual migration situation involving iCloud. Searched high and low and couldn't find this anywhere.
If you just want to load the version of the model that's compatible with a particular existing store try:
NSError *error = nil;
NSDictionary *storeMetadata = [NSPersistentStoreCoordinator metadataForPersistentStoreOfType:NSSQLiteStoreType
URL:storeURL
error:&error];
NSManagedObjectModel *oldManagedObjectModel = [NSManagedObjectModel mergedModelFromBundles:[NSArray arrayWithObject:[NSBundle mainBundle]]
forStoreMetadata:storeMetadata];
Note that if you use XCode version identifiers for your data model versions, the persistent store's current version identifiers are accessible through the NSStoreModelVersionIdentifiersKey entry in the store metadata dictionary.
As far as loading a particular arbitrary version is concerned, the mom files are typically located under the momd directory in your app's bundle, so you could enumerate them using NSFileManager. I believe to find one with a particular version identifier you would have to use NSManagedObjectModel's initWithContentsOfURL: initializer and then inspect the versionIdentifiers property, or use the isConfiguration:compatibleWithStoreMetadata: instance method to determine compatibility.
Made the solution offered by #Schoob into a category, because they rock.
#interface NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version;
#end
#implementation NSManagedObjectModel (version)
+ (NSManagedObjectModel *)modelFromBundle:(NSBundle *)bundle name:(NSString *)modelName version:(NSString *)version
{
if(!bundle)
bundle = [NSBundle mainBundle];
NSString *resource = [[modelName stringByAppendingPathExtension:#"momd"] stringByAppendingPathComponent:version];
NSURL *modelURL = [bundle URLForResource:resource withExtension:#"mom"];
NSAssert(modelURL,#"Unable to find MOM - %#",resource);
NSManagedObjectModel *model = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];
NSAssert(model,#"Unable to load MOM at URL- %#",modelURL);
return model;
}
#end
Swift version. Replace file name.
import CoreData
extension NSManagedObjectModel
{
class func model(forVersion version: Int) -> NSManagedObjectModel?
{
if let fileUrl = Bundle.main.url(forResource: "Model.momd/Model \(version)", withExtension: "mom")
{
return NSManagedObjectModel(contentsOf: fileUrl)
}
return .none
}
}
No, it is not foreseen that this is possible. I deduce that from the NSManagedObjectModel documentation, where it says discussing the property versionIdentifiers:
This value is meant to be used as a debugging hint to help you determine the models that were combined to create a merged model.
So it does not seem you are supposed to use previous model versions for your program logic.
Can someone please shed some light on how I would get this to work:
http://www.icab.de/blog/2009/08/18/url-filtering-with-uiwebview-on-the-iphone/
I tried making the "FilteredWebCache.h" and "FilteredWebCache.m" files in my project, but it said that "FilterManager.h" did not exist. What am I meant to do with those files?
This I put in viewDidLoad:
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = docDir; // the path to the cache file
NSUInteger discCapacity = 10*1024*1024;
NSUInteger memoryCapacity = 512*1024;
FilteredWebCache *cache = [[FilteredWebCache alloc] initWithMemoryCapacity:memoryCapacity diskCapacity:discCapacity diskPath:path];
[NSURLCache setSharedURLCache:cache];
[cache release];
You need to write the FilterManager class yourself (FilterManager.m and FilterManager.h). That post says:
The code first checks if the URL should be blocked (the FilterManager class is doing all these checks, this class isn’t shown here).
The example code seems to call it FilterMgr instead of FilterManager, and it looks like you need to provide a shouldBlockURL: method that decides what gets blocked.
BOOL blockURL = [[FilterMgr sharedFilterMgr] shouldBlockURL:url];