How to append array in file - objective-c

I am trying to write main array in a file and this main array contain sub array . Now whenever I write main array the sub array get overwritten .
Below is my code.
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
#autoreleasepool {
char fname[10];
printf("Type your first name:\n");
scanf("%s",fname);
NSString *firstname = [[NSString alloc] init];
firstname = [NSString stringWithUTF8String:fname];
char lname[10];
printf("Type your last name:\n");
scanf("%s",lname);
NSString *lastname = [[NSString alloc] init];
lastname = [NSString stringWithUTF8String:lname];
long mnumber = 0;
printf("Enter your register mobile number:\n");
scanf("%ld",&mnumber);
NSNumber *mobilenumber = [NSNumber numberWithLong:mnumber];
long anumber = 0;
printf("Enter your account number:\n");
scanf("%ld",&anumber);
NSNumber *accountnumber = [NSNumber numberWithLong:anumber];
NSURL *docdir = [[NSFileManager defaultManager] URLForDirectory:NSDesktopDirectory inDomain:NSUserDomainMask appropriateForURL:nil create:NO error:nil];
NSURL *filepath = [docdir URLByAppendingPathComponent:#"Dexter_apps/filetesting/data.plist"];
NSArray *data = #[firstname,lastname,mobilenumber,accountnumber];
NSMutableArray *mainarray = [[NSMutableArray alloc]init];
mainarray = #[data];
[mainarray writeToURL:filepath atomically:NO];
}
return 0;
}

Related

initWithData:encoding always return null

I am working on an iphone application which need to encode and decode a string,so I code a small script on obj-c to test my code. This is my code which I am using to test:
this code block is not work, the string AwEMT... is a encoded string by dataUsingEncoding:NSUTF8StringEncoding and base64EncodedStringWithOptions:0, just like the working code block but when i decode it is not work and return null
int main (int argc, const char * argv[]) {
NSData *decodedData1 = [[NSData alloc] initWithBase64EncodedString:#"AwEMTqu5FyZFurKQ7givyJEUruVaMg8TBWU8yyMbP2exbOQW9BgDFwxdoD6cuVb4/fR/Jb7J9uryofUAJi1QVDOwl4dzEj+8JzKHS9/zCmryKa3qN5RUCqSrJ//5gTG7b17mfGEqiObZ7a6xJatyfjRJ42+KW1xSH8SSZlnyk5LvtMuSjYRX18NxXCA9E4dmY2po6ehr8cy+UEm9qcjJZ9d6X7z+xubzy/XYv9aPYvxwBe7ZK/kXLEnt2vtafygag/msDuSnLk43wzhAnNnl4YwxFPsx8uZHpsxwBZEvG7wS+YpqhKIZQF9yBqPFkOQXaa55r6p4uChCoVShKGXq4GZtUf6TwF0S2zmlFCpEImonEJa8IIAAhEuU8OTwPCHFga3DhWpXGiWXxtNpCSFlLzXsoPFgYN2OFkf9TH4fIVHAiOm2Xl8SkbXZ/TBTGNevaJNHAEjg+YZmVwnQcCOvcoRdJhx+2ylDdQOswFTsIbkKRARlfHbz4LWqJNW9YTeA21m26dnvCkNWe+tG64j2gse36r2zwya3ULN63AGXtNT8+A==" options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData1 encoding:NSUTF8StringEncoding];
NSLog(#"%#", decodedData1 );
return 0;
}
And this is working code block, I encode the "Developer" string the same way as encoded string: "AwEMT.... But the encoded string from "Developer" can eassily decode by these code.
int main (int argc, const char * argv[]) {
NSString *myString = #"Developer";
NSData *myData = [myString dataUsingEncoding:NSUTF8StringEncoding];
NSString *base64String = [myData base64EncodedStringWithOptions:0];
NSLog(#"%#", base64String);
NSData *decodedData = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
NSString *decodedString = [[NSString alloc] initWithData:decodedData encoding:NSUTF8StringEncoding];
NSLog(#"%#", decodedString);
return 0;
}
Anyone know what I have done wrong on this? please point me out

Getting repeated values when I try to add a dictionary to an array in a loop

This is my code for my test app where I want to show users on the next view controller but when I run and try to retrieve the values it is giving me repeated values. I have used NSMutableDictionary and NSMutableArray.
#import "DBManager.h"
static DBManager *sharedInstance = nil;
static sqlite3 *database = nil;
static sqlite3_stmt *statement = nil;
#implementation DBManager
-(void) getsaveData:(NSString *)Username
{
const char *dbpath = [newFileAtPath UTF8String];
NSMutableArray *userArray = [[NSMutableArray alloc]init];
if (sqlite3_open(dbpath, &database)==SQLITE_OK) {
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSString *getSQL = [NSString stringWithFormat:#"SELECT * FROM USERS WHERE USERNAME != \"%#\"",Username];
const char *retrievestmt = [getSQL UTF8String];
if(sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL)==SQLITE_OK)
{
while(sqlite3_step(statement)==SQLITE_ROW)//in this while loop i am getting repeated values
{
NSString *User_ID = [[NSString alloc] initWithUTF8String: (const char *) sqlite3_column_text(statement, 0)];
[userInfo setObject:User_ID forKey:#"ID"];
//[userArray addObject:User_ID];
NSString *User_Email = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 1)];
[userInfo setObject:User_Email forKey:#"Email"];
//[userArray addObject:User_Email];
NSString *Password = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 2)];
[userInfo setObject:Password forKey:#"Email"];
//[userArray addObject:Password];
NSString *User_name = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 3)];
[userInfo setObject:User_name forKey:#"Username"];
//[userArray addObject:User_name];
NSString *User_Avatar = [[NSString alloc] initWithUTF8String:(const char *) sqlite3_column_text(statement, 4)];
[userInfo setObject:User_Avatar forKey:#"Avatar"];
//[userArray addObject:User_Avatar];
[userArray addObject:userInfo];
NSLog(#"userArray %#",userArray);
}
sqlite3_reset(statement);
}
}
}
#end
In the while loop I am geeting the error.
I tried multiple times with multiple solutions please help me fix this.
The problem is simple - you are incorrectly reusing the userInfo dictionary. You need to create a new instance in each loop iteration.
Move the line:
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
to just after the while loop line.
You also have many other issues with your code:
You never close the database.
You never finalize the prepared statement.
You needlessly reset the prepared statement.
You have insufficient error checking/logging.
You are not using standard naming conventions.
You are not using standard whitespacing which makes your code harder to read.
You don't use consistent curly brace placement. Pick a style and use it everywhere.
You are using static variables when you should not be.
Never build SQL statements using stringWithFormat:. Properly bind values to the query.
Never use SELECT * in a query. Explicitly list out the columns to ensure you get consistent and expected column values.
Here's is your code updated for these issues:
#import "DBManager.h"
static DBManager *sharedInstance = nil;
#implementation DBManager
- (void)getsaveData:(NSString *)username {
const char *dbpath = [newFileAtPath UTF8String];
NSMutableArray *userArray = [[NSMutableArray alloc] init];
sqlite3 *database;
if (sqlite3_open(dbpath, &database) == SQLITE_OK) {
const char *retrievestmt = "SELECT USER_ID, USER_EMAIL, PASSWORD, USER_NAME, USER_AVATAR FROM USERS WHERE USERNAME != ?"; // replace * with actual column names
sqlite3_stmt *statement;
if (sqlite3_prepare_v2(database, retrievestmt, -1, &statement, NULL) == SQLITE_OK) {
sqlite3_bind_text(statement, 1, [username UTF8String], -1, SQLITE_TRANSIENT);
while (sqlite3_step(statement) == SQLITE_ROW) {
NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init];
NSString *userID = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 0)];
userInfo[#"ID"] = userID;
NSString *userEmail = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 1)];
userInfo[#"Email"] = userEmail;
NSString *password = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 2)];
userInfo[#"Password"] = password;
NSString *username = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 3)];
userInfo[#"Username"] = username;
NSString *userAvatar = [[NSString alloc] initWithUTF8String:(const char *)sqlite3_column_text(statement, 4)];
userInfo[#"Avatar"] = userAvatar;
[userArray addObject:userInfo];
}
sqlite3_finalize(statement);
NSLog(#"userArray %#",userArray);
} else {
NSLog(#"Unable to prepare the statement at %s: %s", retrievestmt, sqlite3_errmsg(database));
}
sqlite3_close(database);
} else {
NSLog(#"Unable to open the database at %#: %s", dbpath, sqlite3_errmsg(database));
}
}
#end

How do I loop through Safari tabs?

So I have this code that returns the current safari tab's URL
int main(int argc, const char * argv[]) {
NSAppleScript *script= [[NSAppleScript alloc] initWithSource:#"tell application \"Safari\" to return URL of front document as string"];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(#"Error: %#",scriptError);
} else {
NSAppleEventDescriptor *unicode = [descriptor coerceToDescriptorType:typeUnicodeText];
NSData *data = [unicode data];
NSString *result = [[NSString alloc] initWithCharacters:(unichar*)[data bytes] length:[data length] / sizeof(unichar)];
NSLog(#"Result: %#",result);
}
return 0;
}
How can I implement a loop to switch through all my tabs so it can output all the tab's URLs?
This AppleScript code returns the URLs of all tabs
tell application "Safari" to return URL of tabs of window 1
The result is a list descriptor which must be converted to an NSArray object
int main(int argc, const char * argv[]) {
NSAppleScript *script = [[NSAppleScript alloc] initWithSource:#"tell application \"Safari\" to return URL of tabs of window 1"];
NSDictionary *scriptError = nil;
NSAppleEventDescriptor *descriptor = [script executeAndReturnError:&scriptError];
if(scriptError) {
NSLog(#"Error: %#",scriptError);
} else {
NSAppleEventDescriptor *listDescriptor = [descriptor coerceToDescriptorType:typeAEList];
NSMutableArray *result = [[NSMutableArray alloc] init];
for (NSInteger i = 1; i <= [listDescriptor numberOfItems]; ++i) {
NSAppleEventDescriptor *URLDescriptor = [listDescriptor descriptorAtIndex:i];
[result addObject: URLDescriptor.stringValue];
}
NSLog(#"Result: %#", [result copy]);
}
return 0;
}
Maybe not what you want but here's a solution with Scripting Bridge:
SafariApplication *SafariApp = [SBApplication applicationWithBundleIdentifier:#"com.apple.Safari"];
for (SafariWindow *window in SafariApp.windows)
{
for (SafariTab *tab in window.tabs)
NSLog(#"%#", tab.URL);
}

Saving to plist file issue

I can't save my new data to plist file for some reason. This is code I have been using for saving data:
-(void)saveData:(NSMutableDictionary *)dictionaryData toFile:(NSString *)filename {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = [docDir stringByAppendingPathComponent:filename];
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
[data addObject:dictionaryData];
[data writeToFile:filename atomically:YES];
}
this is code I used to copy file from bundle to app directory in case if it is not there :
-(NSMutableArray *)loadFromFile:(NSString *)filename {
NSError *error;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *docDir = [paths objectAtIndex:0];
NSString *path = [docDir stringByAppendingPathComponent:filename];
NSFileManager *fileMgr = [NSFileManager defaultManager];
if(![fileMgr fileExistsAtPath:path]) {
NSArray *fileArray = [filename componentsSeparatedByString:#"."];
NSString *name = [fileArray objectAtIndex:0];
NSString *ext = [fileArray objectAtIndex:1];
NSString *bundle = [[NSBundle mainBundle] pathForResource:name ofType:ext];
[fileMgr copyItemAtPath:bundle toPath:path error:&error];
}
NSMutableArray *data = [[NSMutableArray alloc] initWithContentsOfFile:path];
return data;
}
For some reason I can't save new data to plist file. When I try to add new NSMutableDictionary object to my plist file (with saveData:toFile: method) and than reload my array variable with the plist file data - new object is not there. Am I doing something wrong?
this is how I load plist file :
#property (nonatomic, strong) NSMutableArray *modules;
#property (nonatomic, strong) NSMutableDictionary *module;
- (void)viewDidLoad {
[super viewDidLoad];
self.modules = [self loadFromFile:#"ModulesList.plist"];
self.module = [self.modules objectAtIndex:0];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"Modules array from plist file, module at index %i : %#",i, [self.modules objectAtIndex:i]);
}
than for testing purpose I have this code to add new module object:
- (IBAction)leftButton:(id)sender {
NSString *mytitle = [[NSString alloc] initWithFormat:#"my title"];
NSString *myauthor = [[NSString alloc] initWithFormat:#"my author2"];
NSUInteger myean = 22023423;
NSString *mytitle2 = [[NSString alloc] initWithFormat:#"my title 2"];
NSString *myauthor2 = [[NSString alloc] initWithFormat:#"my author2"];
NSUInteger myean2 = 29032432;
NSString *mytitle3 = [[NSString alloc] initWithFormat:#"my title 3"];
NSString *myauthor3 = [[NSString alloc] initWithFormat:#"my author 3"];
NSUInteger myean3 = 21023423;
NSMutableDictionary *mybook = [[NSMutableDictionary alloc] init];
NSMutableDictionary *mybook2 = [[NSMutableDictionary alloc] init];
NSMutableDictionary *mybook3 = [[NSMutableDictionary alloc] init];
[mybook setObject:mytitle forKey:#"title"];
[mybook setObject:myauthor forKey:#"author"];
[mybook setObject:[NSNumber numberWithInteger:myean] forKey:#"ean"];
[mybook2 setObject:mytitle2 forKey:#"title"];
[mybook2 setObject:myauthor2 forKey:#"author"];
[mybook2 setObject:[NSNumber numberWithInteger:myean2] forKey:#"ean"];
[mybook3 setObject:mytitle3 forKey:#"title"];
[mybook3 setObject:myauthor3 forKey:#"author"];
[mybook3 setObject:[NSNumber numberWithInteger:myean3] forKey:#"ean"];
NSMutableArray *mybooks = [[NSMutableArray alloc] init];
[mybooks addObject:mybook];
[mybooks addObject:mybook2];
[mybooks addObject:mybook3];
[self.module setObject:mybooks forKey:#"books"];
[self.modules addObject:self.module];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"Modules array after add operation, module at index: %i: %#",i, [self.modules objectAtIndex:i]);
}
[self saveData:self.module toFile:#"ModulesList.plist"];
}
than when I will reload my self.modules array from plist with button action, my new data is not there:
- (IBAction)reload:(id)sender {
self.modules = [self loadFromFile:#"ModulesList.plist"];
for (int i = 0; i < self.modules.count; i++ ) {
NSLog(#"RELOAD: Modules array from plist file, module at index %i : %#",i,[self.modules objectAtIndex:i]);
}
}
this is screenshot of my plist file : http://dl.dropbox.com/u/49076351/Screen%20Shot%202013-02-27%20at%2016.27.45.png

iOS NSMutableData *data = [[NSMutableData alloc] init]; crashes

I m using below mentioned line in a function
NSMutableData *data = [[NSMutableData alloc] init];
And I m calling this function a no of time (e.g. 100 times). So my problem is that initially for about 60 times or more it is working properly but after that it gives me "BAD_EXC_ACCESS"
Function is given below
+ (NSString *) recvToFile:(NSString *)_fileName {
#try {
int _sz = [self recvNumber:4];
uint8_t t[_sz];
NSMutableData *data = [[NSMutableData alloc] init];
NSMutableData *fileData = [[NSMutableData alloc] init];
long _pos = 0;
NSString *_fullPath = _fileName;
while (_sz > _pos) {
long _c = [m_sin read:t maxLength:_sz];
_pos += _c;
data = [NSData dataWithBytes:t length:_c];
if([Misc checkFileExists:_fileName]==nil)
[[NSFileManager defaultManager] createFileAtPath:_fullPath contents:nil attributes:nil];
[fileData appendData:data];
}
[fileData writeToFile:_fullPath atomically:YES];
NSDictionary *attr = [[NSFileManager defaultManager] attributesOfItemAtPath:_fullPath error:nil];
long long length = [[attr valueForKey:#"NSFileSize"] intValue];
if (length >= _sz)
return (_fullPath);
}
#catch (NSException * e) {
}
return (nil);
}
And I m calling this function every time i receive a file. I want to save file from bytes
You should not initialize data here:
NSMutableData *data = [[NSMutableData alloc] init];
just initialize the variable to nil;
NSMutableData* data = nil;
Try adding data like this to nsmutabledata
[data appendBytes:t length:_c];