Append data to an existing file in new line cocoa - cocoa

I'm developing a Cocoa application for Mac. I have to append data of a file to an existing file in new line. I am trying to do this by following code:
NSData * theData = [NSData dataWithContentsOfFile: #"~/Desktop/test/new.rtf"
options: NSMappedRead
error: &error];
NSFileHandle *output = [NSFileHandle fileHandleForWritingAtPath:#"~/Desktop/test/test.rtf"];
[output seekToEndOfFile];
[output writeData:theData];
But this code is not working. This code is doing nothing. Neither giving any error nor writing data of file new.rtf to test.rtf. Any idea how can I append data of file new.rtf to test.rtf in new line??

NSString *readFile = [#"~/Desktop/test/new.rtf" stringByExpandingTildeInPath];
NSString *writeFile = [#"~/Desktop/test/test.rtf" stringByExpandingTildeInPath];
NSData * theData = [NSData dataWithContentsOfFile:readFile
options:NSMappedRead
error:NULL];
NSFileHandle *output = [NSFileHandle fileHandleForUpdatingAtPath:writeFile];
[output seekToEndOfFile];
[output writeData:theData];
[output closeFile];

Related

NSProcessInfo returns different PATH than "echo $PATH"

I am trying to programatically figure out whether there is a specific binary in the system PATH. To get the environment I used both
NSString* path = [[[NSProcessInfo processInfo] environment] objectForKey:#"PATH"];
and
NSString* path2 = [NSString stringWithUTF8String: getenv("PATH")];
both yielding the same result, in both cases different then echo $PATH in console. Both path and path2 does not contain paths set via /etc/paths.d, so the question is how to get the the environment PATH as returned from console programatically?
NSProcessInfo will just access information about current process. For example below i am executing the same echo $PATH command in cocoa and am getting the same output which NSProcessInfo is displaying. So in the terminal when you execute the same command. You will get different ouput. Because it is showing the path of current process in terminal. If you want to see the same output of both you can execute this command in terminal launchctl getenv PATH which will be equivalent to [[[NSProcessInfo processInfo] environment] objectForKey:#"PATH"];
NSTask *task;
task = [[NSTask alloc] init];
[task setLaunchPath: #"/bin/bash"];
[task setArguments:[NSArray arrayWithObjects: #"-c", #"echo $PATH",nil]];
NSPipe *pipe;
pipe = [NSPipe pipe];
[task setStandardOutput: pipe];
NSFileHandle *file;
file = [pipe fileHandleForReading];
[task launch];
NSData *data;
data = [file readDataToEndOfFile];
NSString *response = [[NSString alloc] initWithData: data encoding: NSUTF8StringEncoding];
NSLog(#"%#",response);

Forcing Python to run in 64 mode from a NSTask subprocess

What is a method that forces python to run in 64 mode from a NSTask?
Update: As per Ned's suggestion I tried referencing Python2.7 directly with objective c and that worked. Changed #"/usr/bin/python" to #"/usr/bin/python2.7". The new code is at the bottom of the question.
I have a 64 bit system. When run from terminal python runs in 64 bit.
When I run a plain shell from a NSTask running /usr/bin/uname -m it returns x86_64.
I've tried using arch but the shell running python is still in 32 bit mode.
Example method
-(void) runPython64BitScriptViaArchWithPath:(NSString*)path {
NSTask* task = [[NSTask alloc] init];
task.launchPath = #"/usr/bin/arch" ;
task.arguments = [NSArray arrayWithObjects: #"-x86_64", #"/usr/bin/python", path, nil];
[task setStandardInput:[NSPipe pipe]] ;
NSPipe *stdOutPipe = nil;
stdOutPipe = [NSPipe pipe];
[task setStandardOutput:stdOutPipe];
NSPipe* stdErrPipe = nil;
stdErrPipe = [NSPipe pipe];
[task setStandardError: stdErrPipe];
NSLog(#"%#", [task arguments]) ;
[task launch] ;
NSData* data = [[stdOutPipe fileHandleForReading] readDataToEndOfFile];
[task waitUntilExit];
NSInteger exitCode = task.terminationStatus;
if (exitCode != 0)
{
NSLog(#"Error!");
NSData *error = [[stdErrPipe fileHandleForReading] readDataToEndOfFile] ;
NSLog(#"Exit code : %ld", (long)exitCode) ;
NSString *result = [[NSString alloc] initWithBytes: error.bytes length:error.length encoding: NSUTF8StringEncoding] ;
NSLog(#"%#",result);
[result release];
} else {
NSString *result = [[NSString alloc] initWithBytes: data.bytes length:data.length encoding: NSUTF8StringEncoding] ;
NSLog(#"%#",result) ;
[result release];
}
[task release] ;
}
an example python script that works if run from terminal
#!/usr/bin/env python
import os
os.environ['DJANGO_SETTINGS_MODULE'] = 'social_shields.settings'
try:
import hosts.models
shield = hosts.models.Shield.objects.all()[0]
shield.active = True
shield.save()
except Exception as exception:
import struct
print 'Bits : %s' % ( 8 * struct.calcsize("P"))
print exception
example log
2013-07-04 16:10:31.600 socialshield[88688:303] onShieldDown
2013-07-04 16:10:31.607 socialshield[88688:303] x86_64
2013-07-04 16:10:31.607 socialshield[88688:303] (
"-x86_64",
"/usr/bin/python",
"/source/social_shields/social_shields/shield_down.py"
)
2013-07-04 16:10:31.933 socialshield[88688:303] Bits : 32
Error loading MySQLdb module: dlopen(/Library/Python/2.7/site-packages/_mysql.so, 2): no suitable image found. Did find:
/Library/Python/2.7/site-packages/_mysql.so: mach-o, but wrong architecture
new code that works after applying Ned's suggestion :-)
-(void) runPython64BitScriptViaArchWithPath:(NSString*)path {
NSTask* task = [[NSTask alloc] init];
task.launchPath = #"/usr/bin/arch" ;
task.arguments = [NSArray arrayWithObjects: #"-x86_64", #"/usr/bin/python2.7", path, nil];
[task setStandardInput:[NSPipe pipe]] ;
NSPipe *stdOutPipe = nil;
stdOutPipe = [NSPipe pipe];
[task setStandardOutput:stdOutPipe];
NSPipe* stdErrPipe = nil;
stdErrPipe = [NSPipe pipe];
[task setStandardError: stdErrPipe];
NSLog(#"%#", [task arguments]) ;
[task launch] ;
NSData* data = [[stdOutPipe fileHandleForReading] readDataToEndOfFile];
[task waitUntilExit];
NSInteger exitCode = task.terminationStatus;
if (exitCode != 0)
{
NSLog(#"Error!");
NSData *error = [[stdErrPipe fileHandleForReading] readDataToEndOfFile] ;
NSLog(#"Exit code : %ld", (long)exitCode) ;
NSString *result = [[NSString alloc] initWithBytes: error.bytes length:error.length encoding: NSUTF8StringEncoding] ;
NSLog(#"%#",result);
[result release];
} else {
NSString *result = [[NSString alloc] initWithBytes: data.bytes length:data.length encoding: NSUTF8StringEncoding] ;
NSLog(#"%#",result) ;
[result release];
}
[task release] ;
}
I assume you have verified that /Library/Python/2.7/site-packages/_mysql.so is 64-bit and that you are really using the same Python in both cases. On OS X 10.6 and later systems, /usr/bin/python is actually a wrapper executable that determines which version of Python and which architecture (32-bit or 64-bit) to run; see man 1 python for details. Try executing /usr/bin/python2.7 directly. That should default to 64-bit. You can also check whether Python is running in 32- or 64-bit mode by using this documented test:
import sys; print(sys.maxsize > 2**32)

How do I copy a UNIX Executable File with NSFileManager?

I am trying to use NSFileManager copyItemAtURL:toURL:error: to move a UNIX executable file (a command line program) from one directory to another but I always get an error that says the URL type is unsupported. I assume this is because without an extension on the file it is being viewed as a directory but I'm not sure. Is it possible to move this type of file with NSFileManager?
Edit:
Here is my code
#define SAVE_DIR [#"~/Library/Prog" stringByExpandingTildeInPath]
#define PROG_PATH [SAVE_DIR stringByAppendingString:#"/ProgCom"]
#define RESOURCES [[NSBundle mainBundle] resourcePath]
#define LOCAL_PROG [RESOURCES stringByAppendingString:#"/ProgCom"]
-(void)moveProg
{
NSError *error = nil;
NSURL *fromURL = [NSURL URLWithString:LOCAL_PROG];
NSURL *toURL = [NSURL URLWithString:PROG_PATH];
NSLog(#"%#", [fromURL path]);
NSLog(#"%#", [toURL path]);
if ([fMan fileExistsAtPath:[fromURL path]]) {
[fMan copyItemAtURL:fromURL
toURL:toURL
error:&error];
if (error)
[NSApp presentError:error];
}
}
The error I receive:
The file couldn't be opened because the specified URL type isn't supported.
And finally what gets logged:
fromURL = /Users/Nick/Library/Developer/Xcode/DerivedData/Prog-dpnblqaraeuecyadjgizbinfrtcm/Build/Products/Debug/Prog.app/Contents/Resources/ProgCom
toURL = /Users/Nick/Library/Prog/ProgCom
The problem is you're using +[NSURL URLWithString:]. This is producing an invalid URL, since you're not actually giving it one. What you want is +[NSURL fileURLWithPath:], which will produce a file:///Users/Nick/... URL.

Sending Hex and String to UDP

I am trying to send commands to a server, through UDP. The server requires a few hex bytes at the beginning, though PHP this is easy
'\xFF\xFFcmd command variable'
Then I fwrite() that without a problem.
Now I am building a client in Cocoa and I cannot get the server to understand me at all, the data is sent, but I think it is incorrect or corrupt. I am trying to do it with CocoaAsyncSocket..
NSString *msg = [NSString stringWithFormat:#"%c%ccmd command variable",0xFF,0xFF];[socket connectToHost:#"85.25.248.160" onPort:28960 error:nil];
unsigned char lendata = [msg length];
NSMutableData *senddata = [NSMutableData dataWithBytes: &lendata length:sizeof(lendata)] ;
[senddata appendData:[msg dataUsingEncoding:NSUTF8StringEncoding]];
[socket sendData:senddata withTimeout:-1 tag:0];
NSLog of msg is 'ˇˇcmd command variable' but nothing occurs on the server, which I don't have access to, to listen for a malformed packet.
My guess is that by putting the 0xFF into the string, it is no longer the same, and is sent wrongly..
Solved problem. The NSString was messing with the \xff.
char *bytes = "\xff\xffcmd command variable";
NSData* data = [[NSData alloc] initWithBytes:bytes length:strlen(bytes)];
[socket sendData:data withTimeout:-1 tag:0];
To get variable as an NSString or something else..
char *bytes = "\xff\xff";
NSString *commands = [[NSString alloc] initWithFormat:#"command %#", variable];
NSMutableData *data = [[NSMutableData alloc] initWithBytes:bytes length:strlen(bytes)];
[data appendData:[commands dataUsingEncoding:NSUTF8StringEncoding]];
[socket sendData:data withTimeout:-1 tag:0];

Trying to get bytes and append using NSMutableData for a video through Asset Library gives memory full error

I’m trying to upload a video of size 100MB through Asset Library. But when i try to use -(NSUInteger)getBytes:(uint8_t *)buffer fromOffset:(long long)offset length:(NSUInteger)length error:(NSError **)error of ALAssetRepresentation I get memory full error. I also need to put the data in buffer to NSData. How can i achieve that?
I tried this way:
Byte *buffer = (Byte*)malloc(asset.defaultRepresentation.size);
NSUInteger k = [asset.defaultRepresentation getBytes:buffer fromOffset: 0.0
length:asset.defaultRepresentation.size error:nil];
NSData *adata = NSData *adata = [NSData dataWithBytesNoCopy:buffer
length:j freeWhenDone:YES];
It really works!
As #runeb said the answer is not working properly with large files. You should do something like that:
int bufferSize = 2048;
int offset = 0;
NSString* name=nil;
while(offset<asset.size){
Byte *buffer = (Byte*)malloc(bufferSize);
NSUInteger buffered = [asset getBytes:buffer fromOffset:offset length:bufferSize error:nil];
NSData *data;
data = [NSData dataWithBytesNoCopy:buffer length:buffered freeWhenDone:NO];
if(!name){
//Creates the file and gives it a unique name
name = [FileUtils saveVideoFromAsset:data];
}
else{
//Append data to the file created...
[FileUtils appendData:data toFile:name];
}
offset+=buffered;
free(buffer);
}
In order to append data to a file you can use that:
NSFileHandle *myHandle = [NSFileHandle fileHandleForWritingAtPath:filePath];
[myHandle seekToEndOfFile];
[myHandle writeData:videoData];
I hope that helps!
ust add #autoreleasepool block, so that any autorleased objects should be cleaned up. it looks like that ARC has something changed after iOS7
#autoreleasepool {
NSUInteger readStatus = [rep getBytes:buffer fromOffset:_startFromByte length:chunkSize error:NULL];
}

Resources