I'm writing an application that can change your Mac OS X version for a short period (few seconds) to launch an application that is to old or to new for your Version.
It reads the version from SystemVersion.plist (/System/Library/CoreServices/SystemVersion.plist) then sets the new required version.
Save (overwrite) the file and launch the app and then change the version back
to the orginal version.
This is the first part of the code (reads version and tries to overwrite)
// Get SystemVersion.plist as Dictionary
NSBundle *bundle = [NSBundle bundleWithPath:#"/System/Library/CoreServices"];
NSString *SystemVersionString = [bundle pathForResource:#"SystemVersion" ofType:#"plist"];
NSMutableDictionary *SystemVersionDir = [NSDictionary dictionaryWithContentsOfFile:SystemVersionString];
// Get current version (Systemversion, ProductUserVisibleVersion)
NSString *SystemVersion = [SystemVersionDir objectForKey:#"ProductVersion"];
// Get desired version from text field
NSString *DesiredVersion = [_Text_version stringValue];
[_Text_Info setStringValue:SystemVersion];
// Set new version
[SystemVersionDir setObject:DesiredVersion forKey:#"ProductVersion"];
// Write (save) plist
if([SystemVersionDir writeToFile:#"/System/Library/CoreServices/SystemVersion.plist" atomically:YES])
{
NSLog(#"YES");
}
else
{
NSLog(#"NO");
}
The problem is with the 'writeToFile'. If I write to my desktop or something everything goes fine and it creates a new file. Also if I copy the file to my desktop and overwrite it there it goes fine. But it needs to overwrite the one in /System/Library/CoreServices/.
I guess I need authorization or something. However I've looked into that but it seems an awful lot of work and my mind is mess because of that.
Isn't there a simpler way to do this, perhaps a class that helps?
Note: Mac OS X 10.8 Mountain Lion Developer Preview 3 (Xcode 4.3.1)
Related
I am trying to integrate socketscan SDK with my objective C iOS app. I downloaded scanapisdk, made a copy of scanapisdk inside my project main folder. I Added the files and library references to the Xcode project. compiled and build the app. run it on a device. The following code has been working with no problem for couple of years now.
I have a constant NSString declared as global variable in an m file
NSString *const kSymbology = #"Symbology";
and it is declared as an extern in an h file
extern NSString *const kSymbology;
Then in a database class there is this code fragment
NSMutableDictionary *dict = [[NSMutableDictionary alloc] init];
const char *Symbology = (const char*)sqlite3_column_text(statement, 0);
strSymbology = [NSString stringWithUTF8String:Symbology];
[dict setValue:strSymbology forKey:kSymbology];
[symbologies addObject:dict];
[dict release];
The code crashes on this line
[dict setValue:strSymbology forKey:kSymbology];
When I change it to
[dict setValue:strSymbologyAlias forKey:#"Symbology"];
The app doesn't crash.
It doesn't make sense to me. it seems that the error is somewhere else and it is showing here by accident. The only new thing I have added to my project are the references to the socketScan files and libraries. I don't even call any of the methods in the SDK. I commented out all the methods in ScanApiHelper.mm file, now the app doesn't crash. I started to put back some of the methods in ScanApiHelper.mm and I discovered that when any line that has SktClassFactory mentioned for example (for example [SktClassFactory createScanObject]) is alive, the app crashes.
Can that be related to not using CocoaPods to install the sdk?
It looks like a name space collision. The libScanApiCore.a has a variable named kSymbology and my global variable is also named kSymbology. Once I changed the variable name to ksymbology (lower case s) my app no longer crashes.
What is the best way to programmatically change the order of "preferred" networks in OS X? Objective-C preferred...
I can use CoreWLAN to gather the list, and even add to it, but as far as re-ordering I am at a loss. I can create a copy of the preference file, edit it and change the order of precedence, and then use a bash script to write over the existing configuration, but that seems a but messy.
I am aware of the networksetup -addpreferredwirelessnetworkatindex command, but it does not work correctly in 10.10 (works fine for 10.9 systems) - it adds but does not set order properly.
SystemConfiguration framework? Something else?
Thanks!
I was looking for a way to accomplish this after transitioning a user from an open wireless network to a WPA2E network using EAP-TTLS. Since the user connects to the open network first, it remains higher in the Preferred Networks list.
Here is what I came up with:
CWInterface *interface = [CWInterface interfaceWithName:[
[CWInterface interfaceNames] anyObject]
];
CWMutableConfiguration *config = [CWMutableConfiguration
configurationWithConfiguration:interface.configuration
];
NSMutableArray *networks = [NSMutableArray arrayWithArray:
[config.networkProfiles array]
];
//Remove URI_Open (if present) and
//move URI_Secure (if present) to index 0
for (CWNetworkProfile *profile in [networks copy]) {
if ([[profile ssid] isEqualToString:#"URI_Secure"]) {
[networks removeObject:profile];
} else if ([[profile ssid] isEqualToString:#"URI_Open"]) {
CWNetworkProfile *tmp = profile;
[networks removeObject:tmp];
[networks insertObject:tmp atIndex:0];
}
}
config.networkProfiles = [NSOrderedSet orderedSetWithArray:networks];
SFAuthorization *auth = [SFAuthorization authorization];
BOOL authResult = [auth obtainWithRight:"system.preferences"
flags:(
kAuthorizationFlagExtendRights |
kAuthorizationFlagInteractionAllowed |
kAuthorizationFlagPreAuthorize
) error:nil
];
NSError *error = nil;
[interface commitConfiguration:config authorization:auth error:&error];
Some notes/disclaimers:
I do not use OS X regularly. I have one test Mac in my office. It has 10.7.5 installed.
This is the first thing I have ever written in Objective-C. It is the result of a single afternoon; as such it is probably broken and ugly. YMMV.
Question specified 10.10. I used interfaceWithName and interfaceNames, which are deprecated in 10.10. I am not sure what the proper replacement is, but I suspect CWWifiClient.
My approach was based loosely on this ruby program.
I removed error handling for brevity.
I did look into using networksetup or removing the open network right in the .mobileconfig, but neither seemed to work quite right.
Since I just pull the network profile list out into a mutable array, this is easily adaptable to any arbitrary sorting etc.
Does anyone know of tutorials or existing projects for Airstash SDK iOS integration? I have the frameworks in my project, but the existing comments inside the header files aren't incredibly helpful for initial setup. I've been googling for one, but I get a deluge of tech announcement news instead of developer resources.
-Background-
The Airstash is going to be used with an already-developed iPad application that sets equipment preferences. The targeted equipment has already been developed and has no wireless connectivity, but does have USB capability. The proposed solution is to wirelessly upload files from the iPad to an Airstash connected to the equipment.
In the SDK release there are two directories: AirStashSDK and sdk-demo. The sdk-demo directory contains an XCode project that demonstrates usage of the SDK.
The AirStashSDK folder contains the AirStash.framework to include in your project, and a Resources folder that contains a couple xib files that you should include in your project and may customize. If you plan to customize these files you may want to copy them to a different directory so your changes are not lost if you update to a newer release of the SDK. The xib files are used to display progress while getting a file from the AirStash, or activity when saving a file to the AirStash.
To save a file to an AirStash, look at the saveFileAction: method in sdk-demo/AirStashSDK Demo/RootViewController.m.
- (void)saveFileAction:(NSString*)filename
{
NSLog(#"Save a file to AirStash. filename: %#", filename);
NSURL *docDir = [self getDocumentsDirectory];
NSString *filepath = [[docDir URLByAppendingPathComponent:filename] path];
airstash = [[AirStash alloc] init];
// Save is very simple.
[airstash saveFileToAirStash:filepath
presentingFrom:self
successBlock:^(void){
NSString *msg = [NSString stringWithFormat:#"Success saving file to AirStash: original filename: %#", filename];
NSLog(#"%#", msg);
[self presentAlertWithMessage:msg];
self.airstash = nil;
}
errorBlock:^(AirStashStatus errorCode, NSString *reason) {
NSString *msg = [NSString stringWithFormat:#"Problem saving file to AirStash: (%d) %#", errorCode, reason];
NSLog(#"%#", msg);
[self presentAlertWithMessage:msg];
self.airstash = nil;
}];
}
The demo app presents a list of the files in the app's documents directory. If the user taps on a file, it calls the saveFileAction: method to save the selected file to an AirStash. An app can allocate an AirStash object and make multiple calls to its methods, or as in this case, it just makes the one call and then releases it. (The demo app's presentAlertWithMessage: method just pops up a UIAlertView with the given message and an OK button so you can see that the action is complete.)
The demo app has a couple other buttons, one to get a file from an AirStash (and save it to the app's documents directory), and the other to get the URL of a file on an AirStash. The method used by the second button would be useful for apps that want to stream a file rather than download the whole thing at once.
I have the following function written to randomly pick a file from a directory. It works totally fine when I build the project in Xcode for release with the application that automatically opens. However, if I open the application from finder, pressing the button that triggers this function will cause my program to freeze then crash. The only thing I could think of was changing the argument to contentsOfDirectoryAtPath: to not have the ./, but either version has the same exact issue.
Looking at Console tells me that my program exited abnormally with a Floating Point Exception, but I have no idea what's causing it. Is there something jumping out to you guys that I'm not seeing? I only started learning/using objective-C and cocoa about a week ago, so this is all fairly new to me.
Thanks for taking a look at this...
- (NSMutableString*)setFilePathRandom{
NSArray* files;
NSFileManager* fileManager;
fileManager = [[NSFileManager alloc] init];
files = [fileManager contentsOfDirectoryAtPath:#"./Random Trippy Pics" error:NULL];
NSString* directoryPath = (NSMutableString*)[fileManager currentDirectoryPath];
NSString* fileName;
do{
fileName = [files objectAtIndex:(arc4random()%[files count])];
}while([fileName isEqualToString:#".DS_Store"]);
filePath = [NSString stringWithFormat:#"%#/Random Trippy Pics/%#",directoryPath,fileName];
[fileManager release];
return filePath;
}
When an OS X application is run from Xcode, its current directory is the path to the build folder. When run "normally", the current directory is /. So your program is looking for a directory at /Random Trippy Pics, which almost certainly doesn't exist. Where is that directory normally?
Edit:
You could get the directory in which the application is currently stored with this bit of code:
NSString *currentStoragePath = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent];
However, if the Random Trippy Pics directory is required by the application, you should store it in a known location -- preferably the application's Resource directory. Then you can get the contents with:
NSArray *files = [[NSBundle mainBundle] pathsForResourceOfType:nil inDirectory:#"Random Trippy Pics"];
I have a Cocoa application that stores a reference to multimedia files (images, videos, etc) on the user's computer. I'm wondering if there is a way to get a reference to that file other that using a file path so that if the user moves that file to a different folder on their computer, I would still know where it is. I'm currently storing the array of file paths that are passed back from the standard Cocoa open dialogue:
-(void)addMultimediaDidEnd:(NSOpenPanel*)sheet
returnCode:(int)returnCode
contextInfo:(NSString *)contextInfo
{
if(returnCode == NSOKButton) {
[sheet orderOut:nil];
[self saveFiles:[sheet filenames]];
}
}
In OS X 10.6 (Snow Leopard), an NSURL can be converted to a file reference URL (using -[NSURL fileReferenceURL]) which references a file across moves while your application is running. If you want to persist this file reference, use +[NSURL writeBookmarkData:toURL:options:error:] passing the bookmark data generated with -[NSURL bookmarkDataWithOptions:includingResourceValuesForKeys:relativeToURL:error]. The bookmark can be resolved later with +[NSURL URLByResolvingBookmarkData:options:relativeToURL:bookmarkDataIsStale:error:] passing the bookmark data returned from +[NSURL bookmarkDataWithContentsOfURL:error:].
Prior to OS X 10.6, the same functionality (minus some network aware niceties) is available via the AliasManager, a Carbon-era interface to the OS X file alias system. There are a couple of Objective-C wrappers on top of the Alias Manager that make using it from Cocoa much nicer. My favorite is Wolf Rentzsch's additions to Chris Hanson's BDAlias (available on github).
Here's a quick example of using bookmarks to track files across moves:
- (NSData *)bookmarkFromURL:(NSURL *)url {
NSData *bookmark = [url bookmarkDataWithOptions:NSURLBookmarkCreationMinimalBookmark
includingResourceValuesForKeys:NULL
relativeToURL:NULL
error:NULL];
return bookmark;
}
- (NSURL *)urlFromBookmark:(NSData *)bookmark {
NSURL *url = [NSURL URLByResolvingBookmarkData:bookmark
options:NSURLBookmarkResolutionWithoutUI
relativeToURL:NULL
bookmarkDataIsStale:NO
error:NULL];
return url;
}
From https://github.com/ptrsghr/FileWatcher/blob/master/FileWatcherExample/Classes/FileWatcher.m