The code below pumps the memory to the limit. I loaded about 100 Images and the memory went to 200MB. If I put the app in background and foreground, than it purge the memory from 200MB to around 10MB. How can I release the memory? The #autoreleasepool didn't work
#autoreleasepool {
NSData *imgData = UIImageJPEGRepresentation(image, 0.5);
NSString *name = [[NSUUID UUID] UUIDString];
NSString *path = [NSString stringWithFormat:#"Documents/%#.jpg", name];
NSString *jpgPath = [NSHomeDirectory() stringByAppendingPathComponent:path];
if ([imgData writeToFile:jpgPath atomically:YES]) {
data.imagePath = path;
[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreWithCompletion:nil];
} else {
[[[UIAlertView alloc] initWithTitle:#"Error"
message:#"There was an error saving your photo. Try again."
delegate:nil
cancelButtonTitle:#"OK"
otherButtonTitles: nil] show];
}
imgData = nil;
}
Related
This is for my iOS app using Core Data.
I'm getting some extra information in my CSV export that I'd like to remove. Below is my code and an example of what I am seeing.
Code:
NSOutputStream *stream = [[NSOutputStream alloc] initToMemory];
CHCSVWriter *writer = [[CHCSVWriter alloc] initWithOutputStream:stream encoding:NSUTF8StringEncoding delimiter:','];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:#"Notes"];
self.fetchedObjects = [managedObjectContext executeFetchRequest:fetchRequest error:nil];
for (NSString *instance in self.fetchedObjects) {
[writer writeLineOfFields:#[instance.description]];
}
[writer closeStream];
NSData *buffer = [stream propertyForKey:NSStreamDataWrittenToMemoryStreamKey];
NSString *output = [[NSString alloc] initWithData:buffer encoding:NSUTF8StringEncoding];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDirectory = [paths firstObject];
NSString * csvPath = [documentsDirectory stringByAppendingPathComponent:#"mydata.csv"];
if ([MFMailComposeViewController canSendMail]) {
MFMailComposeViewController * mailView = [[MFMailComposeViewController alloc] init];
mailView.mailComposeDelegate = self;
[[mailView navigationBar] setTintColor:[UIColor whiteColor]];
[mailView setSubject:#"My Subject Line"];
if (![[NSFileManager defaultManager] fileExistsAtPath:csvPath]) {
[[NSFileManager defaultManager] createFileAtPath:csvPath contents:nil attributes:nil];
}
BOOL res = [[output dataUsingEncoding:NSUTF8StringEncoding] writeToFile:csvPath atomically:NO];
if (!res) {
[[[UIAlertView alloc] initWithTitle:#"Error Creating CSV" message:#"Check your permissions to make sure this app can create files so you may email the app data" delegate:nil cancelButtonTitle:#"Okay" otherButtonTitles: nil] show];
} else{
NSLog(#"Data saved! File path = %#", csvPath);
[mailView addAttachmentData:[NSData dataWithContentsOfFile:csvPath] mimeType:#"text/csv" fileName:#"mydata.csv"];
[self presentViewController:mailView animated:YES completion:nil];
}
} else {
UIAlertView * alertView = [[UIAlertView alloc] initWithTitle:#"Mail Error" message:#"Your device is not configured to send mail." delegate:self cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView show];
}
Output Example:
<Notes: 0x1c009fb30> (entity: Notes; id: 0xd000000000080000 <x-coredata://597EDC54-FFDE-43FA-8C61-DE67763C1D13/Notes/p2> ; data: {
// My data shows here.
})
What I want:
I just want the saved data from the user input. Not the extra data about the entity, id, etc.
Also:
My data does not load in the email initially. I have to go into my UIViewController and then when I go to my Settings page and send the email the data shows. What would cause this?
You're getting that result because you're relying the description method to get information about your objects. That method produces a string, and the string is what you're seeing-- something that's not CSV, or easy to convert to CSV.
I'm not familiar with CHCSVParser but it looks like you might want to override description in your Notes class to produce something that CHCSVParser can handle. The default implementation on NSManagedObject-- which is what you're using now-- is not a good choice for this situation.
I have a requirement of downloading .zip file from server and use it to project after extracting it. I have successfully downloaded the .sqlite file and i am able to extract it using right click(manually) but when i am trying to extract it using minizip and SSZipArchive or ZipArchive it's giving an error "Can't open the file".
If i extract .sqlite manually and compress .sqlite file by right clicking in mac then my code is extracting it completely but whenever i try to extract downloaded file directly then this issue is occurring.
I have applied below name formats for writing and extracting file.
While writing file the name was XYZ.sqlite.zip but it is also giving error
XYZ.zip and contained file name is XYZ.sqlite. This also giving error
I also have written file with name XYZ.sqlite.zip and then rename it with XYZ.zip and then extracted but that was also not working.
Below is the code.
For Downloading the file:
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:zipURL]];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *path = [[paths objectAtIndex:0] stringByAppendingPathComponent:[zipURL lastPathComponent]];
operation = [[AFDownloadRequestOperation alloc] initWithRequest:request targetPath:path shouldResume:YES];
[operation.securityPolicy setAllowInvalidCertificates:YES];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
[self unzipDBFile:path];
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
NSLog(#"Error: %#", error);
}];
[operation setProgressiveDownloadProgressBlock:
^(AFDownloadRequestOperation *operation, NSInteger bytesRead, long long totalBytesRead, long long totalBytesExpected, long long totalBytesReadForFile, long long totalBytesExpectedToReadForFile) {
NSArray *progress = [NSArray arrayWithObjects:obj_Pro,[NSNumber numberWithFloat:totalBytesReadForFile/(float)totalBytesExpectedToReadForFile], nil];
[self performSelectorOnMainThread:#selector(updateProgressBar:) withObject:progress waitUntilDone:NO];
}];
[operation start];
For Extracting the file:
-(void)unzipDBFile:(NSString *)filePath
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
NSString *outputPath = [documentDir stringByAppendingPathComponent:#"/DBFolder"];
BOOL isExtracted =[SSZipArchive unzipFileAtPath:outputPath toDestination:documentDir];
// NSString *filepath = [[NSBundle mainBundle] pathForResource:#"ZipFileName" ofType:#"zip"];
// ZipArchive *zipArchive = [[ZipArchive alloc] init];
// [zipArchive UnzipOpenFile:filePath];
// NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
// NSString *path = [paths objectAtIndex:0];
// BOOL isExtracted=[zipArchive UnzipFileTo:path overWrite:YES];
// NSLog(#"PATH=%#",path);
if (!isExtracted)
{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Error in extracting" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}else{
UIAlertView *alert=[[UIAlertView alloc] initWithTitle:#"Extract Success" message:#"" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alert show];
[alert release];
}
// [zipArchive UnzipCloseFile];
// [zipArchive release];
}
Below is the code for update progressbar:
- (void)updateProgressBar:(NSArray *)progress
{
UIProgressView *pgr = (UIProgressView *)[progress objectAtIndex:0];
[pgr setProgress:[[progress objectAtIndex:1] floatValue]];
}
I have examined the issue and found that .net developer, Who created .zip has used gzip compression so minizip is not able to extract it.
For decompress it, I have used iOS zlib framework and below code and that has solved my problem. You have to add below two things in the header before implementing this method.
#import <zlib.h>
#define CHUNK 16384
-(BOOL)unzipDBFile:(NSString *)filePath
{
NSString *documentDir = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory,
NSUserDomainMask, YES) objectAtIndex:0];
documentDir=[documentDir stringByAppendingPathComponent:DATABASE_FILE_NAME];
gzFile file = gzopen([filePath UTF8String], "rb");
FILE *dest = fopen([documentDir UTF8String], "w");
unsigned char buffer[CHUNK];
int uncompressedLength;
while ((uncompressedLength = gzread(file, buffer, CHUNK)) ) {
// got data out of our file
if(fwrite(buffer, 1, uncompressedLength, dest) != uncompressedLength || ferror(dest)) {
return FALSE;
}
}
fclose(dest);
gzclose(file);
return TRUE;
}
I'm new to IOS development and i have a problem in downloading my attachments from mail.when i'm trying to download image or PDF attachments from my mail to documents directory using MailCore2 SDK it is downloading sucessfully.but my problem is that the downloaded image or PDF displays nothing (i.e.,).It gives me the file but with a empty file with zero bytes.im able to know that problem is with the NSData what im using to writeToFile is incorrect.But im unable to solve it.please help me.
Here is the code i'm using to download file from mail
MCOIMAPFetchContentOperation * op = [self.imapSession fetchMessageByUIDOperationWithFolder:#"INBOX" uid:[sender tag]];
[op start:^(NSError * error, NSData * data) {
if ([error code] != MCOErrorNone) {
return;
}
NSAssert(data != nil, #"data != nil");
MCOMessageParser * msg = [MCOMessageParser messageParserWithData:data];
if ([msg.attachments count] > 0)
{
MCOIMAPPart *part = [msg.attachments objectAtIndex:0];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSLog(#"%#",part.filename);
NSString *attachmentPath = [[saveDirectory stringByAppendingString:#"/Downloads"] stringByAppendingPathComponent:part.filename];
if (fileExists) {
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Fail Existed in Download Path."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else{
[msg.data writeToFile:attachmentPath atomically:YES];
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Download Success /n Saved in Downloads"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
[self.tableView reloadData];
}
}];
please help me to get out of this problem and tell me where am i doing mistake.
Thanks in advance.
I used like this:
MCOIMAPFetchContentOperation * op = [self.imapSession fetchMessageByUIDOperationWithFolder:#"INBOX" uid:[sender tag]];
[op start:^(NSError * error, NSData * data)
{
if ([error code] != MCOErrorNone)
{
return;
}
NSAssert(data != nil, #"data != nil");
MCOMessageParser * msg = [MCOMessageParser messageParserWithData:data];
if ([msg.attachments count] > 0)
{
MCOAttachment *attachment = [msg.attachments objectAtIndex:0];
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *saveDirectory = [paths objectAtIndex:0];
NSLog(#"%#",attachment.filename);
NSString *downLoadDirectory = [saveDirectory stringByAppendingString:#"/Downloads"];
if (![[NSFileManager defaultManager] fileExistsAtPath:downLoadDirectory])
{
[[NSFileManager defaultManager] createDirectoryAtPath:downLoadDirectory withIntermediateDirectories:YES attributes:nil error:nil];
}
NSString *attachmentPath = [downLoadDirectory stringByAppendingPathComponent:attachment.filename];
if ([[NSFileManager defaultManager] fileExistsAtPath:attachmentPath])
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Fail Existed in Download Path."
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
else
{
BOOL res = [[attachment data] writeToFile:attachmentPath atomically:YES];
if (res)
{
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:#"Message"
message:#"Download Success /n Saved in Downloads"
delegate:self
cancelButtonTitle:#"OK"
otherButtonTitles:nil];
[alert show];
}
}
}
}];
I hope they are useful.
i want to save a video that i have downloaded before from URL.
I use this code where when i click on Download Button i will Download the video from the URL. I use the connection method and in the last i save video data using NSFileManager.
The problem is that i create a File path but inside it there aren't any type of data. How can i resolve it?
-(IBAction)download:(id)sender{
/*[downloadButton setEnabled:NO];
[webView setUserInteractionEnabled:NO];*/
//Prendo URL
NSString *getURL = #"";
getURL = [webView stringByEvaluatingJavaScriptFromString:#"function getURL() {var player = document.getElementById('player'); var video = player.getElementsByTagName('video')[0]; return video.getAttribute('src');} getURL();"];
//Prendo il titolo
videoTitle = videoTitleField.text;
NSArray *components = [videoTitle componentsSeparatedByCharactersInSet:[[NSCharacterSet alphanumericCharacterSet] invertedSet]];
videoTitle = [components componentsJoinedByString:#" "];
if ([getURL length] > 0) {
if ([videoTitle length] > 0) {
//videoTitle = [getTitle retain];
fileURL = [NSURL URLWithString:getURL];
downloadUrl = fileURL;
bytesReceived = percentComplete = 0;
localFilename = [[[fileURL absoluteString] lastPathComponent] copy];
receivedData = [[NSMutableData alloc] initWithLength:0];
app.networkActivityIndicatorVisible = YES;
//Inserisco alert view
alert = [[UIAlertView alloc] initWithTitle:#"Download" message:[NSString stringWithFormat:#"%.2f",percentComplete] delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alert show];
//Connessione download
DownloadRequest = [[NSURLRequest alloc] initWithURL:fileURL cachePolicy:NSURLRequestReloadIgnoringLocalCacheData timeoutInterval:15];
DownloadConnection = [[NSURLConnection alloc] initWithRequest:DownloadRequest delegate:self startImmediately:YES];
}
else{
//Utente non inserisce il nome per il video
UIAlertView *alertview = [[UIAlertView alloc] initWithTitle:#"TubeDownloader" message:#"You have to insert a name for the video!" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertview show];
}
}else {
//Non si riesce a prendere URL
UIAlertView *alertView1 = [[UIAlertView alloc] initWithTitle:#"TubeDownloader" message:#"Couldn't get MP4 URL." delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil];
[alertView1 show];
[downloadButton setEnabled:YES];
}
}
-(void) connection:(NSURLConnection *)connection didReceiveData:(NSData *)data{
if(!operationBreaked){
[self.receivedData appendData:data];
//[self.receivedData setData:data];
float receivedLen = [data length];
NSLog(#"receive lenght: %f\n",receivedLen);
bytesReceived = (bytesReceived + receivedLen);
if(expectedBytes != NSURLResponseUnknownLength){
//progressView.progress = ((bytesReceived/(float)expectedBytes)*100)/100;
percentComplete = (((bytesReceived/(float)expectedBytes)*100)/100) * 100;
}
NSLog(#"Ricevendo dati..percentuale di completamento:%f",percentComplete);
[alert setMessage:[NSString stringWithFormat:#"Percentage:%.2f",percentComplete]];
}else{
[connection cancel];
NSLog(#"Ricezione dati cancellata...percentuale:%f",percentComplete);
}
[self.receivedData appendData:data];
}
-(void) connection:(NSURLConnection *)connection didFailWithError:(NSError *)error{
operationFailed = YES;
//progressView.progress = 0.0;
}
-(void) connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response{
NSLog(#"Bytes aspettati: %f... Bytes ricevuti:%f\n",(float)expectedBytes,(float)bytesReceived);
NSHTTPURLResponse *r = (NSHTTPURLResponse*) response;//An NSHTTPURLResponse object represents a response to an HTTP URL load request. It’s a subclass of NSURLResponse that provides methods for accessing information specific to HTTP protocol responses.
NSDictionary *headers = [r allHeaderFields];//headerFields:a dictionary representing the keys and values from the server’s response header.
NSLog(#"[DO::didReceiveResponse] response headers: %#", headers);
if (headers){
if ([headers objectForKey: #"Content-Range"]) {
NSString *contentRange = [headers objectForKey: #"Content-Range"];
NSLog(#"Content-Range: %#", contentRange);
NSRange range = [contentRange rangeOfString: #"/"];
NSString *totalBytesCount = [contentRange substringFromIndex: range.location + 1];
expectedBytes = [totalBytesCount floatValue];
} else if ([headers objectForKey: #"Content-Length"]) {
NSLog(#"Content-Length: %#", [headers objectForKey: #"Content-Length"]);
expectedBytes = [[headers objectForKey: #"Content-Length"] floatValue];
} else expectedBytes = -1;
if ([#"Identity" isEqualToString: [headers objectForKey: #"Transfer-Encoding"]]) {
expectedBytes = bytesReceived;
operationFinished = YES;
}
}
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection{
NSLog(#"connessione terminata con successo receive data:%f!!",bytesReceived);
operationFinished = YES;
[alert setMessage:#"Download been succesfully"];
app.networkActivityIndicatorVisible = NO;
//NSData *saveData = [NSData dataWithBytes:&receivedData length:sizeof(receivedData)];
//Attivo timer per dimettere il timer
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:#selector(dismissAlert) userInfo:nil repeats:NO];
//[self.receivedData setData:];
//Chiamo la funzione di salvataggio passandogli come NSData receivedata e localfileName
//[self saveVideo:self.receivedData];
NSFileManager *fileManager = [NSFileManager defaultManager];
NSArray *path = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathdir = [NSString stringWithFormat:#"%#.mp4", [[path objectAtIndex:0] stringByAppendingPathComponent:videoTitle]];
NSLog(#"pathDir: %#",pathdir);
[fileManager createFileAtPath:pathdir contents:receivedData attributes:nil];
NSString *imagePath = [NSString stringWithFormat:#"%#.mp4", [[path objectAtIndex:0]stringByAppendingPathComponent:videoTitle]];
AVAsset *asset = [[AVURLAsset alloc] initWithURL:[NSURL fileURLWithPath:[NSString stringWithFormat:#"%#.mp4",[[path objectAtIndex:0] stringByAppendingPathComponent:videoTitle]]] options:nil]; //AVAsset is an abstract class to represent timed audiovisual media such as videos and sounds. Each asset contains a collection of tracks that are intended to be presented or processed together, each of a uniform media type, including but not limited to audio, video, text, closed captions, and subtitles.
AVAssetImageGenerator *imageGenerator = [[AVAssetImageGenerator alloc] initWithAsset:asset]; //An AVAssetImageGenerator object provides thumbnail or preview images of assets independently of playback. AVAssetImageGenerator uses the default enabled video track(s) to generate images.
Float64 durationSeconds = CMTimeGetSeconds(asset.duration);
CMTime midpoint = CMTimeMakeWithSeconds(durationSeconds / 2.0, 600);
CMTime actualTime;
CGImageRef preImage = [imageGenerator copyCGImageAtTime:midpoint actualTime:&actualTime error:NULL];
if (preImage != NULL) {
CGRect rect = CGRectMake(0.0, 0.0, CGImageGetWidth(preImage) * 0.5, CGImageGetHeight(preImage) * 0.5);
UIImage *image = [UIImage imageWithCGImage:preImage];
UIGraphicsBeginImageContext(rect.size);
[image drawInRect:rect];
NSData *data = UIImagePNGRepresentation(UIGraphicsGetImageFromCurrentImageContext());
[fileManager createFileAtPath:imagePath contents:data attributes:nil];
UIGraphicsEndImageContext();
}
CGImageRelease(preImage);
//videoTitle = nil;
NSLog(#"Salvataggio con successo");
}
I use the following code, but it only checks first column in first row. But I want to check first column of all rows in a csv file. Please help
- (void) SearchStudent
{
NSArray *DocumentPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES); //I upload the csv file to documents folder of the app through itunes
NSString *DocumentDirectory = [DocumentPath objectAtIndex:0];
NSString *FullPath = [DocumentDirectory stringByAppendingPathComponent:[NSString stringWithFormat:#"example.csv"]];
NSString * pstrCSVFile= [NSString stringWithContentsOfFile:FullPath encoding:NSASCIIStringEncoding error:NULL];
NSArray * paRowsOfCSVFile= [pstrCSVFile componentsSeparatedByString:#"\n"];
NSArray *paColumnsOfRow;
NSString *pstrFirstColumn;
for(NSString * pstrRow in paRowsOfCSVFile)
{
paColumnsOfRow= [pstrRow componentsSeparatedByString:#","];
pstrFirstColumn= [paColumnsOfRow objectAtIndex:0];
if([pstrFirstColumn localizedCaseInsensitiveCompare:GWIDText.text] == NSOrderedSame)
{
UIAlertView *alertingFileName = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertingFileName show];
break;
}
else
{
UIAlertView *alertingFileName1 = [[UIAlertView alloc]initWithTitle:#"Error" message:#"Not Found" delegate:nil cancelButtonTitle:#"OK" otherButtonTitles:nil, nil];
[alertingFileName1 show];
}
}
}
paColumnsOfRow contain all rows.